Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ngx_http_stub_status_module.c
Go to the documentation of this file.
1 
2 /*
3  * Copyright (C) Igor Sysoev
4  * Copyright (C) Nginx, Inc.
5  */
6 
7 
8 #include <ngx_config.h>
9 #include <ngx_core.h>
10 #include <ngx_http.h>
11 
12 
13 static ngx_int_t ngx_http_stub_status_variable(ngx_http_request_t *r,
14  ngx_http_variable_value_t *v, uintptr_t data);
15 static ngx_int_t ngx_http_stub_status_add_variables(ngx_conf_t *cf);
16 
17 static char *ngx_http_set_status(ngx_conf_t *cf, ngx_command_t *cmd,
18  void *conf);
19 
20 static ngx_command_t ngx_http_status_commands[] = {
21 
22  { ngx_string("stub_status"),
24  ngx_http_set_status,
25  0,
26  0,
27  NULL },
28 
30 };
31 
32 
33 
34 static ngx_http_module_t ngx_http_stub_status_module_ctx = {
35  ngx_http_stub_status_add_variables, /* preconfiguration */
36  NULL, /* postconfiguration */
37 
38  NULL, /* create main configuration */
39  NULL, /* init main configuration */
40 
41  NULL, /* create server configuration */
42  NULL, /* merge server configuration */
43 
44  NULL, /* create location configuration */
45  NULL /* merge location configuration */
46 };
47 
48 
51  &ngx_http_stub_status_module_ctx, /* module context */
52  ngx_http_status_commands, /* module directives */
53  NGX_HTTP_MODULE, /* module type */
54  NULL, /* init master */
55  NULL, /* init module */
56  NULL, /* init process */
57  NULL, /* init thread */
58  NULL, /* exit thread */
59  NULL, /* exit process */
60  NULL, /* exit master */
62 };
63 
64 
65 static ngx_http_variable_t ngx_http_stub_status_vars[] = {
66 
67  { ngx_string("connections_active"), NULL, ngx_http_stub_status_variable,
69 
70  { ngx_string("connections_reading"), NULL, ngx_http_stub_status_variable,
72 
73  { ngx_string("connections_writing"), NULL, ngx_http_stub_status_variable,
75 
76  { ngx_string("connections_waiting"), NULL, ngx_http_stub_status_variable,
78 
79  { ngx_null_string, NULL, NULL, 0, 0, 0 }
80 };
81 
82 
83 static ngx_int_t ngx_http_status_handler(ngx_http_request_t *r)
84 {
85  size_t size;
86  ngx_int_t rc;
87  ngx_buf_t *b;
88  ngx_chain_t out;
89  ngx_atomic_int_t ap, hn, ac, rq, rd, wr, wa;
90 
91  if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) {
92  return NGX_HTTP_NOT_ALLOWED;
93  }
94 
96 
97  if (rc != NGX_OK) {
98  return rc;
99  }
100 
101  ngx_str_set(&r->headers_out.content_type, "text/plain");
102 
103  if (r->method == NGX_HTTP_HEAD) {
105 
106  rc = ngx_http_send_header(r);
107 
108  if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
109  return rc;
110  }
111  }
112 
113  size = sizeof("Active connections: \n") + NGX_ATOMIC_T_LEN
114  + sizeof("server accepts handled requests\n") - 1
115  + 6 + 3 * NGX_ATOMIC_T_LEN
116  + sizeof("Reading: Writing: Waiting: \n") + 3 * NGX_ATOMIC_T_LEN;
117 
118  b = ngx_create_temp_buf(r->pool, size);
119  if (b == NULL) {
121  }
122 
123  out.buf = b;
124  out.next = NULL;
125 
126  ap = *ngx_stat_accepted;
127  hn = *ngx_stat_handled;
128  ac = *ngx_stat_active;
129  rq = *ngx_stat_requests;
130  rd = *ngx_stat_reading;
131  wr = *ngx_stat_writing;
132  wa = *ngx_stat_waiting;
133 
134  b->last = ngx_sprintf(b->last, "Active connections: %uA \n", ac);
135 
136  b->last = ngx_cpymem(b->last, "server accepts handled requests\n",
137  sizeof("server accepts handled requests\n") - 1);
138 
139  b->last = ngx_sprintf(b->last, " %uA %uA %uA \n", ap, hn, rq);
140 
141  b->last = ngx_sprintf(b->last, "Reading: %uA Writing: %uA Waiting: %uA \n",
142  rd, wr, wa);
143 
145  r->headers_out.content_length_n = b->last - b->pos;
146 
147  b->last_buf = (r == r->main) ? 1 : 0;
148 
149  rc = ngx_http_send_header(r);
150 
151  if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
152  return rc;
153  }
154 
155  return ngx_http_output_filter(r, &out);
156 }
157 
158 
159 static ngx_int_t
160 ngx_http_stub_status_variable(ngx_http_request_t *r,
161  ngx_http_variable_value_t *v, uintptr_t data)
162 {
163  u_char *p;
164  ngx_atomic_int_t value;
165 
167  if (p == NULL) {
168  return NGX_ERROR;
169  }
170 
171  switch (data) {
172  case 0:
173  value = *ngx_stat_active;
174  break;
175 
176  case 1:
177  value = *ngx_stat_reading;
178  break;
179 
180  case 2:
181  value = *ngx_stat_writing;
182  break;
183 
184  case 3:
185  value = *ngx_stat_waiting;
186  break;
187 
188  /* suppress warning */
189  default:
190  value = 0;
191  break;
192  }
193 
194  v->len = ngx_sprintf(p, "%uA", value) - p;
195  v->valid = 1;
196  v->no_cacheable = 0;
197  v->not_found = 0;
198  v->data = p;
199 
200  return NGX_OK;
201 }
202 
203 
204 static ngx_int_t
205 ngx_http_stub_status_add_variables(ngx_conf_t *cf)
206 {
207  ngx_http_variable_t *var, *v;
208 
209  for (v = ngx_http_stub_status_vars; v->name.len; v++) {
210  var = ngx_http_add_variable(cf, &v->name, v->flags);
211  if (var == NULL) {
212  return NGX_ERROR;
213  }
214 
215  var->get_handler = v->get_handler;
216  var->data = v->data;
217  }
218 
219  return NGX_OK;
220 }
221 
222 
223 static char *ngx_http_set_status(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
224 {
226 
228  clcf->handler = ngx_http_status_handler;
229 
230  return NGX_CONF_OK;
231 }