Mercurial > hg > nginx
comparison src/http/modules/ngx_http_status_handler.c @ 369:9c2515d70489
nginx-0.0.7-2004-06-25-18:42:03 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Fri, 25 Jun 2004 14:42:03 +0000 |
parents | 15c84a40e87d |
children | 6f3b20c1ac50 |
comparison
equal
deleted
inserted
replaced
368:15c84a40e87d | 369:9c2515d70489 |
---|---|
2 #include <ngx_config.h> | 2 #include <ngx_config.h> |
3 #include <ngx_core.h> | 3 #include <ngx_core.h> |
4 #include <ngx_http.h> | 4 #include <ngx_http.h> |
5 | 5 |
6 | 6 |
7 static char *ngx_http_status(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); | 7 typedef struct { |
8 ngx_http_request_t *request; | |
9 ngx_pool_t *pool; | |
10 ngx_chain_t *head; | |
11 ngx_buf_t *last; | |
12 size_t size; | |
13 } ngx_http_status_ctx_t; | |
14 | |
15 | |
16 static ngx_int_t ngx_http_status(ngx_http_status_ctx_t *ctx); | |
17 static char *ngx_http_set_status(ngx_conf_t *cf, ngx_command_t *cmd, | |
18 void *conf); | |
8 | 19 |
9 static ngx_command_t ngx_http_status_commands[] = { | 20 static ngx_command_t ngx_http_status_commands[] = { |
10 | 21 |
11 { ngx_string("status"), | 22 { ngx_string("status"), |
12 NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | 23 NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
13 ngx_http_status, | 24 ngx_http_set_status, |
14 0, | 25 0, |
15 0, | 26 0, |
16 NULL }, | 27 NULL }, |
17 | 28 |
18 ngx_null_command | 29 ngx_null_command |
44 }; | 55 }; |
45 | 56 |
46 | 57 |
47 static ngx_int_t ngx_http_status_handler(ngx_http_request_t *r) | 58 static ngx_int_t ngx_http_status_handler(ngx_http_request_t *r) |
48 { | 59 { |
49 u_char ch; | 60 ngx_int_t rc; |
50 size_t len; | 61 ngx_http_status_ctx_t ctx; |
51 ngx_int_t rc; | |
52 ngx_uint_t i, dash; | |
53 ngx_buf_t *b; | |
54 ngx_chain_t out; | |
55 ngx_connection_t *c; | |
56 ngx_http_request_t *rq; | |
57 | 62 |
58 if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) { | 63 if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) { |
59 return NGX_HTTP_NOT_ALLOWED; | 64 return NGX_HTTP_NOT_ALLOWED; |
60 } | 65 } |
61 | 66 |
84 if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { | 89 if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { |
85 return rc; | 90 return rc; |
86 } | 91 } |
87 } | 92 } |
88 | 93 |
89 len = 0; | 94 ctx.request = r; |
95 ctx.pool = r->pool; | |
96 ctx.head = NULL; | |
97 ctx.size = 0; | |
98 | |
99 if (ngx_http_status(&ctx) != NGX_OK) { | |
100 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
101 } | |
102 | |
103 r->headers_out.status = NGX_HTTP_OK; | |
104 r->headers_out.content_length_n = ctx.size; | |
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 if (!r->main) { | |
113 ctx.last->last_buf = 1; | |
114 } | |
115 | |
116 return ngx_http_output_filter(r, ctx.head); | |
117 } | |
118 | |
119 | |
120 static ngx_int_t ngx_http_status(ngx_http_status_ctx_t *ctx) | |
121 { | |
122 u_char ch; | |
123 size_t len, n; | |
124 ngx_uint_t i, dash; | |
125 ngx_buf_t *b; | |
126 ngx_chain_t *cl, **ll; | |
127 ngx_connection_t *c; | |
128 ngx_http_request_t *r; | |
129 ngx_http_core_main_conf_t *cmcf; | |
130 | |
131 cmcf = ngx_http_get_module_main_conf(ctx->request, ngx_http_core_module); | |
132 | |
133 #if (NGX_SUPPRESS_WARN) | |
134 b = NULL; | |
135 ll = NULL; | |
136 #endif | |
137 | |
90 dash = 0; | 138 dash = 0; |
139 | |
140 /* TODO: old connections */ | |
91 | 141 |
92 c = ngx_cycle->connections; | 142 c = ngx_cycle->connections; |
93 for (i = 0; i < ngx_cycle->connection_n; i++) { | 143 for (i = 0; i < ngx_cycle->connection_n; i++) { |
94 rq = c[i].data; | 144 |
95 if (rq && rq->signature == NGX_HTTP_MODULE) { | 145 /* TODO: trylock connection mutex */ |
146 | |
147 r = c[i].data; | |
148 if (r && r->signature == NGX_HTTP_MODULE) { | |
96 | 149 |
97 /* STUB: should be NGX_PID_T_LEN */ | 150 /* STUB: should be NGX_PID_T_LEN */ |
98 len += NGX_INT64_LEN /* pid */ | 151 len = NGX_INT64_LEN /* pid */ |
99 + 1 + NGX_INT32_LEN /* connection */ | 152 + 1 + NGX_INT32_LEN /* connection */ |
100 + 1 + 1 /* state */ | 153 + 1 + 1 /* state */ |
101 + 1 + c[i].addr_text.len | 154 + 1 + INET_ADDRSTRLEN |
102 + 1 + rq->server_name->len | 155 + 1 + (r->server_name ? cmcf->max_server_name_len : 1) |
103 + 2; /* "\r\n" */ | 156 + 2; /* "\r\n" */ |
104 | 157 |
105 if (rq->request_line.len) { | 158 if (r->request_line.len) { |
106 len += 1 + rq->request_line.len + 2; | 159 len += 1 + 1 + r->request_line.len + 1; |
107 } | 160 } |
108 | 161 |
109 dash = 0; | 162 if (!(b = ngx_create_temp_buf(ctx->pool, len))) { |
110 | 163 /* TODO: unlock mutex */ |
111 continue; | 164 return NGX_ERROR; |
112 } | 165 } |
113 | |
114 if (!dash) { | |
115 len += 3; | |
116 dash = 1; | |
117 } | |
118 } | |
119 | |
120 if (!(b = ngx_create_temp_buf(r->pool, len))) { | |
121 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
122 } | |
123 | |
124 dash = 0; | |
125 | |
126 for (i = 0; i < ngx_cycle->connection_n; i++) { | |
127 rq = c[i].data; | |
128 if (rq && rq->signature == NGX_HTTP_MODULE) { | |
129 | 166 |
130 b->last += ngx_snprintf((char *) b->last, | 167 b->last += ngx_snprintf((char *) b->last, |
131 /* STUB: should be NGX_PID_T_LEN */ | 168 /* STUB: should be NGX_PID_T_LEN */ |
132 NGX_INT64_LEN + NGX_INT32_LEN, | 169 NGX_INT64_LEN + NGX_INT32_LEN, |
133 PID_T_FMT " %u", ngx_pid, i); | 170 PID_T_FMT " %4u", ngx_pid, i); |
134 | 171 |
135 switch (rq->http_state) { | 172 switch (r->http_state) { |
136 case NGX_HTTP_INITING_REQUEST_STATE: | 173 case NGX_HTTP_INITING_REQUEST_STATE: |
137 ch = 'I'; | 174 ch = 'I'; |
138 break; | 175 break; |
139 | 176 |
140 case NGX_HTTP_READING_REQUEST_STATE: | 177 case NGX_HTTP_READING_REQUEST_STATE: |
161 *(b->last++) = ch; | 198 *(b->last++) = ch; |
162 | 199 |
163 *(b->last++) = ' '; | 200 *(b->last++) = ' '; |
164 b->last = ngx_cpymem(b->last, c[i].addr_text.data, | 201 b->last = ngx_cpymem(b->last, c[i].addr_text.data, |
165 c[i].addr_text.len); | 202 c[i].addr_text.len); |
203 for (n = c[i].addr_text.len; n < INET_ADDRSTRLEN; n++) { | |
204 *(b->last++) = ' '; | |
205 } | |
166 | 206 |
167 *(b->last++) = ' '; | 207 *(b->last++) = ' '; |
168 b->last = ngx_cpymem(b->last, rq->server_name->data, | 208 if (r->server_name) { |
169 rq->server_name->len); | 209 b->last = ngx_cpymem(b->last, r->server_name->data, |
170 | 210 r->server_name->len); |
171 if (rq->request_line.len) { | 211 for (n = r->server_name->len; |
212 n < cmcf->max_server_name_len; | |
213 n++) | |
214 { | |
215 *(b->last++) = ' '; | |
216 } | |
217 | |
218 } else { | |
219 *(b->last++) = '?'; | |
220 } | |
221 | |
222 if (r->request_line.len) { | |
172 *(b->last++) = ' '; | 223 *(b->last++) = ' '; |
173 *(b->last++) = '"'; | 224 *(b->last++) = '"'; |
174 b->last = ngx_cpymem(b->last, r->request_line.data, | 225 b->last = ngx_cpymem(b->last, r->request_line.data, |
175 r->request_line.len); | 226 r->request_line.len); |
176 *(b->last++) = '"'; | 227 *(b->last++) = '"'; |
179 | 230 |
180 *(b->last++) = CR; *(b->last++) = LF; | 231 *(b->last++) = CR; *(b->last++) = LF; |
181 | 232 |
182 dash = 0; | 233 dash = 0; |
183 | 234 |
235 } else if (c[i].fd != -1) { | |
236 len = NGX_INT64_LEN /* pid */ | |
237 + 1 + NGX_INT32_LEN /* connection */ | |
238 + 1 + 1 /* state */ | |
239 + 2; /* "\r\n" */ | |
240 | |
241 if (!(b = ngx_create_temp_buf(ctx->pool, len))) { | |
242 /* TODO: unlock mutex */ | |
243 return NGX_ERROR; | |
244 } | |
245 | |
246 b->last += ngx_snprintf((char *) b->last, | |
247 /* STUB: should be NGX_PID_T_LEN */ | |
248 NGX_INT64_LEN + NGX_INT32_LEN, | |
249 PID_T_FMT " %4u", ngx_pid, i); | |
250 | |
251 *(b->last++) = ' '; | |
252 *(b->last++) = 's'; | |
253 | |
254 *(b->last++) = CR; *(b->last++) = LF; | |
255 | |
256 dash = 0; | |
257 | |
258 } else if (!dash) { | |
259 len = 3; | |
260 | |
261 if (!(b = ngx_create_temp_buf(ctx->pool, len))) { | |
262 /* TODO: unlock mutex */ | |
263 return NGX_ERROR; | |
264 } | |
265 | |
266 *(b->last++) = '-'; *(b->last++) = CR; *(b->last++) = LF; | |
267 | |
268 dash = 1; | |
269 | |
270 } else { | |
184 continue; | 271 continue; |
185 } | 272 } |
186 | 273 |
187 if (!dash) { | 274 /* TODO: unlock mutex */ |
188 *(b->last++) = '-'; *(b->last++) = CR; *(b->last++) = LF; | 275 |
189 dash = 1; | 276 if (!(cl = ngx_alloc_chain_link(ctx->pool))) { |
277 return NGX_ERROR; | |
190 } | 278 } |
191 } | 279 |
192 | 280 if (ctx->head) { |
193 r->headers_out.status = NGX_HTTP_OK; | 281 *ll = cl; |
194 r->headers_out.content_length_n = b->last - b->pos; | 282 |
195 | 283 } else { |
196 rc = ngx_http_send_header(r); | 284 ctx->head = cl; |
197 | 285 } |
198 if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { | 286 |
199 return rc; | 287 cl->buf = b; |
200 } | 288 cl->next = NULL; |
201 | 289 ll = &cl->next; |
202 if (!r->main) { | 290 |
203 b->last_buf = 1; | 291 ctx->size += b->last - b->pos; |
204 } | 292 } |
205 | 293 |
206 out.buf = b; | 294 ctx->last = b; |
207 out.next = NULL; | 295 |
208 | 296 return NGX_OK; |
209 return ngx_http_output_filter(r, &out); | |
210 } | 297 } |
211 | 298 |
212 | 299 |
213 static char *ngx_http_status(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 300 static char *ngx_http_set_status(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
214 { | 301 { |
215 ngx_http_conf_ctx_t *ctx; | 302 ngx_http_conf_ctx_t *ctx; |
216 ngx_http_core_loc_conf_t *clcf; | 303 ngx_http_core_loc_conf_t *clcf; |
217 | 304 |
218 ctx = cf->ctx; | 305 ctx = cf->ctx; |