Mercurial > hg > nginx-ranges
diff src/http/ngx_http_request.c @ 539:5f4de8cf0d9d
Merge with current.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Tue, 15 Sep 2009 03:43:40 +0400 |
parents | 80f7156c2965 |
children | 005a70f9573b |
line wrap: on
line diff
--- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -36,6 +36,9 @@ static ngx_int_t ngx_http_find_virtual_s u_char *host, size_t len); static void ngx_http_request_handler(ngx_event_t *ev); +static void ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc); +static void ngx_http_terminate_handler(ngx_http_request_t *r); +static void ngx_http_finalize_connection(ngx_http_request_t *r); static ngx_int_t ngx_http_set_write_handler(ngx_http_request_t *r); static void ngx_http_writer(ngx_http_request_t *r); static void ngx_http_request_finalizer(ngx_http_request_t *r); @@ -46,7 +49,7 @@ static void ngx_http_set_lingering_close static void ngx_http_lingering_close_handler(ngx_event_t *ev); static ngx_int_t ngx_http_post_action(ngx_http_request_t *r); static void ngx_http_close_request(ngx_http_request_t *r, ngx_int_t error); -static void ngx_http_request_done(ngx_http_request_t *r, ngx_int_t error); +static void ngx_http_free_request(ngx_http_request_t *r, ngx_int_t error); static void ngx_http_log_request(ngx_http_request_t *r); static void ngx_http_close_connection(ngx_connection_t *c); @@ -478,6 +481,7 @@ ngx_http_init_request(ngx_event_t *rev) c->destroyed = 0; r->main = r; + r->count = 1; tp = ngx_timeofday(); r->start_sec = tp->sec; @@ -889,9 +893,10 @@ ngx_http_process_request_line(ngx_event_ static void ngx_http_process_request_headers(ngx_event_t *rev) { + u_char *p; + size_t len; ssize_t n; ngx_int_t rc, rv; - ngx_str_t header; ngx_table_elt_t *h; ngx_connection_t *c; ngx_http_header_t *hh; @@ -931,19 +936,17 @@ ngx_http_process_request_headers(ngx_eve } if (rv == NGX_DECLINED) { - header.len = r->header_in->end - r->header_name_start; - header.data = r->header_name_start; - - if (header.len > NGX_MAX_ERROR_STR - 300) { - header.len = NGX_MAX_ERROR_STR - 300; - header.data[header.len++] = '.'; - header.data[header.len++] = '.'; - header.data[header.len++] = '.'; + len = r->header_in->end - r->header_name_start; + p = r->header_name_start; + + if (len > NGX_MAX_ERROR_STR - 300) { + len = NGX_MAX_ERROR_STR - 300; + p[len++] = '.'; p[len++] = '.'; p[len++] = '.'; } ngx_log_error(NGX_LOG_INFO, c->log, 0, - "client sent too long header line: \"%V\"", - &header); + "client sent too long header line: \"%*s\"", + len, r->header_name_start); ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); return; } @@ -965,12 +968,10 @@ ngx_http_process_request_headers(ngx_eve /* there was error while a header line parsing */ - header.len = r->header_end - r->header_name_start; - header.data = r->header_name_start; - ngx_log_error(NGX_LOG_INFO, c->log, 0, - "client sent invalid header line: \"%V\"", - &header); + "client sent invalid header line: \"%*s\"", + r->header_end - r->header_name_start, + r->header_name_start); continue; } @@ -1050,11 +1051,10 @@ ngx_http_process_request_headers(ngx_eve /* rc == NGX_HTTP_PARSE_INVALID_HEADER: "\r" is not followed by "\n" */ - header.len = r->header_end - r->header_name_start; - header.data = r->header_name_start; ngx_log_error(NGX_LOG_INFO, c->log, 0, - "client sent invalid header line: \"%V\\r...\"", - &header); + "client sent invalid header line: \"%*s\\r...\"", + r->header_end - r->header_name_start, + r->header_name_start); ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); return; } @@ -1382,8 +1382,13 @@ ngx_http_process_user_agent(ngx_http_req r->headers_in.msie4 = 1; /* fall through */ case '5': + r->headers_in.msie6 = 1; + break; case '6': - r->headers_in.msie6 = 1; + if (ngx_strstrn(msie + 8, "SV1", 3 - 1) == NULL) { + r->headers_in.msie6 = 1; + } + break; } } @@ -1801,13 +1806,15 @@ ngx_http_run_posted_requests(ngx_connect ngx_int_t -ngx_http_post_request(ngx_http_request_t *r) +ngx_http_post_request(ngx_http_request_t *r, ngx_http_posted_request_t *pr) { - ngx_http_posted_request_t *pr, **p; - - pr = ngx_palloc(r->pool, sizeof(ngx_http_posted_request_t)); + ngx_http_posted_request_t **p; + if (pr == NULL) { - return NGX_ERROR; + pr = ngx_palloc(r->pool, sizeof(ngx_http_posted_request_t)); + if (pr == NULL) { + return NGX_ERROR; + } } pr->request = r; @@ -1828,17 +1835,17 @@ ngx_http_finalize_request(ngx_http_reque ngx_http_request_t *pr; ngx_http_core_loc_conf_t *clcf; + c = r->connection; + + ngx_log_debug5(NGX_LOG_DEBUG_HTTP, c->log, 0, + "http finalize request: %d, \"%V?%V\" a:%d, c:%d", + rc, &r->uri, &r->args, r == c->data, r->main->count); + if (rc == NGX_DONE) { - /* the request pool may be already destroyed */ + ngx_http_finalize_connection(r); return; } - c = r->connection; - - ngx_log_debug4(NGX_LOG_DEBUG_HTTP, c->log, 0, - "http finalize request: %d, \"%V?%V\" %d", - rc, &r->uri, &r->args, r == c->data); - if (rc == NGX_OK && r->filter_finalize) { c->error = 1; return; @@ -1860,15 +1867,15 @@ ngx_http_finalize_request(ngx_http_reque || rc == NGX_HTTP_CLIENT_CLOSED_REQUEST || c->error) { - if (rc > 0 && r->headers_out.status == 0) { - r->headers_out.status = rc; - } - if (ngx_http_post_action(r) == NGX_OK) { return; } - ngx_http_close_request(r, 0); + if (r->main->blocked) { + r->write_event_handler = ngx_http_request_finalizer; + } + + ngx_http_terminate_request(r, rc); return; } @@ -1877,7 +1884,7 @@ ngx_http_finalize_request(ngx_http_reque || rc == NGX_HTTP_NO_CONTENT) { if (rc == NGX_HTTP_CLOSE) { - ngx_http_close_request(r, rc); + ngx_http_terminate_request(r, rc); return; } @@ -1903,7 +1910,7 @@ ngx_http_finalize_request(ngx_http_reque if (r->buffered || r->postponed) { if (ngx_http_set_write_handler(r) != NGX_OK) { - ngx_http_close_request(r->main, 0); + ngx_http_terminate_request(r, 0); } return; @@ -1921,6 +1928,8 @@ ngx_http_finalize_request(ngx_http_reque if (r == c->data) { + r->main->count--; + if (!r->logged) { clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); @@ -1954,8 +1963,9 @@ ngx_http_finalize_request(ngx_http_reque } } - if (ngx_http_post_request(pr) != NGX_OK) { - ngx_http_close_request(r->main, 0); + if (ngx_http_post_request(pr, NULL) != NGX_OK) { + r->main->count++; + ngx_http_terminate_request(r, 0); return; } @@ -1966,10 +1976,10 @@ ngx_http_finalize_request(ngx_http_reque return; } - if (r->buffered || c->buffered || r->postponed) { + if (r->buffered || c->buffered || r->postponed || r->blocked) { if (ngx_http_set_write_handler(r) != NGX_OK) { - ngx_http_close_request(r, 0); + ngx_http_terminate_request(r, 0); } return; @@ -2001,11 +2011,77 @@ ngx_http_finalize_request(ngx_http_reque ngx_del_timer(c->write); } - if (c->destroyed) { + if (c->read->eof) { + ngx_http_close_request(r, 0); return; } - if (c->read->eof) { + ngx_http_finalize_connection(r); +} + + +static void +ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc) +{ + ngx_http_cleanup_t *cln; + ngx_http_request_t *mr; + ngx_http_ephemeral_t *e; + + mr = r->main; + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http terminate request count:%d", mr->count); + + cln = mr->cleanup; + mr->cleanup = NULL; + + while (cln) { + if (cln->handler) { + cln->handler(cln->data); + } + + cln = cln->next; + } + + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http terminate cleanup count:%d blk:%d", + mr->count, mr->blocked); + + if (mr->write_event_handler) { + + if (mr->blocked) { + return; + } + + e = ngx_http_ephemeral(mr); + mr->posted_requests = NULL; + mr->write_event_handler = ngx_http_terminate_handler; + (void) ngx_http_post_request(mr, &e->terminal_posted_request); + return; + } + + ngx_http_close_request(mr, rc); +} + + +static void +ngx_http_terminate_handler(ngx_http_request_t *r) +{ + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http terminate handler count:%d", r->count); + + r->count = 1; + + ngx_http_close_request(r, 0); +} + + +static void +ngx_http_finalize_connection(ngx_http_request_t *r) +{ + ngx_http_core_loc_conf_t *clcf; + + if (r->main->count != 1) { ngx_http_close_request(r, 0); return; } @@ -2100,7 +2176,7 @@ ngx_http_writer(ngx_http_request_t *r) } } else { - if (wev->delayed) { + if (wev->delayed || r->aio) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, "http writer delayed"); @@ -2114,10 +2190,6 @@ ngx_http_writer(ngx_http_request_t *r) rc = ngx_http_output_filter(r, NULL); - if (c->destroyed) { - return; - } - ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, "http writer output filter: %d, \"%V?%V\"", rc, &r->uri, &r->args); @@ -2319,7 +2391,7 @@ ngx_http_set_keepalive(ngx_http_request_ } } - ngx_http_request_done(r, 0); + ngx_http_free_request(r, 0); c->data = hc; @@ -2766,19 +2838,33 @@ ngx_http_post_action(ngx_http_request_t static void -ngx_http_close_request(ngx_http_request_t *r, ngx_int_t error) +ngx_http_close_request(ngx_http_request_t *r, ngx_int_t rc) { ngx_connection_t *c; + r = r->main; c = r->connection; - ngx_http_request_done(r->main, error); + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, + "http request count:%d blk:%d", r->count, r->blocked); + + if (r->count == 0) { + ngx_log_error(NGX_LOG_ALERT, c->log, 0, "http request count is zero"); + } + + r->count--; + + if (r->count || r->blocked) { + return; + } + + ngx_http_free_request(r, rc); ngx_http_close_connection(c); } static void -ngx_http_request_done(ngx_http_request_t *r, ngx_int_t error) +ngx_http_free_request(ngx_http_request_t *r, ngx_int_t rc) { ngx_log_t *log; struct linger linger; @@ -2813,8 +2899,8 @@ ngx_http_request_done(ngx_http_request_t #endif - if (error && r->headers_out.status == 0) { - r->headers_out.status = error; + if (rc > 0 && (r->headers_out.status == 0 || r->connection->sent == 0)) { + r->headers_out.status = rc; } log->action = "logging request";