blob: 67921055892718a02f4dfeacb9e00c617e0e1605 [file] [log] [blame]
Igor Sysoev6de5c2c2002-08-06 16:39:45 +00001
2#include <ngx_config.h>
Igor Sysoev0ad17c02002-08-26 15:18:19 +00003#include <ngx_core.h>
4#include <ngx_string.h>
Igor Sysoeva58e3ca2002-09-02 14:48:24 +00005#include <ngx_files.h>
Igor Sysoev6de5c2c2002-08-06 16:39:45 +00006#include <ngx_log.h>
7#include <ngx_alloc.h>
Igor Sysoeva0bb31f2002-12-02 16:09:40 +00008#include <ngx_array.h>
9#include <ngx_table.h>
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000010#include <ngx_hunk.h>
11#include <ngx_connection.h>
Igor Sysoevfcce8d52003-01-23 18:47:54 +000012#include <ngx_event.h>
13#include <ngx_event_timer.h>
Igor Sysoev42feecb2002-12-15 06:25:09 +000014#include <ngx_inet.h>
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000015#include <ngx_http.h>
Igor Sysoeve0268b92002-09-11 15:18:33 +000016#include <ngx_http_config.h>
Igor Sysoev4e9393a2003-01-09 05:36:00 +000017#include <ngx_http_core_module.h>
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000018
Igor Sysoeva58e3ca2002-09-02 14:48:24 +000019/* STUB */
20#include <ngx_http_output_filter.h>
Igor Sysoeva58e3ca2002-09-02 14:48:24 +000021int ngx_http_static_handler(ngx_http_request_t *r);
Igor Sysoeve0268b92002-09-11 15:18:33 +000022int ngx_http_index_handler(ngx_http_request_t *r);
Igor Sysoeva0bb31f2002-12-02 16:09:40 +000023int ngx_http_proxy_handler(ngx_http_request_t *r);
Igor Sysoevb0869052002-12-10 18:05:12 +000024/**/
Igor Sysoeva58e3ca2002-09-02 14:48:24 +000025
Igor Sysoev0ad17c02002-08-26 15:18:19 +000026int ngx_http_init_connection(ngx_connection_t *c);
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000027
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000028static int ngx_http_init_request(ngx_event_t *ev);
Igor Sysoevb0869052002-12-10 18:05:12 +000029static int ngx_http_process_request_header(ngx_event_t *ev);
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000030
Igor Sysoev016b8522002-08-29 16:59:54 +000031static int ngx_http_process_request_line(ngx_http_request_t *r);
Igor Sysoevb0869052002-12-10 18:05:12 +000032static int ngx_http_process_request_headers(ngx_http_request_t *r);
Igor Sysoeva58e3ca2002-09-02 14:48:24 +000033static int ngx_http_process_request_header_line(ngx_http_request_t *r);
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000034
Igor Sysoev42feecb2002-12-15 06:25:09 +000035static int ngx_http_event_request_handler(ngx_http_request_t *r);
Igor Sysoeva58e3ca2002-09-02 14:48:24 +000036
37static int ngx_http_writer(ngx_event_t *ev);
Igor Sysoev42feecb2002-12-15 06:25:09 +000038static int ngx_http_block_read(ngx_event_t *ev);
39static int ngx_http_read_discarded_body(ngx_event_t *ev);
Igor Sysoev1af7c822002-09-13 14:47:42 +000040static int ngx_http_keepalive_handler(ngx_event_t *ev);
Igor Sysoev42feecb2002-12-15 06:25:09 +000041static int ngx_http_set_lingering_close(ngx_http_request_t *r);
42static int ngx_http_lingering_close_handler(ngx_event_t *ev);
Igor Sysoev3a40d482002-09-12 14:42:29 +000043
Igor Sysoevb0869052002-12-10 18:05:12 +000044#if 0
45int ngx_http_special_response(ngx_http_request_t *r, int error);
46int ngx_http_redirect(ngx_http_request_t *r, int redirect);
47int ngx_http_error(ngx_http_request_t *r, int error);
48int ngx_http_close_request(ngx_http_request_t *r);
49#endif
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000050
Igor Sysoev2ba1ee02002-10-04 17:58:04 +000051static int ngx_http_close_connection(ngx_event_t *ev);
Igor Sysoev0ad17c02002-08-26 15:18:19 +000052static size_t ngx_http_log_error(void *data, char *buf, size_t len);
53
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000054
Igor Sysoev0ad17c02002-08-26 15:18:19 +000055
Igor Sysoev016b8522002-08-29 16:59:54 +000056static char *header_errors[] = {
57 "client %s sent invalid method",
58 "client %s sent invalid request",
Igor Sysoev1af7c822002-09-13 14:47:42 +000059 "client %s sent too long URI",
Igor Sysoev016b8522002-08-29 16:59:54 +000060 "client %s sent HEAD method in HTTP/0.9 request"
61};
62
63
Igor Sysoeva0bb31f2002-12-02 16:09:40 +000064static ngx_http_header_t headers_in[] = {
65 { 4, "Host", offsetof(ngx_http_headers_in_t, host) },
66 { 10, "Connection", offsetof(ngx_http_headers_in_t, connection) },
Igor Sysoev42feecb2002-12-15 06:25:09 +000067 { 17, "If-Modified-Since",
68 offsetof(ngx_http_headers_in_t,if_modified_since) },
Igor Sysoeva0bb31f2002-12-02 16:09:40 +000069
70 { 10, "User-Agent", offsetof(ngx_http_headers_in_t, user_agent) },
71
72 { 0, NULL, 0 }
73};
74
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000075
76int ngx_http_init_connection(ngx_connection_t *c)
77{
Igor Sysoev0ad17c02002-08-26 15:18:19 +000078 ngx_event_t *ev;
79 struct sockaddr *addr;
80 ngx_http_log_ctx_t *ctx;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000081
82 ev = c->read;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000083 ev->event_handler = ngx_http_init_request;
Igor Sysoev2ba1ee02002-10-04 17:58:04 +000084
Igor Sysoev1af7c822002-09-13 14:47:42 +000085 ngx_test_null(c->pool,
Igor Sysoev4e9393a2003-01-09 05:36:00 +000086 ngx_create_pool(ngx_http_connection_pool_size, ev->log),
Igor Sysoev1af7c822002-09-13 14:47:42 +000087 NGX_ERROR);
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000088
Igor Sysoev2ba1ee02002-10-04 17:58:04 +000089 ngx_test_null(c->requests, ngx_create_array(c->pool, 10, sizeof(char *)),
90 NGX_ERROR);
91
92 ev->close_handler = ngx_http_close_connection;
93 c->write->close_handler = ngx_http_close_connection;
94
Igor Sysoev0ad17c02002-08-26 15:18:19 +000095 ngx_test_null(addr, ngx_palloc(c->pool, c->socklen), NGX_ERROR);
96 ngx_memcpy(addr, c->sockaddr, c->socklen);
97 c->sockaddr = addr;
98
Igor Sysoev4e9393a2003-01-09 05:36:00 +000099 ngx_test_null(c->addr_text.data, ngx_palloc(c->pool, c->addr_text_max_len),
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000100 NGX_ERROR);
Igor Sysoevb0869052002-12-10 18:05:12 +0000101
Igor Sysoev5518aba2002-12-17 15:48:27 +0000102 c->addr_text.len = ngx_inet_ntop(c->family,
103 (char *)c->sockaddr + c->addr,
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000104 c->addr_text.data, c->addr_text_max_len);
Igor Sysoev88092572002-12-19 07:08:55 +0000105 if (c->addr_text.len == 0)
Igor Sysoev5518aba2002-12-17 15:48:27 +0000106 return NGX_ERROR;
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000107
108 ngx_test_null(ctx, ngx_pcalloc(c->pool, sizeof(ngx_http_log_ctx_t)),
109 NGX_ERROR);
Igor Sysoevb0869052002-12-10 18:05:12 +0000110 ctx->client = c->addr_text.data;
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000111 ctx->action = "reading client request line";
112 c->log->data = ctx;
113 c->log->handler = ngx_http_log_error;
114
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000115#if (HAVE_DEFERRED_ACCEPT)
Igor Sysoev016b8522002-08-29 16:59:54 +0000116 if (ev->ready) {
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000117 return ngx_http_init_request(ev);
Igor Sysoev016b8522002-08-29 16:59:54 +0000118 } else {
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000119#endif
Igor Sysoev016b8522002-08-29 16:59:54 +0000120 ngx_add_timer(ev, c->post_accept_timeout);
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000121#if (USE_KQUEUE)
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000122 return ngx_add_event(ev, NGX_READ_EVENT, NGX_CLEAR_EVENT);
123#else
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000124#if (HAVE_AIO_EVENT)
125 if (ngx_event_type == NGX_AIO_EVENT)
126 return ngx_http_init_request(ev);
127 else
128#endif
129#if (HAVE_CLEAR_EVENT)
130 if (ngx_event_type == NGX_KQUEUE_EVENT)
131 return ngx_add_event(ev, NGX_READ_EVENT, NGX_CLEAR_EVENT);
132 else
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000133#endif
Igor Sysoev016b8522002-08-29 16:59:54 +0000134 return ngx_add_event(ev, NGX_READ_EVENT, NGX_LEVEL_EVENT);
135#endif /* USE_KQUEUE */
136#if (HAVE_DEFERRED_ACCEPT)
137 }
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000138#endif
139}
140
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000141
Igor Sysoev1af7c822002-09-13 14:47:42 +0000142static int ngx_http_init_request(ngx_event_t *ev)
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000143{
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000144 ngx_connection_t *c;
145 ngx_http_request_t *r;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000146
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000147 c = (ngx_connection_t *) ev->data;
Igor Sysoevad22e012003-01-15 07:02:27 +0000148 c->sent = 0;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000149
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000150 ngx_test_null(r, ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)),
151 NGX_ERROR);
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000152
153 c->data = r;
154 r->connection = c;
Igor Sysoev42feecb2002-12-15 06:25:09 +0000155 r->file.fd = NGX_INVALID_FILE;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000156
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000157 if (c->buffer == NULL) {
158 ngx_test_null(c->buffer,
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000159 ngx_create_temp_hunk(c->pool,
160 ngx_http_client_header_buffer_size,
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000161 0, 0),
162 NGX_ERROR);
163 } else {
164 r->header_read = 1;
165 }
166
167 r->header_in = c->buffer;
168
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000169 ngx_test_null(r->pool, ngx_create_pool(ngx_http_request_pool_size, ev->log),
Igor Sysoev016b8522002-08-29 16:59:54 +0000170 ngx_http_close_request(r));
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000171
Igor Sysoev207ed5a2002-12-26 16:26:23 +0000172 ngx_test_null(r->ctx,
173 ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module),
Igor Sysoeve0268b92002-09-11 15:18:33 +0000174 ngx_http_close_request(r));
175
Igor Sysoev42feecb2002-12-15 06:25:09 +0000176 r->headers_out.headers = ngx_create_table(r->pool, 10);
177 r->headers_out.content_length = -1;
178 r->headers_out.last_modified_time = -1;
179
Igor Sysoevb0869052002-12-10 18:05:12 +0000180 ev->event_handler = ngx_http_process_request_header;
Igor Sysoev016b8522002-08-29 16:59:54 +0000181 r->state_handler = ngx_http_process_request_line;
Igor Sysoev1af7c822002-09-13 14:47:42 +0000182 r->header_timeout = 1;
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000183
Igor Sysoevb0869052002-12-10 18:05:12 +0000184 return ngx_http_process_request_header(ev);
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000185}
186
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000187
Igor Sysoevb0869052002-12-10 18:05:12 +0000188static int ngx_http_process_request_header(ngx_event_t *ev)
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000189{
Igor Sysoev016b8522002-08-29 16:59:54 +0000190 int n, rc;
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000191 ngx_connection_t *c ;
192 ngx_http_request_t *r;
Igor Sysoev1af7c822002-09-13 14:47:42 +0000193 ngx_http_log_ctx_t *ctx;
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000194
195 c = (ngx_connection_t *) ev->data;
196 r = (ngx_http_request_t *) c->data;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000197
198 ngx_log_debug(ev->log, "http process request");
199
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000200 if (r->header_read) {
201 r->header_read = 0;
202 ngx_log_debug(ev->log, "http preread %d" _
203 r->header_in->last.mem - r->header_in->pos.mem);
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000204
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000205 } else {
206 n = ngx_event_recv(c, r->header_in->last.mem,
207 r->header_in->end - r->header_in->last.mem);
208
209 if (n == NGX_AGAIN) {
210 if (r->header_timeout) {
211 r->header_timeout = 0;
212 ngx_del_timer(ev);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000213 ngx_add_timer(ev, ngx_http_client_header_timeout);
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000214 }
215 return NGX_AGAIN;
Igor Sysoev016b8522002-08-29 16:59:54 +0000216 }
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000217
218 if (n == NGX_ERROR)
219 return ngx_http_close_request(r);
220
221 ngx_log_debug(ev->log, "http read %d" _ n);
222
223 if (n == 0) {
Igor Sysoevb0869052002-12-10 18:05:12 +0000224 ngx_log_error(NGX_LOG_INFO, c->log, 0,
225 "client has prematurely closed connection");
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000226 return ngx_http_close_request(r);
227 }
228
229 r->header_in->last.mem += n;
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000230 }
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000231
Igor Sysoev016b8522002-08-29 16:59:54 +0000232 /* state_handlers are called in following order:
233 ngx_http_process_request_line(r)
Igor Sysoevb0869052002-12-10 18:05:12 +0000234 ngx_http_process_request_headers(r) */
Igor Sysoev016b8522002-08-29 16:59:54 +0000235
236 do {
237 rc = (r->state_handler)(r);
238
239 if (rc == NGX_ERROR)
240 return rc;
241
Igor Sysoevb0869052002-12-10 18:05:12 +0000242 } while (rc == NGX_AGAIN && r->header_in->pos.mem < r->header_in->last.mem);
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000243
Igor Sysoev830c4ce2003-01-24 16:09:40 +0000244 if (rc == NGX_OK) {
245 /* HTTP header done */
Igor Sysoev016b8522002-08-29 16:59:54 +0000246
Igor Sysoev830c4ce2003-01-24 16:09:40 +0000247 if (r->header_timeout) {
248 r->header_timeout = 0;
249 ngx_del_timer(ev);
250 ngx_add_timer(ev, ngx_http_client_header_timeout);
251 }
252
Igor Sysoev42feecb2002-12-15 06:25:09 +0000253 return ngx_http_event_request_handler(r);
Igor Sysoev830c4ce2003-01-24 16:09:40 +0000254
255 } else {
256
257 if (r->header_timeout) {
258 r->header_timeout = 0;
259 ngx_del_timer(ev);
260 ngx_add_timer(ev, ngx_http_client_header_timeout);
261 }
262
Igor Sysoevb0869052002-12-10 18:05:12 +0000263 return rc;
Igor Sysoev830c4ce2003-01-24 16:09:40 +0000264 }
Igor Sysoev016b8522002-08-29 16:59:54 +0000265}
266
Igor Sysoev1af7c822002-09-13 14:47:42 +0000267
Igor Sysoev016b8522002-08-29 16:59:54 +0000268static int ngx_http_process_request_line(ngx_http_request_t *r)
269{
Igor Sysoev2ba1ee02002-10-04 17:58:04 +0000270 int rc, len;
271 char **request;
272 ngx_connection_t *c;
Igor Sysoev016b8522002-08-29 16:59:54 +0000273 ngx_http_log_ctx_t *ctx;
274
275 rc = ngx_read_http_request_line(r);
276
Igor Sysoev2ba1ee02002-10-04 17:58:04 +0000277 c = r->connection;
278
Igor Sysoev016b8522002-08-29 16:59:54 +0000279 if (rc == NGX_OK) {
Igor Sysoev42feecb2002-12-15 06:25:09 +0000280 r->uri.len = (r->args_start ? r->args_start - 1 : r->uri_end)
281 - r->uri_start;
Igor Sysoevb0869052002-12-10 18:05:12 +0000282 ngx_test_null(r->uri.data, ngx_palloc(r->pool, r->uri.len + 1),
Igor Sysoev016b8522002-08-29 16:59:54 +0000283 ngx_http_close_request(r));
Igor Sysoevb0869052002-12-10 18:05:12 +0000284 ngx_cpystrn(r->uri.data, r->uri_start, r->uri.len + 1);
Igor Sysoev016b8522002-08-29 16:59:54 +0000285
Igor Sysoev2d0d9092002-12-03 15:45:38 +0000286 r->request_line.len = r->request_end - r->header_in->start;
287 ngx_test_null(r->request_line.data,
288 ngx_palloc(r->pool, r->request_line.len + 1),
289 ngx_http_close_request(r));
290 ngx_cpystrn(r->request_line.data, r->header_in->start,
291 r->request_line.len + 1);
292
293 /* TEMP */
Igor Sysoev2ba1ee02002-10-04 17:58:04 +0000294 ngx_test_null(request, ngx_push_array(c->requests),
295 ngx_http_close_request(r));
296
297 if (r->request_end)
298 len = r->request_end - r->header_in->start + 1;
299 else
300 len = 1;
301 c->requests_len += len;
302 ngx_test_null(*request, ngx_palloc(c->pool, len),
303 ngx_http_close_request(r));
304 ngx_cpystrn(*request, r->header_in->start, len);
305
306 ngx_log_debug(c->log, "REQ: '%s'" _ *request);
Igor Sysoev2d0d9092002-12-03 15:45:38 +0000307 /* */
Igor Sysoev2ba1ee02002-10-04 17:58:04 +0000308
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000309 if (r->uri_ext) {
Igor Sysoev42feecb2002-12-15 06:25:09 +0000310 r->exten.len = (r->args_start ? r->args_start - 1 : r->uri_end)
311 - r->uri_ext;
Igor Sysoevb0869052002-12-10 18:05:12 +0000312 ngx_test_null(r->exten.data,
313 ngx_palloc(r->pool, r->exten.len + 1),
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000314 ngx_http_close_request(r));
Igor Sysoevb0869052002-12-10 18:05:12 +0000315 ngx_cpystrn(r->exten.data, r->uri_ext, r->exten.len + 1);
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000316 }
317
Igor Sysoev295bb632002-12-23 18:22:18 +0000318#if 0
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000319 ngx_log_debug(r->connection->log, "HTTP: %d, %d, %s %s" _
Igor Sysoevb0869052002-12-10 18:05:12 +0000320 r->method _ r->http_version _
321 r->uri.data _ r->exten.data);
Igor Sysoev295bb632002-12-23 18:22:18 +0000322#endif
Igor Sysoev016b8522002-08-29 16:59:54 +0000323
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000324 if (r->http_version == 9)
Igor Sysoevb0869052002-12-10 18:05:12 +0000325 return NGX_OK;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000326
Igor Sysoev1af7c822002-09-13 14:47:42 +0000327 /* TODO: check too long URI - no space for header, compact buffer */
328
Igor Sysoeva0bb31f2002-12-02 16:09:40 +0000329 r->headers_in.headers = ngx_create_table(r->pool, 10);
330
Igor Sysoevb0869052002-12-10 18:05:12 +0000331 r->state_handler = ngx_http_process_request_headers;
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000332 ctx = r->connection->log->data;
333 ctx->action = "reading client request headers";
Igor Sysoev016b8522002-08-29 16:59:54 +0000334
Igor Sysoevb0869052002-12-10 18:05:12 +0000335 return NGX_AGAIN;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000336 }
337
Igor Sysoev1af7c822002-09-13 14:47:42 +0000338 if (r->header_in->last.mem >= r->header_in->end) {
Igor Sysoevef259d12002-12-06 16:32:33 +0000339 rc = NGX_HTTP_PARSE_TOO_LONG_URI;
Igor Sysoev1af7c822002-09-13 14:47:42 +0000340
341 } else if (rc == NGX_AGAIN) {
342 return NGX_AGAIN;
343 }
344
Igor Sysoev016b8522002-08-29 16:59:54 +0000345 ctx = r->connection->log->data;
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000346 r->connection->log->handler = NULL;
Igor Sysoev1af7c822002-09-13 14:47:42 +0000347 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
348 header_errors[rc - NGX_HTTP_PARSE_INVALID_METHOD],
349 ctx->client);
Igor Sysoev016b8522002-08-29 16:59:54 +0000350 r->connection->log->handler = ngx_http_log_error;
351
Igor Sysoev1af7c822002-09-13 14:47:42 +0000352 return ngx_http_error(r, (rc == NGX_HTTP_PARSE_TOO_LONG_URI) ?
353 NGX_HTTP_REQUEST_URI_TOO_LARGE:
354 NGX_HTTP_BAD_REQUEST);
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000355}
356
Igor Sysoev1af7c822002-09-13 14:47:42 +0000357
Igor Sysoevb0869052002-12-10 18:05:12 +0000358static int ngx_http_process_request_headers(ngx_http_request_t *r)
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000359{
Igor Sysoev016b8522002-08-29 16:59:54 +0000360 int rc;
361 ngx_http_log_ctx_t *ctx;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000362
Igor Sysoev016b8522002-08-29 16:59:54 +0000363 for ( ;; ) {
Igor Sysoevb0869052002-12-10 18:05:12 +0000364 rc = ngx_read_http_header_line(r, r->header_in);
Igor Sysoev016b8522002-08-29 16:59:54 +0000365
Igor Sysoev1af7c822002-09-13 14:47:42 +0000366 /* TODO: check too long header, compact buffer */
367
Igor Sysoev016b8522002-08-29 16:59:54 +0000368 if (rc == NGX_OK) {
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000369 if (ngx_http_process_request_header_line(r) == NGX_ERROR)
370 return ngx_http_error(r, NGX_HTTP_BAD_REQUEST);
371
Igor Sysoev1af7c822002-09-13 14:47:42 +0000372 } else if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000373 ngx_log_debug(r->connection->log, "HTTP header done");
Igor Sysoev42feecb2002-12-15 06:25:09 +0000374
375 if (r->http_version > NGX_HTTP_VERSION_10
376 && r->headers_in.host == NULL)
377 {
378 return ngx_http_error(r, NGX_HTTP_BAD_REQUEST);
379 } else {
380 return NGX_OK;
381 }
Igor Sysoev016b8522002-08-29 16:59:54 +0000382
383 } else if (rc == NGX_AGAIN) {
384 return NGX_AGAIN;
385
Igor Sysoev1af7c822002-09-13 14:47:42 +0000386 } else if (rc == NGX_HTTP_PARSE_INVALID_HEADER) {
Igor Sysoev016b8522002-08-29 16:59:54 +0000387 ctx = r->connection->log->data;
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000388 r->connection->log->handler = NULL;
Igor Sysoev1af7c822002-09-13 14:47:42 +0000389 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
Igor Sysoev016b8522002-08-29 16:59:54 +0000390 "client %s sent invalid header", ctx->client);
391 r->connection->log->handler = ngx_http_log_error;
392
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000393 return ngx_http_error(r, NGX_HTTP_BAD_REQUEST);
Igor Sysoev016b8522002-08-29 16:59:54 +0000394 }
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000395 }
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000396}
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000397
Igor Sysoev1af7c822002-09-13 14:47:42 +0000398
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000399static int ngx_http_process_request_header_line(ngx_http_request_t *r)
400{
Igor Sysoeva0bb31f2002-12-02 16:09:40 +0000401 int i;
402 ngx_table_elt_t *h;
403
Igor Sysoev2d0d9092002-12-03 15:45:38 +0000404 ngx_test_null(h, ngx_push_table(r->headers_in.headers), NGX_ERROR);
Igor Sysoeva0bb31f2002-12-02 16:09:40 +0000405
406 h->key.len = r->header_name_end - r->header_name_start;
407 ngx_test_null(h->key.data, ngx_palloc(r->pool, h->key.len + 1), NGX_ERROR);
408 ngx_cpystrn(h->key.data, r->header_name_start, h->key.len + 1);
409
410 h->value.len = r->header_end - r->header_start;
411 ngx_test_null(h->value.data, ngx_palloc(r->pool, h->value.len + 1),
412 NGX_ERROR);
413 ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1);
414
415 for (i = 0; headers_in[i].len != 0; i++) {
416 if (headers_in[i].len == h->key.len) {
Igor Sysoevb2620632003-01-10 06:09:20 +0000417 if (ngx_strcasecmp(headers_in[i].data, h->key.data) == 0) {
Igor Sysoeva0bb31f2002-12-02 16:09:40 +0000418 *((ngx_table_elt_t **)
419 ((char *) &r->headers_in + headers_in[i].offset)) = h;
420 }
421 }
422 }
423
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000424 ngx_log_debug(r->connection->log, "HTTP header: '%s: %s'" _
Igor Sysoeva0bb31f2002-12-02 16:09:40 +0000425 h->key.data _ h->value.data);
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000426
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000427 return NGX_OK;
428}
429
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000430
Igor Sysoev42feecb2002-12-15 06:25:09 +0000431static int ngx_http_event_request_handler(ngx_http_request_t *r)
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000432{
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000433 int rc;
Igor Sysoev96f83772002-09-07 10:14:25 +0000434 ngx_msec_t timeout;
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000435
Igor Sysoevb0869052002-12-10 18:05:12 +0000436 ngx_del_timer(r->connection->read);
437 r->header_timeout = 0;
438
439 r->state_handler = NULL;
440 r->connection->read->event_handler = ngx_http_block_read;
Igor Sysoeva0bb31f2002-12-02 16:09:40 +0000441
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000442 rc = ngx_http_handler(r);
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000443
Igor Sysoevef259d12002-12-06 16:32:33 +0000444 /* handler is still busy */
Igor Sysoev6ed07e42002-12-05 16:21:24 +0000445 if (rc == NGX_WAITING)
446 return rc;
447
Igor Sysoevef259d12002-12-06 16:32:33 +0000448 /* handler has done its work but transfer is not completed */
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000449 if (rc == NGX_AGAIN) {
450#if (HAVE_CLEAR_EVENT)
451 if (ngx_add_event(r->connection->write, NGX_WRITE_EVENT,
452 NGX_CLEAR_EVENT) == NGX_ERROR) {
453#else
454 if (ngx_add_event(r->connection->write, NGX_WRITE_EVENT,
455 NGX_ONESHOT_EVENT) == NGX_ERROR) {
456#endif
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000457 return ngx_http_close_request(r);
458 }
459
Igor Sysoev96f83772002-09-07 10:14:25 +0000460 if (r->connection->sent > 0) {
461 ngx_log_debug(r->connection->log, "sent: " QD_FMT _
462 r->connection->sent);
463 timeout = (ngx_msec_t) (r->connection->sent * 10);
464 ngx_log_debug(r->connection->log, "timeout: %d" _ timeout);
465 ngx_add_timer(r->connection->write, timeout);
466
467 } else {
468 ngx_add_timer(r->connection->write, 10000);
469 }
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000470
471 r->connection->write->event_handler = ngx_http_writer;
472 return rc;
473 }
474
475 if (rc == NGX_ERROR) {
476 /* log http request */
477 return ngx_http_close_request(r);
478 }
479
480 if (rc >= NGX_HTTP_SPECIAL_RESPONSE)
481 return ngx_http_special_response(r, rc);
482
483 /* rc == NGX_OK */
484
Igor Sysoev3a40d482002-09-12 14:42:29 +0000485 if (!r->keepalive) {
486 if (r->lingering_close) {
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000487 return ngx_http_set_lingering_close(r);
488
Igor Sysoev3a40d482002-09-12 14:42:29 +0000489 } else {
490 return ngx_http_close_request(r);
491 }
492 }
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000493
494 /* keepalive */
495
496 ngx_http_close_request(r);
497 r->connection->buffer->pos.mem = r->connection->buffer->last.mem
498 = r->connection->buffer->start;
499 r->connection->read->event_handler = ngx_http_keepalive_handler;
500}
501
Igor Sysoevb0869052002-12-10 18:05:12 +0000502
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000503static int ngx_http_writer(ngx_event_t *ev)
504{
505 int rc;
Igor Sysoeva0bb31f2002-12-02 16:09:40 +0000506 ngx_msec_t timeout;
507 ngx_connection_t *c;
508 ngx_http_request_t *r;
509 ngx_http_core_loc_conf_t *conf;
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000510
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000511 c = (ngx_connection_t *) ev->data;
512 r = (ngx_http_request_t *) c->data;
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000513
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000514 rc = ngx_http_output_filter(r, NULL);
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000515
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000516 ngx_log_debug(ev->log, "output filter in writer: %d" _ rc);
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000517
518 if (rc == NGX_AGAIN) {
519
520 if (c->sent > 0) {
Igor Sysoeva0bb31f2002-12-02 16:09:40 +0000521 conf = (ngx_http_core_loc_conf_t *)
Igor Sysoev207ed5a2002-12-26 16:26:23 +0000522 ngx_http_get_module_loc_conf(r->main ? r->main : r,
523 ngx_http_core_module_ctx);
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000524
525 timeout = (ngx_msec_t) (c->sent * conf->send_timeout);
526
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000527 ngx_log_debug(ev->log, "sent: " QD_FMT _ c->sent);
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000528 ngx_log_debug(ev->log, "timeout: %d" _ timeout);
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000529
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000530 ngx_del_timer(ev);
531 ngx_add_timer(ev, timeout);
532 }
533
534 if (ev->oneshot)
535 if (ngx_add_event(r->connection->write, NGX_WRITE_EVENT,
536 NGX_ONESHOT_EVENT) == NGX_ERROR) {
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000537 return ngx_http_close_request(r);
538 }
539
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000540 return rc;
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000541 }
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000542
543 if (rc == NGX_ERROR)
544 return rc;
545
546 /* rc == NGX_OK */
547
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000548 ngx_log_debug(ev->log, "http writer done");
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000549
Igor Sysoev3a40d482002-09-12 14:42:29 +0000550 if (!r->keepalive) {
551 if (r->lingering_close) {
Igor Sysoev3a17f242002-12-24 17:30:59 +0000552 return ngx_http_set_lingering_close(r);
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000553
Igor Sysoev3a40d482002-09-12 14:42:29 +0000554 } else {
555 return ngx_http_close_request(r);
556 }
557 }
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000558
Igor Sysoev3a40d482002-09-12 14:42:29 +0000559 /* keepalive */
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000560
Igor Sysoev3a40d482002-09-12 14:42:29 +0000561 ngx_http_close_request(r);
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000562 c->buffer->pos.mem = c->buffer->last.mem = c->buffer->start;
563 c->read->event_handler = ngx_http_keepalive_handler;
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000564}
565
Igor Sysoevb0869052002-12-10 18:05:12 +0000566
Igor Sysoev42feecb2002-12-15 06:25:09 +0000567static int ngx_http_block_read(ngx_event_t *ev)
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000568{
Igor Sysoev42feecb2002-12-15 06:25:09 +0000569 ngx_log_debug(ev->log, "http read blocked");
570
571 ev->blocked = 1;
572 return ngx_del_event(ev, NGX_READ_EVENT, 0);
573}
574
575
576int ngx_http_discard_body(ngx_http_request_t *r)
577{
578 ngx_log_debug(r->connection->log, "set discard body");
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000579
580 ngx_del_timer(r->connection->read);
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000581
Igor Sysoev42feecb2002-12-15 06:25:09 +0000582 if (r->client_content_length)
583 r->connection->read->event_handler = ngx_http_read_discarded_body;
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000584
585 return NGX_OK;
586}
587
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000588
Igor Sysoev42feecb2002-12-15 06:25:09 +0000589static int ngx_http_read_discarded_body(ngx_event_t *ev)
590{
591 size_t size;
592 ssize_t n;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000593 ngx_connection_t *c;
594 ngx_http_request_t *r;
595 ngx_http_core_loc_conf_t *lcf;
Igor Sysoev42feecb2002-12-15 06:25:09 +0000596
597 ngx_log_debug(ev->log, "http read discarded body");
598
599 if (ev->timedout)
600 return NGX_ERROR;
601
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000602 c = (ngx_connection_t *) ev->data;
603 r = (ngx_http_request_t *) c->data;
604
605 lcf = (ngx_http_core_loc_conf_t *)
606 ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx);
607
Igor Sysoev42feecb2002-12-15 06:25:09 +0000608 if (r->discarded_buffer == NULL)
609 ngx_test_null(r->discarded_buffer,
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000610 ngx_palloc(r->pool, lcf->discarded_buffer_size),
Igor Sysoev42feecb2002-12-15 06:25:09 +0000611 NGX_ERROR);
612
613 size = r->client_content_length;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000614 if (size > lcf->discarded_buffer_size)
615 size = lcf->discarded_buffer_size;
Igor Sysoev42feecb2002-12-15 06:25:09 +0000616
617 n = ngx_event_recv(c, r->discarded_buffer, size);
618 if (n == NGX_ERROR)
619 return NGX_ERROR;
620
621 if (n == NGX_AGAIN)
622 return NGX_OK;
623
624 r->client_content_length -= n;
625 /* XXX: what if r->client_content_length == 0 ? */
626 return NGX_OK;
627}
628
629
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000630static int ngx_http_keepalive_handler(ngx_event_t *ev)
631{
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000632 ssize_t n;
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000633 ngx_connection_t *c;
634 ngx_http_log_ctx_t *ctx;
635
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000636 c = (ngx_connection_t *) ev->data;
637
Igor Sysoev42feecb2002-12-15 06:25:09 +0000638 ngx_log_debug(ev->log, "http keepalive handler");
Igor Sysoev1af7c822002-09-13 14:47:42 +0000639
640 if (ev->timedout)
641 return NGX_DONE;
642
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000643 n = ngx_event_recv(c, c->buffer->last.mem,
644 c->buffer->end - c->buffer->last.mem);
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000645
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000646 if (n == NGX_AGAIN || n == NGX_ERROR)
647 return n;
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000648
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000649 ctx = (ngx_http_log_ctx_t *) ev->log->data;
650 ev->log->handler = NULL;
651
652 if (n == 0) {
653 ngx_log_error(NGX_LOG_INFO, ev->log, 0,
654 "client %s closed keepalive connection", ctx->client);
655 return NGX_DONE;
656 }
657
658 c->buffer->last.mem += n;
659 ev->log->handler = ngx_http_log_error;
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000660 ctx->action = "reading client request line";
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000661
662 return ngx_http_init_request(ev);
663}
664
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000665
Igor Sysoev42feecb2002-12-15 06:25:09 +0000666static int ngx_http_set_lingering_close(ngx_http_request_t *r)
Igor Sysoev1af7c822002-09-13 14:47:42 +0000667{
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000668 ngx_http_core_loc_conf_t *lcf;
669
670 lcf = (ngx_http_core_loc_conf_t *)
671 ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx);
672
673 r->lingering_time = ngx_time() + lcf->lingering_time;
Igor Sysoev42feecb2002-12-15 06:25:09 +0000674 r->connection->read->event_handler = ngx_http_lingering_close_handler;
675
676 ngx_del_timer(r->connection->read);
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000677 ngx_add_timer(r->connection->read, lcf->lingering_timeout);
Igor Sysoev42feecb2002-12-15 06:25:09 +0000678
Igor Sysoev0d2bda52002-12-24 07:09:57 +0000679 if (r->connection->read->blocked) {
680 if (ngx_add_event(r->connection->read, NGX_READ_EVENT,
Igor Sysoev42feecb2002-12-15 06:25:09 +0000681#if (HAVE_CLEAR_EVENT)
Igor Sysoev0d2bda52002-12-24 07:09:57 +0000682 NGX_CLEAR_EVENT) == NGX_ERROR)
Igor Sysoev42feecb2002-12-15 06:25:09 +0000683#else
Igor Sysoev0d2bda52002-12-24 07:09:57 +0000684 NGX_ONESHOT_EVENT) == NGX_ERROR)
Igor Sysoev42feecb2002-12-15 06:25:09 +0000685#endif
Igor Sysoev0d2bda52002-12-24 07:09:57 +0000686 {
687 return ngx_http_close_request(r);
688 }
Igor Sysoev42feecb2002-12-15 06:25:09 +0000689 }
690
691 if (ngx_shutdown_socket(r->connection->fd, NGX_WRITE_SHUTDOWN) == -1)
692 {
693 ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_socket_errno,
694 ngx_shutdown_socket_n " failed");
695 return ngx_http_close_request(r);
696 }
697
698 return NGX_OK;
699}
700
701
702static int ngx_http_lingering_close_handler(ngx_event_t *ev)
703{
704 ssize_t n;
705 ngx_msec_t timer;
Igor Sysoev1af7c822002-09-13 14:47:42 +0000706 ngx_connection_t *c;
707 ngx_http_request_t *r;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000708 ngx_http_core_loc_conf_t *lcf;
Igor Sysoev1af7c822002-09-13 14:47:42 +0000709
Igor Sysoev42feecb2002-12-15 06:25:09 +0000710 ngx_log_debug(ev->log, "http lingering close handler");
Igor Sysoev1af7c822002-09-13 14:47:42 +0000711
Igor Sysoev0d2bda52002-12-24 07:09:57 +0000712 if (ev->timedout) {
713 return ngx_http_close_request(r);
714 }
Igor Sysoev1af7c822002-09-13 14:47:42 +0000715
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000716 c = (ngx_connection_t *) ev->data;
717 r = (ngx_http_request_t *) c->data;
718
Igor Sysoev1af7c822002-09-13 14:47:42 +0000719 timer = r->lingering_time - ngx_time();
Igor Sysoev0d2bda52002-12-24 07:09:57 +0000720 if (timer <= 0) {
721 return ngx_http_close_request(r);
722 }
Igor Sysoev1af7c822002-09-13 14:47:42 +0000723
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000724 lcf = (ngx_http_core_loc_conf_t *)
725 ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx);
726
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000727 if (r->discarded_buffer == NULL) {
728 if (r->header_in->end - r->header_in->last.mem
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000729 >= lcf->discarded_buffer_size) {
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000730 r->discarded_buffer = r->header_in->last.mem;
731
732 } else {
733 ngx_test_null(r->discarded_buffer,
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000734 ngx_palloc(c->pool, lcf->discarded_buffer_size),
Igor Sysoev0d2bda52002-12-24 07:09:57 +0000735 ngx_http_close_request(r));
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000736 }
737 }
Igor Sysoev1af7c822002-09-13 14:47:42 +0000738
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000739 n = ngx_event_recv(c, r->discarded_buffer, lcf->discarded_buffer_size);
Igor Sysoev1af7c822002-09-13 14:47:42 +0000740
Igor Sysoev0d2bda52002-12-24 07:09:57 +0000741 ngx_log_debug(ev->log, "lingering read: %d" _ n);
Igor Sysoev1af7c822002-09-13 14:47:42 +0000742
Igor Sysoev0d2bda52002-12-24 07:09:57 +0000743 if (n == NGX_ERROR || n == 0) {
744 return ngx_http_close_request(r);
745 }
Igor Sysoev1af7c822002-09-13 14:47:42 +0000746
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000747 timer *= 1000;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000748 if (timer > lcf->lingering_timeout) {
749 timer = lcf->lingering_timeout;
Igor Sysoev0d2bda52002-12-24 07:09:57 +0000750 }
Igor Sysoev1af7c822002-09-13 14:47:42 +0000751
752 ngx_del_timer(ev);
Igor Sysoev682bf8e2002-09-16 15:01:44 +0000753 ngx_add_timer(ev, timer);
Igor Sysoev1af7c822002-09-13 14:47:42 +0000754
755 return NGX_OK;
756}
757
Igor Sysoev2b542382002-08-20 14:48:28 +0000758
Igor Sysoev2ba1ee02002-10-04 17:58:04 +0000759static int ngx_http_close_connection(ngx_event_t *ev)
760{
761 int i, len;
762 char **requests, *requests_line, *prev, *new;
763 ngx_connection_t *c = (ngx_connection_t *) ev->data;
764
765 if (c->requests->nelts > 1) {
766 len = c->requests_len + c->requests->nelts * 2 - 1;
767
768 ngx_test_null(requests_line, ngx_palloc(c->pool, len),
769 ngx_event_close_connection(ev));
770
771 requests = (char **) c->requests->elts;
772 prev = requests_line;
773 new = ngx_cpystrn(prev, requests[0], len);
774 len -= new - prev;
775 prev = new;
776
777 for (i = 1; i < c->requests->nelts; i++) {
778 new = ngx_cpystrn(prev, ", ", len);
779 new = ngx_cpystrn(new, requests[i], len);
780 len -= new - prev;
781 prev = new;
782 }
783
784 } else {
785 requests_line = * (char **) c->requests->elts;
786 }
787
788 ngx_log_error(NGX_LOG_INFO, c->log, 0,
789 "REQUESTS: %d, '%s'", c->requests->nelts, requests_line);
790
791 return ngx_event_close_connection(ev);
792}
793
794
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000795static size_t ngx_http_log_error(void *data, char *buf, size_t len)
796{
797 ngx_http_log_ctx_t *ctx = (ngx_http_log_ctx_t *) data;
Igor Sysoeva58e3ca2002-09-02 14:48:24 +0000798
Igor Sysoev0ad17c02002-08-26 15:18:19 +0000799 if (ctx->url)
800 return ngx_snprintf(buf, len, " while %s, client: %s, URL: %s",
801 ctx->action, ctx->client, ctx->url);
802 else
803 return ngx_snprintf(buf, len, " while %s, client: %s",
804 ctx->action, ctx->client);
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000805}