Mercurial > hg > nginx
comparison src/http/ngx_http_event.c @ 12:055ed05235ae
nginx-0.0.1-2002-09-13-18:47:42 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Fri, 13 Sep 2002 14:47:42 +0000 |
parents | f323b4f74e4a |
children | 2aba961a1d34 |
comparison
equal
deleted
inserted
replaced
11:f323b4f74e4a | 12:055ed05235ae |
---|---|
1 /* | |
2 TODO Win32 inet_ntoa | |
3 ngx_inet_ntop | |
4 */ | |
1 | 5 |
2 #include <ngx_config.h> | 6 #include <ngx_config.h> |
3 #include <ngx_core.h> | 7 #include <ngx_core.h> |
4 #include <ngx_string.h> | 8 #include <ngx_string.h> |
5 #include <ngx_files.h> | 9 #include <ngx_files.h> |
34 | 38 |
35 static int ngx_http_handler(ngx_http_request_t *r); | 39 static int ngx_http_handler(ngx_http_request_t *r); |
36 static int ngx_http_set_default_handler(ngx_http_request_t *r); | 40 static int ngx_http_set_default_handler(ngx_http_request_t *r); |
37 | 41 |
38 static int ngx_http_writer(ngx_event_t *ev); | 42 static int ngx_http_writer(ngx_event_t *ev); |
39 | 43 static int ngx_http_keepalive_handler(ngx_event_t *ev); |
40 static int ngx_http_lingering_close(ngx_event_t *ev); | 44 static int ngx_http_lingering_close(ngx_event_t *ev); |
41 | 45 |
42 static int ngx_http_special_response(ngx_http_request_t *r, int error); | 46 static int ngx_http_special_response(ngx_http_request_t *r, int error); |
43 static int ngx_http_redirect(ngx_http_request_t *r, int redirect); | 47 static int ngx_http_redirect(ngx_http_request_t *r, int redirect); |
44 static int ngx_http_error(ngx_http_request_t *r, int error); | 48 static int ngx_http_error(ngx_http_request_t *r, int error); |
45 | 49 |
46 static int ngx_http_close_request(ngx_http_request_t *r); | 50 static int ngx_http_close_request(ngx_http_request_t *r); |
47 static size_t ngx_http_log_error(void *data, char *buf, size_t len); | 51 static size_t ngx_http_log_error(void *data, char *buf, size_t len); |
48 | 52 |
49 | 53 |
50 /* STUB */ | |
51 static int ngx_http_writer(ngx_event_t *ev); | |
52 | |
53 | 54 |
54 static char *header_errors[] = { | 55 static char *header_errors[] = { |
55 "client %s sent invalid method", | 56 "client %s sent invalid method", |
56 "client %s sent invalid request", | 57 "client %s sent invalid request", |
58 "client %s sent too long URI", | |
57 "client %s sent HEAD method in HTTP/0.9 request" | 59 "client %s sent HEAD method in HTTP/0.9 request" |
58 }; | 60 }; |
59 | 61 |
60 | 62 |
61 | 63 |
66 ngx_http_log_ctx_t *ctx; | 68 ngx_http_log_ctx_t *ctx; |
67 | 69 |
68 ev = c->read; | 70 ev = c->read; |
69 ev->event_handler = ngx_http_init_request; | 71 ev->event_handler = ngx_http_init_request; |
70 | 72 |
71 /* TODO: connection's pool size */ | 73 ngx_test_null(c->pool, |
72 ngx_test_null(c->pool, ngx_create_pool(1024, ev->log), NGX_ERROR); | 74 ngx_create_pool(srv->connection_pool_size, ev->log), |
75 NGX_ERROR); | |
73 | 76 |
74 ngx_test_null(addr, ngx_palloc(c->pool, c->socklen), NGX_ERROR); | 77 ngx_test_null(addr, ngx_palloc(c->pool, c->socklen), NGX_ERROR); |
75 ngx_memcpy(addr, c->sockaddr, c->socklen); | 78 ngx_memcpy(addr, c->sockaddr, c->socklen); |
76 c->sockaddr = addr; | 79 c->sockaddr = addr; |
77 | 80 |
78 ngx_test_null(c->addr_text, ngx_palloc(c->pool, c->addr_textlen), | 81 ngx_test_null(c->addr_text, ngx_palloc(c->pool, c->addr_textlen), |
79 NGX_ERROR); | 82 NGX_ERROR); |
80 #if (WIN32) | 83 #if (WIN32) |
81 /* | |
82 c->addr_text = inet_ntoa((struct in_addr) ((char *)c->sockaddr + c->addr)); | 84 c->addr_text = inet_ntoa((struct in_addr) ((char *)c->sockaddr + c->addr)); |
83 */ | |
84 c->addr_text = NULL; | |
85 #else | 85 #else |
86 inet_ntop(c->family, (char *)c->sockaddr + c->addr, | 86 inet_ntop(c->family, (char *)c->sockaddr + c->addr, |
87 c->addr_text, c->addr_textlen); | 87 c->addr_text, c->addr_textlen); |
88 #endif | 88 #endif |
89 | 89 |
119 } | 119 } |
120 #endif | 120 #endif |
121 } | 121 } |
122 | 122 |
123 | 123 |
124 int ngx_http_init_request(ngx_event_t *ev) | 124 static int ngx_http_init_request(ngx_event_t *ev) |
125 { | 125 { |
126 ngx_connection_t *c; | 126 ngx_connection_t *c; |
127 ngx_http_server_t *srv; | 127 ngx_http_server_t *srv; |
128 ngx_http_request_t *r; | 128 ngx_http_request_t *r; |
129 | 129 |
130 c = (ngx_connection_t *) ev->data; | 130 c = (ngx_connection_t *) ev->data; |
131 srv = (ngx_http_server_t *) c->server; | 131 srv = (ngx_http_server_t *) c->server; |
132 | 132 |
133 if (c->buffer == NULL) { | |
134 ngx_test_null(c->buffer, | |
135 ngx_create_temp_hunk(c->pool, srv->header_buffer_size, | |
136 0, 0), | |
137 NGX_ERROR); | |
138 } else { | |
139 c->buffer->pos.mem = c->buffer->last.mem = c->buffer->start; | |
140 } | |
141 | |
133 ngx_test_null(r, ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)), | 142 ngx_test_null(r, ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)), |
134 NGX_ERROR); | 143 NGX_ERROR); |
135 | 144 |
136 c->data = r; | 145 c->data = r; |
137 r->connection = c; | 146 r->connection = c; |
138 r->server = srv; | 147 r->server = srv; |
148 r->header_in = c->buffer; | |
139 | 149 |
140 r->srv_conf = ngx_srv_conf; | 150 r->srv_conf = ngx_srv_conf; |
141 r->loc_conf = ngx_loc_conf; | 151 r->loc_conf = ngx_loc_conf; |
142 | 152 |
143 ngx_test_null(r->pool, ngx_create_pool(srv->request_pool_size, ev->log), | 153 ngx_test_null(r->pool, ngx_create_pool(srv->request_pool_size, ev->log), |
144 ngx_http_close_request(r)); | 154 ngx_http_close_request(r)); |
145 | 155 |
146 ngx_test_null(r->ctx, ngx_pcalloc(r->pool, sizeof(void *) * ngx_max_module), | 156 ngx_test_null(r->ctx, ngx_pcalloc(r->pool, sizeof(void *) * ngx_max_module), |
147 ngx_http_close_request(r)); | |
148 | |
149 ngx_test_null(r->header_in, | |
150 ngx_create_temp_hunk(r->pool, srv->header_buffer_size, 0, 0), | |
151 ngx_http_close_request(r)); | 157 ngx_http_close_request(r)); |
152 | 158 |
153 ev->event_handler = ngx_http_process_request; | 159 ev->event_handler = ngx_http_process_request; |
154 r->state_handler = ngx_http_process_request_line; | 160 r->state_handler = ngx_http_process_request_line; |
155 r->process_header = 1; | 161 r->process_header = 1; |
162 r->header_timeout = 1; | |
156 | 163 |
157 return ngx_http_process_request(ev); | 164 return ngx_http_process_request(ev); |
158 } | 165 } |
159 | 166 |
160 | 167 |
161 static int ngx_http_process_request(ngx_event_t *ev) | 168 static int ngx_http_process_request(ngx_event_t *ev) |
162 { | 169 { |
163 int n, rc; | 170 int n, rc; |
164 ngx_connection_t *c ; | 171 ngx_connection_t *c ; |
165 ngx_http_request_t *r; | 172 ngx_http_request_t *r; |
173 ngx_http_log_ctx_t *ctx; | |
166 | 174 |
167 c = (ngx_connection_t *) ev->data; | 175 c = (ngx_connection_t *) ev->data; |
168 r = (ngx_http_request_t *) c->data; | 176 r = (ngx_http_request_t *) c->data; |
169 | 177 |
170 ngx_log_debug(ev->log, "http process request"); | 178 ngx_log_debug(ev->log, "http process request"); |
171 | 179 |
172 n = ngx_event_recv(c, r->header_in->last.mem, | 180 n = ngx_event_recv(c, r->header_in->last.mem, |
173 r->header_in->end - r->header_in->last.mem); | 181 r->header_in->end - r->header_in->last.mem); |
174 | 182 |
175 if (n == NGX_AGAIN) { | 183 if (n == NGX_AGAIN) { |
176 if (!r->header_timeout) { | 184 if (r->header_timeout) { |
177 r->header_timeout = 1; | 185 r->header_timeout = 0; |
178 ngx_del_timer(ev); | 186 ngx_del_timer(ev); |
179 ngx_add_timer(ev, r->server->header_timeout); | 187 ngx_add_timer(ev, r->server->header_timeout); |
180 } | 188 } |
181 return NGX_AGAIN; | 189 return NGX_AGAIN; |
182 } | 190 } |
208 /* rc == NGX_OK || rc == NGX_AGAIN */ | 216 /* rc == NGX_OK || rc == NGX_AGAIN */ |
209 | 217 |
210 } while (r->process_header | 218 } while (r->process_header |
211 && r->header_in->pos.mem < r->header_in->last.mem); | 219 && r->header_in->pos.mem < r->header_in->last.mem); |
212 | 220 |
213 if (!r->header_timeout) { | 221 if (r->header_timeout) { |
214 r->header_timeout = 1; | 222 r->header_timeout = 0; |
215 ngx_del_timer(ev); | 223 ngx_del_timer(ev); |
216 ngx_add_timer(ev, r->server->header_timeout); | 224 ngx_add_timer(ev, r->server->header_timeout); |
217 } | 225 } |
218 | 226 |
219 return rc; | 227 return rc; |
220 } | 228 } |
229 | |
221 | 230 |
222 static int ngx_http_process_request_line(ngx_http_request_t *r) | 231 static int ngx_http_process_request_line(ngx_http_request_t *r) |
223 { | 232 { |
224 int rc; | 233 int rc; |
225 ngx_http_log_ctx_t *ctx; | 234 ngx_http_log_ctx_t *ctx; |
236 r->method _ r->http_version _ r->uri); | 245 r->method _ r->http_version _ r->uri); |
237 | 246 |
238 if (r->http_version == 9) | 247 if (r->http_version == 9) |
239 return ngx_http_handler(r); | 248 return ngx_http_handler(r); |
240 | 249 |
250 /* TODO: check too long URI - no space for header, compact buffer */ | |
251 | |
241 r->state_handler = ngx_http_process_request_header; | 252 r->state_handler = ngx_http_process_request_header; |
242 ctx = r->connection->log->data; | 253 ctx = r->connection->log->data; |
243 ctx->action = "reading client request headers"; | 254 ctx->action = "reading client request headers"; |
244 | 255 |
245 return NGX_OK; | 256 return NGX_OK; |
246 } | 257 } |
247 | 258 |
259 if (r->header_in->last.mem >= r->header_in->end) { | |
260 rc == NGX_HTTP_PARSE_TOO_LONG_URI; | |
261 | |
262 } else if (rc == NGX_AGAIN) { | |
263 return NGX_AGAIN; | |
264 } | |
265 | |
248 ctx = r->connection->log->data; | 266 ctx = r->connection->log->data; |
249 r->connection->log->handler = NULL; | 267 r->connection->log->handler = NULL; |
250 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, | 268 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
251 header_errors[rc - NGX_HTTP_INVALID_METHOD], ctx->client); | 269 header_errors[rc - NGX_HTTP_PARSE_INVALID_METHOD], |
270 ctx->client); | |
252 r->connection->log->handler = ngx_http_log_error; | 271 r->connection->log->handler = ngx_http_log_error; |
253 | 272 |
254 return ngx_http_error(r, NGX_HTTP_BAD_REQUEST); | 273 return ngx_http_error(r, (rc == NGX_HTTP_PARSE_TOO_LONG_URI) ? |
255 } | 274 NGX_HTTP_REQUEST_URI_TOO_LARGE: |
275 NGX_HTTP_BAD_REQUEST); | |
276 } | |
277 | |
256 | 278 |
257 static int ngx_http_process_request_header(ngx_http_request_t *r) | 279 static int ngx_http_process_request_header(ngx_http_request_t *r) |
258 { | 280 { |
259 int rc; | 281 int rc; |
260 ngx_http_log_ctx_t *ctx; | 282 ngx_http_log_ctx_t *ctx; |
261 | 283 |
262 for ( ;; ) { | 284 for ( ;; ) { |
263 rc = ngx_read_http_header_line(r); | 285 rc = ngx_read_http_header_line(r); |
286 | |
287 /* TODO: check too long header, compact buffer */ | |
264 | 288 |
265 if (rc == NGX_OK) { | 289 if (rc == NGX_OK) { |
266 if (ngx_http_process_request_header_line(r) == NGX_ERROR) | 290 if (ngx_http_process_request_header_line(r) == NGX_ERROR) |
267 return ngx_http_error(r, NGX_HTTP_BAD_REQUEST); | 291 return ngx_http_error(r, NGX_HTTP_BAD_REQUEST); |
268 | 292 |
269 } else if (rc == NGX_HTTP_HEADER_DONE) { | 293 } else if (rc == NGX_HTTP_PARSE_HEADER_DONE) { |
270 ngx_log_debug(r->connection->log, "HTTP header done"); | 294 ngx_log_debug(r->connection->log, "HTTP header done"); |
271 return ngx_http_handler(r); | 295 return ngx_http_handler(r); |
272 | 296 |
273 } else if (rc == NGX_AGAIN) { | 297 } else if (rc == NGX_AGAIN) { |
274 return NGX_AGAIN; | 298 return NGX_AGAIN; |
275 | 299 |
276 } else if (rc == NGX_HTTP_INVALID_HEADER) { | 300 } else if (rc == NGX_HTTP_PARSE_INVALID_HEADER) { |
277 ctx = r->connection->log->data; | 301 ctx = r->connection->log->data; |
278 r->connection->log->handler = NULL; | 302 r->connection->log->handler = NULL; |
279 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, | 303 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
280 "client %s sent invalid header", ctx->client); | 304 "client %s sent invalid header", ctx->client); |
281 r->connection->log->handler = ngx_http_log_error; | 305 r->connection->log->handler = ngx_http_log_error; |
282 | 306 |
283 return ngx_http_error(r, NGX_HTTP_BAD_REQUEST); | 307 return ngx_http_error(r, NGX_HTTP_BAD_REQUEST); |
284 } | 308 } |
285 } | 309 } |
286 } | 310 } |
311 | |
287 | 312 |
288 static int ngx_http_process_request_header_line(ngx_http_request_t *r) | 313 static int ngx_http_process_request_header_line(ngx_http_request_t *r) |
289 { | 314 { |
290 /* STUB */ | 315 /* STUB */ |
291 *r->header_name_end = '\0'; | 316 *r->header_name_end = '\0'; |
294 r->header_name_start _ r->header_start); | 319 r->header_name_start _ r->header_start); |
295 | 320 |
296 return NGX_OK; | 321 return NGX_OK; |
297 } | 322 } |
298 | 323 |
299 static int ngx_http_block_read(ngx_event_t *ev) | 324 |
300 { | 325 /* ******************** */ |
301 ngx_log_debug(ev->log, "http read blocked"); | |
302 | |
303 ngx_del_event(ev, NGX_READ_EVENT); | |
304 ev->blocked = 1; | |
305 } | |
306 | 326 |
307 void ngx_http_discard_body(ngx_http_request_t *r) | 327 void ngx_http_discard_body(ngx_http_request_t *r) |
308 { | 328 { |
309 ngx_log_debug(r->connection->log, "set discard body"); | 329 ngx_log_debug(r->connection->log, "set discard body"); |
310 | 330 |
373 r->server->discarded_buffer_size); | 393 r->server->discarded_buffer_size); |
374 | 394 |
375 return n; | 395 return n; |
376 } | 396 } |
377 | 397 |
398 /* ******************** */ | |
399 | |
378 static int ngx_http_handler(ngx_http_request_t *r) | 400 static int ngx_http_handler(ngx_http_request_t *r) |
379 { | 401 { |
380 int rc; | 402 int rc; |
381 ngx_msec_t timeout; | 403 ngx_msec_t timeout; |
382 | 404 |
383 ngx_del_timer(r->connection->read); | 405 ngx_del_timer(r->connection->read); |
384 r->header_timeout = 1; | 406 r->header_timeout = 0; |
385 | 407 |
386 r->process_header = 0; | 408 r->process_header = 0; |
387 r->state_handler = NULL; | 409 r->state_handler = NULL; |
388 r->connection->unexpected_eof = 0; | 410 r->connection->unexpected_eof = 0; |
389 r->lingering_close = 1; | 411 r->lingering_close = 1; |
406 NGX_CLEAR_EVENT) == NGX_ERROR) { | 428 NGX_CLEAR_EVENT) == NGX_ERROR) { |
407 #else | 429 #else |
408 if (ngx_add_event(r->connection->write, NGX_WRITE_EVENT, | 430 if (ngx_add_event(r->connection->write, NGX_WRITE_EVENT, |
409 NGX_ONESHOT_EVENT) == NGX_ERROR) { | 431 NGX_ONESHOT_EVENT) == NGX_ERROR) { |
410 #endif | 432 #endif |
411 /* log http request */ | |
412 return ngx_http_close_request(r); | 433 return ngx_http_close_request(r); |
413 } | 434 } |
414 | 435 |
415 if (r->connection->sent > 0) { | 436 if (r->connection->sent > 0) { |
416 ngx_log_debug(r->connection->log, "sent: " QD_FMT _ | 437 ngx_log_debug(r->connection->log, "sent: " QD_FMT _ |
458 return ngx_http_close_request(r); | 479 return ngx_http_close_request(r); |
459 } | 480 } |
460 } | 481 } |
461 } | 482 } |
462 | 483 |
463 static int ngx_http_lingering_close(ngx_event_t *ev) | |
464 { | |
465 ssize_t n; | |
466 ngx_msec_t timer; | |
467 ngx_connection_t *c; | |
468 ngx_http_request_t *r; | |
469 | |
470 c = (ngx_connection_t *) ev->data; | |
471 r = (ngx_http_request_t *) c->data; | |
472 | |
473 ngx_log_debug(ev->log, "http lingering close"); | |
474 | |
475 if (ev->timedout) | |
476 return NGX_DONE; | |
477 | |
478 /* STUB */ | |
479 timer = r->lingering_time - ngx_time(); | |
480 if (timer <= 0) | |
481 return NGX_DONE; | |
482 | |
483 if (r->discarded_buffer == NULL) | |
484 ngx_test_null(r->discarded_buffer, | |
485 ngx_palloc(r->pool, r->server->discarded_buffer_size), | |
486 NGX_ERROR); | |
487 | |
488 n = ngx_event_recv(c, r->discarded_buffer, | |
489 r->server->discarded_buffer_size); | |
490 | |
491 if (n == NGX_ERROR) | |
492 return NGX_ERROR; | |
493 | |
494 if (n == 0) | |
495 return NGX_DONE; | |
496 | |
497 if (timer > LINGERING_TIMEOUT) | |
498 timer = LINGERING_TIMEOUT; | |
499 | |
500 ngx_del_timer(ev); | |
501 ngx_add_timer(ev, timer * 1000); | |
502 | |
503 return NGX_OK; | |
504 } | |
505 | |
506 int ngx_http_internal_redirect(ngx_http_request_t *r, char *uri) | 484 int ngx_http_internal_redirect(ngx_http_request_t *r, char *uri) |
507 { | 485 { |
508 ngx_log_debug(r->connection->log, "internal redirect: '%s'" _ uri); | 486 ngx_log_debug(r->connection->log, "internal redirect: '%s'" _ uri); |
509 | 487 |
510 r->uri = uri; | 488 r->uri = uri; |
561 } | 539 } |
562 | 540 |
563 r->handler = ngx_http_static_handler; | 541 r->handler = ngx_http_static_handler; |
564 | 542 |
565 return NGX_OK; | 543 return NGX_OK; |
544 } | |
545 | |
546 | |
547 static int ngx_http_block_read(ngx_event_t *ev) | |
548 { | |
549 ngx_log_debug(ev->log, "http read blocked"); | |
550 | |
551 ngx_del_event(ev, NGX_READ_EVENT); | |
552 ev->blocked = 1; | |
566 } | 553 } |
567 | 554 |
568 | 555 |
569 static int ngx_http_writer(ngx_event_t *ev) | 556 static int ngx_http_writer(ngx_event_t *ev) |
570 { | 557 { |
642 static int ngx_http_keepalive_handler(ngx_event_t *ev) | 629 static int ngx_http_keepalive_handler(ngx_event_t *ev) |
643 { | 630 { |
644 ngx_connection_t *c; | 631 ngx_connection_t *c; |
645 ngx_http_log_ctx_t *ctx; | 632 ngx_http_log_ctx_t *ctx; |
646 | 633 |
634 ngx_log_debug(ev->log, "http keepalive"); | |
635 | |
636 if (ev->timedout) | |
637 return NGX_DONE; | |
638 | |
647 if (closed) | 639 if (closed) |
648 /* NGX_LOG_INFO or even silent */ | 640 /* NGX_LOG_INFO or even silent */ |
649 return NGX_ERROR; | 641 return NGX_ERROR; |
650 | 642 |
651 c = (ngx_connection_t *) ev->data; | 643 c = (ngx_connection_t *) ev->data; |
656 | 648 |
657 return ngx_http_init_request(ev); | 649 return ngx_http_init_request(ev); |
658 } | 650 } |
659 | 651 |
660 #endif | 652 #endif |
653 | |
654 static int ngx_http_lingering_close(ngx_event_t *ev) | |
655 { | |
656 ssize_t n; | |
657 ngx_msec_t timer; | |
658 ngx_connection_t *c; | |
659 ngx_http_request_t *r; | |
660 | |
661 c = (ngx_connection_t *) ev->data; | |
662 r = (ngx_http_request_t *) c->data; | |
663 | |
664 ngx_log_debug(ev->log, "http lingering close"); | |
665 | |
666 if (ev->timedout) | |
667 return NGX_DONE; | |
668 | |
669 /* STUB */ | |
670 timer = r->lingering_time - ngx_time(); | |
671 if (timer <= 0) | |
672 return NGX_DONE; | |
673 | |
674 if (r->discarded_buffer == NULL) | |
675 ngx_test_null(r->discarded_buffer, | |
676 ngx_palloc(r->pool, r->server->discarded_buffer_size), | |
677 NGX_ERROR); | |
678 | |
679 n = ngx_event_recv(c, r->discarded_buffer, | |
680 r->server->discarded_buffer_size); | |
681 | |
682 if (n == NGX_ERROR) | |
683 return NGX_ERROR; | |
684 | |
685 if (n == 0) | |
686 return NGX_DONE; | |
687 | |
688 if (timer > LINGERING_TIMEOUT) | |
689 timer = LINGERING_TIMEOUT; | |
690 | |
691 ngx_del_timer(ev); | |
692 ngx_add_timer(ev, timer * 1000); | |
693 | |
694 return NGX_OK; | |
695 } | |
661 | 696 |
662 | 697 |
663 static int ngx_http_special_response(ngx_http_request_t *r, int error) | 698 static int ngx_http_special_response(ngx_http_request_t *r, int error) |
664 { | 699 { |
665 return ngx_http_error(r, error); | 700 return ngx_http_error(r, error); |