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);