Mercurial > hg > nginx
comparison src/http/ngx_http_event.c @ 6:669801705ab1
nginx-0.0.1-2002-08-26-19:18:19 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 26 Aug 2002 15:18:19 +0000 |
parents | 34a521b1a148 |
children | b5481d6fbbd4 |
comparison
equal
deleted
inserted
replaced
5:62b1a364857c | 6:669801705ab1 |
---|---|
1 | 1 |
2 #include <ngx_config.h> | 2 #include <ngx_config.h> |
3 #include <ngx_core.h> | |
4 #include <ngx_string.h> | |
3 #include <ngx_file.h> | 5 #include <ngx_file.h> |
4 #include <ngx_log.h> | 6 #include <ngx_log.h> |
5 #include <ngx_alloc.h> | 7 #include <ngx_alloc.h> |
6 #include <ngx_hunk.h> | 8 #include <ngx_hunk.h> |
7 #include <ngx_connection.h> | 9 #include <ngx_connection.h> |
8 | 10 |
9 #include <ngx_http.h> | 11 #include <ngx_http.h> |
10 | 12 |
11 /* | 13 int ngx_http_init_connection(ngx_connection_t *c); |
12 ngx_read should check errors (if we ask) and return | 14 |
13 -2 EAGAIN | |
14 -1 error | |
15 0 EOF | |
16 >0 number of bytes | |
17 */ | |
18 | |
19 int ngx_http_init_connection(ngx_connection_t *c); | |
20 static int ngx_http_init_request(ngx_event_t *ev); | 15 static int ngx_http_init_request(ngx_event_t *ev); |
21 static int ngx_http_process_request(ngx_event_t *ev); | 16 static int ngx_http_process_request(ngx_event_t *ev); |
22 | 17 |
23 static int ngx_process_http_request_line(ngx_http_request_t *r); | 18 static int ngx_process_http_request_line(ngx_http_request_t *r); |
24 static int ngx_process_http_request_header(ngx_http_request_t *r); | 19 static int ngx_process_http_request_header(ngx_http_request_t *r); |
25 | 20 |
26 static int ngx_process_http_request(ngx_http_request_t *r); | 21 static int ngx_process_http_request(ngx_http_request_t *r); |
27 | 22 |
28 static int ngx_http_close_request(ngx_event_t *ev); | 23 static int ngx_http_close_request(ngx_event_t *ev); |
24 static size_t ngx_http_log_error(void *data, char *buf, size_t len); | |
25 | |
29 | 26 |
30 /* STUB */ | 27 /* STUB */ |
31 static int ngx_http_writer(ngx_event_t *ev); | 28 static int ngx_http_writer(ngx_event_t *ev); |
32 | 29 |
33 /* | 30 |
34 returns | |
35 -1 if error | |
36 0 need more data or EOF (filter is deleted) | |
37 1 there is unread data | |
38 */ | |
39 | 31 |
40 int ngx_http_init_connection(ngx_connection_t *c) | 32 int ngx_http_init_connection(ngx_connection_t *c) |
41 { | 33 { |
42 ngx_event_t *ev; | 34 ngx_event_t *ev; |
35 struct sockaddr *addr; | |
36 ngx_http_log_ctx_t *ctx; | |
43 | 37 |
44 ev = c->read; | 38 ev = c->read; |
45 ev->event_handler = ngx_http_init_request; | 39 ev->event_handler = ngx_http_init_request; |
46 ev->log->action = "reading client request line"; | 40 |
47 | 41 /* TODO: connection's pool size */ |
48 ngx_log_debug(ev->log, "ngx_http_init_connection: entered"); | 42 ngx_test_null(c->pool, ngx_create_pool(1024, ev->log), NGX_ERROR); |
49 | 43 |
50 /* XXX: ev->timer ? */ | 44 ngx_test_null(addr, ngx_palloc(c->pool, c->socklen), NGX_ERROR); |
51 if (ngx_add_event(ev, NGX_TIMER_EVENT, ev->timer) == -1) | 45 ngx_memcpy(addr, c->sockaddr, c->socklen); |
52 return -1; | 46 c->sockaddr = addr; |
47 | |
48 ngx_test_null(c->addr_text, ngx_palloc(c->pool, c->addr_textlen), | |
49 NGX_ERROR); | |
50 inet_ntop(c->family, (char *)c->sockaddr + c->addr, | |
51 c->addr_text, c->addr_textlen); | |
52 | |
53 ngx_test_null(ctx, ngx_pcalloc(c->pool, sizeof(ngx_http_log_ctx_t)), | |
54 NGX_ERROR); | |
55 ctx->client = c->addr_text; | |
56 ctx->action = "reading client request line"; | |
57 c->log->data = ctx; | |
58 c->log->handler = ngx_http_log_error; | |
59 | |
60 ngx_add_timer(ev, c->post_accept_timeout); | |
53 | 61 |
54 #if (HAVE_DEFERRED_ACCEPT) | 62 #if (HAVE_DEFERRED_ACCEPT) |
55 if (ev->ready) | 63 if (ev->ready) |
56 return ngx_http_init_request(ev); | 64 return ngx_http_init_request(ev); |
57 else | 65 else |
58 #endif | 66 #endif |
59 #if (NGX_CLEAR_EVENT) | 67 #if (USE_KQUEUE) |
60 return ngx_add_event(ev, NGX_READ_EVENT, NGX_CLEAR_EVENT); | 68 return ngx_add_event(ev, NGX_READ_EVENT, NGX_CLEAR_EVENT); |
61 #else | 69 #else |
62 return ngx_add_event(ev, NGX_READ_EVENT, NGX_ONESHOT_EVENT); | 70 #if (HAVE_AIO_EVENT) |
63 #endif | 71 if (ngx_event_type == NGX_AIO_EVENT) |
64 } | 72 return ngx_http_init_request(ev); |
73 else | |
74 #endif | |
75 #if (HAVE_CLEAR_EVENT) | |
76 if (ngx_event_type == NGX_KQUEUE_EVENT) | |
77 return ngx_add_event(ev, NGX_READ_EVENT, NGX_CLEAR_EVENT); | |
78 else | |
79 #else | |
80 return ngx_add_event(ev, NGX_READ_EVENT, NGX_LEVEL_EVENT); | |
81 #endif | |
82 #endif | |
83 } | |
84 | |
65 | 85 |
66 int ngx_http_init_request(ngx_event_t *ev) | 86 int ngx_http_init_request(ngx_event_t *ev) |
67 { | 87 { |
68 ngx_connection_t *c = (ngx_connection_t *) ev->data; | 88 ngx_connection_t *c; |
69 ngx_http_server_t *srv = (ngx_http_server_t *) c->server; | 89 ngx_http_server_t *srv; |
70 ngx_http_request_t *r; | 90 ngx_http_request_t *r; |
71 | 91 |
72 ngx_log_debug(ev->log, "ngx_http_init_request: entered"); | 92 c = (ngx_connection_t *) ev->data; |
73 | 93 srv = (ngx_http_server_t *) c->server; |
74 ngx_test_null(c->pool, ngx_create_pool(16384, ev->log), -1); | 94 |
75 ngx_test_null(r, ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)), -1); | 95 ngx_test_null(r, ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)), |
96 NGX_ERROR); | |
76 | 97 |
77 c->data = r; | 98 c->data = r; |
78 r->connection = c; | 99 r->connection = c; |
79 r->server = srv; | 100 r->server = srv; |
80 | 101 |
81 ngx_test_null(r->pool, ngx_create_pool(16384, ev->log), -1); | 102 ngx_test_null(r->pool, ngx_create_pool(16384, ev->log), NGX_ERROR); |
82 ngx_test_null(r->buff, ngx_palloc(r->pool, sizeof(ngx_buff_t)), -1); | 103 |
83 ngx_test_null(r->buff->buff, ngx_palloc(r->pool, srv->buff_size), -1); | 104 /* TODO: buff -> hunk */ |
105 ngx_test_null(r->buff, ngx_palloc(r->pool, sizeof(ngx_buff_t)), NGX_ERROR); | |
106 ngx_test_null(r->buff->buff, ngx_palloc(r->pool, srv->buff_size), | |
107 NGX_ERROR); | |
84 | 108 |
85 r->buff->pos = r->buff->last = r->buff->buff; | 109 r->buff->pos = r->buff->last = r->buff->buff; |
86 r->buff->end = r->buff->buff + srv->buff_size; | 110 r->buff->end = r->buff->buff + srv->buff_size; |
87 | 111 |
88 r->state_handler = ngx_process_http_request_line; | 112 r->state_handler = ngx_process_http_request_line; |
89 | 113 |
90 ev->event_handler = ngx_http_process_request; | 114 ev->event_handler = ngx_http_process_request; |
91 ev->close_handler = ngx_http_close_request; | 115 ev->close_handler = ngx_http_close_request; |
92 c->write->close_handler = ngx_http_close_request; | 116 c->write->close_handler = ngx_http_close_request; |
117 | |
93 return ngx_http_process_request(ev); | 118 return ngx_http_process_request(ev); |
94 } | 119 } |
95 | 120 |
121 | |
96 int ngx_http_process_request(ngx_event_t *ev) | 122 int ngx_http_process_request(ngx_event_t *ev) |
97 { | 123 { |
98 int n; | 124 int n; |
99 ngx_connection_t *c = (ngx_connection_t *) ev->data; | 125 ngx_connection_t *c ; |
100 ngx_http_request_t *r = (ngx_http_request_t *) c->data; | 126 ngx_http_request_t *r; |
127 | |
128 c = (ngx_connection_t *) ev->data; | |
129 r = (ngx_http_request_t *) c->data; | |
101 | 130 |
102 ngx_log_debug(ev->log, "http process request"); | 131 ngx_log_debug(ev->log, "http process request"); |
103 | 132 |
104 n = ngx_event_recv(ev, r->buff->last, r->buff->end - r->buff->last); | 133 n = ngx_event_recv(ev, r->buff->last, r->buff->end - r->buff->last); |
105 | 134 |
106 if (n == -2) | 135 if (n == NGX_AGAIN) |
107 return 0; | 136 return NGX_AGAIN; |
108 | 137 |
109 if (n == -1) | 138 if (n == NGX_ERROR) { |
110 return -1; | 139 /* close request */ |
140 return NGX_ERROR; | |
141 } | |
111 | 142 |
112 ngx_log_debug(ev->log, "http read %d" _ n); | 143 ngx_log_debug(ev->log, "http read %d" _ n); |
113 | 144 |
114 if (n == 0) { | 145 if (n == 0) { |
115 if (ev->unexpected_eof) { | 146 if (ev->unexpected_eof) { |
116 ngx_log_error(NGX_LOG_INFO, ev->log, 0, | 147 ngx_log_error(NGX_LOG_INFO, ev->log, 0, "connection is closed"); |
117 "ngx_http_process_request: " | 148 /* close request */ |
118 "connection is closed while %s", ev->action); | 149 return NGX_ERROR; |
119 return -1; | |
120 } | 150 } |
121 | 151 |
122 return ngx_http_close_request(ev); | 152 return ngx_http_close_request(ev); |
123 } | 153 } |
124 | 154 |
181 ngx_log_debug(r->connection->log, "HTTP header done"); | 211 ngx_log_debug(r->connection->log, "HTTP header done"); |
182 | 212 |
183 return ngx_process_http_request(r); | 213 return ngx_process_http_request(r); |
184 } | 214 } |
185 | 215 |
216 #if 0 | |
217 static int ngx_http_lock_read(ngx_event_t *ev) | |
218 { | |
219 ngx_del_event(ev, NGX_READ_EVENT); | |
220 ev->read_blocked = 1; | |
221 } | |
222 #endif | |
223 | |
186 static int ngx_process_http_request(ngx_http_request_t *r) | 224 static int ngx_process_http_request(ngx_http_request_t *r) |
187 { | 225 { |
188 int err, rc; | 226 int err, rc; |
189 char *name, *loc, *file; | 227 char *name, *loc, *file; |
190 | 228 |
242 return rc; | 280 return rc; |
243 | 281 |
244 r->handler = NGX_HTTP_STATIC_HANDLER; | 282 r->handler = NGX_HTTP_STATIC_HANDLER; |
245 return NGX_OK; | 283 return NGX_OK; |
246 } | 284 } |
285 | |
286 #if 0 | |
287 | |
288 static int ngx_http_handler(ngx_http_request_t *r) | |
289 { | |
290 find_http_handler(); | |
291 | |
292 if (r->discard_body && r->connection->read->ready) | |
293 ngx_http_discarad_body(); | |
294 | |
295 rc = http_handler(); | |
296 | |
297 /* transfer not completed */ | |
298 if (rc == NGX_AGAIN) | |
299 return rc; | |
300 | |
301 if (rc == NGX_ERROR) { | |
302 log http request | |
303 close http request | |
304 return rc; | |
305 } | |
306 | |
307 if (rc > 300) { | |
308 send special response | |
309 } | |
310 | |
311 /* rc == NGX_OK */ | |
312 | |
313 if (!keepalive) | |
314 if (linger) | |
315 set linger timeout on read | |
316 shutdown socket | |
317 else | |
318 close socket | |
319 | |
320 log http request | |
321 close http request | |
322 if (keepalive) | |
323 return NGX_OK; | |
324 else | |
325 close connection | |
326 return NGX_OK; | |
327 } | |
328 | |
329 static int ngx_http_writer(ngx_event_t *ev) | |
330 { | |
331 int rc; | |
332 | |
333 ngx_connection_t *c = (ngx_connection_t *) ev->data; | |
334 ngx_http_request_t *r = (ngx_http_request_t *) c->data; | |
335 | |
336 rc = ngx_http_filter(r, NULL); | |
337 | |
338 if (rc == NGX_AGAIN) | |
339 return rc; | |
340 | |
341 if (rc == NGX_ERROR) | |
342 return rc; | |
343 | |
344 /* rc == NGX_OK */ | |
345 | |
346 | |
347 if (!keepalive) | |
348 if (linger) | |
349 shutdown socket | |
350 else | |
351 close socket | |
352 | |
353 log http request | |
354 close http request | |
355 if (keepalive) | |
356 return NGX_OK; | |
357 else | |
358 close connection | |
359 return NGX_OK; | |
360 } | |
361 | |
362 static int ngx_http_discarded_read(ngx_event_t *ev) | |
363 { | |
364 if (ev->timedout) | |
365 return NGX_ERROR; | |
366 | |
367 while (full) { | |
368 recv(); | |
369 } | |
370 | |
371 return NGX_OK; | |
372 } | |
373 | |
374 static int ngx_http_keepalive_handler(ngx_event_t *ev) | |
375 { | |
376 ngx_connection_t *c; | |
377 ngx_http_log_ctx_t *ctx; | |
378 | |
379 if (closed) | |
380 /* NGX_LOG_INFO or even silent */ | |
381 return NGX_ERROR; | |
382 | |
383 c = (ngx_connection_t *) ev->data; | |
384 | |
385 ctx = (ngx_http_log_ctx_t *) c->log->data; | |
386 ctx->action = "reading client request line"; | |
387 c->log->handler = ngx_http_log_error; | |
388 | |
389 return ngx_http_init_request(ev); | |
390 } | |
391 | |
392 #endif | |
247 | 393 |
248 | 394 |
249 static int ngx_http_writer(ngx_event_t *ev) | 395 static int ngx_http_writer(ngx_event_t *ev) |
250 { | 396 { |
251 int rc; | 397 int rc; |
350 ngx_log_debug(ev->log, "http close"); | 496 ngx_log_debug(ev->log, "http close"); |
351 | 497 |
352 ngx_del_event(c->read, NGX_TIMER_EVENT); | 498 ngx_del_event(c->read, NGX_TIMER_EVENT); |
353 ngx_del_event(c->write, NGX_TIMER_EVENT); | 499 ngx_del_event(c->write, NGX_TIMER_EVENT); |
354 | 500 |
355 return ngx_event_close(ev); | 501 return ngx_event_close_connection(ev); |
356 } | 502 } |
503 | |
504 | |
505 static size_t ngx_http_log_error(void *data, char *buf, size_t len) | |
506 { | |
507 ngx_http_log_ctx_t *ctx = (ngx_http_log_ctx_t *) data; | |
508 if (ctx->url) | |
509 return ngx_snprintf(buf, len, " while %s, client: %s, URL: %s", | |
510 ctx->action, ctx->client, ctx->url); | |
511 else | |
512 return ngx_snprintf(buf, len, " while %s, client: %s", | |
513 ctx->action, ctx->client); | |
514 } |