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;