Mercurial > hg > nginx
comparison src/http/modules/ngx_http_status_module.c @ 501:d4ea69372b94 release-0.1.25
nginx-0.1.25-RELEASE import
*) Bugfix: nginx did run on Linux parisc.
*) Feature: nginx now does not start under FreeBSD if the sysctl
kern.ipc.somaxconn value is too big.
*) Bugfix: if a request was internally redirected by the
ngx_http_index_module module to the ngx_http_proxy_module or
ngx_http_fastcgi_module modules, then the index file was not closed
after request completion.
*) Feature: the "proxy_pass" can be used in location with regular
expression.
*) Feature: the ngx_http_rewrite_filter_module module supports the
condition like "if ($HTTP_USER_AGENT ~ MSIE)".
*) Bugfix: nginx started too slow if the large number of addresses and
text values were used in the "geo" directive.
*) Change: a variable name must be declared as "$name" in the "geo"
directive. The previous variant without "$" is still supported, but
will be removed soon.
*) Feature: the "%{VARIABLE}v" logging parameter.
*) Feature: the "set $name value" directive.
*) Bugfix: gcc 4.0 compatibility.
*) Feature: the --with-openssl-opt=OPTIONS autoconfiguration directive.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Sat, 19 Mar 2005 12:38:37 +0000 |
parents | src/http/modules/ngx_http_status_handler.c@a88a3e4e158f |
children | 4d9ea73a627a |
comparison
equal
deleted
inserted
replaced
500:9a0f304470f5 | 501:d4ea69372b94 |
---|---|
1 | |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4 */ | |
5 | |
6 | |
7 #include <ngx_config.h> | |
8 #include <ngx_core.h> | |
9 #include <ngx_http.h> | |
10 | |
11 | |
12 typedef struct { | |
13 ngx_http_request_t *request; | |
14 ngx_pool_t *pool; | |
15 ngx_chain_t *head; | |
16 ngx_buf_t *last; | |
17 size_t size; | |
18 } ngx_http_status_ctx_t; | |
19 | |
20 | |
21 static ngx_int_t ngx_http_status(ngx_http_status_ctx_t *ctx); | |
22 static char *ngx_http_set_status(ngx_conf_t *cf, ngx_command_t *cmd, | |
23 void *conf); | |
24 | |
25 static ngx_command_t ngx_http_status_commands[] = { | |
26 | |
27 { ngx_string("status"), | |
28 NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | |
29 ngx_http_set_status, | |
30 0, | |
31 0, | |
32 NULL }, | |
33 | |
34 ngx_null_command | |
35 }; | |
36 | |
37 | |
38 | |
39 ngx_http_module_t ngx_http_status_module_ctx = { | |
40 NULL, /* pre conf */ | |
41 | |
42 NULL, /* create main configuration */ | |
43 NULL, /* init main configuration */ | |
44 | |
45 NULL, /* create server configuration */ | |
46 NULL, /* merge server configuration */ | |
47 | |
48 NULL, /* create location configuration */ | |
49 NULL /* merge location configuration */ | |
50 }; | |
51 | |
52 | |
53 ngx_module_t ngx_http_status_module = { | |
54 NGX_MODULE, | |
55 &ngx_http_status_module_ctx, /* module context */ | |
56 ngx_http_status_commands, /* module directives */ | |
57 NGX_HTTP_MODULE, /* module type */ | |
58 NULL, /* init module */ | |
59 NULL /* init process */ | |
60 }; | |
61 | |
62 | |
63 static ngx_int_t ngx_http_status_handler(ngx_http_request_t *r) | |
64 { | |
65 ngx_int_t rc; | |
66 ngx_http_status_ctx_t ctx; | |
67 | |
68 if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) { | |
69 return NGX_HTTP_NOT_ALLOWED; | |
70 } | |
71 | |
72 rc = ngx_http_discard_body(r); | |
73 | |
74 if (rc != NGX_OK && rc != NGX_AGAIN) { | |
75 return rc; | |
76 } | |
77 | |
78 r->headers_out.content_type = ngx_list_push(&r->headers_out.headers); | |
79 if (r->headers_out.content_type == NULL) { | |
80 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
81 } | |
82 | |
83 r->headers_out.content_type->key.len = 0; | |
84 r->headers_out.content_type->key.data = NULL; | |
85 r->headers_out.content_type->value.len = sizeof("text/plain") - 1; | |
86 r->headers_out.content_type->value.data = (u_char *) "text/plain"; | |
87 | |
88 if (r->method == NGX_HTTP_HEAD) { | |
89 r->headers_out.status = NGX_HTTP_OK; | |
90 | |
91 rc = ngx_http_send_header(r); | |
92 | |
93 if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { | |
94 return rc; | |
95 } | |
96 } | |
97 | |
98 ctx.request = r; | |
99 ctx.pool = r->pool; | |
100 ctx.head = NULL; | |
101 ctx.size = 0; | |
102 | |
103 if (ngx_http_status(&ctx) != NGX_OK) { | |
104 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
105 } | |
106 | |
107 r->headers_out.status = NGX_HTTP_OK; | |
108 r->headers_out.content_length_n = ctx.size; | |
109 | |
110 rc = ngx_http_send_header(r); | |
111 | |
112 if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { | |
113 return rc; | |
114 } | |
115 | |
116 if (!r->main) { | |
117 ctx.last->last_buf = 1; | |
118 } | |
119 | |
120 return ngx_http_output_filter(r, ctx.head); | |
121 } | |
122 | |
123 | |
124 static ngx_int_t ngx_http_status(ngx_http_status_ctx_t *ctx) | |
125 { | |
126 u_char ch; | |
127 size_t len, n; | |
128 ngx_uint_t i, dash; | |
129 ngx_buf_t *b; | |
130 ngx_chain_t *cl, **ll; | |
131 ngx_connection_t *c; | |
132 ngx_http_request_t *r; | |
133 ngx_http_core_main_conf_t *cmcf; | |
134 | |
135 cmcf = ngx_http_get_module_main_conf(ctx->request, ngx_http_core_module); | |
136 | |
137 #if (NGX_SUPPRESS_WARN) | |
138 b = NULL; | |
139 ll = NULL; | |
140 #endif | |
141 | |
142 dash = 0; | |
143 | |
144 /* TODO: old connections */ | |
145 | |
146 c = ngx_cycle->connections; | |
147 for (i = 0; i < ngx_cycle->connection_n; i++) { | |
148 | |
149 /* TODO: trylock connection mutex */ | |
150 | |
151 r = c[i].data; | |
152 if (r && r->signature == NGX_HTTP_MODULE) { | |
153 | |
154 /* STUB: should be NGX_PID_T_LEN */ | |
155 len = NGX_INT64_LEN /* pid */ | |
156 + 1 + NGX_INT32_LEN /* connection */ | |
157 + 1 + 1 /* state */ | |
158 + 1 + INET_ADDRSTRLEN | |
159 + 1 + (r->server_name ? cmcf->max_server_name_len : 1) | |
160 + 2; /* "\r\n" */ | |
161 | |
162 /* BUG: cmcf->max_server_name_len and "*.domain.tld" */ | |
163 | |
164 | |
165 if (r->request_line.len) { | |
166 len += 1 + 1 + r->request_line.len + 1; | |
167 } | |
168 | |
169 if (!(b = ngx_create_temp_buf(ctx->pool, len))) { | |
170 /* TODO: unlock mutex */ | |
171 return NGX_ERROR; | |
172 } | |
173 | |
174 b->last = ngx_sprintf(b->last, "%P %5ui", ngx_pid, i); | |
175 | |
176 switch (r->http_state) { | |
177 case NGX_HTTP_INITING_REQUEST_STATE: | |
178 ch = 'I'; | |
179 break; | |
180 | |
181 case NGX_HTTP_READING_REQUEST_STATE: | |
182 ch = 'R'; | |
183 break; | |
184 | |
185 case NGX_HTTP_PROCESS_REQUEST_STATE: | |
186 ch = 'P'; | |
187 break; | |
188 | |
189 case NGX_HTTP_WRITING_REQUEST_STATE: | |
190 ch = 'W'; | |
191 break; | |
192 | |
193 case NGX_HTTP_KEEPALIVE_STATE: | |
194 ch = 'K'; | |
195 break; | |
196 | |
197 default: | |
198 ch = '?'; | |
199 } | |
200 | |
201 *(b->last++) = ' '; | |
202 *(b->last++) = ch; | |
203 | |
204 *(b->last++) = ' '; | |
205 b->last = ngx_cpymem(b->last, c[i].addr_text.data, | |
206 c[i].addr_text.len); | |
207 for (n = c[i].addr_text.len; n < INET_ADDRSTRLEN; n++) { | |
208 *(b->last++) = ' '; | |
209 } | |
210 | |
211 *(b->last++) = ' '; | |
212 if (r->server_name) { | |
213 b->last = ngx_cpymem(b->last, r->server_name->data, | |
214 r->server_name->len); | |
215 for (n = r->server_name->len; | |
216 n < cmcf->max_server_name_len; | |
217 n++) | |
218 { | |
219 *(b->last++) = ' '; | |
220 } | |
221 | |
222 } else { | |
223 *(b->last++) = '?'; | |
224 } | |
225 | |
226 if (r->request_line.len) { | |
227 *(b->last++) = ' '; | |
228 *(b->last++) = '"'; | |
229 b->last = ngx_cpymem(b->last, r->request_line.data, | |
230 r->request_line.len); | |
231 *(b->last++) = '"'; | |
232 | |
233 } | |
234 | |
235 *(b->last++) = CR; *(b->last++) = LF; | |
236 | |
237 dash = 0; | |
238 | |
239 } else if (c[i].fd != -1) { | |
240 len = NGX_INT64_LEN /* pid */ | |
241 + 1 + NGX_INT32_LEN /* connection */ | |
242 + 1 + 1 /* state */ | |
243 + 2; /* "\r\n" */ | |
244 | |
245 if (!(b = ngx_create_temp_buf(ctx->pool, len))) { | |
246 /* TODO: unlock mutex */ | |
247 return NGX_ERROR; | |
248 } | |
249 | |
250 b->last = ngx_sprintf(b->last, "%P %5ui", ngx_pid, i); | |
251 | |
252 *(b->last++) = ' '; | |
253 *(b->last++) = 's'; | |
254 | |
255 *(b->last++) = CR; *(b->last++) = LF; | |
256 | |
257 dash = 0; | |
258 | |
259 } else if (!dash) { | |
260 len = 3; | |
261 | |
262 if (!(b = ngx_create_temp_buf(ctx->pool, len))) { | |
263 /* TODO: unlock mutex */ | |
264 return NGX_ERROR; | |
265 } | |
266 | |
267 *(b->last++) = '-'; *(b->last++) = CR; *(b->last++) = LF; | |
268 | |
269 dash = 1; | |
270 | |
271 } else { | |
272 continue; | |
273 } | |
274 | |
275 /* TODO: unlock mutex */ | |
276 | |
277 if (!(cl = ngx_alloc_chain_link(ctx->pool))) { | |
278 return NGX_ERROR; | |
279 } | |
280 | |
281 if (ctx->head) { | |
282 *ll = cl; | |
283 | |
284 } else { | |
285 ctx->head = cl; | |
286 } | |
287 | |
288 cl->buf = b; | |
289 cl->next = NULL; | |
290 ll = &cl->next; | |
291 | |
292 ctx->size += b->last - b->pos; | |
293 } | |
294 | |
295 ctx->last = b; | |
296 | |
297 return NGX_OK; | |
298 } | |
299 | |
300 | |
301 static char *ngx_http_set_status(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
302 { | |
303 ngx_http_core_loc_conf_t *clcf; | |
304 | |
305 clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); | |
306 clcf->handler = ngx_http_status_handler; | |
307 | |
308 return NGX_CONF_OK; | |
309 } |