comparison src/http/ngx_http_request.c @ 324:7cf404023f50 NGINX_0_5_32

nginx 0.5.32 *) Change: now nginx tries to set the "worker_priority", "worker_rlimit_nofile", "worker_rlimit_core", and "worker_rlimit_sigpending" without super-user privileges. *) Change: now nginx escapes space and "%" in request to a mail proxy authentication server. *) Change: now nginx escapes "%" in $memcached_key variable. *) Change: the special make target "upgrade1" was defined for online upgrade of 0.1.x versions. *) Feature: the "add_header Last-Modified ..." directive changes the "Last-Modified" response header line. *) Feature: the mail proxy supports AUTHENTICATE in IMAP mode. Thanks to Maxim Dounin. *) Feature: the mail proxy supports STARTTLS in SMTP mode. Thanks to Maxim Dounin. *) Bugfix: nginx did not close directory file on HEAD request if autoindex was used. Thanks to Arkadiusz Patyk. *) Bugfix: the "proxy_hide_header" and "fastcgi_hide_header" directives did not hide response header lines whose name was longer than 32 characters. Thanks to Manlio Perillo. *) Bugfix: active connection counter always increased if mail proxy was used. *) Bugfix: if backend returned response header only using non-buffered proxy, then nginx closed backend connection on timeout. *) Bugfix: nginx did not support several "Connection" request header lines. *) Bugfix: a charset set by the "charset" directive was not appended to the "Content-Type" header set by $r->send_http_header(). *) Bugfix: a segmentation fault might occur in worker process if /dev/poll method was used. *) Bugfix: nginx did not work on FreeBSD/sparc64. *) Bugfix: a segmentation fault occurred in worker process if invalid address was set in the "auth_http" directive. *) Bugfix: now nginx uses default listen backlog value 511 on all platforms except FreeBSD. Thanks to Jiang Hong. *) Bugfix: now Solaris sendfilev() is not used to transfer the client request body to FastCGI-server via the unix domain socket. *) Bugfix: if the same host without specified port was used as backend for HTTP and HTTPS, then nginx used only one port - 80 or 443. *) Bugfix: the "proxy_ignore_client_abort" and "fastcgi_ignore_client_abort" directives did not work; bug appeared in 0.5.13.
author Igor Sysoev <http://sysoev.ru>
date Mon, 24 Sep 2007 00:00:00 +0400
parents 94e16de3c33f
children f70f2f565fe0
comparison
equal deleted inserted replaced
323:85aeb2da6e4c 324:7cf404023f50
19 19
20 static ngx_int_t ngx_http_process_header_line(ngx_http_request_t *r, 20 static ngx_int_t ngx_http_process_header_line(ngx_http_request_t *r,
21 ngx_table_elt_t *h, ngx_uint_t offset); 21 ngx_table_elt_t *h, ngx_uint_t offset);
22 static ngx_int_t ngx_http_process_unique_header_line(ngx_http_request_t *r, 22 static ngx_int_t ngx_http_process_unique_header_line(ngx_http_request_t *r,
23 ngx_table_elt_t *h, ngx_uint_t offset); 23 ngx_table_elt_t *h, ngx_uint_t offset);
24 static ngx_int_t ngx_http_process_connection(ngx_http_request_t *r,
25 ngx_table_elt_t *h, ngx_uint_t offset);
24 static ngx_int_t ngx_http_process_cookie(ngx_http_request_t *r, 26 static ngx_int_t ngx_http_process_cookie(ngx_http_request_t *r,
25 ngx_table_elt_t *h, ngx_uint_t offset); 27 ngx_table_elt_t *h, ngx_uint_t offset);
26 28
27 static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r); 29 static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r);
28 static void ngx_http_process_request(ngx_http_request_t *r); 30 static void ngx_http_process_request(ngx_http_request_t *r);
32 static void ngx_http_request_handler(ngx_event_t *ev); 34 static void ngx_http_request_handler(ngx_event_t *ev);
33 static ngx_int_t ngx_http_set_write_handler(ngx_http_request_t *r); 35 static ngx_int_t ngx_http_set_write_handler(ngx_http_request_t *r);
34 static void ngx_http_writer(ngx_http_request_t *r); 36 static void ngx_http_writer(ngx_http_request_t *r);
35 37
36 static void ngx_http_block_read(ngx_http_request_t *r); 38 static void ngx_http_block_read(ngx_http_request_t *r);
39 static void ngx_http_test_read(ngx_http_request_t *r);
37 static void ngx_http_set_keepalive(ngx_http_request_t *r); 40 static void ngx_http_set_keepalive(ngx_http_request_t *r);
38 static void ngx_http_keepalive_handler(ngx_event_t *ev); 41 static void ngx_http_keepalive_handler(ngx_event_t *ev);
39 static void ngx_http_set_lingering_close(ngx_http_request_t *r); 42 static void ngx_http_set_lingering_close(ngx_http_request_t *r);
40 static void ngx_http_lingering_close_handler(ngx_event_t *ev); 43 static void ngx_http_lingering_close_handler(ngx_event_t *ev);
41 static ngx_int_t ngx_http_post_action(ngx_http_request_t *r); 44 static ngx_int_t ngx_http_post_action(ngx_http_request_t *r);
69 ngx_http_header_t ngx_http_headers_in[] = { 72 ngx_http_header_t ngx_http_headers_in[] = {
70 { ngx_string("Host"), offsetof(ngx_http_headers_in_t, host), 73 { ngx_string("Host"), offsetof(ngx_http_headers_in_t, host),
71 ngx_http_process_unique_header_line }, 74 ngx_http_process_unique_header_line },
72 75
73 { ngx_string("Connection"), offsetof(ngx_http_headers_in_t, connection), 76 { ngx_string("Connection"), offsetof(ngx_http_headers_in_t, connection),
74 ngx_http_process_unique_header_line }, 77 ngx_http_process_connection },
75 78
76 { ngx_string("If-Modified-Since"), 79 { ngx_string("If-Modified-Since"),
77 offsetof(ngx_http_headers_in_t, if_modified_since), 80 offsetof(ngx_http_headers_in_t, if_modified_since),
78 ngx_http_process_header_line }, 81 ngx_http_process_unique_header_line },
79 82
80 { ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent), 83 { ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent),
81 ngx_http_process_header_line }, 84 ngx_http_process_header_line },
82 85
83 { ngx_string("Referer"), offsetof(ngx_http_headers_in_t, referer), 86 { ngx_string("Referer"), offsetof(ngx_http_headers_in_t, referer),
834 } 837 }
835 838
836 ngx_log_error(NGX_LOG_INFO, c->log, 0, 839 ngx_log_error(NGX_LOG_INFO, c->log, 0,
837 "client sent too long header line: \"%V\"", 840 "client sent too long header line: \"%V\"",
838 &header); 841 &header);
839 ngx_http_close_request(r, NGX_HTTP_BAD_REQUEST); 842 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
840 return; 843 return;
841 } 844 }
842 } 845 }
843 846
844 n = ngx_http_read_request_header(r); 847 n = ngx_http_read_request_header(r);
946 header.len = r->header_end - r->header_name_start; 949 header.len = r->header_end - r->header_name_start;
947 header.data = r->header_name_start; 950 header.data = r->header_name_start;
948 ngx_log_error(NGX_LOG_INFO, c->log, 0, 951 ngx_log_error(NGX_LOG_INFO, c->log, 0,
949 "client sent invalid header line: \"%V\\r...\"", 952 "client sent invalid header line: \"%V\\r...\"",
950 &header); 953 &header);
951 ngx_http_close_request(r, NGX_HTTP_BAD_REQUEST); 954 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
952 return; 955 return;
953 } 956 }
954 } 957 }
955 958
956 959
1193 &h->key, &h->value, &(*ph)->key, &(*ph)->value); 1196 &h->key, &h->value, &(*ph)->key, &(*ph)->value);
1194 1197
1195 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); 1198 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
1196 1199
1197 return NGX_ERROR; 1200 return NGX_ERROR;
1201 }
1202
1203
1204 static ngx_int_t
1205 ngx_http_process_connection(ngx_http_request_t *r, ngx_table_elt_t *h,
1206 ngx_uint_t offset)
1207 {
1208 if (ngx_strstr(h->value.data, "close")) {
1209 r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE;
1210
1211 } else if (ngx_strstr(h->value.data, "keep-alive")) {
1212 r->headers_in.connection_type = NGX_HTTP_CONNECTION_KEEP_ALIVE;
1213 }
1214
1215 return NGX_OK;
1198 } 1216 }
1199 1217
1200 1218
1201 static ngx_int_t 1219 static ngx_int_t
1202 ngx_http_process_cookie(ngx_http_request_t *r, ngx_table_elt_t *h, 1220 ngx_http_process_cookie(ngx_http_request_t *r, ngx_table_elt_t *h,
1292 "client sent POST method without \"Content-Length\" header"); 1310 "client sent POST method without \"Content-Length\" header");
1293 ngx_http_finalize_request(r, NGX_HTTP_LENGTH_REQUIRED); 1311 ngx_http_finalize_request(r, NGX_HTTP_LENGTH_REQUIRED);
1294 return NGX_ERROR; 1312 return NGX_ERROR;
1295 } 1313 }
1296 1314
1297 if (r->method & (NGX_HTTP_TRACE)) { 1315 if (r->method & NGX_HTTP_TRACE) {
1298 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, 1316 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1299 "client sent TRACE method"); 1317 "client sent TRACE method");
1300 ngx_http_finalize_request(r, NGX_HTTP_NOT_ALLOWED); 1318 ngx_http_finalize_request(r, NGX_HTTP_NOT_ALLOWED);
1301 return NGX_ERROR; 1319 return NGX_ERROR;
1302 } 1320 }
1315 "client sent plain HTTP request to HTTPS port"); 1333 "client sent plain HTTP request to HTTPS port");
1316 ngx_http_finalize_request(r, NGX_HTTP_TO_HTTPS); 1334 ngx_http_finalize_request(r, NGX_HTTP_TO_HTTPS);
1317 return NGX_ERROR; 1335 return NGX_ERROR;
1318 } 1336 }
1319 1337
1320 if (r->headers_in.connection) { 1338 if (r->headers_in.connection_type == NGX_HTTP_CONNECTION_KEEP_ALIVE) {
1321 if (r->headers_in.connection->value.len == 5 1339 if (r->headers_in.keep_alive) {
1322 && ngx_strcasecmp(r->headers_in.connection->value.data, 1340 r->headers_in.keep_alive_n =
1323 (u_char *) "close") 1341 ngx_atotm(r->headers_in.keep_alive->value.data,
1324 == 0) 1342 r->headers_in.keep_alive->value.len);
1325 {
1326 r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE;
1327
1328 } else if (r->headers_in.connection->value.len == 10
1329 && ngx_strcasecmp(r->headers_in.connection->value.data,
1330 (u_char *) "keep-alive")
1331 == 0)
1332 {
1333 r->headers_in.connection_type = NGX_HTTP_CONNECTION_KEEP_ALIVE;
1334
1335 if (r->headers_in.keep_alive) {
1336 r->headers_in.keep_alive_n =
1337 ngx_atotm(r->headers_in.keep_alive->value.data,
1338 r->headers_in.keep_alive->value.len);
1339 }
1340 } 1343 }
1341 } 1344 }
1342 1345
1343 if (r->headers_in.user_agent) { 1346 if (r->headers_in.user_agent) {
1344 1347
1708 ngx_event_t *wev; 1711 ngx_event_t *wev;
1709 ngx_http_core_loc_conf_t *clcf; 1712 ngx_http_core_loc_conf_t *clcf;
1710 1713
1711 r->http_state = NGX_HTTP_WRITING_REQUEST_STATE; 1714 r->http_state = NGX_HTTP_WRITING_REQUEST_STATE;
1712 1715
1713 r->read_event_handler = ngx_http_block_read; 1716 r->read_event_handler = ngx_http_test_read;
1714 r->write_event_handler = ngx_http_writer; 1717 r->write_event_handler = ngx_http_writer;
1715 1718
1716 wev = r->connection->write; 1719 wev = r->connection->write;
1717 1720
1718 if (wev->ready && wev->delayed) { 1721 if (wev->ready && wev->delayed) {
1821 1824
1822 1825
1823 static void 1826 static void
1824 ngx_http_block_read(ngx_http_request_t *r) 1827 ngx_http_block_read(ngx_http_request_t *r)
1825 { 1828 {
1829 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1830 "http read blocked");
1831
1832 /* aio does not call this handler */
1833
1834 if ((ngx_event_flags & NGX_USE_LEVEL_EVENT)
1835 && r->connection->read->active)
1836 {
1837 if (ngx_del_event(r->connection->read, NGX_READ_EVENT, 0)
1838 == NGX_ERROR)
1839 {
1840 ngx_http_close_request(r, 0);
1841 }
1842 }
1843 }
1844
1845
1846 static void
1847 ngx_http_test_read(ngx_http_request_t *r)
1848 {
1826 int n; 1849 int n;
1827 char buf[1]; 1850 char buf[1];
1828 ngx_err_t err; 1851 ngx_err_t err;
1829 ngx_event_t *rev; 1852 ngx_event_t *rev;
1830 ngx_connection_t *c; 1853 ngx_connection_t *c;
1831 1854
1832 c = r->connection; 1855 c = r->connection;
1833 rev = c->read; 1856 rev = c->read;
1834 1857
1835 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http read blocked"); 1858 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http test read");
1836 1859
1837 #if (NGX_HAVE_KQUEUE) 1860 #if (NGX_HAVE_KQUEUE)
1838 1861
1839 if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { 1862 if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
1840 1863