3 * Copyright (C) Igor Sysoev
7 #include <ngx_config.h>
12 static void ngx_http_init_request(ngx_event_t
*ev
);
13 static void ngx_http_process_request_line(ngx_event_t
*rev
);
14 static void ngx_http_process_request_headers(ngx_event_t
*rev
);
15 static ssize_t
ngx_http_read_request_header(ngx_http_request_t
*r
);
16 static ngx_int_t
ngx_http_alloc_large_header_buffer(ngx_http_request_t
*r
,
17 ngx_uint_t request_line
);
19 static ngx_int_t
ngx_http_process_header_line(ngx_http_request_t
*r
,
20 ngx_table_elt_t
*h
, ngx_uint_t offset
);
21 static ngx_int_t
ngx_http_process_unique_header_line(ngx_http_request_t
*r
,
22 ngx_table_elt_t
*h
, ngx_uint_t offset
);
23 static ngx_int_t
ngx_http_process_host(ngx_http_request_t
*r
,
24 ngx_table_elt_t
*h
, ngx_uint_t offset
);
25 static ngx_int_t
ngx_http_process_connection(ngx_http_request_t
*r
,
26 ngx_table_elt_t
*h
, ngx_uint_t offset
);
27 static ngx_int_t
ngx_http_process_user_agent(ngx_http_request_t
*r
,
28 ngx_table_elt_t
*h
, ngx_uint_t offset
);
29 static ngx_int_t
ngx_http_process_cookie(ngx_http_request_t
*r
,
30 ngx_table_elt_t
*h
, ngx_uint_t offset
);
32 static ngx_int_t
ngx_http_process_request_header(ngx_http_request_t
*r
);
33 static void ngx_http_process_request(ngx_http_request_t
*r
);
34 static ssize_t
ngx_http_validate_host(u_char
*host
, size_t len
);
35 static ngx_int_t
ngx_http_find_virtual_server(ngx_http_request_t
*r
,
36 u_char
*host
, size_t len
);
38 static void ngx_http_request_handler(ngx_event_t
*ev
);
39 static void ngx_http_terminate_request(ngx_http_request_t
*r
, ngx_int_t rc
);
40 static void ngx_http_terminate_handler(ngx_http_request_t
*r
);
41 static void ngx_http_finalize_connection(ngx_http_request_t
*r
);
42 static ngx_int_t
ngx_http_set_write_handler(ngx_http_request_t
*r
);
43 static void ngx_http_writer(ngx_http_request_t
*r
);
44 static void ngx_http_request_finalizer(ngx_http_request_t
*r
);
46 static void ngx_http_set_keepalive(ngx_http_request_t
*r
);
47 static void ngx_http_keepalive_handler(ngx_event_t
*ev
);
48 static void ngx_http_set_lingering_close(ngx_http_request_t
*r
);
49 static void ngx_http_lingering_close_handler(ngx_event_t
*ev
);
50 static ngx_int_t
ngx_http_post_action(ngx_http_request_t
*r
);
51 static void ngx_http_close_request(ngx_http_request_t
*r
, ngx_int_t error
);
52 static void ngx_http_free_request(ngx_http_request_t
*r
, ngx_int_t error
);
53 static void ngx_http_log_request(ngx_http_request_t
*r
);
54 static void ngx_http_close_connection(ngx_connection_t
*c
);
56 static u_char
*ngx_http_log_error(ngx_log_t
*log
, u_char
*buf
, size_t len
);
57 static u_char
*ngx_http_log_error_handler(ngx_http_request_t
*r
,
58 ngx_http_request_t
*sr
, u_char
*buf
, size_t len
);
61 static void ngx_http_ssl_handshake(ngx_event_t
*rev
);
62 static void ngx_http_ssl_handshake_handler(ngx_connection_t
*c
);
66 static char *ngx_http_client_errors
[] = {
68 /* NGX_HTTP_PARSE_INVALID_METHOD */
69 "client sent invalid method",
71 /* NGX_HTTP_PARSE_INVALID_REQUEST */
72 "client sent invalid request",
74 /* NGX_HTTP_PARSE_INVALID_09_METHOD */
75 "client sent invalid method in HTTP/0.9 request"
79 ngx_http_header_t ngx_http_headers_in
[] = {
80 { ngx_string("Host"), offsetof(ngx_http_headers_in_t
, host
),
81 ngx_http_process_host
},
83 { ngx_string("Connection"), offsetof(ngx_http_headers_in_t
, connection
),
84 ngx_http_process_connection
},
86 { ngx_string("If-Modified-Since"),
87 offsetof(ngx_http_headers_in_t
, if_modified_since
),
88 ngx_http_process_unique_header_line
},
90 { ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t
, user_agent
),
91 ngx_http_process_user_agent
},
93 { ngx_string("Referer"), offsetof(ngx_http_headers_in_t
, referer
),
94 ngx_http_process_header_line
},
96 { ngx_string("Content-Length"),
97 offsetof(ngx_http_headers_in_t
, content_length
),
98 ngx_http_process_unique_header_line
},
100 { ngx_string("Content-Type"),
101 offsetof(ngx_http_headers_in_t
, content_type
),
102 ngx_http_process_header_line
},
104 { ngx_string("Range"), offsetof(ngx_http_headers_in_t
, range
),
105 ngx_http_process_header_line
},
107 { ngx_string("If-Range"),
108 offsetof(ngx_http_headers_in_t
, if_range
),
109 ngx_http_process_unique_header_line
},
111 { ngx_string("Transfer-Encoding"),
112 offsetof(ngx_http_headers_in_t
, transfer_encoding
),
113 ngx_http_process_header_line
},
115 { ngx_string("Expect"),
116 offsetof(ngx_http_headers_in_t
, expect
),
117 ngx_http_process_unique_header_line
},
120 { ngx_string("Accept-Encoding"),
121 offsetof(ngx_http_headers_in_t
, accept_encoding
),
122 ngx_http_process_header_line
},
124 { ngx_string("Via"), offsetof(ngx_http_headers_in_t
, via
),
125 ngx_http_process_header_line
},
128 { ngx_string("Authorization"),
129 offsetof(ngx_http_headers_in_t
, authorization
),
130 ngx_http_process_unique_header_line
},
132 { ngx_string("Keep-Alive"), offsetof(ngx_http_headers_in_t
, keep_alive
),
133 ngx_http_process_header_line
},
135 #if (NGX_HTTP_PROXY || NGX_HTTP_REALIP || NGX_HTTP_GEO)
136 { ngx_string("X-Forwarded-For"),
137 offsetof(ngx_http_headers_in_t
, x_forwarded_for
),
138 ngx_http_process_header_line
},
141 #if (NGX_HTTP_REALIP)
142 { ngx_string("X-Real-IP"),
143 offsetof(ngx_http_headers_in_t
, x_real_ip
),
144 ngx_http_process_header_line
},
147 #if (NGX_HTTP_HEADERS)
148 { ngx_string("Accept"), offsetof(ngx_http_headers_in_t
, accept
),
149 ngx_http_process_header_line
},
151 { ngx_string("Accept-Language"),
152 offsetof(ngx_http_headers_in_t
, accept_language
),
153 ngx_http_process_header_line
},
157 { ngx_string("Depth"), offsetof(ngx_http_headers_in_t
, depth
),
158 ngx_http_process_header_line
},
160 { ngx_string("Destination"), offsetof(ngx_http_headers_in_t
, destination
),
161 ngx_http_process_header_line
},
163 { ngx_string("Overwrite"), offsetof(ngx_http_headers_in_t
, overwrite
),
164 ngx_http_process_header_line
},
166 { ngx_string("Date"), offsetof(ngx_http_headers_in_t
, date
),
167 ngx_http_process_header_line
},
170 { ngx_string("Cookie"), 0, ngx_http_process_cookie
},
172 { ngx_null_string
, 0, NULL
}
177 ngx_http_init_connection(ngx_connection_t
*c
)
180 ngx_http_log_ctx_t
*ctx
;
182 ctx
= ngx_palloc(c
->pool
, sizeof(ngx_http_log_ctx_t
));
184 ngx_http_close_connection(c
);
190 ctx
->current_request
= NULL
;
192 c
->log
->connection
= c
->number
;
193 c
->log
->handler
= ngx_http_log_error
;
195 c
->log
->action
= "reading client request line";
197 c
->log_error
= NGX_ERROR_INFO
;
200 rev
->handler
= ngx_http_init_request
;
201 c
->write
->handler
= ngx_http_empty_handler
;
204 (void) ngx_atomic_fetch_add(ngx_stat_reading
, 1);
208 /* the deferred accept(), rtsig, aio, iocp */
210 if (ngx_use_accept_mutex
) {
211 ngx_post_event(rev
, &ngx_posted_events
);
215 ngx_http_init_request(rev
);
219 ngx_add_timer(rev
, c
->listening
->post_accept_timeout
);
221 if (ngx_handle_read_event(rev
, 0) != NGX_OK
) {
223 (void) ngx_atomic_fetch_add(ngx_stat_reading
, -1);
225 ngx_http_close_connection(c
);
232 ngx_http_init_request(ngx_event_t
*rev
)
237 ngx_http_request_t
*r
;
238 struct sockaddr_in
*sin
;
239 ngx_http_port_t
*port
;
240 ngx_http_in_addr_t
*addr
;
241 ngx_http_log_ctx_t
*ctx
;
242 ngx_http_addr_conf_t
*addr_conf
;
243 ngx_http_connection_t
*hc
;
244 ngx_http_core_srv_conf_t
*cscf
;
245 ngx_http_core_loc_conf_t
*clcf
;
246 ngx_http_core_main_conf_t
*cmcf
;
248 struct sockaddr_in6
*sin6
;
249 ngx_http_in6_addr_t
*addr6
;
253 (void) ngx_atomic_fetch_add(ngx_stat_reading
, -1);
259 ngx_log_error(NGX_LOG_INFO
, c
->log
, NGX_ETIMEDOUT
, "client timed out");
261 ngx_http_close_connection(c
);
270 hc
= ngx_pcalloc(c
->pool
, sizeof(ngx_http_connection_t
));
272 ngx_http_close_connection(c
);
280 ngx_memzero(r
, sizeof(ngx_http_request_t
));
282 r
->pipeline
= hc
->pipeline
;
285 r
->header_in
= hc
->busy
[0];
289 r
= ngx_pcalloc(c
->pool
, sizeof(ngx_http_request_t
));
291 ngx_http_close_connection(c
);
299 r
->http_connection
= hc
;
302 r
->signature
= NGX_HTTP_MODULE
;
304 /* find the server configuration for the address:port */
306 port
= c
->listening
->servers
;
310 if (port
->naddrs
> 1) {
313 * there are several addresses on this port and one of them
314 * is an "*:port" wildcard so getsockname() in ngx_http_server_addr()
315 * is required to determine a server address
318 if (ngx_connection_local_sockaddr(c
, NULL
, 0) != NGX_OK
) {
319 ngx_http_close_connection(c
);
323 switch (c
->local_sockaddr
->sa_family
) {
327 sin6
= (struct sockaddr_in6
*) c
->local_sockaddr
;
331 /* the last address is "*" */
333 for (i
= 0; i
< port
->naddrs
- 1; i
++) {
334 if (ngx_memcmp(&addr6
[i
].addr6
, &sin6
->sin6_addr
, 16) == 0) {
339 addr_conf
= &addr6
[i
].conf
;
344 default: /* AF_INET */
345 sin
= (struct sockaddr_in
*) c
->local_sockaddr
;
349 /* the last address is "*" */
351 for (i
= 0; i
< port
->naddrs
- 1; i
++) {
352 if (addr
[i
].addr
== sin
->sin_addr
.s_addr
) {
357 addr_conf
= &addr
[i
].conf
;
364 switch (c
->local_sockaddr
->sa_family
) {
369 addr_conf
= &addr6
[0].conf
;
373 default: /* AF_INET */
375 addr_conf
= &addr
[0].conf
;
380 r
->virtual_names
= addr_conf
->virtual_names
;
382 /* the default server configuration for the address:port */
383 cscf
= addr_conf
->core_srv_conf
;
385 r
->main_conf
= cscf
->ctx
->main_conf
;
386 r
->srv_conf
= cscf
->ctx
->srv_conf
;
387 r
->loc_conf
= cscf
->ctx
->loc_conf
;
389 rev
->handler
= ngx_http_process_request_line
;
390 r
->read_event_handler
= ngx_http_block_reading
;
395 ngx_http_ssl_srv_conf_t
*sscf
;
397 sscf
= ngx_http_get_module_srv_conf(r
, ngx_http_ssl_module
);
398 if (sscf
->enable
|| addr_conf
->ssl
) {
400 if (c
->ssl
== NULL
) {
402 c
->log
->action
= "SSL handshaking";
404 if (addr_conf
->ssl
&& sscf
->ssl
.ctx
== NULL
) {
405 ngx_log_error(NGX_LOG_ERR
, c
->log
, 0,
406 "no \"ssl_certificate\" is defined "
407 "in server listening on SSL port");
408 ngx_http_close_connection(c
);
412 if (ngx_ssl_create_connection(&sscf
->ssl
, c
, NGX_SSL_BUFFER
)
415 ngx_http_close_connection(c
);
419 rev
->handler
= ngx_http_ssl_handshake
;
422 r
->main_filter_need_in_memory
= 1;
428 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
429 c
->log
->file
= clcf
->error_log
->file
;
430 if (!(c
->log
->log_level
& NGX_LOG_DEBUG_CONNECTION
)) {
431 c
->log
->log_level
= clcf
->error_log
->log_level
;
434 if (c
->buffer
== NULL
) {
435 c
->buffer
= ngx_create_temp_buf(c
->pool
,
436 cscf
->client_header_buffer_size
);
437 if (c
->buffer
== NULL
) {
438 ngx_http_close_connection(c
);
443 if (r
->header_in
== NULL
) {
444 r
->header_in
= c
->buffer
;
447 r
->pool
= ngx_create_pool(cscf
->request_pool_size
, c
->log
);
448 if (r
->pool
== NULL
) {
449 ngx_http_close_connection(c
);
454 if (ngx_list_init(&r
->headers_out
.headers
, r
->pool
, 20,
455 sizeof(ngx_table_elt_t
))
458 ngx_destroy_pool(r
->pool
);
459 ngx_http_close_connection(c
);
463 r
->ctx
= ngx_pcalloc(r
->pool
, sizeof(void *) * ngx_http_max_module
);
464 if (r
->ctx
== NULL
) {
465 ngx_destroy_pool(r
->pool
);
466 ngx_http_close_connection(c
);
470 cmcf
= ngx_http_get_module_main_conf(r
, ngx_http_core_module
);
472 r
->variables
= ngx_pcalloc(r
->pool
, cmcf
->variables
.nelts
473 * sizeof(ngx_http_variable_value_t
));
474 if (r
->variables
== NULL
) {
475 ngx_destroy_pool(r
->pool
);
476 ngx_http_close_connection(c
);
480 c
->single_connection
= 1;
486 tp
= ngx_timeofday();
487 r
->start_sec
= tp
->sec
;
488 r
->start_msec
= tp
->msec
;
490 r
->method
= NGX_HTTP_UNKNOWN
;
492 r
->headers_in
.content_length_n
= -1;
493 r
->headers_in
.keep_alive_n
= -1;
494 r
->headers_out
.content_length_n
= -1;
495 r
->headers_out
.last_modified_time
= -1;
497 r
->uri_changes
= NGX_HTTP_MAX_URI_CHANGES
+ 1;
498 r
->subrequests
= NGX_HTTP_MAX_SUBREQUESTS
+ 1;
500 r
->http_state
= NGX_HTTP_READING_REQUEST_STATE
;
504 ctx
->current_request
= r
;
505 r
->log_handler
= ngx_http_log_error_handler
;
508 (void) ngx_atomic_fetch_add(ngx_stat_reading
, 1);
510 (void) ngx_atomic_fetch_add(ngx_stat_requests
, 1);
520 ngx_http_ssl_handshake(ngx_event_t
*rev
)
526 ngx_http_request_t
*r
;
531 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, rev
->log
, 0,
532 "http check ssl handshake");
535 ngx_log_error(NGX_LOG_INFO
, c
->log
, NGX_ETIMEDOUT
, "client timed out");
537 ngx_http_close_request(r
, NGX_HTTP_REQUEST_TIME_OUT
);
541 n
= recv(c
->fd
, (char *) buf
, 1, MSG_PEEK
);
543 if (n
== -1 && ngx_socket_errno
== NGX_EAGAIN
) {
545 if (!rev
->timer_set
) {
546 ngx_add_timer(rev
, c
->listening
->post_accept_timeout
);
549 if (ngx_handle_read_event(rev
, 0) != NGX_OK
) {
550 ngx_http_close_request(r
, NGX_HTTP_INTERNAL_SERVER_ERROR
);
557 if (buf
[0] == 0x80 /* SSLv2 */ || buf
[0] == 0x16 /* SSLv3/TLSv1 */) {
558 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, rev
->log
, 0,
559 "https ssl handshake: 0x%02Xd", buf
[0]);
561 rc
= ngx_ssl_handshake(c
);
563 if (rc
== NGX_AGAIN
) {
565 if (!rev
->timer_set
) {
566 ngx_add_timer(rev
, c
->listening
->post_accept_timeout
);
569 c
->ssl
->handler
= ngx_http_ssl_handshake_handler
;
573 ngx_http_ssl_handshake_handler(c
);
578 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, rev
->log
, 0,
585 c
->log
->action
= "reading client request line";
587 rev
->handler
= ngx_http_process_request_line
;
588 ngx_http_process_request_line(rev
);
593 ngx_http_ssl_handshake_handler(ngx_connection_t
*c
)
595 ngx_http_request_t
*r
;
597 if (c
->ssl
->handshaked
) {
600 * The majority of browsers do not send the "close notify" alert.
601 * Among them are MSIE, old Mozilla, Netscape 4, Konqueror,
602 * and Links. And what is more, MSIE ignores the server's alert.
604 * Opera and recent Mozilla send the alert.
607 c
->ssl
->no_wait_shutdown
= 1;
609 c
->read
->handler
= ngx_http_process_request_line
;
610 /* STUB: epoll edge */ c
->write
->handler
= ngx_http_empty_handler
;
612 ngx_http_process_request_line(c
->read
);
619 ngx_http_close_request(r
, NGX_HTTP_BAD_REQUEST
);
624 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
627 ngx_http_ssl_servername(ngx_ssl_conn_t
*ssl_conn
, int *ad
, void *arg
)
630 const char *servername
;
632 ngx_http_request_t
*r
;
633 ngx_http_ssl_srv_conf_t
*sscf
;
635 servername
= SSL_get_servername(ssl_conn
, TLSEXT_NAMETYPE_host_name
);
637 if (servername
== NULL
) {
638 return SSL_TLSEXT_ERR_NOACK
;
641 c
= ngx_ssl_get_connection(ssl_conn
);
643 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
644 "SSL server name: \"%s\"", servername
);
646 len
= ngx_strlen(servername
);
649 return SSL_TLSEXT_ERR_NOACK
;
654 if (ngx_http_find_virtual_server(r
, (u_char
*) servername
, len
) != NGX_OK
) {
655 return SSL_TLSEXT_ERR_NOACK
;
658 sscf
= ngx_http_get_module_srv_conf(r
, ngx_http_ssl_module
);
660 SSL_set_SSL_CTX(ssl_conn
, sscf
->ssl
.ctx
);
662 return SSL_TLSEXT_ERR_OK
;
671 ngx_http_process_request_line(ngx_event_t
*rev
)
676 ngx_http_request_t
*r
;
677 ngx_http_core_srv_conf_t
*cscf
;
682 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, rev
->log
, 0,
683 "http process request line");
686 ngx_log_error(NGX_LOG_INFO
, c
->log
, NGX_ETIMEDOUT
, "client timed out");
688 ngx_http_close_request(r
, NGX_HTTP_REQUEST_TIME_OUT
);
696 if (rc
== NGX_AGAIN
) {
697 n
= ngx_http_read_request_header(r
);
699 if (n
== NGX_AGAIN
|| n
== NGX_ERROR
) {
704 rc
= ngx_http_parse_request_line(r
, r
->header_in
);
708 /* the request line has been parsed successfully */
710 r
->request_line
.len
= r
->request_end
- r
->request_start
;
711 r
->request_line
.data
= r
->request_start
;
715 r
->uri
.len
= r
->args_start
- 1 - r
->uri_start
;
717 r
->uri
.len
= r
->uri_end
- r
->uri_start
;
721 if (r
->complex_uri
|| r
->quoted_uri
) {
723 r
->uri
.data
= ngx_pnalloc(r
->pool
, r
->uri
.len
+ 1);
724 if (r
->uri
.data
== NULL
) {
725 ngx_http_close_request(r
, NGX_HTTP_INTERNAL_SERVER_ERROR
);
729 cscf
= ngx_http_get_module_srv_conf(r
, ngx_http_core_module
);
731 rc
= ngx_http_parse_complex_uri(r
, cscf
->merge_slashes
);
733 if (rc
== NGX_HTTP_PARSE_INVALID_REQUEST
) {
734 ngx_log_error(NGX_LOG_INFO
, c
->log
, 0,
735 "client sent invalid request");
736 ngx_http_finalize_request(r
, NGX_HTTP_BAD_REQUEST
);
741 r
->uri
.data
= r
->uri_start
;
745 r
->unparsed_uri
.len
= r
->uri_end
- r
->uri_start
;
746 r
->unparsed_uri
.data
= r
->uri_start
;
749 r
->method_name
.len
= r
->method_end
- r
->request_start
+ 1;
750 r
->method_name
.data
= r
->request_line
.data
;
753 if (r
->http_protocol
.data
) {
754 r
->http_protocol
.len
= r
->request_end
- r
->http_protocol
.data
;
760 r
->exten
.len
= r
->args_start
- 1 - r
->uri_ext
;
762 r
->exten
.len
= r
->uri_end
- r
->uri_ext
;
765 r
->exten
.data
= r
->uri_ext
;
769 if (r
->args_start
&& r
->uri_end
> r
->args_start
) {
770 r
->args
.len
= r
->uri_end
- r
->args_start
;
771 r
->args
.data
= r
->args_start
;
778 p
= r
->uri
.data
+ r
->uri
.len
- 1;
782 while (--p
> r
->uri
.data
&& *p
== '.') { /* void */ }
784 r
->uri
.len
= p
+ 1 - r
->uri
.data
;
786 ngx_http_set_exten(r
);
791 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
792 "http request line: \"%V\"", &r
->request_line
);
794 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
795 "http uri: \"%V\"", &r
->uri
);
797 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
798 "http args: \"%V\"", &r
->args
);
800 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
801 "http exten: \"%V\"", &r
->exten
);
803 if (r
->host_start
&& r
->host_end
) {
804 n
= ngx_http_validate_host(r
->host_start
,
805 r
->host_end
- r
->host_start
);
808 ngx_log_error(NGX_LOG_INFO
, c
->log
, 0,
809 "client sent invalid host in request line");
810 ngx_http_finalize_request(r
, NGX_HTTP_BAD_REQUEST
);
814 r
->headers_in
.server
.len
= n
;
815 r
->headers_in
.server
.data
= r
->host_start
;
818 if (r
->http_version
< NGX_HTTP_VERSION_10
) {
820 if (ngx_http_find_virtual_server(r
, r
->headers_in
.server
.data
,
821 r
->headers_in
.server
.len
)
824 ngx_http_close_request(r
, NGX_HTTP_INTERNAL_SERVER_ERROR
);
828 ngx_http_process_request(r
);
833 if (ngx_list_init(&r
->headers_in
.headers
, r
->pool
, 20,
834 sizeof(ngx_table_elt_t
))
837 ngx_http_close_request(r
, NGX_HTTP_INTERNAL_SERVER_ERROR
);
842 if (ngx_array_init(&r
->headers_in
.cookies
, r
->pool
, 2,
843 sizeof(ngx_table_elt_t
*))
846 ngx_http_close_request(r
, NGX_HTTP_INTERNAL_SERVER_ERROR
);
850 c
->log
->action
= "reading client request headers";
852 rev
->handler
= ngx_http_process_request_headers
;
853 ngx_http_process_request_headers(rev
);
858 if (rc
!= NGX_AGAIN
) {
860 /* there was error while a request line parsing */
862 ngx_log_error(NGX_LOG_INFO
, c
->log
, 0,
863 ngx_http_client_errors
[rc
- NGX_HTTP_CLIENT_ERROR
]);
864 ngx_http_finalize_request(r
, NGX_HTTP_BAD_REQUEST
);
868 /* NGX_AGAIN: a request line parsing is still incomplete */
870 if (r
->header_in
->pos
== r
->header_in
->end
) {
872 rv
= ngx_http_alloc_large_header_buffer(r
, 1);
874 if (rv
== NGX_ERROR
) {
875 ngx_http_close_request(r
, NGX_HTTP_INTERNAL_SERVER_ERROR
);
879 if (rv
== NGX_DECLINED
) {
880 r
->request_line
.len
= r
->header_in
->end
- r
->request_start
;
881 r
->request_line
.data
= r
->request_start
;
883 ngx_log_error(NGX_LOG_INFO
, c
->log
, 0,
884 "client sent too long URI");
885 ngx_http_finalize_request(r
, NGX_HTTP_REQUEST_URI_TOO_LARGE
);
894 ngx_http_process_request_headers(ngx_event_t
*rev
)
902 ngx_http_header_t
*hh
;
903 ngx_http_request_t
*r
;
904 ngx_http_core_srv_conf_t
*cscf
;
905 ngx_http_core_main_conf_t
*cmcf
;
910 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, rev
->log
, 0,
911 "http process request header line");
914 ngx_log_error(NGX_LOG_INFO
, c
->log
, NGX_ETIMEDOUT
, "client timed out");
916 ngx_http_close_request(r
, NGX_HTTP_REQUEST_TIME_OUT
);
920 cmcf
= ngx_http_get_module_main_conf(r
, ngx_http_core_module
);
921 cscf
= ngx_http_get_module_srv_conf(r
, ngx_http_core_module
);
927 if (rc
== NGX_AGAIN
) {
929 if (r
->header_in
->pos
== r
->header_in
->end
) {
931 rv
= ngx_http_alloc_large_header_buffer(r
, 0);
933 if (rv
== NGX_ERROR
) {
934 ngx_http_close_request(r
, NGX_HTTP_INTERNAL_SERVER_ERROR
);
938 if (rv
== NGX_DECLINED
) {
939 len
= r
->header_in
->end
- r
->header_name_start
;
940 p
= r
->header_name_start
;
942 if (len
> NGX_MAX_ERROR_STR
- 300) {
943 len
= NGX_MAX_ERROR_STR
- 300;
944 p
[len
++] = '.'; p
[len
++] = '.'; p
[len
++] = '.';
947 ngx_log_error(NGX_LOG_INFO
, c
->log
, 0,
948 "client sent too long header line: \"%*s\"",
949 len
, r
->header_name_start
);
950 ngx_http_finalize_request(r
, NGX_HTTP_BAD_REQUEST
);
955 n
= ngx_http_read_request_header(r
);
957 if (n
== NGX_AGAIN
|| n
== NGX_ERROR
) {
962 rc
= ngx_http_parse_header_line(r
, r
->header_in
,
963 cscf
->underscores_in_headers
);
967 if (r
->invalid_header
&& cscf
->ignore_invalid_headers
) {
969 /* there was error while a header line parsing */
971 ngx_log_error(NGX_LOG_INFO
, c
->log
, 0,
972 "client sent invalid header line: \"%*s\"",
973 r
->header_end
- r
->header_name_start
,
974 r
->header_name_start
);
978 /* a header line has been parsed successfully */
980 h
= ngx_list_push(&r
->headers_in
.headers
);
982 ngx_http_close_request(r
, NGX_HTTP_INTERNAL_SERVER_ERROR
);
986 h
->hash
= r
->header_hash
;
988 h
->key
.len
= r
->header_name_end
- r
->header_name_start
;
989 h
->key
.data
= r
->header_name_start
;
990 h
->key
.data
[h
->key
.len
] = '\0';
992 h
->value
.len
= r
->header_end
- r
->header_start
;
993 h
->value
.data
= r
->header_start
;
994 h
->value
.data
[h
->value
.len
] = '\0';
996 h
->lowcase_key
= ngx_pnalloc(r
->pool
, h
->key
.len
);
997 if (h
->lowcase_key
== NULL
) {
998 ngx_http_close_request(r
, NGX_HTTP_INTERNAL_SERVER_ERROR
);
1002 if (h
->key
.len
== r
->lowcase_index
) {
1003 ngx_memcpy(h
->lowcase_key
, r
->lowcase_header
, h
->key
.len
);
1006 ngx_strlow(h
->lowcase_key
, h
->key
.data
, h
->key
.len
);
1009 hh
= ngx_hash_find(&cmcf
->headers_in_hash
, h
->hash
,
1010 h
->lowcase_key
, h
->key
.len
);
1012 if (hh
&& hh
->handler(r
, h
, hh
->offset
) != NGX_OK
) {
1016 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
1017 "http header: \"%V: %V\"",
1018 &h
->key
, &h
->value
);
1023 if (rc
== NGX_HTTP_PARSE_HEADER_DONE
) {
1025 /* a whole header has been parsed successfully */
1027 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
1028 "http header done");
1030 r
->request_length
+= r
->header_in
->pos
- r
->header_in
->start
;
1032 r
->http_state
= NGX_HTTP_PROCESS_REQUEST_STATE
;
1034 rc
= ngx_http_process_request_header(r
);
1040 ngx_http_process_request(r
);
1045 if (rc
== NGX_AGAIN
) {
1047 /* a header line parsing is still not complete */
1052 /* rc == NGX_HTTP_PARSE_INVALID_HEADER: "\r" is not followed by "\n" */
1054 ngx_log_error(NGX_LOG_INFO
, c
->log
, 0,
1055 "client sent invalid header line: \"%*s\\r...\"",
1056 r
->header_end
- r
->header_name_start
,
1057 r
->header_name_start
);
1058 ngx_http_finalize_request(r
, NGX_HTTP_BAD_REQUEST
);
1065 ngx_http_read_request_header(ngx_http_request_t
*r
)
1069 ngx_connection_t
*c
;
1070 ngx_http_core_srv_conf_t
*cscf
;
1075 n
= r
->header_in
->last
- r
->header_in
->pos
;
1082 n
= c
->recv(c
, r
->header_in
->last
,
1083 r
->header_in
->end
- r
->header_in
->last
);
1088 if (n
== NGX_AGAIN
) {
1089 if (!rev
->timer_set
) {
1090 cscf
= ngx_http_get_module_srv_conf(r
, ngx_http_core_module
);
1091 ngx_add_timer(rev
, cscf
->client_header_timeout
);
1094 if (ngx_handle_read_event(rev
, 0) != NGX_OK
) {
1095 ngx_http_close_request(r
, NGX_HTTP_INTERNAL_SERVER_ERROR
);
1103 ngx_log_error(NGX_LOG_INFO
, c
->log
, 0,
1104 "client closed prematurely connection");
1107 if (n
== 0 || n
== NGX_ERROR
) {
1109 c
->log
->action
= "reading client request headers";
1111 ngx_http_finalize_request(r
, NGX_HTTP_BAD_REQUEST
);
1115 r
->header_in
->last
+= n
;
1122 ngx_http_alloc_large_header_buffer(ngx_http_request_t
*r
,
1123 ngx_uint_t request_line
)
1127 ngx_http_connection_t
*hc
;
1128 ngx_http_core_srv_conf_t
*cscf
;
1130 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
1131 "http alloc large header buffer");
1133 if (request_line
&& r
->state
== 0) {
1135 /* the client fills up the buffer with "\r\n" */
1137 r
->request_length
+= r
->header_in
->end
- r
->header_in
->start
;
1139 r
->header_in
->pos
= r
->header_in
->start
;
1140 r
->header_in
->last
= r
->header_in
->start
;
1145 old
= request_line
? r
->request_start
: r
->header_name_start
;
1147 cscf
= ngx_http_get_module_srv_conf(r
, ngx_http_core_module
);
1150 && (size_t) (r
->header_in
->pos
- old
)
1151 >= cscf
->large_client_header_buffers
.size
)
1153 return NGX_DECLINED
;
1156 hc
= r
->http_connection
;
1159 b
= hc
->free
[--hc
->nfree
];
1161 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
1162 "http large header free: %p %uz",
1163 b
->pos
, b
->end
- b
->last
);
1165 } else if (hc
->nbusy
< cscf
->large_client_header_buffers
.num
) {
1167 if (hc
->busy
== NULL
) {
1168 hc
->busy
= ngx_palloc(r
->connection
->pool
,
1169 cscf
->large_client_header_buffers
.num
* sizeof(ngx_buf_t
*));
1170 if (hc
->busy
== NULL
) {
1175 b
= ngx_create_temp_buf(r
->connection
->pool
,
1176 cscf
->large_client_header_buffers
.size
);
1181 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
1182 "http large header alloc: %p %uz",
1183 b
->pos
, b
->end
- b
->last
);
1186 return NGX_DECLINED
;
1189 hc
->busy
[hc
->nbusy
++] = b
;
1191 if (r
->state
== 0) {
1193 * r->state == 0 means that a header line was parsed successfully
1194 * and we do not need to copy incomplete header line and
1195 * to relocate the parser header pointers
1198 r
->request_length
+= r
->header_in
->end
- r
->header_in
->start
;
1205 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
1206 "http large header copy: %d", r
->header_in
->pos
- old
);
1208 r
->request_length
+= old
- r
->header_in
->start
;
1212 ngx_memcpy(new, old
, r
->header_in
->pos
- old
);
1214 b
->pos
= new + (r
->header_in
->pos
- old
);
1215 b
->last
= new + (r
->header_in
->pos
- old
);
1218 r
->request_start
= new;
1220 if (r
->request_end
) {
1221 r
->request_end
= new + (r
->request_end
- old
);
1224 r
->method_end
= new + (r
->method_end
- old
);
1226 r
->uri_start
= new + (r
->uri_start
- old
);
1227 r
->uri_end
= new + (r
->uri_end
- old
);
1229 if (r
->schema_start
) {
1230 r
->schema_start
= new + (r
->schema_start
- old
);
1231 r
->schema_end
= new + (r
->schema_end
- old
);
1234 if (r
->host_start
) {
1235 r
->host_start
= new + (r
->host_start
- old
);
1237 r
->host_end
= new + (r
->host_end
- old
);
1241 if (r
->port_start
) {
1242 r
->port_start
= new + (r
->port_start
- old
);
1243 r
->port_end
= new + (r
->port_end
- old
);
1247 r
->uri_ext
= new + (r
->uri_ext
- old
);
1250 if (r
->args_start
) {
1251 r
->args_start
= new + (r
->args_start
- old
);
1254 if (r
->http_protocol
.data
) {
1255 r
->http_protocol
.data
= new + (r
->http_protocol
.data
- old
);
1259 r
->header_name_start
= new;
1260 r
->header_name_end
= new + (r
->header_name_end
- old
);
1261 r
->header_start
= new + (r
->header_start
- old
);
1262 r
->header_end
= new + (r
->header_end
- old
);
1272 ngx_http_process_header_line(ngx_http_request_t
*r
, ngx_table_elt_t
*h
,
1275 ngx_table_elt_t
**ph
;
1277 ph
= (ngx_table_elt_t
**) ((char *) &r
->headers_in
+ offset
);
1288 ngx_http_process_unique_header_line(ngx_http_request_t
*r
, ngx_table_elt_t
*h
,
1291 ngx_table_elt_t
**ph
;
1293 ph
= (ngx_table_elt_t
**) ((char *) &r
->headers_in
+ offset
);
1300 ngx_log_error(NGX_LOG_INFO
, r
->connection
->log
, 0,
1301 "client sent duplicate header line: \"%V: %V\", "
1302 "previous value: \"%V: %V\"",
1303 &h
->key
, &h
->value
, &(*ph
)->key
, &(*ph
)->value
);
1305 ngx_http_finalize_request(r
, NGX_HTTP_BAD_REQUEST
);
1312 ngx_http_process_host(ngx_http_request_t
*r
, ngx_table_elt_t
*h
,
1317 if (r
->headers_in
.host
== NULL
) {
1318 r
->headers_in
.host
= h
;
1321 len
= ngx_http_validate_host(h
->value
.data
, h
->value
.len
);
1324 ngx_log_error(NGX_LOG_INFO
, r
->connection
->log
, 0,
1325 "client sent invalid host header");
1326 ngx_http_finalize_request(r
, NGX_HTTP_BAD_REQUEST
);
1330 if (r
->headers_in
.server
.len
) {
1334 r
->headers_in
.server
.len
= len
;
1335 r
->headers_in
.server
.data
= h
->value
.data
;
1342 ngx_http_process_connection(ngx_http_request_t
*r
, ngx_table_elt_t
*h
,
1345 if (ngx_strcasestrn(h
->value
.data
, "close", 5 - 1)) {
1346 r
->headers_in
.connection_type
= NGX_HTTP_CONNECTION_CLOSE
;
1348 } else if (ngx_strcasestrn(h
->value
.data
, "keep-alive", 10 - 1)) {
1349 r
->headers_in
.connection_type
= NGX_HTTP_CONNECTION_KEEP_ALIVE
;
1357 ngx_http_process_user_agent(ngx_http_request_t
*r
, ngx_table_elt_t
*h
,
1360 u_char
*user_agent
, *msie
;
1362 if (r
->headers_in
.user_agent
) {
1366 r
->headers_in
.user_agent
= h
;
1368 /* check some widespread browsers while the header is in CPU cache */
1370 user_agent
= h
->value
.data
;
1372 msie
= ngx_strstrn(user_agent
, "MSIE ", 5 - 1);
1374 if (msie
&& msie
+ 7 < user_agent
+ h
->value
.len
) {
1376 r
->headers_in
.msie
= 1;
1378 if (msie
[6] == '.') {
1382 r
->headers_in
.msie4
= 1;
1385 r
->headers_in
.msie6
= 1;
1388 if (ngx_strstrn(msie
+ 8, "SV1", 3 - 1) == NULL
) {
1389 r
->headers_in
.msie6
= 1;
1396 /* MSIE ignores the SSL "close notify" alert */
1398 c
->ssl
->no_send_shutdown
= 1;
1403 if (ngx_strstrn(user_agent
, "Opera", 5 - 1)) {
1404 r
->headers_in
.opera
= 1;
1405 r
->headers_in
.msie
= 0;
1406 r
->headers_in
.msie4
= 0;
1407 r
->headers_in
.msie6
= 0;
1410 if (!r
->headers_in
.msie
&& !r
->headers_in
.opera
) {
1412 if (ngx_strstrn(user_agent
, "Gecko/", 6 - 1)) {
1413 r
->headers_in
.gecko
= 1;
1415 } else if (ngx_strstrn(user_agent
, "Konqueror", 9 - 1)) {
1416 r
->headers_in
.konqueror
= 1;
1425 ngx_http_process_cookie(ngx_http_request_t
*r
, ngx_table_elt_t
*h
,
1428 ngx_table_elt_t
**cookie
;
1430 cookie
= ngx_array_push(&r
->headers_in
.cookies
);
1436 ngx_http_close_request(r
, NGX_HTTP_INTERNAL_SERVER_ERROR
);
1443 ngx_http_process_request_header(ngx_http_request_t
*r
)
1445 if (ngx_http_find_virtual_server(r
, r
->headers_in
.server
.data
,
1446 r
->headers_in
.server
.len
)
1449 ngx_http_finalize_request(r
, NGX_HTTP_INTERNAL_SERVER_ERROR
);
1453 if (r
->headers_in
.host
== NULL
&& r
->http_version
> NGX_HTTP_VERSION_10
) {
1454 ngx_log_error(NGX_LOG_INFO
, r
->connection
->log
, 0,
1455 "client sent HTTP/1.1 request without \"Host\" header");
1456 ngx_http_finalize_request(r
, NGX_HTTP_BAD_REQUEST
);
1460 if (r
->headers_in
.content_length
) {
1461 r
->headers_in
.content_length_n
=
1462 ngx_atoof(r
->headers_in
.content_length
->value
.data
,
1463 r
->headers_in
.content_length
->value
.len
);
1465 if (r
->headers_in
.content_length_n
== NGX_ERROR
) {
1466 ngx_log_error(NGX_LOG_INFO
, r
->connection
->log
, 0,
1467 "client sent invalid \"Content-Length\" header");
1468 ngx_http_finalize_request(r
, NGX_HTTP_LENGTH_REQUIRED
);
1473 if (r
->method
& NGX_HTTP_PUT
&& r
->headers_in
.content_length_n
== -1) {
1474 ngx_log_error(NGX_LOG_INFO
, r
->connection
->log
, 0,
1475 "client sent %V method without \"Content-Length\" header",
1477 ngx_http_finalize_request(r
, NGX_HTTP_LENGTH_REQUIRED
);
1481 if (r
->method
& NGX_HTTP_TRACE
) {
1482 ngx_log_error(NGX_LOG_INFO
, r
->connection
->log
, 0,
1483 "client sent TRACE method");
1484 ngx_http_finalize_request(r
, NGX_HTTP_NOT_ALLOWED
);
1488 if (r
->headers_in
.transfer_encoding
1489 && ngx_strcasestrn(r
->headers_in
.transfer_encoding
->value
.data
,
1492 ngx_log_error(NGX_LOG_INFO
, r
->connection
->log
, 0,
1493 "client sent \"Transfer-Encoding: chunked\" header");
1494 ngx_http_finalize_request(r
, NGX_HTTP_LENGTH_REQUIRED
);
1498 if (r
->headers_in
.connection_type
== NGX_HTTP_CONNECTION_KEEP_ALIVE
) {
1499 if (r
->headers_in
.keep_alive
) {
1500 r
->headers_in
.keep_alive_n
=
1501 ngx_atotm(r
->headers_in
.keep_alive
->value
.data
,
1502 r
->headers_in
.keep_alive
->value
.len
);
1511 ngx_http_process_request(ngx_http_request_t
*r
)
1513 ngx_connection_t
*c
;
1517 if (r
->plain_http
) {
1518 ngx_log_error(NGX_LOG_INFO
, c
->log
, 0,
1519 "client sent plain HTTP request to HTTPS port");
1520 ngx_http_finalize_request(r
, NGX_HTTP_TO_HTTPS
);
1529 ngx_http_ssl_srv_conf_t
*sscf
;
1531 sscf
= ngx_http_get_module_srv_conf(r
, ngx_http_ssl_module
);
1534 rc
= SSL_get_verify_result(c
->ssl
->connection
);
1536 if (rc
!= X509_V_OK
) {
1537 ngx_log_error(NGX_LOG_INFO
, c
->log
, 0,
1538 "client SSL certificate verify error: (%l:%s)",
1539 rc
, X509_verify_cert_error_string(rc
));
1541 ngx_ssl_remove_cached_session(sscf
->ssl
.ctx
,
1542 (SSL_get0_session(c
->ssl
->connection
)));
1544 ngx_http_finalize_request(r
, NGX_HTTPS_CERT_ERROR
);
1548 if (sscf
->verify
== 1) {
1549 cert
= SSL_get_peer_certificate(c
->ssl
->connection
);
1552 ngx_log_error(NGX_LOG_INFO
, c
->log
, 0,
1553 "client sent no required SSL certificate");
1555 ngx_ssl_remove_cached_session(sscf
->ssl
.ctx
,
1556 (SSL_get0_session(c
->ssl
->connection
)));
1558 ngx_http_finalize_request(r
, NGX_HTTPS_NO_CERT
);
1569 if (c
->read
->timer_set
) {
1570 ngx_del_timer(c
->read
);
1574 (void) ngx_atomic_fetch_add(ngx_stat_reading
, -1);
1575 r
->stat_reading
= 0;
1576 (void) ngx_atomic_fetch_add(ngx_stat_writing
, 1);
1577 r
->stat_writing
= 1;
1580 c
->read
->handler
= ngx_http_request_handler
;
1581 c
->write
->handler
= ngx_http_request_handler
;
1582 r
->read_event_handler
= ngx_http_block_reading
;
1584 ngx_http_handler(r
);
1586 ngx_http_run_posted_requests(c
);
1591 ngx_http_validate_host(u_char
*host
, size_t len
)
1600 for (i
= 0; i
< len
; i
++) {
1619 if (ngx_path_separator(ch
) || ch
== '\0') {
1633 ngx_http_find_virtual_server(ngx_http_request_t
*r
, u_char
*host
, size_t len
)
1637 ngx_http_core_loc_conf_t
*clcf
;
1638 ngx_http_core_srv_conf_t
*cscf
;
1641 if (r
->virtual_names
== NULL
) {
1642 return NGX_DECLINED
;
1649 server
= ngx_pnalloc(r
->pool
, len
);
1650 if (server
== NULL
) {
1655 hash
= ngx_hash_strlow(server
, host
, len
);
1657 cscf
= ngx_hash_find_combined(&r
->virtual_names
->names
, hash
, server
, len
);
1665 if (r
->virtual_names
->nregex
) {
1670 ngx_http_server_name_t
*sn
;
1677 sn
= r
->virtual_names
->regex
;
1679 for (i
= 0; i
< r
->virtual_names
->nregex
; i
++) {
1681 if (sn
[i
].captures
&& r
->captures
== NULL
) {
1683 ncaptures
= (NGX_HTTP_MAX_CAPTURES
+ 1) * 3;
1685 r
->captures
= ngx_palloc(r
->pool
, ncaptures
* sizeof(int));
1686 if (r
->captures
== NULL
) {
1690 if (server
== buf
) {
1691 server
= ngx_pnalloc(r
->pool
, len
);
1692 if (server
== NULL
) {
1696 ngx_memcpy(server
, buf
, len
);
1701 n
= ngx_regex_exec(sn
[i
].regex
, &name
, r
->captures
, ncaptures
);
1703 if (n
== NGX_REGEX_NO_MATCHED
) {
1708 ngx_log_error(NGX_LOG_ALERT
, r
->connection
->log
, 0,
1710 " failed: %d on \"%V\" using \"%V\"",
1711 n
, &name
, &sn
[i
].name
);
1717 cscf
= sn
[i
].core_srv_conf
;
1719 r
->ncaptures
= ncaptures
;
1720 r
->captures_data
= server
;
1732 r
->srv_conf
= cscf
->ctx
->srv_conf
;
1733 r
->loc_conf
= cscf
->ctx
->loc_conf
;
1735 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
1736 r
->connection
->log
->file
= clcf
->error_log
->file
;
1738 if (!(r
->connection
->log
->log_level
& NGX_LOG_DEBUG_CONNECTION
)) {
1739 r
->connection
->log
->log_level
= clcf
->error_log
->log_level
;
1747 ngx_http_request_handler(ngx_event_t
*ev
)
1749 ngx_connection_t
*c
;
1750 ngx_http_request_t
*r
;
1751 ngx_http_log_ctx_t
*ctx
;
1757 ctx
->current_request
= r
;
1759 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
1760 "http run request: \"%V?%V\"", &r
->uri
, &r
->args
);
1763 r
->write_event_handler(r
);
1766 r
->read_event_handler(r
);
1769 ngx_http_run_posted_requests(c
);
1774 ngx_http_run_posted_requests(ngx_connection_t
*c
)
1776 ngx_http_request_t
*r
;
1777 ngx_http_log_ctx_t
*ctx
;
1778 ngx_http_posted_request_t
*pr
;
1787 pr
= r
->main
->posted_requests
;
1793 r
->main
->posted_requests
= pr
->next
;
1798 ctx
->current_request
= r
;
1800 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
1801 "http posted request: \"%V?%V\"", &r
->uri
, &r
->args
);
1803 r
->write_event_handler(r
);
1809 ngx_http_post_request(ngx_http_request_t
*r
, ngx_http_posted_request_t
*pr
)
1811 ngx_http_posted_request_t
**p
;
1814 pr
= ngx_palloc(r
->pool
, sizeof(ngx_http_posted_request_t
));
1823 for (p
= &r
->main
->posted_requests
; *p
; p
= &(*p
)->next
) { /* void */ }
1832 ngx_http_finalize_request(ngx_http_request_t
*r
, ngx_int_t rc
)
1834 ngx_connection_t
*c
;
1835 ngx_http_request_t
*pr
;
1836 ngx_http_core_loc_conf_t
*clcf
;
1840 ngx_log_debug5(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
1841 "http finalize request: %d, \"%V?%V\" a:%d, c:%d",
1842 rc
, &r
->uri
, &r
->args
, r
== c
->data
, r
->main
->count
);
1844 if (rc
== NGX_DONE
) {
1845 ngx_http_finalize_connection(r
);
1849 if (rc
== NGX_OK
&& r
->filter_finalize
) {
1854 if (rc
== NGX_DECLINED
) {
1855 r
->content_handler
= NULL
;
1856 r
->write_event_handler
= ngx_http_core_run_phases
;
1857 ngx_http_core_run_phases(r
);
1861 if (r
!= r
->main
&& r
->post_subrequest
) {
1862 rc
= r
->post_subrequest
->handler(r
, r
->post_subrequest
->data
, rc
);
1866 || rc
== NGX_HTTP_REQUEST_TIME_OUT
1867 || rc
== NGX_HTTP_CLIENT_CLOSED_REQUEST
1870 if (ngx_http_post_action(r
) == NGX_OK
) {
1874 if (r
->main
->blocked
) {
1875 r
->write_event_handler
= ngx_http_request_finalizer
;
1878 ngx_http_terminate_request(r
, rc
);
1882 if (rc
>= NGX_HTTP_SPECIAL_RESPONSE
1883 || rc
== NGX_HTTP_CREATED
1884 || rc
== NGX_HTTP_NO_CONTENT
)
1886 if (rc
== NGX_HTTP_CLOSE
) {
1887 ngx_http_terminate_request(r
, rc
);
1892 if (c
->read
->timer_set
) {
1893 ngx_del_timer(c
->read
);
1896 if (c
->write
->timer_set
) {
1897 ngx_del_timer(c
->write
);
1901 c
->read
->handler
= ngx_http_request_handler
;
1902 c
->write
->handler
= ngx_http_request_handler
;
1904 ngx_http_finalize_request(r
, ngx_http_special_response_handler(r
, rc
));
1910 if (r
->buffered
|| r
->postponed
) {
1912 if (ngx_http_set_write_handler(r
) != NGX_OK
) {
1913 ngx_http_terminate_request(r
, 0);
1921 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
1922 "http finalize non-active request: \"%V?%V\"",
1935 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
1937 if (clcf
->log_subrequest
) {
1938 ngx_http_log_request(r
);
1944 ngx_log_error(NGX_LOG_ALERT
, c
->log
, 0,
1945 "subrequest: \"%V?%V\" logged again",
1951 if (pr
->postponed
&& pr
->postponed
->request
== r
) {
1952 pr
->postponed
= pr
->postponed
->next
;
1959 r
->write_event_handler
= ngx_http_request_finalizer
;
1966 if (ngx_http_post_request(pr
, NULL
) != NGX_OK
) {
1968 ngx_http_terminate_request(r
, 0);
1972 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
1973 "http wake parent request: \"%V?%V\"",
1974 &pr
->uri
, &pr
->args
);
1979 if (r
->buffered
|| c
->buffered
|| r
->postponed
|| r
->blocked
) {
1981 if (ngx_http_set_write_handler(r
) != NGX_OK
) {
1982 ngx_http_terminate_request(r
, 0);
1989 ngx_log_error(NGX_LOG_ALERT
, c
->log
, 0,
1990 "http finalize non-active request: \"%V?%V\"",
1997 if (!r
->post_action
) {
1998 r
->request_complete
= 1;
2001 if (ngx_http_post_action(r
) == NGX_OK
) {
2005 if (c
->read
->timer_set
) {
2006 ngx_del_timer(c
->read
);
2009 if (c
->write
->timer_set
) {
2010 c
->write
->delayed
= 0;
2011 ngx_del_timer(c
->write
);
2015 ngx_http_close_request(r
, 0);
2019 ngx_http_finalize_connection(r
);
2024 ngx_http_terminate_request(ngx_http_request_t
*r
, ngx_int_t rc
)
2026 ngx_http_cleanup_t
*cln
;
2027 ngx_http_request_t
*mr
;
2028 ngx_http_ephemeral_t
*e
;
2032 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
2033 "http terminate request count:%d", mr
->count
);
2040 cln
->handler(cln
->data
);
2046 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
2047 "http terminate cleanup count:%d blk:%d",
2048 mr
->count
, mr
->blocked
);
2050 if (mr
->write_event_handler
) {
2056 e
= ngx_http_ephemeral(mr
);
2057 mr
->posted_requests
= NULL
;
2058 mr
->write_event_handler
= ngx_http_terminate_handler
;
2059 (void) ngx_http_post_request(mr
, &e
->terminal_posted_request
);
2063 ngx_http_close_request(mr
, rc
);
2068 ngx_http_terminate_handler(ngx_http_request_t
*r
)
2070 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
2071 "http terminate handler count:%d", r
->count
);
2075 ngx_http_close_request(r
, 0);
2080 ngx_http_finalize_connection(ngx_http_request_t
*r
)
2082 ngx_http_core_loc_conf_t
*clcf
;
2084 if (r
->main
->count
!= 1) {
2085 ngx_http_close_request(r
, 0);
2089 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
2094 && clcf
->keepalive_timeout
> 0)
2096 ngx_http_set_keepalive(r
);
2099 } else if (r
->lingering_close
&& clcf
->lingering_timeout
> 0) {
2100 ngx_http_set_lingering_close(r
);
2104 ngx_http_close_request(r
, 0);
2109 ngx_http_set_write_handler(ngx_http_request_t
*r
)
2112 ngx_http_core_loc_conf_t
*clcf
;
2114 r
->http_state
= NGX_HTTP_WRITING_REQUEST_STATE
;
2116 r
->read_event_handler
= ngx_http_test_reading
;
2117 r
->write_event_handler
= ngx_http_writer
;
2119 wev
= r
->connection
->write
;
2121 if (wev
->ready
&& wev
->delayed
) {
2125 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
2126 if (!wev
->delayed
) {
2127 ngx_add_timer(wev
, clcf
->send_timeout
);
2130 if (ngx_handle_write_event(wev
, clcf
->send_lowat
) != NGX_OK
) {
2131 ngx_http_close_request(r
, 0);
2140 ngx_http_writer(ngx_http_request_t
*r
)
2144 ngx_connection_t
*c
;
2145 ngx_http_core_loc_conf_t
*clcf
;
2150 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, wev
->log
, 0,
2151 "http writer handler: \"%V?%V\"", &r
->uri
, &r
->args
);
2153 clcf
= ngx_http_get_module_loc_conf(r
->main
, ngx_http_core_module
);
2155 if (wev
->timedout
) {
2156 if (!wev
->delayed
) {
2157 ngx_log_error(NGX_LOG_INFO
, c
->log
, NGX_ETIMEDOUT
,
2158 "client timed out");
2161 ngx_http_finalize_request(r
, NGX_HTTP_REQUEST_TIME_OUT
);
2169 ngx_add_timer(wev
, clcf
->send_timeout
);
2171 if (ngx_handle_write_event(wev
, clcf
->send_lowat
) != NGX_OK
) {
2172 ngx_http_close_request(r
, 0);
2179 if (wev
->delayed
|| r
->aio
) {
2180 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, wev
->log
, 0,
2181 "http writer delayed");
2183 if (ngx_handle_write_event(wev
, clcf
->send_lowat
) != NGX_OK
) {
2184 ngx_http_close_request(r
, 0);
2191 rc
= ngx_http_output_filter(r
, NULL
);
2193 ngx_log_debug3(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
2194 "http writer output filter: %d, \"%V?%V\"",
2195 rc
, &r
->uri
, &r
->args
);
2197 if (rc
== NGX_ERROR
) {
2198 ngx_http_finalize_request(r
, rc
);
2202 if (r
->buffered
|| r
->postponed
|| (r
== r
->main
&& c
->buffered
)) {
2204 if (!wev
->ready
&& !wev
->delayed
) {
2205 ngx_add_timer(wev
, clcf
->send_timeout
);
2208 if (ngx_handle_write_event(wev
, clcf
->send_lowat
) != NGX_OK
) {
2209 ngx_http_close_request(r
, 0);
2215 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, wev
->log
, 0,
2216 "http writer done: \"%V?%V\"", &r
->uri
, &r
->args
);
2218 ngx_http_finalize_request(r
, rc
);
2223 ngx_http_request_finalizer(ngx_http_request_t
*r
)
2225 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
2226 "http finalizer done: \"%V?%V\"", &r
->uri
, &r
->args
);
2228 ngx_http_finalize_request(r
, 0);
2233 ngx_http_block_reading(ngx_http_request_t
*r
)
2235 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
2236 "http reading blocked");
2238 /* aio does not call this handler */
2240 if ((ngx_event_flags
& NGX_USE_LEVEL_EVENT
)
2241 && r
->connection
->read
->active
)
2243 if (ngx_del_event(r
->connection
->read
, NGX_READ_EVENT
, 0) != NGX_OK
) {
2244 ngx_http_close_request(r
, 0);
2251 ngx_http_test_reading(ngx_http_request_t
*r
)
2257 ngx_connection_t
*c
;
2262 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, c
->log
, 0, "http test reading");
2264 #if (NGX_HAVE_KQUEUE)
2266 if (ngx_event_flags
& NGX_USE_KQUEUE_EVENT
) {
2268 if (!rev
->pending_eof
) {
2274 err
= rev
->kq_errno
;
2281 n
= recv(c
->fd
, buf
, 1, MSG_PEEK
);
2290 } else if (n
== -1) {
2291 err
= ngx_socket_errno
;
2293 if (err
!= NGX_EAGAIN
) {
2301 /* aio does not call this handler */
2303 if ((ngx_event_flags
& NGX_USE_LEVEL_EVENT
) && rev
->active
) {
2305 if (ngx_del_event(rev
, NGX_READ_EVENT
, 0) != NGX_OK
) {
2306 ngx_http_close_request(r
, 0);
2318 ngx_log_error(NGX_LOG_INFO
, c
->log
, err
,
2319 "client closed prematurely connection");
2321 ngx_http_finalize_request(r
, 0);
2326 ngx_http_set_keepalive(ngx_http_request_t
*r
)
2331 ngx_event_t
*rev
, *wev
;
2332 ngx_connection_t
*c
;
2333 ngx_http_connection_t
*hc
;
2334 ngx_http_core_srv_conf_t
*cscf
;
2335 ngx_http_core_loc_conf_t
*clcf
;
2340 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
2342 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, c
->log
, 0, "set http keepalive handler");
2344 if (r
->discard_body
) {
2345 r
->write_event_handler
= ngx_http_request_empty_handler
;
2346 r
->lingering_time
= ngx_time() + (time_t) (clcf
->lingering_time
/ 1000);
2347 ngx_add_timer(rev
, clcf
->lingering_timeout
);
2351 c
->log
->action
= "closing request";
2353 hc
= r
->http_connection
;
2356 if (b
->pos
< b
->last
) {
2358 /* the pipelined request */
2360 if (b
!= c
->buffer
) {
2363 * If the large header buffers were allocated while the previous
2364 * request processing then we do not use c->buffer for
2365 * the pipelined request (see ngx_http_init_request()).
2367 * Now we would move the large header buffers to the free list.
2370 cscf
= ngx_http_get_module_srv_conf(r
, ngx_http_core_module
);
2372 if (hc
->free
== NULL
) {
2373 hc
->free
= ngx_palloc(c
->pool
,
2374 cscf
->large_client_header_buffers
.num
* sizeof(ngx_buf_t
*));
2376 if (hc
->free
== NULL
) {
2377 ngx_http_close_request(r
, 0);
2382 for (i
= 0; i
< hc
->nbusy
- 1; i
++) {
2384 hc
->free
[hc
->nfree
++] = f
;
2394 ngx_http_free_request(r
, 0);
2398 ngx_add_timer(rev
, clcf
->keepalive_timeout
);
2400 if (ngx_handle_read_event(rev
, 0) != NGX_OK
) {
2401 ngx_http_close_connection(c
);
2406 wev
->handler
= ngx_http_empty_handler
;
2408 if (b
->pos
< b
->last
) {
2410 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, c
->log
, 0, "pipelined request");
2413 (void) ngx_atomic_fetch_add(ngx_stat_reading
, 1);
2417 c
->log
->action
= "reading client pipelined request line";
2419 rev
->handler
= ngx_http_init_request
;
2420 ngx_post_event(rev
, &ngx_posted_events
);
2427 * To keep a memory footprint as small as possible for an idle
2428 * keepalive connection we try to free the ngx_http_request_t and
2429 * c->buffer's memory if they were allocated outside the c->pool.
2430 * The large header buffers are always allocated outside the c->pool and
2434 if (ngx_pfree(c
->pool
, r
) == NGX_OK
) {
2440 if (ngx_pfree(c
->pool
, b
->start
) == NGX_OK
) {
2443 * the special note for ngx_http_keepalive_handler() that
2444 * c->buffer's memory was freed
2454 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, c
->log
, 0, "hc free: %p %d",
2455 hc
->free
, hc
->nfree
);
2458 for (i
= 0; i
< hc
->nfree
; i
++) {
2459 ngx_pfree(c
->pool
, hc
->free
[i
]->start
);
2466 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, c
->log
, 0, "hc busy: %p %d",
2467 hc
->busy
, hc
->nbusy
);
2470 for (i
= 0; i
< hc
->nbusy
; i
++) {
2471 ngx_pfree(c
->pool
, hc
->busy
[i
]->start
);
2480 ngx_ssl_free_buffer(c
);
2484 rev
->handler
= ngx_http_keepalive_handler
;
2486 if (wev
->active
&& (ngx_event_flags
& NGX_USE_LEVEL_EVENT
)) {
2487 if (ngx_del_event(wev
, NGX_WRITE_EVENT
, 0) != NGX_OK
) {
2488 ngx_http_close_connection(c
);
2493 c
->log
->action
= "keepalive";
2495 if (c
->tcp_nopush
== NGX_TCP_NOPUSH_SET
) {
2496 if (ngx_tcp_push(c
->fd
) == -1) {
2497 ngx_connection_error(c
, ngx_socket_errno
, ngx_tcp_push_n
" failed");
2498 ngx_http_close_connection(c
);
2502 c
->tcp_nopush
= NGX_TCP_NOPUSH_UNSET
;
2503 tcp_nodelay
= ngx_tcp_nodelay_and_tcp_nopush
? 1 : 0;
2510 && clcf
->tcp_nodelay
2511 && c
->tcp_nodelay
== NGX_TCP_NODELAY_UNSET
)
2513 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, c
->log
, 0, "tcp_nodelay");
2515 if (setsockopt(c
->fd
, IPPROTO_TCP
, TCP_NODELAY
,
2516 (const void *) &tcp_nodelay
, sizeof(int))
2520 /* Solaris returns EINVAL if a socket has been shut down */
2521 c
->log_error
= NGX_ERROR_IGNORE_EINVAL
;
2524 ngx_connection_error(c
, ngx_socket_errno
,
2525 "setsockopt(TCP_NODELAY) failed");
2527 c
->log_error
= NGX_ERROR_INFO
;
2528 ngx_http_close_connection(c
);
2532 c
->tcp_nodelay
= NGX_TCP_NODELAY_SET
;
2536 /* if ngx_http_request_t was freed then we need some other place */
2537 r
->http_state
= NGX_HTTP_KEEPALIVE_STATE
;
2543 ngx_post_event(rev
, &ngx_posted_events
);
2549 ngx_http_keepalive_handler(ngx_event_t
*rev
)
2554 ngx_connection_t
*c
;
2558 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, c
->log
, 0, "http keepalive handler");
2560 if (rev
->timedout
|| c
->close
) {
2561 ngx_http_close_connection(c
);
2565 #if (NGX_HAVE_KQUEUE)
2567 if (ngx_event_flags
& NGX_USE_KQUEUE_EVENT
) {
2568 if (rev
->pending_eof
) {
2569 c
->log
->handler
= NULL
;
2570 ngx_log_error(NGX_LOG_INFO
, c
->log
, rev
->kq_errno
,
2571 "kevent() reported that client %V closed "
2572 "keepalive connection", &c
->addr_text
);
2575 c
->ssl
->no_send_shutdown
= 1;
2578 ngx_http_close_connection(c
);
2586 size
= b
->end
- b
->start
;
2588 if (b
->pos
== NULL
) {
2591 * The c->buffer's memory was freed by ngx_http_set_keepalive().
2592 * However, the c->buffer->start and c->buffer->end were not changed
2593 * to keep the buffer size.
2596 b
->pos
= ngx_palloc(c
->pool
, size
);
2597 if (b
->pos
== NULL
) {
2598 ngx_http_close_connection(c
);
2604 b
->end
= b
->pos
+ size
;
2608 * MSIE closes a keepalive connection with RST flag
2609 * so we ignore ECONNRESET here.
2612 c
->log_error
= NGX_ERROR_IGNORE_ECONNRESET
;
2613 ngx_set_socket_errno(0);
2615 n
= c
->recv(c
, b
->last
, size
);
2616 c
->log_error
= NGX_ERROR_INFO
;
2618 if (n
== NGX_AGAIN
) {
2619 if (ngx_handle_read_event(rev
, 0) != NGX_OK
) {
2620 ngx_http_close_connection(c
);
2626 if (n
== NGX_ERROR
) {
2627 ngx_http_close_connection(c
);
2631 c
->log
->handler
= NULL
;
2634 ngx_log_error(NGX_LOG_INFO
, c
->log
, ngx_socket_errno
,
2635 "client %V closed keepalive connection", &c
->addr_text
);
2636 ngx_http_close_connection(c
);
2643 (void) ngx_atomic_fetch_add(ngx_stat_reading
, 1);
2646 c
->log
->handler
= ngx_http_log_error
;
2647 c
->log
->action
= "reading client request line";
2651 ngx_http_init_request(rev
);
2656 ngx_http_set_lingering_close(ngx_http_request_t
*r
)
2658 ngx_event_t
*rev
, *wev
;
2659 ngx_connection_t
*c
;
2660 ngx_http_core_loc_conf_t
*clcf
;
2664 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
2667 rev
->handler
= ngx_http_lingering_close_handler
;
2669 r
->lingering_time
= ngx_time() + (time_t) (clcf
->lingering_time
/ 1000);
2670 ngx_add_timer(rev
, clcf
->lingering_timeout
);
2672 if (ngx_handle_read_event(rev
, 0) != NGX_OK
) {
2673 ngx_http_close_request(r
, 0);
2678 wev
->handler
= ngx_http_empty_handler
;
2680 if (wev
->active
&& (ngx_event_flags
& NGX_USE_LEVEL_EVENT
)) {
2681 if (ngx_del_event(wev
, NGX_WRITE_EVENT
, 0) != NGX_OK
) {
2682 ngx_http_close_request(r
, 0);
2687 if (ngx_shutdown_socket(c
->fd
, NGX_WRITE_SHUTDOWN
) == -1) {
2688 ngx_connection_error(c
, ngx_socket_errno
,
2689 ngx_shutdown_socket_n
" failed");
2690 ngx_http_close_request(r
, 0);
2695 ngx_http_lingering_close_handler(rev
);
2701 ngx_http_lingering_close_handler(ngx_event_t
*rev
)
2705 ngx_connection_t
*c
;
2706 ngx_http_request_t
*r
;
2707 ngx_http_core_loc_conf_t
*clcf
;
2708 u_char buffer
[NGX_HTTP_LINGERING_BUFFER_SIZE
];
2713 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
2714 "http lingering close handler");
2716 if (rev
->timedout
) {
2718 ngx_http_close_request(r
, 0);
2722 timer
= (ngx_msec_t
) (r
->lingering_time
- ngx_time());
2724 ngx_http_close_request(r
, 0);
2729 n
= c
->recv(c
, buffer
, NGX_HTTP_LINGERING_BUFFER_SIZE
);
2731 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, c
->log
, 0, "lingering read: %d", n
);
2733 if (n
== NGX_ERROR
|| n
== 0) {
2734 ngx_http_close_request(r
, 0);
2738 } while (rev
->ready
);
2740 if (ngx_handle_read_event(rev
, 0) != NGX_OK
) {
2741 ngx_http_close_request(r
, 0);
2745 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
2749 if (timer
> clcf
->lingering_timeout
) {
2750 timer
= clcf
->lingering_timeout
;
2753 ngx_add_timer(rev
, timer
);
2758 ngx_http_empty_handler(ngx_event_t
*wev
)
2760 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, wev
->log
, 0, "http empty handler");
2767 ngx_http_request_empty_handler(ngx_http_request_t
*r
)
2769 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
2770 "http request empty handler");
2777 ngx_http_send_special(ngx_http_request_t
*r
, ngx_uint_t flags
)
2782 b
= ngx_calloc_buf(r
->pool
);
2787 if (flags
& NGX_HTTP_LAST
) {
2789 if (r
== r
->main
&& !r
->post_action
) {
2794 b
->last_in_chain
= 1;
2798 if (flags
& NGX_HTTP_FLUSH
) {
2805 return ngx_http_output_filter(r
, &out
);
2810 ngx_http_post_action(ngx_http_request_t
*r
)
2812 ngx_http_core_loc_conf_t
*clcf
;
2814 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
2816 if (clcf
->post_action
.data
== NULL
) {
2817 return NGX_DECLINED
;
2820 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
2821 "post action: \"%V\"", &clcf
->post_action
);
2825 r
->http_version
= NGX_HTTP_VERSION_9
;
2829 r
->read_event_handler
= ngx_http_block_reading
;
2831 if (clcf
->post_action
.data
[0] == '/') {
2832 ngx_http_internal_redirect(r
, &clcf
->post_action
, NULL
);
2835 ngx_http_named_location(r
, &clcf
->post_action
);
2843 ngx_http_close_request(ngx_http_request_t
*r
, ngx_int_t rc
)
2845 ngx_connection_t
*c
;
2850 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
2851 "http request count:%d blk:%d", r
->count
, r
->blocked
);
2853 if (r
->count
== 0) {
2854 ngx_log_error(NGX_LOG_ALERT
, c
->log
, 0, "http request count is zero");
2859 if (r
->count
|| r
->blocked
) {
2863 ngx_http_free_request(r
, rc
);
2864 ngx_http_close_connection(c
);
2869 ngx_http_free_request(ngx_http_request_t
*r
, ngx_int_t rc
)
2872 struct linger linger
;
2873 ngx_http_cleanup_t
*cln
;
2874 ngx_http_log_ctx_t
*ctx
;
2875 ngx_http_core_loc_conf_t
*clcf
;
2877 log
= r
->connection
->log
;
2879 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, log
, 0, "http close request");
2881 if (r
->pool
== NULL
) {
2882 ngx_log_error(NGX_LOG_ALERT
, log
, 0, "http request already closed");
2886 for (cln
= r
->cleanup
; cln
; cln
= cln
->next
) {
2888 cln
->handler(cln
->data
);
2894 if (r
->stat_reading
) {
2895 (void) ngx_atomic_fetch_add(ngx_stat_reading
, -1);
2898 if (r
->stat_writing
) {
2899 (void) ngx_atomic_fetch_add(ngx_stat_writing
, -1);
2904 if (rc
> 0 && (r
->headers_out
.status
== 0 || r
->connection
->sent
== 0)) {
2905 r
->headers_out
.status
= rc
;
2908 log
->action
= "logging request";
2910 ngx_http_log_request(r
);
2912 log
->action
= "closing request";
2914 if (r
->connection
->timedout
) {
2915 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
2917 if (clcf
->reset_timedout_connection
) {
2919 linger
.l_linger
= 0;
2921 if (setsockopt(r
->connection
->fd
, SOL_SOCKET
, SO_LINGER
,
2922 (const void *) &linger
, sizeof(struct linger
)) == -1)
2924 ngx_log_error(NGX_LOG_ALERT
, log
, ngx_socket_errno
,
2925 "setsockopt(SO_LINGER) failed");
2930 /* the various request strings were allocated from r->pool */
2932 ctx
->request
= NULL
;
2934 r
->request_line
.len
= 0;
2936 r
->connection
->destroyed
= 1;
2938 ngx_destroy_pool(r
->pool
);
2943 ngx_http_log_request(ngx_http_request_t
*r
)
2946 ngx_http_handler_pt
*log_handler
;
2947 ngx_http_core_main_conf_t
*cmcf
;
2949 cmcf
= ngx_http_get_module_main_conf(r
, ngx_http_core_module
);
2951 log_handler
= cmcf
->phases
[NGX_HTTP_LOG_PHASE
].handlers
.elts
;
2952 n
= cmcf
->phases
[NGX_HTTP_LOG_PHASE
].handlers
.nelts
;
2954 for (i
= 0; i
< n
; i
++) {
2961 ngx_http_close_connection(ngx_connection_t
*c
)
2965 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
2966 "close http connection: %d", c
->fd
);
2971 if (ngx_ssl_shutdown(c
) == NGX_AGAIN
) {
2972 c
->ssl
->handler
= ngx_http_close_connection
;
2980 (void) ngx_atomic_fetch_add(ngx_stat_active
, -1);
2987 ngx_close_connection(c
);
2989 ngx_destroy_pool(pool
);
2994 ngx_http_log_error(ngx_log_t
*log
, u_char
*buf
, size_t len
)
2997 ngx_http_request_t
*r
;
2998 ngx_http_log_ctx_t
*ctx
;
3001 p
= ngx_snprintf(buf
, len
, " while %s", log
->action
);
3008 p
= ngx_snprintf(buf
, len
, ", client: %V", &ctx
->connection
->addr_text
);
3014 return r
->log_handler(r
, ctx
->current_request
, p
, len
);
3017 p
= ngx_snprintf(p
, len
, ", server: %V",
3018 &ctx
->connection
->listening
->addr_text
);
3026 ngx_http_log_error_handler(ngx_http_request_t
*r
, ngx_http_request_t
*sr
,
3027 u_char
*buf
, size_t len
)
3029 char *uri_separator
;
3031 ngx_http_upstream_t
*u
;
3032 ngx_http_core_srv_conf_t
*cscf
;
3034 cscf
= ngx_http_get_module_srv_conf(r
, ngx_http_core_module
);
3036 p
= ngx_snprintf(buf
, len
, ", server: %V", &cscf
->server_name
);
3040 if (r
->request_line
.data
== NULL
&& r
->request_start
) {
3041 for (p
= r
->request_start
; p
< r
->header_in
->last
; p
++) {
3042 if (*p
== CR
|| *p
== LF
) {
3047 r
->request_line
.len
= p
- r
->request_start
;
3048 r
->request_line
.data
= r
->request_start
;
3051 if (r
->request_line
.len
) {
3052 p
= ngx_snprintf(buf
, len
, ", request: \"%V\"", &r
->request_line
);
3058 p
= ngx_snprintf(buf
, len
, ", subrequest: \"%V\"", &sr
->uri
);
3065 if (u
&& u
->peer
.name
) {
3069 #if (NGX_HAVE_UNIX_DOMAIN)
3070 if (u
->peer
.sockaddr
&& u
->peer
.sockaddr
->sa_family
== AF_UNIX
) {
3071 uri_separator
= ":";
3075 p
= ngx_snprintf(buf
, len
, ", upstream: \"%V%V%s%V\"",
3076 &u
->schema
, u
->peer
.name
,
3077 uri_separator
, &u
->uri
);
3082 if (r
->headers_in
.host
) {
3083 p
= ngx_snprintf(buf
, len
, ", host: \"%V\"",
3084 &r
->headers_in
.host
->value
);
3089 if (r
->headers_in
.referer
) {
3090 p
= ngx_snprintf(buf
, len
, ", referrer: \"%V\"",
3091 &r
->headers_in
.referer
->value
);