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(ngx_http_request_t
*r
, u_char
**host
,
35 size_t len
, ngx_uint_t alloc
);
36 static ngx_int_t
ngx_http_find_virtual_server(ngx_http_request_t
*r
,
37 u_char
*host
, size_t len
);
39 static void ngx_http_request_handler(ngx_event_t
*ev
);
40 static void ngx_http_terminate_request(ngx_http_request_t
*r
, ngx_int_t rc
);
41 static void ngx_http_terminate_handler(ngx_http_request_t
*r
);
42 static void ngx_http_finalize_connection(ngx_http_request_t
*r
);
43 static ngx_int_t
ngx_http_set_write_handler(ngx_http_request_t
*r
);
44 static void ngx_http_writer(ngx_http_request_t
*r
);
45 static void ngx_http_request_finalizer(ngx_http_request_t
*r
);
47 static void ngx_http_set_keepalive(ngx_http_request_t
*r
);
48 static void ngx_http_keepalive_handler(ngx_event_t
*ev
);
49 static void ngx_http_set_lingering_close(ngx_http_request_t
*r
);
50 static void ngx_http_lingering_close_handler(ngx_event_t
*ev
);
51 static ngx_int_t
ngx_http_post_action(ngx_http_request_t
*r
);
52 static void ngx_http_close_request(ngx_http_request_t
*r
, ngx_int_t error
);
53 static void ngx_http_free_request(ngx_http_request_t
*r
, ngx_int_t error
);
54 static void ngx_http_log_request(ngx_http_request_t
*r
);
55 static void ngx_http_close_connection(ngx_connection_t
*c
);
57 static u_char
*ngx_http_log_error(ngx_log_t
*log
, u_char
*buf
, size_t len
);
58 static u_char
*ngx_http_log_error_handler(ngx_http_request_t
*r
,
59 ngx_http_request_t
*sr
, u_char
*buf
, size_t len
);
62 static void ngx_http_ssl_handshake(ngx_event_t
*rev
);
63 static void ngx_http_ssl_handshake_handler(ngx_connection_t
*c
);
67 static char *ngx_http_client_errors
[] = {
69 /* NGX_HTTP_PARSE_INVALID_METHOD */
70 "client sent invalid method",
72 /* NGX_HTTP_PARSE_INVALID_REQUEST */
73 "client sent invalid request",
75 /* NGX_HTTP_PARSE_INVALID_09_METHOD */
76 "client sent invalid method in HTTP/0.9 request"
80 ngx_http_header_t ngx_http_headers_in
[] = {
81 { ngx_string("Host"), offsetof(ngx_http_headers_in_t
, host
),
82 ngx_http_process_host
},
84 { ngx_string("Connection"), offsetof(ngx_http_headers_in_t
, connection
),
85 ngx_http_process_connection
},
87 { ngx_string("If-Modified-Since"),
88 offsetof(ngx_http_headers_in_t
, if_modified_since
),
89 ngx_http_process_unique_header_line
},
91 { ngx_string("If-Unmodified-Since"),
92 offsetof(ngx_http_headers_in_t
, if_unmodified_since
),
93 ngx_http_process_unique_header_line
},
95 { ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t
, user_agent
),
96 ngx_http_process_user_agent
},
98 { ngx_string("Referer"), offsetof(ngx_http_headers_in_t
, referer
),
99 ngx_http_process_header_line
},
101 { ngx_string("Content-Length"),
102 offsetof(ngx_http_headers_in_t
, content_length
),
103 ngx_http_process_unique_header_line
},
105 { ngx_string("Content-Type"),
106 offsetof(ngx_http_headers_in_t
, content_type
),
107 ngx_http_process_header_line
},
109 { ngx_string("Range"), offsetof(ngx_http_headers_in_t
, range
),
110 ngx_http_process_header_line
},
112 { ngx_string("If-Range"),
113 offsetof(ngx_http_headers_in_t
, if_range
),
114 ngx_http_process_unique_header_line
},
116 { ngx_string("Transfer-Encoding"),
117 offsetof(ngx_http_headers_in_t
, transfer_encoding
),
118 ngx_http_process_header_line
},
120 { ngx_string("Expect"),
121 offsetof(ngx_http_headers_in_t
, expect
),
122 ngx_http_process_unique_header_line
},
125 { ngx_string("Accept-Encoding"),
126 offsetof(ngx_http_headers_in_t
, accept_encoding
),
127 ngx_http_process_header_line
},
129 { ngx_string("Via"), offsetof(ngx_http_headers_in_t
, via
),
130 ngx_http_process_header_line
},
133 { ngx_string("Authorization"),
134 offsetof(ngx_http_headers_in_t
, authorization
),
135 ngx_http_process_unique_header_line
},
137 { ngx_string("Keep-Alive"), offsetof(ngx_http_headers_in_t
, keep_alive
),
138 ngx_http_process_header_line
},
140 #if (NGX_HTTP_PROXY || NGX_HTTP_REALIP || NGX_HTTP_GEO)
141 { ngx_string("X-Forwarded-For"),
142 offsetof(ngx_http_headers_in_t
, x_forwarded_for
),
143 ngx_http_process_header_line
},
146 #if (NGX_HTTP_REALIP)
147 { ngx_string("X-Real-IP"),
148 offsetof(ngx_http_headers_in_t
, x_real_ip
),
149 ngx_http_process_header_line
},
152 #if (NGX_HTTP_HEADERS)
153 { ngx_string("Accept"), offsetof(ngx_http_headers_in_t
, accept
),
154 ngx_http_process_header_line
},
156 { ngx_string("Accept-Language"),
157 offsetof(ngx_http_headers_in_t
, accept_language
),
158 ngx_http_process_header_line
},
162 { ngx_string("Depth"), offsetof(ngx_http_headers_in_t
, depth
),
163 ngx_http_process_header_line
},
165 { ngx_string("Destination"), offsetof(ngx_http_headers_in_t
, destination
),
166 ngx_http_process_header_line
},
168 { ngx_string("Overwrite"), offsetof(ngx_http_headers_in_t
, overwrite
),
169 ngx_http_process_header_line
},
171 { ngx_string("Date"), offsetof(ngx_http_headers_in_t
, date
),
172 ngx_http_process_header_line
},
175 { ngx_string("Cookie"), 0, ngx_http_process_cookie
},
177 { ngx_null_string
, 0, NULL
}
182 ngx_http_init_connection(ngx_connection_t
*c
)
185 ngx_http_log_ctx_t
*ctx
;
187 ctx
= ngx_palloc(c
->pool
, sizeof(ngx_http_log_ctx_t
));
189 ngx_http_close_connection(c
);
195 ctx
->current_request
= NULL
;
197 c
->log
->connection
= c
->number
;
198 c
->log
->handler
= ngx_http_log_error
;
200 c
->log
->action
= "reading client request line";
202 c
->log_error
= NGX_ERROR_INFO
;
205 rev
->handler
= ngx_http_init_request
;
206 c
->write
->handler
= ngx_http_empty_handler
;
209 (void) ngx_atomic_fetch_add(ngx_stat_reading
, 1);
213 /* the deferred accept(), rtsig, aio, iocp */
215 if (ngx_use_accept_mutex
) {
216 ngx_post_event(rev
, &ngx_posted_events
);
220 ngx_http_init_request(rev
);
224 ngx_add_timer(rev
, c
->listening
->post_accept_timeout
);
226 if (ngx_handle_read_event(rev
, 0) != NGX_OK
) {
228 (void) ngx_atomic_fetch_add(ngx_stat_reading
, -1);
230 ngx_http_close_connection(c
);
237 ngx_http_init_request(ngx_event_t
*rev
)
242 ngx_http_request_t
*r
;
243 struct sockaddr_in
*sin
;
244 ngx_http_port_t
*port
;
245 ngx_http_in_addr_t
*addr
;
246 ngx_http_log_ctx_t
*ctx
;
247 ngx_http_addr_conf_t
*addr_conf
;
248 ngx_http_connection_t
*hc
;
249 ngx_http_core_srv_conf_t
*cscf
;
250 ngx_http_core_loc_conf_t
*clcf
;
251 ngx_http_core_main_conf_t
*cmcf
;
253 struct sockaddr_in6
*sin6
;
254 ngx_http_in6_addr_t
*addr6
;
258 (void) ngx_atomic_fetch_add(ngx_stat_reading
, -1);
264 ngx_log_error(NGX_LOG_INFO
, c
->log
, NGX_ETIMEDOUT
, "client timed out");
266 ngx_http_close_connection(c
);
275 hc
= ngx_pcalloc(c
->pool
, sizeof(ngx_http_connection_t
));
277 ngx_http_close_connection(c
);
285 ngx_memzero(r
, sizeof(ngx_http_request_t
));
287 r
->pipeline
= hc
->pipeline
;
290 r
->header_in
= hc
->busy
[0];
294 r
= ngx_pcalloc(c
->pool
, sizeof(ngx_http_request_t
));
296 ngx_http_close_connection(c
);
304 r
->http_connection
= hc
;
307 r
->signature
= NGX_HTTP_MODULE
;
309 /* find the server configuration for the address:port */
311 port
= c
->listening
->servers
;
315 if (port
->naddrs
> 1) {
318 * there are several addresses on this port and one of them
319 * is an "*:port" wildcard so getsockname() in ngx_http_server_addr()
320 * is required to determine a server address
323 if (ngx_connection_local_sockaddr(c
, NULL
, 0) != NGX_OK
) {
324 ngx_http_close_connection(c
);
328 switch (c
->local_sockaddr
->sa_family
) {
332 sin6
= (struct sockaddr_in6
*) c
->local_sockaddr
;
336 /* the last address is "*" */
338 for (i
= 0; i
< port
->naddrs
- 1; i
++) {
339 if (ngx_memcmp(&addr6
[i
].addr6
, &sin6
->sin6_addr
, 16) == 0) {
344 addr_conf
= &addr6
[i
].conf
;
349 default: /* AF_INET */
350 sin
= (struct sockaddr_in
*) c
->local_sockaddr
;
354 /* the last address is "*" */
356 for (i
= 0; i
< port
->naddrs
- 1; i
++) {
357 if (addr
[i
].addr
== sin
->sin_addr
.s_addr
) {
362 addr_conf
= &addr
[i
].conf
;
369 switch (c
->local_sockaddr
->sa_family
) {
374 addr_conf
= &addr6
[0].conf
;
378 default: /* AF_INET */
380 addr_conf
= &addr
[0].conf
;
385 r
->virtual_names
= addr_conf
->virtual_names
;
387 /* the default server configuration for the address:port */
388 cscf
= addr_conf
->default_server
;
390 r
->main_conf
= cscf
->ctx
->main_conf
;
391 r
->srv_conf
= cscf
->ctx
->srv_conf
;
392 r
->loc_conf
= cscf
->ctx
->loc_conf
;
394 rev
->handler
= ngx_http_process_request_line
;
395 r
->read_event_handler
= ngx_http_block_reading
;
400 ngx_http_ssl_srv_conf_t
*sscf
;
402 sscf
= ngx_http_get_module_srv_conf(r
, ngx_http_ssl_module
);
403 if (sscf
->enable
|| addr_conf
->ssl
) {
405 if (c
->ssl
== NULL
) {
407 c
->log
->action
= "SSL handshaking";
409 if (addr_conf
->ssl
&& sscf
->ssl
.ctx
== NULL
) {
410 ngx_log_error(NGX_LOG_ERR
, c
->log
, 0,
411 "no \"ssl_certificate\" is defined "
412 "in server listening on SSL port");
413 ngx_http_close_connection(c
);
417 if (ngx_ssl_create_connection(&sscf
->ssl
, c
, NGX_SSL_BUFFER
)
420 ngx_http_close_connection(c
);
424 rev
->handler
= ngx_http_ssl_handshake
;
427 r
->main_filter_need_in_memory
= 1;
433 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
434 c
->log
->file
= clcf
->error_log
->file
;
435 if (!(c
->log
->log_level
& NGX_LOG_DEBUG_CONNECTION
)) {
436 c
->log
->log_level
= clcf
->error_log
->log_level
;
439 if (c
->buffer
== NULL
) {
440 c
->buffer
= ngx_create_temp_buf(c
->pool
,
441 cscf
->client_header_buffer_size
);
442 if (c
->buffer
== NULL
) {
443 ngx_http_close_connection(c
);
448 if (r
->header_in
== NULL
) {
449 r
->header_in
= c
->buffer
;
452 r
->pool
= ngx_create_pool(cscf
->request_pool_size
, c
->log
);
453 if (r
->pool
== NULL
) {
454 ngx_http_close_connection(c
);
459 if (ngx_list_init(&r
->headers_out
.headers
, r
->pool
, 20,
460 sizeof(ngx_table_elt_t
))
463 ngx_destroy_pool(r
->pool
);
464 ngx_http_close_connection(c
);
468 r
->ctx
= ngx_pcalloc(r
->pool
, sizeof(void *) * ngx_http_max_module
);
469 if (r
->ctx
== NULL
) {
470 ngx_destroy_pool(r
->pool
);
471 ngx_http_close_connection(c
);
475 cmcf
= ngx_http_get_module_main_conf(r
, ngx_http_core_module
);
477 r
->variables
= ngx_pcalloc(r
->pool
, cmcf
->variables
.nelts
478 * sizeof(ngx_http_variable_value_t
));
479 if (r
->variables
== NULL
) {
480 ngx_destroy_pool(r
->pool
);
481 ngx_http_close_connection(c
);
485 c
->single_connection
= 1;
491 tp
= ngx_timeofday();
492 r
->start_sec
= tp
->sec
;
493 r
->start_msec
= tp
->msec
;
495 r
->method
= NGX_HTTP_UNKNOWN
;
497 r
->headers_in
.content_length_n
= -1;
498 r
->headers_in
.keep_alive_n
= -1;
499 r
->headers_out
.content_length_n
= -1;
500 r
->headers_out
.last_modified_time
= -1;
502 r
->uri_changes
= NGX_HTTP_MAX_URI_CHANGES
+ 1;
503 r
->subrequests
= NGX_HTTP_MAX_SUBREQUESTS
+ 1;
505 r
->http_state
= NGX_HTTP_READING_REQUEST_STATE
;
509 ctx
->current_request
= r
;
510 r
->log_handler
= ngx_http_log_error_handler
;
513 (void) ngx_atomic_fetch_add(ngx_stat_reading
, 1);
515 (void) ngx_atomic_fetch_add(ngx_stat_requests
, 1);
525 ngx_http_ssl_handshake(ngx_event_t
*rev
)
531 ngx_http_request_t
*r
;
536 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, rev
->log
, 0,
537 "http check ssl handshake");
540 ngx_log_error(NGX_LOG_INFO
, c
->log
, NGX_ETIMEDOUT
, "client timed out");
542 ngx_http_close_request(r
, NGX_HTTP_REQUEST_TIME_OUT
);
546 n
= recv(c
->fd
, (char *) buf
, 1, MSG_PEEK
);
548 if (n
== -1 && ngx_socket_errno
== NGX_EAGAIN
) {
550 if (!rev
->timer_set
) {
551 ngx_add_timer(rev
, c
->listening
->post_accept_timeout
);
554 if (ngx_handle_read_event(rev
, 0) != NGX_OK
) {
555 ngx_http_close_request(r
, NGX_HTTP_INTERNAL_SERVER_ERROR
);
562 if (buf
[0] & 0x80 /* SSLv2 */ || buf
[0] == 0x16 /* SSLv3/TLSv1 */) {
563 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, rev
->log
, 0,
564 "https ssl handshake: 0x%02Xd", buf
[0]);
566 rc
= ngx_ssl_handshake(c
);
568 if (rc
== NGX_AGAIN
) {
570 if (!rev
->timer_set
) {
571 ngx_add_timer(rev
, c
->listening
->post_accept_timeout
);
574 c
->ssl
->handler
= ngx_http_ssl_handshake_handler
;
578 ngx_http_ssl_handshake_handler(c
);
583 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, rev
->log
, 0,
590 c
->log
->action
= "reading client request line";
592 rev
->handler
= ngx_http_process_request_line
;
593 ngx_http_process_request_line(rev
);
598 ngx_http_ssl_handshake_handler(ngx_connection_t
*c
)
600 ngx_http_request_t
*r
;
602 if (c
->ssl
->handshaked
) {
605 * The majority of browsers do not send the "close notify" alert.
606 * Among them are MSIE, old Mozilla, Netscape 4, Konqueror,
607 * and Links. And what is more, MSIE ignores the server's alert.
609 * Opera and recent Mozilla send the alert.
612 c
->ssl
->no_wait_shutdown
= 1;
614 c
->read
->handler
= ngx_http_process_request_line
;
615 /* STUB: epoll edge */ c
->write
->handler
= ngx_http_empty_handler
;
617 ngx_http_process_request_line(c
->read
);
624 ngx_http_close_request(r
, NGX_HTTP_BAD_REQUEST
);
629 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
632 ngx_http_ssl_servername(ngx_ssl_conn_t
*ssl_conn
, int *ad
, void *arg
)
636 const char *servername
;
638 ngx_http_request_t
*r
;
639 ngx_http_ssl_srv_conf_t
*sscf
;
641 servername
= SSL_get_servername(ssl_conn
, TLSEXT_NAMETYPE_host_name
);
643 if (servername
== NULL
) {
644 return SSL_TLSEXT_ERR_NOACK
;
647 c
= ngx_ssl_get_connection(ssl_conn
);
649 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
650 "SSL server name: \"%s\"", servername
);
652 len
= ngx_strlen(servername
);
655 return SSL_TLSEXT_ERR_NOACK
;
660 host
= (u_char
*) servername
;
662 len
= ngx_http_validate_host(r
, &host
, len
, 1);
665 return SSL_TLSEXT_ERR_NOACK
;
668 if (ngx_http_find_virtual_server(r
, host
, len
) != NGX_OK
) {
669 return SSL_TLSEXT_ERR_NOACK
;
672 sscf
= ngx_http_get_module_srv_conf(r
, ngx_http_ssl_module
);
675 SSL_set_SSL_CTX(ssl_conn
, sscf
->ssl
.ctx
);
678 * SSL_set_SSL_CTX() only changes certs as of 1.0.0d
679 * adjust other things we care about
682 SSL_set_verify(ssl_conn
, SSL_CTX_get_verify_mode(sscf
->ssl
.ctx
),
683 SSL_CTX_get_verify_callback(sscf
->ssl
.ctx
));
685 SSL_set_verify_depth(ssl_conn
, SSL_CTX_get_verify_depth(sscf
->ssl
.ctx
));
687 #ifdef SSL_CTRL_CLEAR_OPTIONS
688 /* only in 0.9.8m+ */
689 SSL_clear_options(ssl_conn
, SSL_get_options(ssl_conn
) &
690 ~SSL_CTX_get_options(sscf
->ssl
.ctx
));
693 SSL_set_options(ssl_conn
, SSL_CTX_get_options(sscf
->ssl
.ctx
));
696 return SSL_TLSEXT_ERR_OK
;
705 ngx_http_process_request_line(ngx_event_t
*rev
)
711 ngx_http_request_t
*r
;
712 ngx_http_core_srv_conf_t
*cscf
;
717 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, rev
->log
, 0,
718 "http process request line");
721 ngx_log_error(NGX_LOG_INFO
, c
->log
, NGX_ETIMEDOUT
, "client timed out");
723 ngx_http_close_request(r
, NGX_HTTP_REQUEST_TIME_OUT
);
731 if (rc
== NGX_AGAIN
) {
732 n
= ngx_http_read_request_header(r
);
734 if (n
== NGX_AGAIN
|| n
== NGX_ERROR
) {
739 rc
= ngx_http_parse_request_line(r
, r
->header_in
);
743 /* the request line has been parsed successfully */
745 r
->request_line
.len
= r
->request_end
- r
->request_start
;
746 r
->request_line
.data
= r
->request_start
;
750 r
->uri
.len
= r
->args_start
- 1 - r
->uri_start
;
752 r
->uri
.len
= r
->uri_end
- r
->uri_start
;
756 if (r
->complex_uri
|| r
->quoted_uri
) {
758 r
->uri
.data
= ngx_pnalloc(r
->pool
, r
->uri
.len
+ 1);
759 if (r
->uri
.data
== NULL
) {
760 ngx_http_close_request(r
, NGX_HTTP_INTERNAL_SERVER_ERROR
);
764 cscf
= ngx_http_get_module_srv_conf(r
, ngx_http_core_module
);
766 rc
= ngx_http_parse_complex_uri(r
, cscf
->merge_slashes
);
768 if (rc
== NGX_HTTP_PARSE_INVALID_REQUEST
) {
769 ngx_log_error(NGX_LOG_INFO
, c
->log
, 0,
770 "client sent invalid request");
771 ngx_http_finalize_request(r
, NGX_HTTP_BAD_REQUEST
);
776 r
->uri
.data
= r
->uri_start
;
780 r
->unparsed_uri
.len
= r
->uri_end
- r
->uri_start
;
781 r
->unparsed_uri
.data
= r
->uri_start
;
783 r
->valid_unparsed_uri
= r
->space_in_uri
? 0 : 1;
785 r
->method_name
.len
= r
->method_end
- r
->request_start
+ 1;
786 r
->method_name
.data
= r
->request_line
.data
;
789 if (r
->http_protocol
.data
) {
790 r
->http_protocol
.len
= r
->request_end
- r
->http_protocol
.data
;
796 r
->exten
.len
= r
->args_start
- 1 - r
->uri_ext
;
798 r
->exten
.len
= r
->uri_end
- r
->uri_ext
;
801 r
->exten
.data
= r
->uri_ext
;
805 if (r
->args_start
&& r
->uri_end
> r
->args_start
) {
806 r
->args
.len
= r
->uri_end
- r
->args_start
;
807 r
->args
.data
= r
->args_start
;
814 p
= r
->uri
.data
+ r
->uri
.len
- 1;
816 while (p
> r
->uri
.data
) {
828 if (ngx_strncasecmp(p
- 6, (u_char
*) "::$data", 7) == 0) {
836 if (p
!= r
->uri
.data
+ r
->uri
.len
- 1) {
837 r
->uri
.len
= p
+ 1 - r
->uri
.data
;
838 ngx_http_set_exten(r
);
844 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
845 "http request line: \"%V\"", &r
->request_line
);
847 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
848 "http uri: \"%V\"", &r
->uri
);
850 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
851 "http args: \"%V\"", &r
->args
);
853 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
854 "http exten: \"%V\"", &r
->exten
);
856 if (r
->host_start
&& r
->host_end
) {
858 host
= r
->host_start
;
859 n
= ngx_http_validate_host(r
, &host
,
860 r
->host_end
- r
->host_start
, 0);
863 ngx_log_error(NGX_LOG_INFO
, c
->log
, 0,
864 "client sent invalid host in request line");
865 ngx_http_finalize_request(r
, NGX_HTTP_BAD_REQUEST
);
870 ngx_http_close_request(r
, NGX_HTTP_INTERNAL_SERVER_ERROR
);
874 r
->headers_in
.server
.len
= n
;
875 r
->headers_in
.server
.data
= host
;
878 if (r
->http_version
< NGX_HTTP_VERSION_10
) {
880 if (ngx_http_find_virtual_server(r
, r
->headers_in
.server
.data
,
881 r
->headers_in
.server
.len
)
884 ngx_http_close_request(r
, NGX_HTTP_INTERNAL_SERVER_ERROR
);
888 ngx_http_process_request(r
);
893 if (ngx_list_init(&r
->headers_in
.headers
, r
->pool
, 20,
894 sizeof(ngx_table_elt_t
))
897 ngx_http_close_request(r
, NGX_HTTP_INTERNAL_SERVER_ERROR
);
902 if (ngx_array_init(&r
->headers_in
.cookies
, r
->pool
, 2,
903 sizeof(ngx_table_elt_t
*))
906 ngx_http_close_request(r
, NGX_HTTP_INTERNAL_SERVER_ERROR
);
910 c
->log
->action
= "reading client request headers";
912 rev
->handler
= ngx_http_process_request_headers
;
913 ngx_http_process_request_headers(rev
);
918 if (rc
!= NGX_AGAIN
) {
920 /* there was error while a request line parsing */
922 ngx_log_error(NGX_LOG_INFO
, c
->log
, 0,
923 ngx_http_client_errors
[rc
- NGX_HTTP_CLIENT_ERROR
]);
924 ngx_http_finalize_request(r
, NGX_HTTP_BAD_REQUEST
);
928 /* NGX_AGAIN: a request line parsing is still incomplete */
930 if (r
->header_in
->pos
== r
->header_in
->end
) {
932 rv
= ngx_http_alloc_large_header_buffer(r
, 1);
934 if (rv
== NGX_ERROR
) {
935 ngx_http_close_request(r
, NGX_HTTP_INTERNAL_SERVER_ERROR
);
939 if (rv
== NGX_DECLINED
) {
940 r
->request_line
.len
= r
->header_in
->end
- r
->request_start
;
941 r
->request_line
.data
= r
->request_start
;
943 ngx_log_error(NGX_LOG_INFO
, c
->log
, 0,
944 "client sent too long URI");
945 ngx_http_finalize_request(r
, NGX_HTTP_REQUEST_URI_TOO_LARGE
);
954 ngx_http_process_request_headers(ngx_event_t
*rev
)
962 ngx_http_header_t
*hh
;
963 ngx_http_request_t
*r
;
964 ngx_http_core_srv_conf_t
*cscf
;
965 ngx_http_core_main_conf_t
*cmcf
;
970 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, rev
->log
, 0,
971 "http process request header line");
974 ngx_log_error(NGX_LOG_INFO
, c
->log
, NGX_ETIMEDOUT
, "client timed out");
976 ngx_http_close_request(r
, NGX_HTTP_REQUEST_TIME_OUT
);
980 cmcf
= ngx_http_get_module_main_conf(r
, ngx_http_core_module
);
981 cscf
= ngx_http_get_module_srv_conf(r
, ngx_http_core_module
);
987 if (rc
== NGX_AGAIN
) {
989 if (r
->header_in
->pos
== r
->header_in
->end
) {
991 rv
= ngx_http_alloc_large_header_buffer(r
, 0);
993 if (rv
== NGX_ERROR
) {
994 ngx_http_close_request(r
, NGX_HTTP_INTERNAL_SERVER_ERROR
);
998 if (rv
== NGX_DECLINED
) {
999 p
= r
->header_name_start
;
1001 r
->lingering_close
= 1;
1004 ngx_log_error(NGX_LOG_INFO
, c
->log
, 0,
1005 "client sent too large request");
1006 ngx_http_finalize_request(r
,
1007 NGX_HTTP_REQUEST_HEADER_TOO_LARGE
);
1011 len
= r
->header_in
->end
- p
;
1013 if (len
> NGX_MAX_ERROR_STR
- 300) {
1014 len
= NGX_MAX_ERROR_STR
- 300;
1015 p
[len
++] = '.'; p
[len
++] = '.'; p
[len
++] = '.';
1018 ngx_log_error(NGX_LOG_INFO
, c
->log
, 0,
1019 "client sent too long header line: \"%*s\"",
1020 len
, r
->header_name_start
);
1022 ngx_http_finalize_request(r
,
1023 NGX_HTTP_REQUEST_HEADER_TOO_LARGE
);
1028 n
= ngx_http_read_request_header(r
);
1030 if (n
== NGX_AGAIN
|| n
== NGX_ERROR
) {
1035 rc
= ngx_http_parse_header_line(r
, r
->header_in
,
1036 cscf
->underscores_in_headers
);
1040 if (r
->invalid_header
&& cscf
->ignore_invalid_headers
) {
1042 /* there was error while a header line parsing */
1044 ngx_log_error(NGX_LOG_INFO
, c
->log
, 0,
1045 "client sent invalid header line: \"%*s\"",
1046 r
->header_end
- r
->header_name_start
,
1047 r
->header_name_start
);
1051 /* a header line has been parsed successfully */
1053 h
= ngx_list_push(&r
->headers_in
.headers
);
1055 ngx_http_close_request(r
, NGX_HTTP_INTERNAL_SERVER_ERROR
);
1059 h
->hash
= r
->header_hash
;
1061 h
->key
.len
= r
->header_name_end
- r
->header_name_start
;
1062 h
->key
.data
= r
->header_name_start
;
1063 h
->key
.data
[h
->key
.len
] = '\0';
1065 h
->value
.len
= r
->header_end
- r
->header_start
;
1066 h
->value
.data
= r
->header_start
;
1067 h
->value
.data
[h
->value
.len
] = '\0';
1069 h
->lowcase_key
= ngx_pnalloc(r
->pool
, h
->key
.len
);
1070 if (h
->lowcase_key
== NULL
) {
1071 ngx_http_close_request(r
, NGX_HTTP_INTERNAL_SERVER_ERROR
);
1075 if (h
->key
.len
== r
->lowcase_index
) {
1076 ngx_memcpy(h
->lowcase_key
, r
->lowcase_header
, h
->key
.len
);
1079 ngx_strlow(h
->lowcase_key
, h
->key
.data
, h
->key
.len
);
1082 hh
= ngx_hash_find(&cmcf
->headers_in_hash
, h
->hash
,
1083 h
->lowcase_key
, h
->key
.len
);
1085 if (hh
&& hh
->handler(r
, h
, hh
->offset
) != NGX_OK
) {
1089 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
1090 "http header: \"%V: %V\"",
1091 &h
->key
, &h
->value
);
1096 if (rc
== NGX_HTTP_PARSE_HEADER_DONE
) {
1098 /* a whole header has been parsed successfully */
1100 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
1101 "http header done");
1103 r
->request_length
+= r
->header_in
->pos
- r
->header_in
->start
;
1105 r
->http_state
= NGX_HTTP_PROCESS_REQUEST_STATE
;
1107 rc
= ngx_http_process_request_header(r
);
1113 ngx_http_process_request(r
);
1118 if (rc
== NGX_AGAIN
) {
1120 /* a header line parsing is still not complete */
1125 /* rc == NGX_HTTP_PARSE_INVALID_HEADER: "\r" is not followed by "\n" */
1127 ngx_log_error(NGX_LOG_INFO
, c
->log
, 0,
1128 "client sent invalid header line: \"%*s\\r...\"",
1129 r
->header_end
- r
->header_name_start
,
1130 r
->header_name_start
);
1131 ngx_http_finalize_request(r
, NGX_HTTP_BAD_REQUEST
);
1138 ngx_http_read_request_header(ngx_http_request_t
*r
)
1142 ngx_connection_t
*c
;
1143 ngx_http_core_srv_conf_t
*cscf
;
1148 n
= r
->header_in
->last
- r
->header_in
->pos
;
1155 n
= c
->recv(c
, r
->header_in
->last
,
1156 r
->header_in
->end
- r
->header_in
->last
);
1161 if (n
== NGX_AGAIN
) {
1162 if (!rev
->timer_set
) {
1163 cscf
= ngx_http_get_module_srv_conf(r
, ngx_http_core_module
);
1164 ngx_add_timer(rev
, cscf
->client_header_timeout
);
1167 if (ngx_handle_read_event(rev
, 0) != NGX_OK
) {
1168 ngx_http_close_request(r
, NGX_HTTP_INTERNAL_SERVER_ERROR
);
1176 ngx_log_error(NGX_LOG_INFO
, c
->log
, 0,
1177 "client closed prematurely connection");
1180 if (n
== 0 || n
== NGX_ERROR
) {
1182 c
->log
->action
= "reading client request headers";
1184 ngx_http_finalize_request(r
, NGX_HTTP_BAD_REQUEST
);
1188 r
->header_in
->last
+= n
;
1195 ngx_http_alloc_large_header_buffer(ngx_http_request_t
*r
,
1196 ngx_uint_t request_line
)
1200 ngx_http_connection_t
*hc
;
1201 ngx_http_core_srv_conf_t
*cscf
;
1203 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
1204 "http alloc large header buffer");
1206 if (request_line
&& r
->state
== 0) {
1208 /* the client fills up the buffer with "\r\n" */
1210 r
->request_length
+= r
->header_in
->end
- r
->header_in
->start
;
1212 r
->header_in
->pos
= r
->header_in
->start
;
1213 r
->header_in
->last
= r
->header_in
->start
;
1218 old
= request_line
? r
->request_start
: r
->header_name_start
;
1220 cscf
= ngx_http_get_module_srv_conf(r
, ngx_http_core_module
);
1223 && (size_t) (r
->header_in
->pos
- old
)
1224 >= cscf
->large_client_header_buffers
.size
)
1226 return NGX_DECLINED
;
1229 hc
= r
->http_connection
;
1232 b
= hc
->free
[--hc
->nfree
];
1234 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
1235 "http large header free: %p %uz",
1236 b
->pos
, b
->end
- b
->last
);
1238 } else if (hc
->nbusy
< cscf
->large_client_header_buffers
.num
) {
1240 if (hc
->busy
== NULL
) {
1241 hc
->busy
= ngx_palloc(r
->connection
->pool
,
1242 cscf
->large_client_header_buffers
.num
* sizeof(ngx_buf_t
*));
1243 if (hc
->busy
== NULL
) {
1248 b
= ngx_create_temp_buf(r
->connection
->pool
,
1249 cscf
->large_client_header_buffers
.size
);
1254 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
1255 "http large header alloc: %p %uz",
1256 b
->pos
, b
->end
- b
->last
);
1259 return NGX_DECLINED
;
1262 hc
->busy
[hc
->nbusy
++] = b
;
1264 if (r
->state
== 0) {
1266 * r->state == 0 means that a header line was parsed successfully
1267 * and we do not need to copy incomplete header line and
1268 * to relocate the parser header pointers
1271 r
->request_length
+= r
->header_in
->end
- r
->header_in
->start
;
1278 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
1279 "http large header copy: %d", r
->header_in
->pos
- old
);
1281 r
->request_length
+= old
- r
->header_in
->start
;
1285 ngx_memcpy(new, old
, r
->header_in
->pos
- old
);
1287 b
->pos
= new + (r
->header_in
->pos
- old
);
1288 b
->last
= new + (r
->header_in
->pos
- old
);
1291 r
->request_start
= new;
1293 if (r
->request_end
) {
1294 r
->request_end
= new + (r
->request_end
- old
);
1297 r
->method_end
= new + (r
->method_end
- old
);
1299 r
->uri_start
= new + (r
->uri_start
- old
);
1300 r
->uri_end
= new + (r
->uri_end
- old
);
1302 if (r
->schema_start
) {
1303 r
->schema_start
= new + (r
->schema_start
- old
);
1304 r
->schema_end
= new + (r
->schema_end
- old
);
1307 if (r
->host_start
) {
1308 r
->host_start
= new + (r
->host_start
- old
);
1310 r
->host_end
= new + (r
->host_end
- old
);
1314 if (r
->port_start
) {
1315 r
->port_start
= new + (r
->port_start
- old
);
1316 r
->port_end
= new + (r
->port_end
- old
);
1320 r
->uri_ext
= new + (r
->uri_ext
- old
);
1323 if (r
->args_start
) {
1324 r
->args_start
= new + (r
->args_start
- old
);
1327 if (r
->http_protocol
.data
) {
1328 r
->http_protocol
.data
= new + (r
->http_protocol
.data
- old
);
1332 r
->header_name_start
= new;
1333 r
->header_name_end
= new + (r
->header_name_end
- old
);
1334 r
->header_start
= new + (r
->header_start
- old
);
1335 r
->header_end
= new + (r
->header_end
- old
);
1345 ngx_http_process_header_line(ngx_http_request_t
*r
, ngx_table_elt_t
*h
,
1348 ngx_table_elt_t
**ph
;
1350 ph
= (ngx_table_elt_t
**) ((char *) &r
->headers_in
+ offset
);
1361 ngx_http_process_unique_header_line(ngx_http_request_t
*r
, ngx_table_elt_t
*h
,
1364 ngx_table_elt_t
**ph
;
1366 ph
= (ngx_table_elt_t
**) ((char *) &r
->headers_in
+ offset
);
1373 ngx_log_error(NGX_LOG_INFO
, r
->connection
->log
, 0,
1374 "client sent duplicate header line: \"%V: %V\", "
1375 "previous value: \"%V: %V\"",
1376 &h
->key
, &h
->value
, &(*ph
)->key
, &(*ph
)->value
);
1378 ngx_http_finalize_request(r
, NGX_HTTP_BAD_REQUEST
);
1385 ngx_http_process_host(ngx_http_request_t
*r
, ngx_table_elt_t
*h
,
1391 if (r
->headers_in
.host
== NULL
) {
1392 r
->headers_in
.host
= h
;
1395 host
= h
->value
.data
;
1396 len
= ngx_http_validate_host(r
, &host
, h
->value
.len
, 0);
1399 ngx_log_error(NGX_LOG_INFO
, r
->connection
->log
, 0,
1400 "client sent invalid host header");
1401 ngx_http_finalize_request(r
, NGX_HTTP_BAD_REQUEST
);
1406 ngx_http_close_request(r
, NGX_HTTP_INTERNAL_SERVER_ERROR
);
1410 if (r
->headers_in
.server
.len
) {
1414 r
->headers_in
.server
.len
= len
;
1415 r
->headers_in
.server
.data
= host
;
1422 ngx_http_process_connection(ngx_http_request_t
*r
, ngx_table_elt_t
*h
,
1425 if (ngx_strcasestrn(h
->value
.data
, "close", 5 - 1)) {
1426 r
->headers_in
.connection_type
= NGX_HTTP_CONNECTION_CLOSE
;
1428 } else if (ngx_strcasestrn(h
->value
.data
, "keep-alive", 10 - 1)) {
1429 r
->headers_in
.connection_type
= NGX_HTTP_CONNECTION_KEEP_ALIVE
;
1437 ngx_http_process_user_agent(ngx_http_request_t
*r
, ngx_table_elt_t
*h
,
1440 u_char
*user_agent
, *msie
;
1442 if (r
->headers_in
.user_agent
) {
1446 r
->headers_in
.user_agent
= h
;
1448 /* check some widespread browsers while the header is in CPU cache */
1450 user_agent
= h
->value
.data
;
1452 msie
= ngx_strstrn(user_agent
, "MSIE ", 5 - 1);
1454 if (msie
&& msie
+ 7 < user_agent
+ h
->value
.len
) {
1456 r
->headers_in
.msie
= 1;
1458 if (msie
[6] == '.') {
1463 r
->headers_in
.msie6
= 1;
1466 if (ngx_strstrn(msie
+ 8, "SV1", 3 - 1) == NULL
) {
1467 r
->headers_in
.msie6
= 1;
1474 /* MSIE ignores the SSL "close notify" alert */
1476 c
->ssl
->no_send_shutdown
= 1;
1481 if (ngx_strstrn(user_agent
, "Opera", 5 - 1)) {
1482 r
->headers_in
.opera
= 1;
1483 r
->headers_in
.msie
= 0;
1484 r
->headers_in
.msie6
= 0;
1487 if (!r
->headers_in
.msie
&& !r
->headers_in
.opera
) {
1489 if (ngx_strstrn(user_agent
, "Gecko/", 6 - 1)) {
1490 r
->headers_in
.gecko
= 1;
1492 } else if (ngx_strstrn(user_agent
, "Chrome/", 7 - 1)) {
1493 r
->headers_in
.chrome
= 1;
1495 } else if (ngx_strstrn(user_agent
, "Safari/", 7 - 1)) {
1496 r
->headers_in
.safari
= 1;
1498 } else if (ngx_strstrn(user_agent
, "Konqueror", 9 - 1)) {
1499 r
->headers_in
.konqueror
= 1;
1508 ngx_http_process_cookie(ngx_http_request_t
*r
, ngx_table_elt_t
*h
,
1511 ngx_table_elt_t
**cookie
;
1513 cookie
= ngx_array_push(&r
->headers_in
.cookies
);
1519 ngx_http_close_request(r
, NGX_HTTP_INTERNAL_SERVER_ERROR
);
1526 ngx_http_process_request_header(ngx_http_request_t
*r
)
1528 if (ngx_http_find_virtual_server(r
, r
->headers_in
.server
.data
,
1529 r
->headers_in
.server
.len
)
1532 ngx_http_finalize_request(r
, NGX_HTTP_INTERNAL_SERVER_ERROR
);
1536 if (r
->headers_in
.host
== NULL
&& r
->http_version
> NGX_HTTP_VERSION_10
) {
1537 ngx_log_error(NGX_LOG_INFO
, r
->connection
->log
, 0,
1538 "client sent HTTP/1.1 request without \"Host\" header");
1539 ngx_http_finalize_request(r
, NGX_HTTP_BAD_REQUEST
);
1543 if (r
->headers_in
.content_length
) {
1544 r
->headers_in
.content_length_n
=
1545 ngx_atoof(r
->headers_in
.content_length
->value
.data
,
1546 r
->headers_in
.content_length
->value
.len
);
1548 if (r
->headers_in
.content_length_n
== NGX_ERROR
) {
1549 ngx_log_error(NGX_LOG_INFO
, r
->connection
->log
, 0,
1550 "client sent invalid \"Content-Length\" header");
1551 ngx_http_finalize_request(r
, NGX_HTTP_LENGTH_REQUIRED
);
1556 if (r
->method
& NGX_HTTP_PUT
&& r
->headers_in
.content_length_n
== -1) {
1557 ngx_log_error(NGX_LOG_INFO
, r
->connection
->log
, 0,
1558 "client sent %V method without \"Content-Length\" header",
1560 ngx_http_finalize_request(r
, NGX_HTTP_LENGTH_REQUIRED
);
1564 if (r
->method
& NGX_HTTP_TRACE
) {
1565 ngx_log_error(NGX_LOG_INFO
, r
->connection
->log
, 0,
1566 "client sent TRACE method");
1567 ngx_http_finalize_request(r
, NGX_HTTP_NOT_ALLOWED
);
1571 if (r
->headers_in
.transfer_encoding
1572 && ngx_strcasestrn(r
->headers_in
.transfer_encoding
->value
.data
,
1575 ngx_log_error(NGX_LOG_INFO
, r
->connection
->log
, 0,
1576 "client sent \"Transfer-Encoding: chunked\" header");
1577 ngx_http_finalize_request(r
, NGX_HTTP_LENGTH_REQUIRED
);
1581 if (r
->headers_in
.connection_type
== NGX_HTTP_CONNECTION_KEEP_ALIVE
) {
1582 if (r
->headers_in
.keep_alive
) {
1583 r
->headers_in
.keep_alive_n
=
1584 ngx_atotm(r
->headers_in
.keep_alive
->value
.data
,
1585 r
->headers_in
.keep_alive
->value
.len
);
1594 ngx_http_process_request(ngx_http_request_t
*r
)
1596 ngx_connection_t
*c
;
1600 if (r
->plain_http
) {
1601 ngx_log_error(NGX_LOG_INFO
, c
->log
, 0,
1602 "client sent plain HTTP request to HTTPS port");
1603 ngx_http_finalize_request(r
, NGX_HTTP_TO_HTTPS
);
1612 ngx_http_ssl_srv_conf_t
*sscf
;
1614 sscf
= ngx_http_get_module_srv_conf(r
, ngx_http_ssl_module
);
1617 rc
= SSL_get_verify_result(c
->ssl
->connection
);
1619 if (rc
!= X509_V_OK
) {
1620 ngx_log_error(NGX_LOG_INFO
, c
->log
, 0,
1621 "client SSL certificate verify error: (%l:%s)",
1622 rc
, X509_verify_cert_error_string(rc
));
1624 ngx_ssl_remove_cached_session(sscf
->ssl
.ctx
,
1625 (SSL_get0_session(c
->ssl
->connection
)));
1627 ngx_http_finalize_request(r
, NGX_HTTPS_CERT_ERROR
);
1631 if (sscf
->verify
== 1) {
1632 cert
= SSL_get_peer_certificate(c
->ssl
->connection
);
1635 ngx_log_error(NGX_LOG_INFO
, c
->log
, 0,
1636 "client sent no required SSL certificate");
1638 ngx_ssl_remove_cached_session(sscf
->ssl
.ctx
,
1639 (SSL_get0_session(c
->ssl
->connection
)));
1641 ngx_http_finalize_request(r
, NGX_HTTPS_NO_CERT
);
1652 if (c
->read
->timer_set
) {
1653 ngx_del_timer(c
->read
);
1657 (void) ngx_atomic_fetch_add(ngx_stat_reading
, -1);
1658 r
->stat_reading
= 0;
1659 (void) ngx_atomic_fetch_add(ngx_stat_writing
, 1);
1660 r
->stat_writing
= 1;
1663 c
->read
->handler
= ngx_http_request_handler
;
1664 c
->write
->handler
= ngx_http_request_handler
;
1665 r
->read_event_handler
= ngx_http_block_reading
;
1667 ngx_http_handler(r
);
1669 ngx_http_run_posted_requests(c
);
1674 ngx_http_validate_host(ngx_http_request_t
*r
, u_char
**host
, size_t len
,
1678 size_t i
, dot_pos
, host_len
;
1693 for (i
= 0; i
< len
; i
++) {
1699 if (dot_pos
== i
- 1) {
1706 if (state
== sw_usual
) {
1719 if (state
== sw_literal
) {
1730 if (ngx_path_separator(ch
)) {
1734 if (ch
>= 'A' && ch
<= 'Z') {
1742 if (dot_pos
== host_len
- 1) {
1747 *host
= ngx_pnalloc(r
->pool
, host_len
);
1748 if (*host
== NULL
) {
1752 ngx_strlow(*host
, h
, host_len
);
1760 ngx_http_find_virtual_server(ngx_http_request_t
*r
, u_char
*host
, size_t len
)
1762 ngx_http_core_loc_conf_t
*clcf
;
1763 ngx_http_core_srv_conf_t
*cscf
;
1765 if (r
->virtual_names
== NULL
) {
1766 return NGX_DECLINED
;
1769 cscf
= ngx_hash_find_combined(&r
->virtual_names
->names
,
1770 ngx_hash_key(host
, len
), host
, len
);
1778 if (len
&& r
->virtual_names
->nregex
) {
1782 ngx_http_server_name_t
*sn
;
1787 sn
= r
->virtual_names
->regex
;
1789 for (i
= 0; i
< r
->virtual_names
->nregex
; i
++) {
1791 n
= ngx_http_regex_exec(r
, sn
[i
].regex
, &name
);
1794 cscf
= sn
[i
].server
;
1798 if (n
== NGX_DECLINED
) {
1812 r
->srv_conf
= cscf
->ctx
->srv_conf
;
1813 r
->loc_conf
= cscf
->ctx
->loc_conf
;
1815 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
1816 r
->connection
->log
->file
= clcf
->error_log
->file
;
1818 if (!(r
->connection
->log
->log_level
& NGX_LOG_DEBUG_CONNECTION
)) {
1819 r
->connection
->log
->log_level
= clcf
->error_log
->log_level
;
1827 ngx_http_request_handler(ngx_event_t
*ev
)
1829 ngx_connection_t
*c
;
1830 ngx_http_request_t
*r
;
1831 ngx_http_log_ctx_t
*ctx
;
1837 ctx
->current_request
= r
;
1839 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
1840 "http run request: \"%V?%V\"", &r
->uri
, &r
->args
);
1843 r
->write_event_handler(r
);
1846 r
->read_event_handler(r
);
1849 ngx_http_run_posted_requests(c
);
1854 ngx_http_run_posted_requests(ngx_connection_t
*c
)
1856 ngx_http_request_t
*r
;
1857 ngx_http_log_ctx_t
*ctx
;
1858 ngx_http_posted_request_t
*pr
;
1867 pr
= r
->main
->posted_requests
;
1873 r
->main
->posted_requests
= pr
->next
;
1878 ctx
->current_request
= r
;
1880 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
1881 "http posted request: \"%V?%V\"", &r
->uri
, &r
->args
);
1883 r
->write_event_handler(r
);
1889 ngx_http_post_request(ngx_http_request_t
*r
, ngx_http_posted_request_t
*pr
)
1891 ngx_http_posted_request_t
**p
;
1894 pr
= ngx_palloc(r
->pool
, sizeof(ngx_http_posted_request_t
));
1903 for (p
= &r
->main
->posted_requests
; *p
; p
= &(*p
)->next
) { /* void */ }
1912 ngx_http_finalize_request(ngx_http_request_t
*r
, ngx_int_t rc
)
1914 ngx_connection_t
*c
;
1915 ngx_http_request_t
*pr
;
1916 ngx_http_core_loc_conf_t
*clcf
;
1920 ngx_log_debug5(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
1921 "http finalize request: %d, \"%V?%V\" a:%d, c:%d",
1922 rc
, &r
->uri
, &r
->args
, r
== c
->data
, r
->main
->count
);
1924 if (rc
== NGX_DONE
) {
1925 ngx_http_finalize_connection(r
);
1929 if (rc
== NGX_OK
&& r
->filter_finalize
) {
1934 if (rc
== NGX_DECLINED
) {
1935 r
->content_handler
= NULL
;
1936 r
->write_event_handler
= ngx_http_core_run_phases
;
1937 ngx_http_core_run_phases(r
);
1941 if (r
!= r
->main
&& r
->post_subrequest
) {
1942 rc
= r
->post_subrequest
->handler(r
, r
->post_subrequest
->data
, rc
);
1946 || rc
== NGX_HTTP_REQUEST_TIME_OUT
1947 || rc
== NGX_HTTP_CLIENT_CLOSED_REQUEST
1950 if (ngx_http_post_action(r
) == NGX_OK
) {
1954 if (r
->main
->blocked
) {
1955 r
->write_event_handler
= ngx_http_request_finalizer
;
1958 ngx_http_terminate_request(r
, rc
);
1962 if (rc
>= NGX_HTTP_SPECIAL_RESPONSE
1963 || rc
== NGX_HTTP_CREATED
1964 || rc
== NGX_HTTP_NO_CONTENT
)
1966 if (rc
== NGX_HTTP_CLOSE
) {
1967 ngx_http_terminate_request(r
, rc
);
1972 if (c
->read
->timer_set
) {
1973 ngx_del_timer(c
->read
);
1976 if (c
->write
->timer_set
) {
1977 ngx_del_timer(c
->write
);
1981 c
->read
->handler
= ngx_http_request_handler
;
1982 c
->write
->handler
= ngx_http_request_handler
;
1984 ngx_http_finalize_request(r
, ngx_http_special_response_handler(r
, rc
));
1990 if (r
->buffered
|| r
->postponed
) {
1992 if (ngx_http_set_write_handler(r
) != NGX_OK
) {
1993 ngx_http_terminate_request(r
, 0);
2001 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
2002 "http finalize non-active request: \"%V?%V\"",
2015 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
2017 if (clcf
->log_subrequest
) {
2018 ngx_http_log_request(r
);
2024 ngx_log_error(NGX_LOG_ALERT
, c
->log
, 0,
2025 "subrequest: \"%V?%V\" logged again",
2031 if (pr
->postponed
&& pr
->postponed
->request
== r
) {
2032 pr
->postponed
= pr
->postponed
->next
;
2039 r
->write_event_handler
= ngx_http_request_finalizer
;
2046 if (ngx_http_post_request(pr
, NULL
) != NGX_OK
) {
2048 ngx_http_terminate_request(r
, 0);
2052 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
2053 "http wake parent request: \"%V?%V\"",
2054 &pr
->uri
, &pr
->args
);
2059 if (r
->buffered
|| c
->buffered
|| r
->postponed
|| r
->blocked
) {
2061 if (ngx_http_set_write_handler(r
) != NGX_OK
) {
2062 ngx_http_terminate_request(r
, 0);
2069 ngx_log_error(NGX_LOG_ALERT
, c
->log
, 0,
2070 "http finalize non-active request: \"%V?%V\"",
2076 r
->write_event_handler
= ngx_http_request_empty_handler
;
2078 if (!r
->post_action
) {
2079 r
->request_complete
= 1;
2082 if (ngx_http_post_action(r
) == NGX_OK
) {
2086 if (c
->read
->timer_set
) {
2087 ngx_del_timer(c
->read
);
2090 if (c
->write
->timer_set
) {
2091 c
->write
->delayed
= 0;
2092 ngx_del_timer(c
->write
);
2096 ngx_http_close_request(r
, 0);
2100 ngx_http_finalize_connection(r
);
2105 ngx_http_terminate_request(ngx_http_request_t
*r
, ngx_int_t rc
)
2107 ngx_http_cleanup_t
*cln
;
2108 ngx_http_request_t
*mr
;
2109 ngx_http_ephemeral_t
*e
;
2113 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
2114 "http terminate request count:%d", mr
->count
);
2116 if (rc
> 0 && (mr
->headers_out
.status
== 0 || mr
->connection
->sent
== 0)) {
2117 mr
->headers_out
.status
= rc
;
2125 cln
->handler(cln
->data
);
2131 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
2132 "http terminate cleanup count:%d blk:%d",
2133 mr
->count
, mr
->blocked
);
2135 if (mr
->write_event_handler
) {
2141 e
= ngx_http_ephemeral(mr
);
2142 mr
->posted_requests
= NULL
;
2143 mr
->write_event_handler
= ngx_http_terminate_handler
;
2144 (void) ngx_http_post_request(mr
, &e
->terminal_posted_request
);
2148 ngx_http_close_request(mr
, rc
);
2153 ngx_http_terminate_handler(ngx_http_request_t
*r
)
2155 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
2156 "http terminate handler count:%d", r
->count
);
2160 ngx_http_close_request(r
, 0);
2165 ngx_http_finalize_connection(ngx_http_request_t
*r
)
2167 ngx_http_core_loc_conf_t
*clcf
;
2169 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
2171 if (r
->main
->count
!= 1) {
2173 if (r
->discard_body
) {
2174 r
->read_event_handler
= ngx_http_discarded_request_body_handler
;
2175 ngx_add_timer(r
->connection
->read
, clcf
->lingering_timeout
);
2177 if (r
->lingering_time
== 0) {
2178 r
->lingering_time
= ngx_time()
2179 + (time_t) (clcf
->lingering_time
/ 1000);
2183 ngx_http_close_request(r
, 0);
2190 && clcf
->keepalive_timeout
> 0)
2192 ngx_http_set_keepalive(r
);
2196 if (clcf
->lingering_close
== NGX_HTTP_LINGERING_ALWAYS
2197 || (clcf
->lingering_close
== NGX_HTTP_LINGERING_ON
2198 && (r
->lingering_close
2199 || r
->header_in
->pos
< r
->header_in
->last
2200 || r
->connection
->read
->ready
)))
2202 ngx_http_set_lingering_close(r
);
2206 ngx_http_close_request(r
, 0);
2211 ngx_http_set_write_handler(ngx_http_request_t
*r
)
2214 ngx_http_core_loc_conf_t
*clcf
;
2216 r
->http_state
= NGX_HTTP_WRITING_REQUEST_STATE
;
2218 r
->read_event_handler
= r
->discard_body
?
2219 ngx_http_discarded_request_body_handler
:
2220 ngx_http_test_reading
;
2221 r
->write_event_handler
= ngx_http_writer
;
2223 wev
= r
->connection
->write
;
2225 if (wev
->ready
&& wev
->delayed
) {
2229 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
2230 if (!wev
->delayed
) {
2231 ngx_add_timer(wev
, clcf
->send_timeout
);
2234 if (ngx_handle_write_event(wev
, clcf
->send_lowat
) != NGX_OK
) {
2235 ngx_http_close_request(r
, 0);
2244 ngx_http_writer(ngx_http_request_t
*r
)
2248 ngx_connection_t
*c
;
2249 ngx_http_core_loc_conf_t
*clcf
;
2254 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, wev
->log
, 0,
2255 "http writer handler: \"%V?%V\"", &r
->uri
, &r
->args
);
2257 clcf
= ngx_http_get_module_loc_conf(r
->main
, ngx_http_core_module
);
2259 if (wev
->timedout
) {
2260 if (!wev
->delayed
) {
2261 ngx_log_error(NGX_LOG_INFO
, c
->log
, NGX_ETIMEDOUT
,
2262 "client timed out");
2265 ngx_http_finalize_request(r
, NGX_HTTP_REQUEST_TIME_OUT
);
2273 ngx_add_timer(wev
, clcf
->send_timeout
);
2275 if (ngx_handle_write_event(wev
, clcf
->send_lowat
) != NGX_OK
) {
2276 ngx_http_close_request(r
, 0);
2284 if (wev
->delayed
|| r
->aio
) {
2285 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, wev
->log
, 0,
2286 "http writer delayed");
2288 if (ngx_handle_write_event(wev
, clcf
->send_lowat
) != NGX_OK
) {
2289 ngx_http_close_request(r
, 0);
2295 rc
= ngx_http_output_filter(r
, NULL
);
2297 ngx_log_debug3(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
2298 "http writer output filter: %d, \"%V?%V\"",
2299 rc
, &r
->uri
, &r
->args
);
2301 if (rc
== NGX_ERROR
) {
2302 ngx_http_finalize_request(r
, rc
);
2306 if (r
->buffered
|| r
->postponed
|| (r
== r
->main
&& c
->buffered
)) {
2308 if (!wev
->delayed
) {
2309 ngx_add_timer(wev
, clcf
->send_timeout
);
2312 if (ngx_handle_write_event(wev
, clcf
->send_lowat
) != NGX_OK
) {
2313 ngx_http_close_request(r
, 0);
2319 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, wev
->log
, 0,
2320 "http writer done: \"%V?%V\"", &r
->uri
, &r
->args
);
2322 r
->write_event_handler
= ngx_http_request_empty_handler
;
2324 ngx_http_finalize_request(r
, rc
);
2329 ngx_http_request_finalizer(ngx_http_request_t
*r
)
2331 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
2332 "http finalizer done: \"%V?%V\"", &r
->uri
, &r
->args
);
2334 ngx_http_finalize_request(r
, 0);
2339 ngx_http_block_reading(ngx_http_request_t
*r
)
2341 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
2342 "http reading blocked");
2344 /* aio does not call this handler */
2346 if ((ngx_event_flags
& NGX_USE_LEVEL_EVENT
)
2347 && r
->connection
->read
->active
)
2349 if (ngx_del_event(r
->connection
->read
, NGX_READ_EVENT
, 0) != NGX_OK
) {
2350 ngx_http_close_request(r
, 0);
2357 ngx_http_test_reading(ngx_http_request_t
*r
)
2363 ngx_connection_t
*c
;
2368 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, c
->log
, 0, "http test reading");
2370 #if (NGX_HAVE_KQUEUE)
2372 if (ngx_event_flags
& NGX_USE_KQUEUE_EVENT
) {
2374 if (!rev
->pending_eof
) {
2380 err
= rev
->kq_errno
;
2387 n
= recv(c
->fd
, buf
, 1, MSG_PEEK
);
2396 } else if (n
== -1) {
2397 err
= ngx_socket_errno
;
2399 if (err
!= NGX_EAGAIN
) {
2407 /* aio does not call this handler */
2409 if ((ngx_event_flags
& NGX_USE_LEVEL_EVENT
) && rev
->active
) {
2411 if (ngx_del_event(rev
, NGX_READ_EVENT
, 0) != NGX_OK
) {
2412 ngx_http_close_request(r
, 0);
2424 ngx_log_error(NGX_LOG_INFO
, c
->log
, err
,
2425 "client closed prematurely connection");
2427 ngx_http_finalize_request(r
, 0);
2432 ngx_http_set_keepalive(ngx_http_request_t
*r
)
2437 ngx_event_t
*rev
, *wev
;
2438 ngx_connection_t
*c
;
2439 ngx_http_connection_t
*hc
;
2440 ngx_http_core_srv_conf_t
*cscf
;
2441 ngx_http_core_loc_conf_t
*clcf
;
2446 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
2448 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, c
->log
, 0, "set http keepalive handler");
2450 if (r
->discard_body
) {
2451 r
->write_event_handler
= ngx_http_request_empty_handler
;
2452 r
->lingering_time
= ngx_time() + (time_t) (clcf
->lingering_time
/ 1000);
2453 ngx_add_timer(rev
, clcf
->lingering_timeout
);
2457 c
->log
->action
= "closing request";
2459 hc
= r
->http_connection
;
2462 if (b
->pos
< b
->last
) {
2464 /* the pipelined request */
2466 if (b
!= c
->buffer
) {
2469 * If the large header buffers were allocated while the previous
2470 * request processing then we do not use c->buffer for
2471 * the pipelined request (see ngx_http_init_request()).
2473 * Now we would move the large header buffers to the free list.
2476 cscf
= ngx_http_get_module_srv_conf(r
, ngx_http_core_module
);
2478 if (hc
->free
== NULL
) {
2479 hc
->free
= ngx_palloc(c
->pool
,
2480 cscf
->large_client_header_buffers
.num
* sizeof(ngx_buf_t
*));
2482 if (hc
->free
== NULL
) {
2483 ngx_http_close_request(r
, 0);
2488 for (i
= 0; i
< hc
->nbusy
- 1; i
++) {
2490 hc
->free
[hc
->nfree
++] = f
;
2502 ngx_http_free_request(r
, 0);
2506 ngx_add_timer(rev
, clcf
->keepalive_timeout
);
2508 if (ngx_handle_read_event(rev
, 0) != NGX_OK
) {
2509 ngx_http_close_connection(c
);
2514 wev
->handler
= ngx_http_empty_handler
;
2516 if (b
->pos
< b
->last
) {
2518 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, c
->log
, 0, "pipelined request");
2521 (void) ngx_atomic_fetch_add(ngx_stat_reading
, 1);
2525 c
->log
->action
= "reading client pipelined request line";
2527 rev
->handler
= ngx_http_init_request
;
2528 ngx_post_event(rev
, &ngx_posted_events
);
2535 * To keep a memory footprint as small as possible for an idle
2536 * keepalive connection we try to free the ngx_http_request_t and
2537 * c->buffer's memory if they were allocated outside the c->pool.
2538 * The large header buffers are always allocated outside the c->pool and
2542 if (ngx_pfree(c
->pool
, r
) == NGX_OK
) {
2548 if (ngx_pfree(c
->pool
, b
->start
) == NGX_OK
) {
2551 * the special note for ngx_http_keepalive_handler() that
2552 * c->buffer's memory was freed
2562 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, c
->log
, 0, "hc free: %p %d",
2563 hc
->free
, hc
->nfree
);
2566 for (i
= 0; i
< hc
->nfree
; i
++) {
2567 ngx_pfree(c
->pool
, hc
->free
[i
]->start
);
2574 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, c
->log
, 0, "hc busy: %p %d",
2575 hc
->busy
, hc
->nbusy
);
2578 for (i
= 0; i
< hc
->nbusy
; i
++) {
2579 ngx_pfree(c
->pool
, hc
->busy
[i
]->start
);
2588 ngx_ssl_free_buffer(c
);
2592 rev
->handler
= ngx_http_keepalive_handler
;
2594 if (wev
->active
&& (ngx_event_flags
& NGX_USE_LEVEL_EVENT
)) {
2595 if (ngx_del_event(wev
, NGX_WRITE_EVENT
, 0) != NGX_OK
) {
2596 ngx_http_close_connection(c
);
2601 c
->log
->action
= "keepalive";
2603 if (c
->tcp_nopush
== NGX_TCP_NOPUSH_SET
) {
2604 if (ngx_tcp_push(c
->fd
) == -1) {
2605 ngx_connection_error(c
, ngx_socket_errno
, ngx_tcp_push_n
" failed");
2606 ngx_http_close_connection(c
);
2610 c
->tcp_nopush
= NGX_TCP_NOPUSH_UNSET
;
2611 tcp_nodelay
= ngx_tcp_nodelay_and_tcp_nopush
? 1 : 0;
2618 && clcf
->tcp_nodelay
2619 && c
->tcp_nodelay
== NGX_TCP_NODELAY_UNSET
)
2621 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, c
->log
, 0, "tcp_nodelay");
2623 if (setsockopt(c
->fd
, IPPROTO_TCP
, TCP_NODELAY
,
2624 (const void *) &tcp_nodelay
, sizeof(int))
2628 /* Solaris returns EINVAL if a socket has been shut down */
2629 c
->log_error
= NGX_ERROR_IGNORE_EINVAL
;
2632 ngx_connection_error(c
, ngx_socket_errno
,
2633 "setsockopt(TCP_NODELAY) failed");
2635 c
->log_error
= NGX_ERROR_INFO
;
2636 ngx_http_close_connection(c
);
2640 c
->tcp_nodelay
= NGX_TCP_NODELAY_SET
;
2644 /* if ngx_http_request_t was freed then we need some other place */
2645 r
->http_state
= NGX_HTTP_KEEPALIVE_STATE
;
2649 ngx_reusable_connection(c
, 1);
2652 ngx_post_event(rev
, &ngx_posted_events
);
2658 ngx_http_keepalive_handler(ngx_event_t
*rev
)
2663 ngx_connection_t
*c
;
2667 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, c
->log
, 0, "http keepalive handler");
2669 if (rev
->timedout
|| c
->close
) {
2670 ngx_http_close_connection(c
);
2674 #if (NGX_HAVE_KQUEUE)
2676 if (ngx_event_flags
& NGX_USE_KQUEUE_EVENT
) {
2677 if (rev
->pending_eof
) {
2678 c
->log
->handler
= NULL
;
2679 ngx_log_error(NGX_LOG_INFO
, c
->log
, rev
->kq_errno
,
2680 "kevent() reported that client %V closed "
2681 "keepalive connection", &c
->addr_text
);
2684 c
->ssl
->no_send_shutdown
= 1;
2687 ngx_http_close_connection(c
);
2695 size
= b
->end
- b
->start
;
2697 if (b
->pos
== NULL
) {
2700 * The c->buffer's memory was freed by ngx_http_set_keepalive().
2701 * However, the c->buffer->start and c->buffer->end were not changed
2702 * to keep the buffer size.
2705 b
->pos
= ngx_palloc(c
->pool
, size
);
2706 if (b
->pos
== NULL
) {
2707 ngx_http_close_connection(c
);
2713 b
->end
= b
->pos
+ size
;
2717 * MSIE closes a keepalive connection with RST flag
2718 * so we ignore ECONNRESET here.
2721 c
->log_error
= NGX_ERROR_IGNORE_ECONNRESET
;
2722 ngx_set_socket_errno(0);
2724 n
= c
->recv(c
, b
->last
, size
);
2725 c
->log_error
= NGX_ERROR_INFO
;
2727 if (n
== NGX_AGAIN
) {
2728 if (ngx_handle_read_event(rev
, 0) != NGX_OK
) {
2729 ngx_http_close_connection(c
);
2735 if (n
== NGX_ERROR
) {
2736 ngx_http_close_connection(c
);
2740 c
->log
->handler
= NULL
;
2743 ngx_log_error(NGX_LOG_INFO
, c
->log
, ngx_socket_errno
,
2744 "client %V closed keepalive connection", &c
->addr_text
);
2745 ngx_http_close_connection(c
);
2752 (void) ngx_atomic_fetch_add(ngx_stat_reading
, 1);
2755 c
->log
->handler
= ngx_http_log_error
;
2756 c
->log
->action
= "reading client request line";
2759 ngx_reusable_connection(c
, 0);
2761 ngx_http_init_request(rev
);
2766 ngx_http_set_lingering_close(ngx_http_request_t
*r
)
2768 ngx_event_t
*rev
, *wev
;
2769 ngx_connection_t
*c
;
2770 ngx_http_core_loc_conf_t
*clcf
;
2774 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
2777 rev
->handler
= ngx_http_lingering_close_handler
;
2779 r
->lingering_time
= ngx_time() + (time_t) (clcf
->lingering_time
/ 1000);
2780 ngx_add_timer(rev
, clcf
->lingering_timeout
);
2782 if (ngx_handle_read_event(rev
, 0) != NGX_OK
) {
2783 ngx_http_close_request(r
, 0);
2788 wev
->handler
= ngx_http_empty_handler
;
2790 if (wev
->active
&& (ngx_event_flags
& NGX_USE_LEVEL_EVENT
)) {
2791 if (ngx_del_event(wev
, NGX_WRITE_EVENT
, 0) != NGX_OK
) {
2792 ngx_http_close_request(r
, 0);
2797 if (ngx_shutdown_socket(c
->fd
, NGX_WRITE_SHUTDOWN
) == -1) {
2798 ngx_connection_error(c
, ngx_socket_errno
,
2799 ngx_shutdown_socket_n
" failed");
2800 ngx_http_close_request(r
, 0);
2805 ngx_http_lingering_close_handler(rev
);
2811 ngx_http_lingering_close_handler(ngx_event_t
*rev
)
2815 ngx_connection_t
*c
;
2816 ngx_http_request_t
*r
;
2817 ngx_http_core_loc_conf_t
*clcf
;
2818 u_char buffer
[NGX_HTTP_LINGERING_BUFFER_SIZE
];
2823 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
2824 "http lingering close handler");
2826 if (rev
->timedout
) {
2827 ngx_http_close_request(r
, 0);
2831 timer
= (ngx_msec_t
) (r
->lingering_time
- ngx_time());
2833 ngx_http_close_request(r
, 0);
2838 n
= c
->recv(c
, buffer
, NGX_HTTP_LINGERING_BUFFER_SIZE
);
2840 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, c
->log
, 0, "lingering read: %d", n
);
2842 if (n
== NGX_ERROR
|| n
== 0) {
2843 ngx_http_close_request(r
, 0);
2847 } while (rev
->ready
);
2849 if (ngx_handle_read_event(rev
, 0) != NGX_OK
) {
2850 ngx_http_close_request(r
, 0);
2854 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
2858 if (timer
> clcf
->lingering_timeout
) {
2859 timer
= clcf
->lingering_timeout
;
2862 ngx_add_timer(rev
, timer
);
2867 ngx_http_empty_handler(ngx_event_t
*wev
)
2869 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, wev
->log
, 0, "http empty handler");
2876 ngx_http_request_empty_handler(ngx_http_request_t
*r
)
2878 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
2879 "http request empty handler");
2886 ngx_http_send_special(ngx_http_request_t
*r
, ngx_uint_t flags
)
2891 b
= ngx_calloc_buf(r
->pool
);
2896 if (flags
& NGX_HTTP_LAST
) {
2898 if (r
== r
->main
&& !r
->post_action
) {
2903 b
->last_in_chain
= 1;
2907 if (flags
& NGX_HTTP_FLUSH
) {
2914 return ngx_http_output_filter(r
, &out
);
2919 ngx_http_post_action(ngx_http_request_t
*r
)
2921 ngx_http_core_loc_conf_t
*clcf
;
2923 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
2925 if (clcf
->post_action
.data
== NULL
) {
2926 return NGX_DECLINED
;
2929 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
2930 "post action: \"%V\"", &clcf
->post_action
);
2934 r
->http_version
= NGX_HTTP_VERSION_9
;
2938 r
->read_event_handler
= ngx_http_block_reading
;
2940 if (clcf
->post_action
.data
[0] == '/') {
2941 ngx_http_internal_redirect(r
, &clcf
->post_action
, NULL
);
2944 ngx_http_named_location(r
, &clcf
->post_action
);
2952 ngx_http_close_request(ngx_http_request_t
*r
, ngx_int_t rc
)
2954 ngx_connection_t
*c
;
2959 ngx_log_debug2(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
2960 "http request count:%d blk:%d", r
->count
, r
->blocked
);
2962 if (r
->count
== 0) {
2963 ngx_log_error(NGX_LOG_ALERT
, c
->log
, 0, "http request count is zero");
2968 if (r
->count
|| r
->blocked
) {
2972 ngx_http_free_request(r
, rc
);
2973 ngx_http_close_connection(c
);
2978 ngx_http_free_request(ngx_http_request_t
*r
, ngx_int_t rc
)
2981 struct linger linger
;
2982 ngx_http_cleanup_t
*cln
;
2983 ngx_http_log_ctx_t
*ctx
;
2984 ngx_http_core_loc_conf_t
*clcf
;
2986 log
= r
->connection
->log
;
2988 ngx_log_debug0(NGX_LOG_DEBUG_HTTP
, log
, 0, "http close request");
2990 if (r
->pool
== NULL
) {
2991 ngx_log_error(NGX_LOG_ALERT
, log
, 0, "http request already closed");
2995 for (cln
= r
->cleanup
; cln
; cln
= cln
->next
) {
2997 cln
->handler(cln
->data
);
3003 if (r
->stat_reading
) {
3004 (void) ngx_atomic_fetch_add(ngx_stat_reading
, -1);
3007 if (r
->stat_writing
) {
3008 (void) ngx_atomic_fetch_add(ngx_stat_writing
, -1);
3013 if (rc
> 0 && (r
->headers_out
.status
== 0 || r
->connection
->sent
== 0)) {
3014 r
->headers_out
.status
= rc
;
3017 log
->action
= "logging request";
3019 ngx_http_log_request(r
);
3021 log
->action
= "closing request";
3023 if (r
->connection
->timedout
) {
3024 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
3026 if (clcf
->reset_timedout_connection
) {
3028 linger
.l_linger
= 0;
3030 if (setsockopt(r
->connection
->fd
, SOL_SOCKET
, SO_LINGER
,
3031 (const void *) &linger
, sizeof(struct linger
)) == -1)
3033 ngx_log_error(NGX_LOG_ALERT
, log
, ngx_socket_errno
,
3034 "setsockopt(SO_LINGER) failed");
3039 /* the various request strings were allocated from r->pool */
3041 ctx
->request
= NULL
;
3043 r
->request_line
.len
= 0;
3045 r
->connection
->destroyed
= 1;
3047 ngx_destroy_pool(r
->pool
);
3052 ngx_http_log_request(ngx_http_request_t
*r
)
3055 ngx_http_handler_pt
*log_handler
;
3056 ngx_http_core_main_conf_t
*cmcf
;
3058 cmcf
= ngx_http_get_module_main_conf(r
, ngx_http_core_module
);
3060 log_handler
= cmcf
->phases
[NGX_HTTP_LOG_PHASE
].handlers
.elts
;
3061 n
= cmcf
->phases
[NGX_HTTP_LOG_PHASE
].handlers
.nelts
;
3063 for (i
= 0; i
< n
; i
++) {
3070 ngx_http_close_connection(ngx_connection_t
*c
)
3074 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, c
->log
, 0,
3075 "close http connection: %d", c
->fd
);
3080 if (ngx_ssl_shutdown(c
) == NGX_AGAIN
) {
3081 c
->ssl
->handler
= ngx_http_close_connection
;
3089 (void) ngx_atomic_fetch_add(ngx_stat_active
, -1);
3096 ngx_close_connection(c
);
3098 ngx_destroy_pool(pool
);
3103 ngx_http_log_error(ngx_log_t
*log
, u_char
*buf
, size_t len
)
3106 ngx_http_request_t
*r
;
3107 ngx_http_log_ctx_t
*ctx
;
3110 p
= ngx_snprintf(buf
, len
, " while %s", log
->action
);
3117 p
= ngx_snprintf(buf
, len
, ", client: %V", &ctx
->connection
->addr_text
);
3123 return r
->log_handler(r
, ctx
->current_request
, p
, len
);
3126 p
= ngx_snprintf(p
, len
, ", server: %V",
3127 &ctx
->connection
->listening
->addr_text
);
3135 ngx_http_log_error_handler(ngx_http_request_t
*r
, ngx_http_request_t
*sr
,
3136 u_char
*buf
, size_t len
)
3138 char *uri_separator
;
3140 ngx_http_upstream_t
*u
;
3141 ngx_http_core_srv_conf_t
*cscf
;
3143 cscf
= ngx_http_get_module_srv_conf(r
, ngx_http_core_module
);
3145 p
= ngx_snprintf(buf
, len
, ", server: %V", &cscf
->server_name
);
3149 if (r
->request_line
.data
== NULL
&& r
->request_start
) {
3150 for (p
= r
->request_start
; p
< r
->header_in
->last
; p
++) {
3151 if (*p
== CR
|| *p
== LF
) {
3156 r
->request_line
.len
= p
- r
->request_start
;
3157 r
->request_line
.data
= r
->request_start
;
3160 if (r
->request_line
.len
) {
3161 p
= ngx_snprintf(buf
, len
, ", request: \"%V\"", &r
->request_line
);
3167 p
= ngx_snprintf(buf
, len
, ", subrequest: \"%V\"", &sr
->uri
);
3174 if (u
&& u
->peer
.name
) {
3178 #if (NGX_HAVE_UNIX_DOMAIN)
3179 if (u
->peer
.sockaddr
&& u
->peer
.sockaddr
->sa_family
== AF_UNIX
) {
3180 uri_separator
= ":";
3184 p
= ngx_snprintf(buf
, len
, ", upstream: \"%V%V%s%V\"",
3185 &u
->schema
, u
->peer
.name
,
3186 uri_separator
, &u
->uri
);
3191 if (r
->headers_in
.host
) {
3192 p
= ngx_snprintf(buf
, len
, ", host: \"%V\"",
3193 &r
->headers_in
.host
->value
);
3198 if (r
->headers_in
.referer
) {
3199 p
= ngx_snprintf(buf
, len
, ", referrer: \"%V\"",
3200 &r
->headers_in
.referer
->value
);