Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ngx_http_request.c
Go to the documentation of this file.
1 
2 /*
3  * Copyright (C) Igor Sysoev
4  * Copyright (C) Nginx, Inc.
5  */
6 
7 
8 #include <ngx_config.h>
9 #include <ngx_core.h>
10 #include <ngx_http.h>
11 
12 
13 static void ngx_http_wait_request_handler(ngx_event_t *ev);
14 static void ngx_http_process_request_line(ngx_event_t *rev);
15 static void ngx_http_process_request_headers(ngx_event_t *rev);
16 static ssize_t ngx_http_read_request_header(ngx_http_request_t *r);
17 static ngx_int_t ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
18  ngx_uint_t request_line);
19 
20 static ngx_int_t ngx_http_process_header_line(ngx_http_request_t *r,
21  ngx_table_elt_t *h, ngx_uint_t offset);
22 static ngx_int_t ngx_http_process_unique_header_line(ngx_http_request_t *r,
23  ngx_table_elt_t *h, ngx_uint_t offset);
24 static ngx_int_t ngx_http_process_multi_header_lines(ngx_http_request_t *r,
25  ngx_table_elt_t *h, ngx_uint_t offset);
26 static ngx_int_t ngx_http_process_host(ngx_http_request_t *r,
27  ngx_table_elt_t *h, ngx_uint_t offset);
28 static ngx_int_t ngx_http_process_connection(ngx_http_request_t *r,
29  ngx_table_elt_t *h, ngx_uint_t offset);
30 static ngx_int_t ngx_http_process_user_agent(ngx_http_request_t *r,
31  ngx_table_elt_t *h, ngx_uint_t offset);
32 
33 static ngx_int_t ngx_http_validate_host(ngx_str_t *host, ngx_pool_t *pool,
34  ngx_uint_t alloc);
35 static ngx_int_t ngx_http_set_virtual_server(ngx_http_request_t *r,
36  ngx_str_t *host);
37 static ngx_int_t ngx_http_find_virtual_server(ngx_connection_t *c,
38  ngx_http_virtual_names_t *virtual_names, ngx_str_t *host,
40 
41 static void ngx_http_request_handler(ngx_event_t *ev);
42 static void ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc);
43 static void ngx_http_terminate_handler(ngx_http_request_t *r);
44 static void ngx_http_finalize_connection(ngx_http_request_t *r);
45 static ngx_int_t ngx_http_set_write_handler(ngx_http_request_t *r);
46 static void ngx_http_writer(ngx_http_request_t *r);
47 static void ngx_http_request_finalizer(ngx_http_request_t *r);
48 
49 static void ngx_http_set_keepalive(ngx_http_request_t *r);
50 static void ngx_http_keepalive_handler(ngx_event_t *ev);
51 static void ngx_http_set_lingering_close(ngx_http_request_t *r);
52 static void ngx_http_lingering_close_handler(ngx_event_t *ev);
53 static ngx_int_t ngx_http_post_action(ngx_http_request_t *r);
54 static void ngx_http_close_request(ngx_http_request_t *r, ngx_int_t error);
55 static void ngx_http_log_request(ngx_http_request_t *r);
56 
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);
60 
61 #if (NGX_HTTP_SSL)
62 static void ngx_http_ssl_handshake(ngx_event_t *rev);
63 static void ngx_http_ssl_handshake_handler(ngx_connection_t *c);
64 #endif
65 
66 
67 static char *ngx_http_client_errors[] = {
68 
69  /* NGX_HTTP_PARSE_INVALID_METHOD */
70  "client sent invalid method",
71 
72  /* NGX_HTTP_PARSE_INVALID_REQUEST */
73  "client sent invalid request",
74 
75  /* NGX_HTTP_PARSE_INVALID_09_METHOD */
76  "client sent invalid method in HTTP/0.9 request"
77 };
78 
79 
81  { ngx_string("Host"), offsetof(ngx_http_headers_in_t, host),
82  ngx_http_process_host },
83 
84  { ngx_string("Connection"), offsetof(ngx_http_headers_in_t, connection),
85  ngx_http_process_connection },
86 
87  { ngx_string("If-Modified-Since"),
88  offsetof(ngx_http_headers_in_t, if_modified_since),
89  ngx_http_process_unique_header_line },
90 
91  { ngx_string("If-Unmodified-Since"),
92  offsetof(ngx_http_headers_in_t, if_unmodified_since),
93  ngx_http_process_unique_header_line },
94 
95  { ngx_string("If-Match"),
96  offsetof(ngx_http_headers_in_t, if_match),
97  ngx_http_process_unique_header_line },
98 
99  { ngx_string("If-None-Match"),
100  offsetof(ngx_http_headers_in_t, if_none_match),
101  ngx_http_process_unique_header_line },
102 
103  { ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent),
104  ngx_http_process_user_agent },
105 
106  { ngx_string("Referer"), offsetof(ngx_http_headers_in_t, referer),
107  ngx_http_process_header_line },
108 
109  { ngx_string("Content-Length"),
110  offsetof(ngx_http_headers_in_t, content_length),
111  ngx_http_process_unique_header_line },
112 
113  { ngx_string("Content-Type"),
114  offsetof(ngx_http_headers_in_t, content_type),
115  ngx_http_process_header_line },
116 
117  { ngx_string("Range"), offsetof(ngx_http_headers_in_t, range),
118  ngx_http_process_header_line },
119 
120  { ngx_string("If-Range"),
121  offsetof(ngx_http_headers_in_t, if_range),
122  ngx_http_process_unique_header_line },
123 
124  { ngx_string("Transfer-Encoding"),
125  offsetof(ngx_http_headers_in_t, transfer_encoding),
126  ngx_http_process_header_line },
127 
128  { ngx_string("Expect"),
129  offsetof(ngx_http_headers_in_t, expect),
130  ngx_http_process_unique_header_line },
131 
132  { ngx_string("Upgrade"),
133  offsetof(ngx_http_headers_in_t, upgrade),
134  ngx_http_process_header_line },
135 
136 #if (NGX_HTTP_GZIP)
137  { ngx_string("Accept-Encoding"),
138  offsetof(ngx_http_headers_in_t, accept_encoding),
139  ngx_http_process_header_line },
140 
141  { ngx_string("Via"), offsetof(ngx_http_headers_in_t, via),
142  ngx_http_process_header_line },
143 #endif
144 
145  { ngx_string("Authorization"),
146  offsetof(ngx_http_headers_in_t, authorization),
147  ngx_http_process_unique_header_line },
148 
149  { ngx_string("Keep-Alive"), offsetof(ngx_http_headers_in_t, keep_alive),
150  ngx_http_process_header_line },
151 
152 #if (NGX_HTTP_X_FORWARDED_FOR)
153  { ngx_string("X-Forwarded-For"),
154  offsetof(ngx_http_headers_in_t, x_forwarded_for),
155  ngx_http_process_multi_header_lines },
156 #endif
157 
158 #if (NGX_HTTP_REALIP)
159  { ngx_string("X-Real-IP"),
160  offsetof(ngx_http_headers_in_t, x_real_ip),
161  ngx_http_process_header_line },
162 #endif
163 
164 #if (NGX_HTTP_HEADERS)
165  { ngx_string("Accept"), offsetof(ngx_http_headers_in_t, accept),
166  ngx_http_process_header_line },
167 
168  { ngx_string("Accept-Language"),
169  offsetof(ngx_http_headers_in_t, accept_language),
170  ngx_http_process_header_line },
171 #endif
172 
173 #if (NGX_HTTP_DAV)
174  { ngx_string("Depth"), offsetof(ngx_http_headers_in_t, depth),
175  ngx_http_process_header_line },
176 
177  { ngx_string("Destination"), offsetof(ngx_http_headers_in_t, destination),
178  ngx_http_process_header_line },
179 
180  { ngx_string("Overwrite"), offsetof(ngx_http_headers_in_t, overwrite),
181  ngx_http_process_header_line },
182 
183  { ngx_string("Date"), offsetof(ngx_http_headers_in_t, date),
184  ngx_http_process_header_line },
185 #endif
186 
187  { ngx_string("Cookie"), offsetof(ngx_http_headers_in_t, cookies),
188  ngx_http_process_multi_header_lines },
189 
190  { ngx_null_string, 0, NULL }
191 };
192 
193 
194 void
196 {
197  ngx_uint_t i;
198  ngx_event_t *rev;
199  struct sockaddr_in *sin;
200  ngx_http_port_t *port;
201  ngx_http_in_addr_t *addr;
202  ngx_http_log_ctx_t *ctx;
204 #if (NGX_HAVE_INET6)
205  struct sockaddr_in6 *sin6;
206  ngx_http_in6_addr_t *addr6;
207 #endif
208 
209  hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t));
210  if (hc == NULL) {
212  return;
213  }
214 
215  c->data = hc;
216 
217  /* find the server configuration for the address:port */
218 
219  port = c->listening->servers;
220 
221  if (port->naddrs > 1) {
222 
223  /*
224  * there are several addresses on this port and one of them
225  * is an "*:port" wildcard so getsockname() in ngx_http_server_addr()
226  * is required to determine a server address
227  */
228 
229  if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) {
231  return;
232  }
233 
234  switch (c->local_sockaddr->sa_family) {
235 
236 #if (NGX_HAVE_INET6)
237  case AF_INET6:
238  sin6 = (struct sockaddr_in6 *) c->local_sockaddr;
239 
240  addr6 = port->addrs;
241 
242  /* the last address is "*" */
243 
244  for (i = 0; i < port->naddrs - 1; i++) {
245  if (ngx_memcmp(&addr6[i].addr6, &sin6->sin6_addr, 16) == 0) {
246  break;
247  }
248  }
249 
250  hc->addr_conf = &addr6[i].conf;
251 
252  break;
253 #endif
254 
255  default: /* AF_INET */
256  sin = (struct sockaddr_in *) c->local_sockaddr;
257 
258  addr = port->addrs;
259 
260  /* the last address is "*" */
261 
262  for (i = 0; i < port->naddrs - 1; i++) {
263  if (addr[i].addr == sin->sin_addr.s_addr) {
264  break;
265  }
266  }
267 
268  hc->addr_conf = &addr[i].conf;
269 
270  break;
271  }
272 
273  } else {
274 
275  switch (c->local_sockaddr->sa_family) {
276 
277 #if (NGX_HAVE_INET6)
278  case AF_INET6:
279  addr6 = port->addrs;
280  hc->addr_conf = &addr6[0].conf;
281  break;
282 #endif
283 
284  default: /* AF_INET */
285  addr = port->addrs;
286  hc->addr_conf = &addr[0].conf;
287  break;
288  }
289  }
290 
291  /* the default server configuration for the address:port */
292  hc->conf_ctx = hc->addr_conf->default_server->ctx;
293 
294  ctx = ngx_palloc(c->pool, sizeof(ngx_http_log_ctx_t));
295  if (ctx == NULL) {
297  return;
298  }
299 
300  ctx->connection = c;
301  ctx->request = NULL;
302  ctx->current_request = NULL;
303 
304  c->log->connection = c->number;
305  c->log->handler = ngx_http_log_error;
306  c->log->data = ctx;
307  c->log->action = "waiting for request";
308 
310 
311  rev = c->read;
312  rev->handler = ngx_http_wait_request_handler;
314 
315 #if (NGX_HTTP_SPDY)
316  if (hc->addr_conf->spdy) {
318  }
319 #endif
320 
321 #if (NGX_HTTP_SSL)
322  {
324 
326 
327  if (sscf->enable || hc->addr_conf->ssl) {
328 
329  c->log->action = "SSL handshaking";
330 
331  if (hc->addr_conf->ssl && sscf->ssl.ctx == NULL) {
333  "no \"ssl_certificate\" is defined "
334  "in server listening on SSL port");
336  return;
337  }
338 
339  hc->ssl = 1;
340 
341  rev->handler = ngx_http_ssl_handshake;
342  }
343  }
344 #endif
345 
346  if (rev->ready) {
347  /* the deferred accept(), rtsig, aio, iocp */
348 
349  if (ngx_use_accept_mutex) {
351  return;
352  }
353 
354  rev->handler(rev);
355  return;
356  }
357 
360 
361  if (ngx_handle_read_event(rev, 0) != NGX_OK) {
363  return;
364  }
365 }
366 
367 
368 static void
369 ngx_http_wait_request_handler(ngx_event_t *rev)
370 {
371  size_t size;
372  ssize_t n;
373  ngx_buf_t *b;
374  ngx_connection_t *c;
377 
378  c = rev->data;
379 
380  ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http wait request handler");
381 
382  if (rev->timedout) {
383  ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
385  return;
386  }
387 
388  if (c->close) {
390  return;
391  }
392 
393  hc = c->data;
395 
396  size = cscf->client_header_buffer_size;
397 
398  b = c->buffer;
399 
400  if (b == NULL) {
401  b = ngx_create_temp_buf(c->pool, size);
402  if (b == NULL) {
404  return;
405  }
406 
407  c->buffer = b;
408 
409  } else if (b->start == NULL) {
410 
411  b->start = ngx_palloc(c->pool, size);
412  if (b->start == NULL) {
414  return;
415  }
416 
417  b->pos = b->start;
418  b->last = b->start;
419  b->end = b->last + size;
420  }
421 
422  n = c->recv(c, b->last, size);
423 
424  if (n == NGX_AGAIN) {
425 
426 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
427  if (c->listening->deferred_accept
428 #if (NGX_HTTP_SSL)
429  && c->ssl == NULL
430 #endif
431  )
432  {
434  "client timed out in deferred accept");
436  return;
437  }
438 #endif
439 
440  if (!rev->timer_set) {
443  }
444 
445  if (ngx_handle_read_event(rev, 0) != NGX_OK) {
447  return;
448  }
449 
450  /*
451  * We are trying to not hold c->buffer's memory for an idle connection.
452  */
453 
454  if (ngx_pfree(c->pool, b->start) == NGX_OK) {
455  b->start = NULL;
456  }
457 
458  return;
459  }
460 
461  if (n == NGX_ERROR) {
463  return;
464  }
465 
466  if (n == 0) {
468  "client closed connection");
470  return;
471  }
472 
473  b->last += n;
474 
475  c->log->action = "reading client request line";
476 
478 
480  if (c->data == NULL) {
482  return;
483  }
484 
485  rev->handler = ngx_http_process_request_line;
486  ngx_http_process_request_line(rev);
487 }
488 
489 
492 {
493  ngx_pool_t *pool;
494  ngx_time_t *tp;
496  ngx_http_log_ctx_t *ctx;
501 
502  c->requests++;
503 
504  hc = c->data;
505 
507 
508  pool = ngx_create_pool(cscf->request_pool_size, c->log);
509  if (pool == NULL) {
510  return NULL;
511  }
512 
513  r = ngx_pcalloc(pool, sizeof(ngx_http_request_t));
514  if (r == NULL) {
515  ngx_destroy_pool(pool);
516  return NULL;
517  }
518 
519  r->pool = pool;
520 
521  r->http_connection = hc;
523  r->connection = c;
524 
525  r->main_conf = hc->conf_ctx->main_conf;
526  r->srv_conf = hc->conf_ctx->srv_conf;
527  r->loc_conf = hc->conf_ctx->loc_conf;
528 
530 
532 
534 
535  r->header_in = hc->nbusy ? hc->busy[0] : c->buffer;
536 
537  if (ngx_list_init(&r->headers_out.headers, r->pool, 20,
538  sizeof(ngx_table_elt_t))
539  != NGX_OK)
540  {
542  return NULL;
543  }
544 
545  r->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
546  if (r->ctx == NULL) {
548  return NULL;
549  }
550 
552 
553  r->variables = ngx_pcalloc(r->pool, cmcf->variables.nelts
554  * sizeof(ngx_http_variable_value_t));
555  if (r->variables == NULL) {
557  return NULL;
558  }
559 
560 #if (NGX_HTTP_SSL)
561  if (c->ssl) {
563  }
564 #endif
565 
566  r->main = r;
567  r->count = 1;
568 
569  tp = ngx_timeofday();
570  r->start_sec = tp->sec;
571  r->start_msec = tp->msec;
572 
574 
576  r->headers_in.keep_alive_n = -1;
579 
582 
584 
585  ctx = c->log->data;
586  ctx->request = r;
587  ctx->current_request = r;
588  r->log_handler = ngx_http_log_error_handler;
589 
590 #if (NGX_STAT_STUB)
591  (void) ngx_atomic_fetch_add(ngx_stat_reading, 1);
592  r->stat_reading = 1;
593  (void) ngx_atomic_fetch_add(ngx_stat_requests, 1);
594 #endif
595 
596  return r;
597 }
598 
599 
600 #if (NGX_HTTP_SSL)
601 
602 static void
603 ngx_http_ssl_handshake(ngx_event_t *rev)
604 {
605  u_char buf[1];
606  ssize_t n;
607  ngx_err_t err;
608  ngx_int_t rc;
609  ngx_connection_t *c;
612 
613  c = rev->data;
614 
616  "http check ssl handshake");
617 
618  if (rev->timedout) {
619  ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
621  return;
622  }
623 
624  if (c->close) {
626  return;
627  }
628 
629  n = recv(c->fd, (char *) buf, 1, MSG_PEEK);
630 
631  err = ngx_socket_errno;
632 
633  ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http recv(): %d", n);
634 
635  if (n == -1) {
636  if (err == NGX_EAGAIN) {
637 
638 #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
639  if (c->listening->deferred_accept) {
641  "client timed out in deferred accept");
643  return;
644  }
645 #endif
646 
647  if (!rev->timer_set) {
650  }
651 
652  if (ngx_handle_read_event(rev, 0) != NGX_OK) {
654  }
655 
656  return;
657  }
658 
659  ngx_connection_error(c, err, "recv() failed");
661 
662  return;
663  }
664 
665  if (n == 1) {
666  if (buf[0] & 0x80 /* SSLv2 */ || buf[0] == 0x16 /* SSLv3/TLSv1 */) {
668  "https ssl handshake: 0x%02Xd", buf[0]);
669 
670  hc = c->data;
673 
675  != NGX_OK)
676  {
678  return;
679  }
680 
681  rc = ngx_ssl_handshake(c);
682 
683  if (rc == NGX_AGAIN) {
684 
685  if (!rev->timer_set) {
687  }
688 
690 
691  c->ssl->handler = ngx_http_ssl_handshake_handler;
692  return;
693  }
694 
695  ngx_http_ssl_handshake_handler(c);
696 
697  return;
698  }
699 
700  ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "plain http");
701 
702  c->log->action = "waiting for request";
703 
704  rev->handler = ngx_http_wait_request_handler;
705  ngx_http_wait_request_handler(rev);
706 
707  return;
708  }
709 
710  ngx_log_error(NGX_LOG_INFO, c->log, 0, "client closed connection");
712 }
713 
714 
715 static void
716 ngx_http_ssl_handshake_handler(ngx_connection_t *c)
717 {
718  if (c->ssl->handshaked) {
719 
720  /*
721  * The majority of browsers do not send the "close notify" alert.
722  * Among them are MSIE, old Mozilla, Netscape 4, Konqueror,
723  * and Links. And what is more, MSIE ignores the server's alert.
724  *
725  * Opera and recent Mozilla send the alert.
726  */
727 
728  c->ssl->no_wait_shutdown = 1;
729 
730 #if (NGX_HTTP_SPDY && defined TLSEXT_TYPE_next_proto_neg)
731  {
732  unsigned int len;
733  const unsigned char *data;
734  static const ngx_str_t spdy = ngx_string(NGX_SPDY_NPN_NEGOTIATED);
735 
736  SSL_get0_next_proto_negotiated(c->ssl->connection, &data, &len);
737 
738  if (len == spdy.len && ngx_strncmp(data, spdy.data, spdy.len) == 0) {
740  return;
741  }
742  }
743 #endif
744 
745  c->log->action = "waiting for request";
746 
747  c->read->handler = ngx_http_wait_request_handler;
748  /* STUB: epoll edge */ c->write->handler = ngx_http_empty_handler;
749 
751 
752  ngx_http_wait_request_handler(c->read);
753 
754  return;
755  }
756 
757  if (c->read->timedout) {
758  ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
759  }
760 
762 }
763 
764 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
765 
766 int
767 ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
768 {
769  ngx_str_t host;
770  const char *servername;
771  ngx_connection_t *c;
776 
777  servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name);
778 
779  if (servername == NULL) {
780  return SSL_TLSEXT_ERR_NOACK;
781  }
782 
783  c = ngx_ssl_get_connection(ssl_conn);
784 
786  "SSL server name: \"%s\"", servername);
787 
788  host.len = ngx_strlen(servername);
789 
790  if (host.len == 0) {
791  return SSL_TLSEXT_ERR_NOACK;
792  }
793 
794  host.data = (u_char *) servername;
795 
796  if (ngx_http_validate_host(&host, c->pool, 1) != NGX_OK) {
797  return SSL_TLSEXT_ERR_NOACK;
798  }
799 
800  hc = c->data;
801 
802  if (ngx_http_find_virtual_server(c, hc->addr_conf->virtual_names, &host,
803  NULL, &cscf)
804  != NGX_OK)
805  {
806  return SSL_TLSEXT_ERR_NOACK;
807  }
808 
809  hc->ssl_servername = ngx_palloc(c->pool, sizeof(ngx_str_t));
810  if (hc->ssl_servername == NULL) {
811  return SSL_TLSEXT_ERR_NOACK;
812  }
813 
814  *hc->ssl_servername = host;
815 
816  hc->conf_ctx = cscf->ctx;
817 
819 
821 
823 
824  if (sscf->ssl.ctx) {
825  SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx);
826 
827  /*
828  * SSL_set_SSL_CTX() only changes certs as of 1.0.0d
829  * adjust other things we care about
830  */
831 
832  SSL_set_verify(ssl_conn, SSL_CTX_get_verify_mode(sscf->ssl.ctx),
833  SSL_CTX_get_verify_callback(sscf->ssl.ctx));
834 
835  SSL_set_verify_depth(ssl_conn, SSL_CTX_get_verify_depth(sscf->ssl.ctx));
836 
837 #ifdef SSL_CTRL_CLEAR_OPTIONS
838  /* only in 0.9.8m+ */
839  SSL_clear_options(ssl_conn, SSL_get_options(ssl_conn) &
840  ~SSL_CTX_get_options(sscf->ssl.ctx));
841 #endif
842 
843  SSL_set_options(ssl_conn, SSL_CTX_get_options(sscf->ssl.ctx));
844  }
845 
846  return SSL_TLSEXT_ERR_OK;
847 }
848 
849 #endif
850 
851 #endif
852 
853 
854 static void
855 ngx_http_process_request_line(ngx_event_t *rev)
856 {
857  ssize_t n;
858  ngx_int_t rc, rv;
859  ngx_str_t host;
860  ngx_connection_t *c;
862 
863  c = rev->data;
864  r = c->data;
865 
867  "http process request line");
868 
869  if (rev->timedout) {
870  ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
871  c->timedout = 1;
872  ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT);
873  return;
874  }
875 
876  rc = NGX_AGAIN;
877 
878  for ( ;; ) {
879 
880  if (rc == NGX_AGAIN) {
881  n = ngx_http_read_request_header(r);
882 
883  if (n == NGX_AGAIN || n == NGX_ERROR) {
884  return;
885  }
886  }
887 
889 
890  if (rc == NGX_OK) {
891 
892  /* the request line has been parsed successfully */
893 
897 
899  "http request line: \"%V\"", &r->request_line);
900 
901  r->method_name.len = r->method_end - r->request_start + 1;
903 
904  if (r->http_protocol.data) {
906  }
907 
909  return;
910  }
911 
912  if (r->host_start && r->host_end) {
913 
914  host.len = r->host_end - r->host_start;
915  host.data = r->host_start;
916 
917  rc = ngx_http_validate_host(&host, r->pool, 0);
918 
919  if (rc == NGX_DECLINED) {
921  "client sent invalid host in request line");
923  return;
924  }
925 
926  if (rc == NGX_ERROR) {
927  ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
928  return;
929  }
930 
931  if (ngx_http_set_virtual_server(r, &host) == NGX_ERROR) {
932  return;
933  }
934 
935  r->headers_in.server = host;
936  }
937 
939 
940  if (r->headers_in.server.len == 0
941  && ngx_http_set_virtual_server(r, &r->headers_in.server)
942  == NGX_ERROR)
943  {
944  return;
945  }
946 
948  return;
949  }
950 
951 
952  if (ngx_list_init(&r->headers_in.headers, r->pool, 20,
953  sizeof(ngx_table_elt_t))
954  != NGX_OK)
955  {
956  ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
957  return;
958  }
959 
960  c->log->action = "reading client request headers";
961 
962  rev->handler = ngx_http_process_request_headers;
963  ngx_http_process_request_headers(rev);
964 
965  return;
966  }
967 
968  if (rc != NGX_AGAIN) {
969 
970  /* there was error while a request line parsing */
971 
973  ngx_http_client_errors[rc - NGX_HTTP_CLIENT_ERROR]);
975  return;
976  }
977 
978  /* NGX_AGAIN: a request line parsing is still incomplete */
979 
980  if (r->header_in->pos == r->header_in->end) {
981 
982  rv = ngx_http_alloc_large_header_buffer(r, 1);
983 
984  if (rv == NGX_ERROR) {
985  ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
986  return;
987  }
988 
989  if (rv == NGX_DECLINED) {
992 
994  "client sent too long URI");
996  return;
997  }
998  }
999  }
1000 }
1001 
1002 
1003 ngx_int_t
1005 {
1007 
1008  if (r->args_start) {
1009  r->uri.len = r->args_start - 1 - r->uri_start;
1010  } else {
1011  r->uri.len = r->uri_end - r->uri_start;
1012  }
1013 
1014  if (r->complex_uri || r->quoted_uri) {
1015 
1016  r->uri.data = ngx_pnalloc(r->pool, r->uri.len + 1);
1017  if (r->uri.data == NULL) {
1018  ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1019  return NGX_ERROR;
1020  }
1021 
1023 
1024  if (ngx_http_parse_complex_uri(r, cscf->merge_slashes) != NGX_OK) {
1026  "client sent invalid request");
1028  return NGX_ERROR;
1029  }
1030 
1031  } else {
1032  r->uri.data = r->uri_start;
1033  }
1034 
1035  r->unparsed_uri.len = r->uri_end - r->uri_start;
1036  r->unparsed_uri.data = r->uri_start;
1037 
1038  r->valid_unparsed_uri = r->space_in_uri ? 0 : 1;
1039 
1040  if (r->uri_ext) {
1041  if (r->args_start) {
1042  r->exten.len = r->args_start - 1 - r->uri_ext;
1043  } else {
1044  r->exten.len = r->uri_end - r->uri_ext;
1045  }
1046 
1047  r->exten.data = r->uri_ext;
1048  }
1049 
1050  if (r->args_start && r->uri_end > r->args_start) {
1051  r->args.len = r->uri_end - r->args_start;
1052  r->args.data = r->args_start;
1053  }
1054 
1055 #if (NGX_WIN32)
1056  {
1057  u_char *p, *last;
1058 
1059  p = r->uri.data;
1060  last = r->uri.data + r->uri.len;
1061 
1062  while (p < last) {
1063 
1064  if (*p++ == ':') {
1065 
1066  /*
1067  * this check covers "::$data", "::$index_allocation" and
1068  * ":$i30:$index_allocation"
1069  */
1070 
1071  if (p < last && *p == '$') {
1073  "client sent unsafe win32 URI");
1075  return NGX_ERROR;
1076  }
1077  }
1078  }
1079 
1080  p = r->uri.data + r->uri.len - 1;
1081 
1082  while (p > r->uri.data) {
1083 
1084  if (*p == ' ') {
1085  p--;
1086  continue;
1087  }
1088 
1089  if (*p == '.') {
1090  p--;
1091  continue;
1092  }
1093 
1094  break;
1095  }
1096 
1097  if (p != r->uri.data + r->uri.len - 1) {
1098  r->uri.len = p + 1 - r->uri.data;
1099  ngx_http_set_exten(r);
1100  }
1101 
1102  }
1103 #endif
1104 
1106  "http uri: \"%V\"", &r->uri);
1107 
1109  "http args: \"%V\"", &r->args);
1110 
1112  "http exten: \"%V\"", &r->exten);
1113 
1114  return NGX_OK;
1115 }
1116 
1117 
1118 static void
1119 ngx_http_process_request_headers(ngx_event_t *rev)
1120 {
1121  u_char *p;
1122  size_t len;
1123  ssize_t n;
1124  ngx_int_t rc, rv;
1125  ngx_table_elt_t *h;
1126  ngx_connection_t *c;
1127  ngx_http_header_t *hh;
1128  ngx_http_request_t *r;
1131 
1132  c = rev->data;
1133  r = c->data;
1134 
1136  "http process request header line");
1137 
1138  if (rev->timedout) {
1139  ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
1140  c->timedout = 1;
1141  ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT);
1142  return;
1143  }
1144 
1146 
1147  rc = NGX_AGAIN;
1148 
1149  for ( ;; ) {
1150 
1151  if (rc == NGX_AGAIN) {
1152 
1153  if (r->header_in->pos == r->header_in->end) {
1154 
1155  rv = ngx_http_alloc_large_header_buffer(r, 0);
1156 
1157  if (rv == NGX_ERROR) {
1158  ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1159  return;
1160  }
1161 
1162  if (rv == NGX_DECLINED) {
1163  p = r->header_name_start;
1164 
1165  r->lingering_close = 1;
1166 
1167  if (p == NULL) {
1169  "client sent too large request");
1172  return;
1173  }
1174 
1175  len = r->header_in->end - p;
1176 
1177  if (len > NGX_MAX_ERROR_STR - 300) {
1178  len = NGX_MAX_ERROR_STR - 300;
1179  p[len++] = '.'; p[len++] = '.'; p[len++] = '.';
1180  }
1181 
1183  "client sent too long header line: \"%*s\"",
1184  len, r->header_name_start);
1185 
1188  return;
1189  }
1190  }
1191 
1192  n = ngx_http_read_request_header(r);
1193 
1194  if (n == NGX_AGAIN || n == NGX_ERROR) {
1195  return;
1196  }
1197  }
1198 
1199  /* the host header could change the server configuration context */
1201 
1203  cscf->underscores_in_headers);
1204 
1205  if (rc == NGX_OK) {
1206 
1208 
1209  if (r->invalid_header && cscf->ignore_invalid_headers) {
1210 
1211  /* there was error while a header line parsing */
1212 
1214  "client sent invalid header line: \"%*s\"",
1215  r->header_end - r->header_name_start,
1216  r->header_name_start);
1217  continue;
1218  }
1219 
1220  /* a header line has been parsed successfully */
1221 
1222  h = ngx_list_push(&r->headers_in.headers);
1223  if (h == NULL) {
1224  ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1225  return;
1226  }
1227 
1228  h->hash = r->header_hash;
1229 
1231  h->key.data = r->header_name_start;
1232  h->key.data[h->key.len] = '\0';
1233 
1234  h->value.len = r->header_end - r->header_start;
1235  h->value.data = r->header_start;
1236  h->value.data[h->value.len] = '\0';
1237 
1238  h->lowcase_key = ngx_pnalloc(r->pool, h->key.len);
1239  if (h->lowcase_key == NULL) {
1240  ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1241  return;
1242  }
1243 
1244  if (h->key.len == r->lowcase_index) {
1246 
1247  } else {
1248  ngx_strlow(h->lowcase_key, h->key.data, h->key.len);
1249  }
1250 
1251  hh = ngx_hash_find(&cmcf->headers_in_hash, h->hash,
1252  h->lowcase_key, h->key.len);
1253 
1254  if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
1255  return;
1256  }
1257 
1259  "http header: \"%V: %V\"",
1260  &h->key, &h->value);
1261 
1262  continue;
1263  }
1264 
1265  if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
1266 
1267  /* a whole header has been parsed successfully */
1268 
1270  "http header done");
1271 
1273 
1275 
1277 
1278  if (rc != NGX_OK) {
1279  return;
1280  }
1281 
1283 
1284  return;
1285  }
1286 
1287  if (rc == NGX_AGAIN) {
1288 
1289  /* a header line parsing is still not complete */
1290 
1291  continue;
1292  }
1293 
1294  /* rc == NGX_HTTP_PARSE_INVALID_HEADER: "\r" is not followed by "\n" */
1295 
1297  "client sent invalid header line: \"%*s\\r...\"",
1298  r->header_end - r->header_name_start,
1299  r->header_name_start);
1301  return;
1302  }
1303 }
1304 
1305 
1306 static ssize_t
1307 ngx_http_read_request_header(ngx_http_request_t *r)
1308 {
1309  ssize_t n;
1310  ngx_event_t *rev;
1311  ngx_connection_t *c;
1313 
1314  c = r->connection;
1315  rev = c->read;
1316 
1317  n = r->header_in->last - r->header_in->pos;
1318 
1319  if (n > 0) {
1320  return n;
1321  }
1322 
1323  if (rev->ready) {
1324  n = c->recv(c, r->header_in->last,
1325  r->header_in->end - r->header_in->last);
1326  } else {
1327  n = NGX_AGAIN;
1328  }
1329 
1330  if (n == NGX_AGAIN) {
1331  if (!rev->timer_set) {
1334  }
1335 
1336  if (ngx_handle_read_event(rev, 0) != NGX_OK) {
1337  ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1338  return NGX_ERROR;
1339  }
1340 
1341  return NGX_AGAIN;
1342  }
1343 
1344  if (n == 0) {
1346  "client prematurely closed connection");
1347  }
1348 
1349  if (n == 0 || n == NGX_ERROR) {
1350  c->error = 1;
1351  c->log->action = "reading client request headers";
1352 
1354  return NGX_ERROR;
1355  }
1356 
1357  r->header_in->last += n;
1358 
1359  return n;
1360 }
1361 
1362 
1363 static ngx_int_t
1364 ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
1365  ngx_uint_t request_line)
1366 {
1367  u_char *old, *new;
1368  ngx_buf_t *b;
1371 
1373  "http alloc large header buffer");
1374 
1375  if (request_line && r->state == 0) {
1376 
1377  /* the client fills up the buffer with "\r\n" */
1378 
1379  r->header_in->pos = r->header_in->start;
1380  r->header_in->last = r->header_in->start;
1381 
1382  return NGX_OK;
1383  }
1384 
1385  old = request_line ? r->request_start : r->header_name_start;
1386 
1388 
1389  if (r->state != 0
1390  && (size_t) (r->header_in->pos - old)
1392  {
1393  return NGX_DECLINED;
1394  }
1395 
1396  hc = r->http_connection;
1397 
1398  if (hc->nfree) {
1399  b = hc->free[--hc->nfree];
1400 
1402  "http large header free: %p %uz",
1403  b->pos, b->end - b->last);
1404 
1405  } else if (hc->nbusy < cscf->large_client_header_buffers.num) {
1406 
1407  if (hc->busy == NULL) {
1408  hc->busy = ngx_palloc(r->connection->pool,
1409  cscf->large_client_header_buffers.num * sizeof(ngx_buf_t *));
1410  if (hc->busy == NULL) {
1411  return NGX_ERROR;
1412  }
1413  }
1414 
1417  if (b == NULL) {
1418  return NGX_ERROR;
1419  }
1420 
1422  "http large header alloc: %p %uz",
1423  b->pos, b->end - b->last);
1424 
1425  } else {
1426  return NGX_DECLINED;
1427  }
1428 
1429  hc->busy[hc->nbusy++] = b;
1430 
1431  if (r->state == 0) {
1432  /*
1433  * r->state == 0 means that a header line was parsed successfully
1434  * and we do not need to copy incomplete header line and
1435  * to relocate the parser header pointers
1436  */
1437 
1438  r->header_in = b;
1439 
1440  return NGX_OK;
1441  }
1442 
1444  "http large header copy: %d", r->header_in->pos - old);
1445 
1446  new = b->start;
1447 
1448  ngx_memcpy(new, old, r->header_in->pos - old);
1449 
1450  b->pos = new + (r->header_in->pos - old);
1451  b->last = new + (r->header_in->pos - old);
1452 
1453  if (request_line) {
1454  r->request_start = new;
1455 
1456  if (r->request_end) {
1457  r->request_end = new + (r->request_end - old);
1458  }
1459 
1460  r->method_end = new + (r->method_end - old);
1461 
1462  r->uri_start = new + (r->uri_start - old);
1463  r->uri_end = new + (r->uri_end - old);
1464 
1465  if (r->schema_start) {
1466  r->schema_start = new + (r->schema_start - old);
1467  r->schema_end = new + (r->schema_end - old);
1468  }
1469 
1470  if (r->host_start) {
1471  r->host_start = new + (r->host_start - old);
1472  if (r->host_end) {
1473  r->host_end = new + (r->host_end - old);
1474  }
1475  }
1476 
1477  if (r->port_start) {
1478  r->port_start = new + (r->port_start - old);
1479  r->port_end = new + (r->port_end - old);
1480  }
1481 
1482  if (r->uri_ext) {
1483  r->uri_ext = new + (r->uri_ext - old);
1484  }
1485 
1486  if (r->args_start) {
1487  r->args_start = new + (r->args_start - old);
1488  }
1489 
1490  if (r->http_protocol.data) {
1491  r->http_protocol.data = new + (r->http_protocol.data - old);
1492  }
1493 
1494  } else {
1495  r->header_name_start = new;
1496  r->header_name_end = new + (r->header_name_end - old);
1497  r->header_start = new + (r->header_start - old);
1498  r->header_end = new + (r->header_end - old);
1499  }
1500 
1501  r->header_in = b;
1502 
1503  return NGX_OK;
1504 }
1505 
1506 
1507 static ngx_int_t
1508 ngx_http_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
1509  ngx_uint_t offset)
1510 {
1511  ngx_table_elt_t **ph;
1512 
1513  ph = (ngx_table_elt_t **) ((char *) &r->headers_in + offset);
1514 
1515  if (*ph == NULL) {
1516  *ph = h;
1517  }
1518 
1519  return NGX_OK;
1520 }
1521 
1522 
1523 static ngx_int_t
1524 ngx_http_process_unique_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
1525  ngx_uint_t offset)
1526 {
1527  ngx_table_elt_t **ph;
1528 
1529  ph = (ngx_table_elt_t **) ((char *) &r->headers_in + offset);
1530 
1531  if (*ph == NULL) {
1532  *ph = h;
1533  return NGX_OK;
1534  }
1535 
1537  "client sent duplicate header line: \"%V: %V\", "
1538  "previous value: \"%V: %V\"",
1539  &h->key, &h->value, &(*ph)->key, &(*ph)->value);
1540 
1542 
1543  return NGX_ERROR;
1544 }
1545 
1546 
1547 static ngx_int_t
1548 ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h,
1549  ngx_uint_t offset)
1550 {
1551  ngx_int_t rc;
1552  ngx_str_t host;
1553 
1554  if (r->headers_in.host == NULL) {
1555  r->headers_in.host = h;
1556  }
1557 
1558  host = h->value;
1559 
1560  rc = ngx_http_validate_host(&host, r->pool, 0);
1561 
1562  if (rc == NGX_DECLINED) {
1564  "client sent invalid host header");
1566  return NGX_ERROR;
1567  }
1568 
1569  if (rc == NGX_ERROR) {
1570  ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1571  return NGX_ERROR;
1572  }
1573 
1574  if (r->headers_in.server.len) {
1575  return NGX_OK;
1576  }
1577 
1578  if (ngx_http_set_virtual_server(r, &host) == NGX_ERROR) {
1579  return NGX_ERROR;
1580  }
1581 
1582  r->headers_in.server = host;
1583 
1584  return NGX_OK;
1585 }
1586 
1587 
1588 static ngx_int_t
1589 ngx_http_process_connection(ngx_http_request_t *r, ngx_table_elt_t *h,
1590  ngx_uint_t offset)
1591 {
1592  if (ngx_strcasestrn(h->value.data, "close", 5 - 1)) {
1594 
1595  } else if (ngx_strcasestrn(h->value.data, "keep-alive", 10 - 1)) {
1597  }
1598 
1599  return NGX_OK;
1600 }
1601 
1602 
1603 static ngx_int_t
1604 ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h,
1605  ngx_uint_t offset)
1606 {
1607  u_char *user_agent, *msie;
1608 
1609  if (r->headers_in.user_agent) {
1610  return NGX_OK;
1611  }
1612 
1613  r->headers_in.user_agent = h;
1614 
1615  /* check some widespread browsers while the header is in CPU cache */
1616 
1617  user_agent = h->value.data;
1618 
1619  msie = ngx_strstrn(user_agent, "MSIE ", 5 - 1);
1620 
1621  if (msie && msie + 7 < user_agent + h->value.len) {
1622 
1623  r->headers_in.msie = 1;
1624 
1625  if (msie[6] == '.') {
1626 
1627  switch (msie[5]) {
1628  case '4':
1629  case '5':
1630  r->headers_in.msie6 = 1;
1631  break;
1632  case '6':
1633  if (ngx_strstrn(msie + 8, "SV1", 3 - 1) == NULL) {
1634  r->headers_in.msie6 = 1;
1635  }
1636  break;
1637  }
1638  }
1639 
1640 #if 0
1641  /* MSIE ignores the SSL "close notify" alert */
1642  if (c->ssl) {
1643  c->ssl->no_send_shutdown = 1;
1644  }
1645 #endif
1646  }
1647 
1648  if (ngx_strstrn(user_agent, "Opera", 5 - 1)) {
1649  r->headers_in.opera = 1;
1650  r->headers_in.msie = 0;
1651  r->headers_in.msie6 = 0;
1652  }
1653 
1654  if (!r->headers_in.msie && !r->headers_in.opera) {
1655 
1656  if (ngx_strstrn(user_agent, "Gecko/", 6 - 1)) {
1657  r->headers_in.gecko = 1;
1658 
1659  } else if (ngx_strstrn(user_agent, "Chrome/", 7 - 1)) {
1660  r->headers_in.chrome = 1;
1661 
1662  } else if (ngx_strstrn(user_agent, "Safari/", 7 - 1)
1663  && ngx_strstrn(user_agent, "Mac OS X", 8 - 1))
1664  {
1665  r->headers_in.safari = 1;
1666 
1667  } else if (ngx_strstrn(user_agent, "Konqueror", 9 - 1)) {
1668  r->headers_in.konqueror = 1;
1669  }
1670  }
1671 
1672  return NGX_OK;
1673 }
1674 
1675 
1676 static ngx_int_t
1677 ngx_http_process_multi_header_lines(ngx_http_request_t *r, ngx_table_elt_t *h,
1678  ngx_uint_t offset)
1679 {
1680  ngx_array_t *headers;
1681  ngx_table_elt_t **ph;
1682 
1683  headers = (ngx_array_t *) ((char *) &r->headers_in + offset);
1684 
1685  if (headers->elts == NULL) {
1686  if (ngx_array_init(headers, r->pool, 1, sizeof(ngx_table_elt_t *))
1687  != NGX_OK)
1688  {
1689  ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1690  return NGX_ERROR;
1691  }
1692  }
1693 
1694  ph = ngx_array_push(headers);
1695  if (ph == NULL) {
1696  ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1697  return NGX_ERROR;
1698  }
1699 
1700  *ph = h;
1701  return NGX_OK;
1702 }
1703 
1704 
1705 ngx_int_t
1707 {
1708  if (r->headers_in.server.len == 0
1709  && ngx_http_set_virtual_server(r, &r->headers_in.server)
1710  == NGX_ERROR)
1711  {
1712  return NGX_ERROR;
1713  }
1714 
1715  if (r->headers_in.host == NULL && r->http_version > NGX_HTTP_VERSION_10) {
1717  "client sent HTTP/1.1 request without \"Host\" header");
1719  return NGX_ERROR;
1720  }
1721 
1722  if (r->headers_in.content_length) {
1726 
1729  "client sent invalid \"Content-Length\" header");
1731  return NGX_ERROR;
1732  }
1733  }
1734 
1735  if (r->method & NGX_HTTP_TRACE) {
1737  "client sent TRACE method");
1739  return NGX_ERROR;
1740  }
1741 
1742  if (r->headers_in.transfer_encoding) {
1743  if (r->headers_in.transfer_encoding->value.len == 7
1745  (u_char *) "chunked", 7) == 0)
1746  {
1747  r->headers_in.content_length = NULL;
1748  r->headers_in.content_length_n = -1;
1749  r->headers_in.chunked = 1;
1750 
1751  } else if (r->headers_in.transfer_encoding->value.len != 8
1753  (u_char *) "identity", 8) != 0)
1754  {
1756  "client sent unknown \"Transfer-Encoding\": \"%V\"",
1759  return NGX_ERROR;
1760  }
1761  }
1762 
1764  if (r->headers_in.keep_alive) {
1768  }
1769  }
1770 
1771  return NGX_OK;
1772 }
1773 
1774 
1775 void
1777 {
1778  ngx_connection_t *c;
1779 
1780  c = r->connection;
1781 
1782 #if (NGX_HTTP_SSL)
1783 
1784  if (r->http_connection->ssl) {
1785  long rc;
1786  X509 *cert;
1788 
1789  if (c->ssl == NULL) {
1791  "client sent plain HTTP request to HTTPS port");
1793  return;
1794  }
1795 
1797 
1798  if (sscf->verify) {
1799  rc = SSL_get_verify_result(c->ssl->connection);
1800 
1801  if (rc != X509_V_OK
1802  && (sscf->verify != 3 || !ngx_ssl_verify_error_optional(rc)))
1803  {
1805  "client SSL certificate verify error: (%l:%s)",
1806  rc, X509_verify_cert_error_string(rc));
1807 
1809  (SSL_get0_session(c->ssl->connection)));
1810 
1812  return;
1813  }
1814 
1815  if (sscf->verify == 1) {
1816  cert = SSL_get_peer_certificate(c->ssl->connection);
1817 
1818  if (cert == NULL) {
1820  "client sent no required SSL certificate");
1821 
1823  (SSL_get0_session(c->ssl->connection)));
1824 
1826  return;
1827  }
1828 
1829  X509_free(cert);
1830  }
1831  }
1832  }
1833 
1834 #endif
1835 
1836  if (c->read->timer_set) {
1837  ngx_del_timer(c->read);
1838  }
1839 
1840 #if (NGX_STAT_STUB)
1841  (void) ngx_atomic_fetch_add(ngx_stat_reading, -1);
1842  r->stat_reading = 0;
1843  (void) ngx_atomic_fetch_add(ngx_stat_writing, 1);
1844  r->stat_writing = 1;
1845 #endif
1846 
1847  c->read->handler = ngx_http_request_handler;
1848  c->write->handler = ngx_http_request_handler;
1850 
1851  ngx_http_handler(r);
1852 
1854 }
1855 
1856 
1857 static ngx_int_t
1858 ngx_http_validate_host(ngx_str_t *host, ngx_pool_t *pool, ngx_uint_t alloc)
1859 {
1860  u_char *h, ch;
1861  size_t i, dot_pos, host_len;
1862 
1863  enum {
1864  sw_usual = 0,
1865  sw_literal,
1866  sw_rest
1867  } state;
1868 
1869  dot_pos = host->len;
1870  host_len = host->len;
1871 
1872  h = host->data;
1873 
1874  state = sw_usual;
1875 
1876  for (i = 0; i < host->len; i++) {
1877  ch = h[i];
1878 
1879  switch (ch) {
1880 
1881  case '.':
1882  if (dot_pos == i - 1) {
1883  return NGX_DECLINED;
1884  }
1885  dot_pos = i;
1886  break;
1887 
1888  case ':':
1889  if (state == sw_usual) {
1890  host_len = i;
1891  state = sw_rest;
1892  }
1893  break;
1894 
1895  case '[':
1896  if (i == 0) {
1897  state = sw_literal;
1898  }
1899  break;
1900 
1901  case ']':
1902  if (state == sw_literal) {
1903  host_len = i + 1;
1904  state = sw_rest;
1905  }
1906  break;
1907 
1908  case '\0':
1909  return NGX_DECLINED;
1910 
1911  default:
1912 
1913  if (ngx_path_separator(ch)) {
1914  return NGX_DECLINED;
1915  }
1916 
1917  if (ch >= 'A' && ch <= 'Z') {
1918  alloc = 1;
1919  }
1920 
1921  break;
1922  }
1923  }
1924 
1925  if (dot_pos == host_len - 1) {
1926  host_len--;
1927  }
1928 
1929  if (host_len == 0) {
1930  return NGX_DECLINED;
1931  }
1932 
1933  if (alloc) {
1934  host->data = ngx_pnalloc(pool, host_len);
1935  if (host->data == NULL) {
1936  return NGX_ERROR;
1937  }
1938 
1939  ngx_strlow(host->data, h, host_len);
1940  }
1941 
1942  host->len = host_len;
1943 
1944  return NGX_OK;
1945 }
1946 
1947 
1948 static ngx_int_t
1949 ngx_http_set_virtual_server(ngx_http_request_t *r, ngx_str_t *host)
1950 {
1951  ngx_int_t rc;
1955 
1956  hc = r->http_connection;
1957 
1958 #if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)
1959 
1960  if (hc->ssl_servername) {
1961  if (hc->ssl_servername->len == host->len
1962  && ngx_strncmp(hc->ssl_servername->data,
1963  host->data, host->len) == 0)
1964  {
1965 #if (NGX_PCRE)
1966  if (hc->ssl_servername_regex
1967  && ngx_http_regex_exec(r, hc->ssl_servername_regex,
1968  hc->ssl_servername) != NGX_OK)
1969  {
1970  ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1971  return NGX_ERROR;
1972  }
1973 #endif
1974  return NGX_OK;
1975  }
1976  }
1977 
1978 #endif
1979 
1980  rc = ngx_http_find_virtual_server(r->connection,
1981  hc->addr_conf->virtual_names,
1982  host, r, &cscf);
1983 
1984  if (rc == NGX_ERROR) {
1985  ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1986  return NGX_ERROR;
1987  }
1988 
1989 #if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)
1990 
1991  if (hc->ssl_servername) {
1993 
1994  if (rc == NGX_DECLINED) {
1995  cscf = hc->addr_conf->default_server;
1996  rc = NGX_OK;
1997  }
1998 
2000 
2001  if (sscf->verify) {
2003  "client attempted to request the server name "
2004  "different from that one was negotiated");
2006  return NGX_ERROR;
2007  }
2008  }
2009 
2010 #endif
2011 
2012  if (rc == NGX_DECLINED) {
2013  return NGX_OK;
2014  }
2015 
2016  r->srv_conf = cscf->ctx->srv_conf;
2017  r->loc_conf = cscf->ctx->loc_conf;
2018 
2020 
2022 
2023  return NGX_OK;
2024 }
2025 
2026 
2027 static ngx_int_t
2028 ngx_http_find_virtual_server(ngx_connection_t *c,
2029  ngx_http_virtual_names_t *virtual_names, ngx_str_t *host,
2031 {
2033 
2034  if (virtual_names == NULL) {
2035  return NGX_DECLINED;
2036  }
2037 
2038  cscf = ngx_hash_find_combined(&virtual_names->names,
2039  ngx_hash_key(host->data, host->len),
2040  host->data, host->len);
2041 
2042  if (cscf) {
2043  *cscfp = cscf;
2044  return NGX_OK;
2045  }
2046 
2047 #if (NGX_PCRE)
2048 
2049  if (host->len && virtual_names->nregex) {
2050  ngx_int_t n;
2051  ngx_uint_t i;
2053 
2054  sn = virtual_names->regex;
2055 
2056 #if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)
2057 
2058  if (r == NULL) {
2060 
2061  for (i = 0; i < virtual_names->nregex; i++) {
2062 
2063  n = ngx_regex_exec(sn[i].regex->regex, host, NULL, 0);
2064 
2065  if (n == NGX_REGEX_NO_MATCHED) {
2066  continue;
2067  }
2068 
2069  if (n >= 0) {
2070  hc = c->data;
2071  hc->ssl_servername_regex = sn[i].regex;
2072 
2073  *cscfp = sn[i].server;
2074  return NGX_OK;
2075  }
2076 
2078  ngx_regex_exec_n " failed: %i "
2079  "on \"%V\" using \"%V\"",
2080  n, host, &sn[i].regex->name);
2081 
2082  return NGX_ERROR;
2083  }
2084 
2085  return NGX_DECLINED;
2086  }
2087 
2088 #endif /* NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME */
2089 
2090  for (i = 0; i < virtual_names->nregex; i++) {
2091 
2092  n = ngx_http_regex_exec(r, sn[i].regex, host);
2093 
2094  if (n == NGX_DECLINED) {
2095  continue;
2096  }
2097 
2098  if (n == NGX_OK) {
2099  *cscfp = sn[i].server;
2100  return NGX_OK;
2101  }
2102 
2103  return NGX_ERROR;
2104  }
2105  }
2106 
2107 #endif /* NGX_PCRE */
2108 
2109  return NGX_DECLINED;
2110 }
2111 
2112 
2113 static void
2114 ngx_http_request_handler(ngx_event_t *ev)
2115 {
2116  ngx_connection_t *c;
2117  ngx_http_request_t *r;
2119 
2120  c = ev->data;
2121  r = c->data;
2122 
2123  ctx = c->log->data;
2124  ctx->current_request = r;
2125 
2127  "http run request: \"%V?%V\"", &r->uri, &r->args);
2128 
2129  if (ev->write) {
2130  r->write_event_handler(r);
2131 
2132  } else {
2133  r->read_event_handler(r);
2134  }
2135 
2137 }
2138 
2139 
2140 void
2142 {
2143  ngx_http_request_t *r;
2144  ngx_http_log_ctx_t *ctx;
2146 
2147  for ( ;; ) {
2148 
2149  if (c->destroyed) {
2150  return;
2151  }
2152 
2153  r = c->data;
2154  pr = r->main->posted_requests;
2155 
2156  if (pr == NULL) {
2157  return;
2158  }
2159 
2160  r->main->posted_requests = pr->next;
2161 
2162  r = pr->request;
2163 
2164  ctx = c->log->data;
2165  ctx->current_request = r;
2166 
2168  "http posted request: \"%V?%V\"", &r->uri, &r->args);
2169 
2170  r->write_event_handler(r);
2171  }
2172 }
2173 
2174 
2175 ngx_int_t
2177 {
2179 
2180  if (pr == NULL) {
2181  pr = ngx_palloc(r->pool, sizeof(ngx_http_posted_request_t));
2182  if (pr == NULL) {
2183  return NGX_ERROR;
2184  }
2185  }
2186 
2187  pr->request = r;
2188  pr->next = NULL;
2189 
2190  for (p = &r->main->posted_requests; *p; p = &(*p)->next) { /* void */ }
2191 
2192  *p = pr;
2193 
2194  return NGX_OK;
2195 }
2196 
2197 
2198 void
2200 {
2201  ngx_connection_t *c;
2202  ngx_http_request_t *pr;
2204 
2205  c = r->connection;
2206 
2208  "http finalize request: %d, \"%V?%V\" a:%d, c:%d",
2209  rc, &r->uri, &r->args, r == c->data, r->main->count);
2210 
2211  if (rc == NGX_DONE) {
2212  ngx_http_finalize_connection(r);
2213  return;
2214  }
2215 
2216  if (rc == NGX_OK && r->filter_finalize) {
2217  c->error = 1;
2218  }
2219 
2220  if (rc == NGX_DECLINED) {
2221  r->content_handler = NULL;
2224  return;
2225  }
2226 
2227  if (r != r->main && r->post_subrequest) {
2228  rc = r->post_subrequest->handler(r, r->post_subrequest->data, rc);
2229  }
2230 
2231  if (rc == NGX_ERROR
2232  || rc == NGX_HTTP_REQUEST_TIME_OUT
2234  || c->error)
2235  {
2236  if (ngx_http_post_action(r) == NGX_OK) {
2237  return;
2238  }
2239 
2240  if (r->main->blocked) {
2241  r->write_event_handler = ngx_http_request_finalizer;
2242  }
2243 
2244  ngx_http_terminate_request(r, rc);
2245  return;
2246  }
2247 
2248  if (rc >= NGX_HTTP_SPECIAL_RESPONSE
2249  || rc == NGX_HTTP_CREATED
2250  || rc == NGX_HTTP_NO_CONTENT)
2251  {
2252  if (rc == NGX_HTTP_CLOSE) {
2253  ngx_http_terminate_request(r, rc);
2254  return;
2255  }
2256 
2257  if (r == r->main) {
2258  if (c->read->timer_set) {
2259  ngx_del_timer(c->read);
2260  }
2261 
2262  if (c->write->timer_set) {
2263  ngx_del_timer(c->write);
2264  }
2265  }
2266 
2267  c->read->handler = ngx_http_request_handler;
2268  c->write->handler = ngx_http_request_handler;
2269 
2271  return;
2272  }
2273 
2274  if (r != r->main) {
2275 
2276  if (r->buffered || r->postponed) {
2277 
2278  if (ngx_http_set_write_handler(r) != NGX_OK) {
2279  ngx_http_terminate_request(r, 0);
2280  }
2281 
2282  return;
2283  }
2284 
2285  pr = r->parent;
2286 
2287  if (r == c->data) {
2288 
2289  r->main->count--;
2290  r->main->subrequests++;
2291 
2292  if (!r->logged) {
2293 
2295 
2296  if (clcf->log_subrequest) {
2297  ngx_http_log_request(r);
2298  }
2299 
2300  r->logged = 1;
2301 
2302  } else {
2304  "subrequest: \"%V?%V\" logged again",
2305  &r->uri, &r->args);
2306  }
2307 
2308  r->done = 1;
2309 
2310  if (pr->postponed && pr->postponed->request == r) {
2311  pr->postponed = pr->postponed->next;
2312  }
2313 
2314  c->data = pr;
2315 
2316  } else {
2317 
2319  "http finalize non-active request: \"%V?%V\"",
2320  &r->uri, &r->args);
2321 
2322  r->write_event_handler = ngx_http_request_finalizer;
2323 
2324  if (r->waited) {
2325  r->done = 1;
2326  }
2327  }
2328 
2329  if (ngx_http_post_request(pr, NULL) != NGX_OK) {
2330  r->main->count++;
2331  ngx_http_terminate_request(r, 0);
2332  return;
2333  }
2334 
2336  "http wake parent request: \"%V?%V\"",
2337  &pr->uri, &pr->args);
2338 
2339  return;
2340  }
2341 
2342  if (r->buffered || c->buffered || r->postponed || r->blocked) {
2343 
2344  if (ngx_http_set_write_handler(r) != NGX_OK) {
2345  ngx_http_terminate_request(r, 0);
2346  }
2347 
2348  return;
2349  }
2350 
2351  if (r != c->data) {
2353  "http finalize non-active request: \"%V?%V\"",
2354  &r->uri, &r->args);
2355  return;
2356  }
2357 
2358  r->done = 1;
2360 
2361  if (!r->post_action) {
2362  r->request_complete = 1;
2363  }
2364 
2365  if (ngx_http_post_action(r) == NGX_OK) {
2366  return;
2367  }
2368 
2369  if (c->read->timer_set) {
2370  ngx_del_timer(c->read);
2371  }
2372 
2373  if (c->write->timer_set) {
2374  c->write->delayed = 0;
2375  ngx_del_timer(c->write);
2376  }
2377 
2378  if (c->read->eof) {
2379  ngx_http_close_request(r, 0);
2380  return;
2381  }
2382 
2383  ngx_http_finalize_connection(r);
2384 }
2385 
2386 
2387 static void
2388 ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc)
2389 {
2390  ngx_http_cleanup_t *cln;
2391  ngx_http_request_t *mr;
2393 
2394  mr = r->main;
2395 
2397  "http terminate request count:%d", mr->count);
2398 
2399  if (rc > 0 && (mr->headers_out.status == 0 || mr->connection->sent == 0)) {
2400  mr->headers_out.status = rc;
2401  }
2402 
2403  cln = mr->cleanup;
2404  mr->cleanup = NULL;
2405 
2406  while (cln) {
2407  if (cln->handler) {
2408  cln->handler(cln->data);
2409  }
2410 
2411  cln = cln->next;
2412  }
2413 
2415  "http terminate cleanup count:%d blk:%d",
2416  mr->count, mr->blocked);
2417 
2418  if (mr->write_event_handler) {
2419 
2420  if (mr->blocked) {
2421  return;
2422  }
2423 
2424  e = ngx_http_ephemeral(mr);
2425  mr->posted_requests = NULL;
2426  mr->write_event_handler = ngx_http_terminate_handler;
2428  return;
2429  }
2430 
2431  ngx_http_close_request(mr, rc);
2432 }
2433 
2434 
2435 static void
2436 ngx_http_terminate_handler(ngx_http_request_t *r)
2437 {
2439  "http terminate handler count:%d", r->count);
2440 
2441  r->count = 1;
2442 
2443  ngx_http_close_request(r, 0);
2444 }
2445 
2446 
2447 static void
2448 ngx_http_finalize_connection(ngx_http_request_t *r)
2449 {
2451 
2452 #if (NGX_HTTP_SPDY)
2453  if (r->spdy_stream) {
2454  ngx_http_close_request(r, 0);
2455  return;
2456  }
2457 #endif
2458 
2460 
2461  if (r->main->count != 1) {
2462 
2463  if (r->discard_body) {
2466 
2467  if (r->lingering_time == 0) {
2468  r->lingering_time = ngx_time()
2469  + (time_t) (clcf->lingering_time / 1000);
2470  }
2471  }
2472 
2473  ngx_http_close_request(r, 0);
2474  return;
2475  }
2476 
2477  if (!ngx_terminate
2478  && !ngx_exiting
2479  && r->keepalive
2480  && clcf->keepalive_timeout > 0)
2481  {
2482  ngx_http_set_keepalive(r);
2483  return;
2484  }
2485 
2488  && (r->lingering_close
2489  || r->header_in->pos < r->header_in->last
2490  || r->connection->read->ready)))
2491  {
2492  ngx_http_set_lingering_close(r);
2493  return;
2494  }
2495 
2496  ngx_http_close_request(r, 0);
2497 }
2498 
2499 
2500 static ngx_int_t
2501 ngx_http_set_write_handler(ngx_http_request_t *r)
2502 {
2503  ngx_event_t *wev;
2505 
2507 
2511  r->write_event_handler = ngx_http_writer;
2512 
2513 #if (NGX_HTTP_SPDY)
2514  if (r->spdy_stream) {
2515  return NGX_OK;
2516  }
2517 #endif
2518 
2519  wev = r->connection->write;
2520 
2521  if (wev->ready && wev->delayed) {
2522  return NGX_OK;
2523  }
2524 
2526  if (!wev->delayed) {
2527  ngx_add_timer(wev, clcf->send_timeout);
2528  }
2529 
2530  if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
2531  ngx_http_close_request(r, 0);
2532  return NGX_ERROR;
2533  }
2534 
2535  return NGX_OK;
2536 }
2537 
2538 
2539 static void
2540 ngx_http_writer(ngx_http_request_t *r)
2541 {
2542  int rc;
2543  ngx_event_t *wev;
2544  ngx_connection_t *c;
2546 
2547  c = r->connection;
2548  wev = c->write;
2549 
2551  "http writer handler: \"%V?%V\"", &r->uri, &r->args);
2552 
2554 
2555  if (wev->timedout) {
2556  if (!wev->delayed) {
2558  "client timed out");
2559  c->timedout = 1;
2560 
2562  return;
2563  }
2564 
2565  wev->timedout = 0;
2566  wev->delayed = 0;
2567 
2568  if (!wev->ready) {
2569  ngx_add_timer(wev, clcf->send_timeout);
2570 
2571  if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
2572  ngx_http_close_request(r, 0);
2573  }
2574 
2575  return;
2576  }
2577 
2578  }
2579 
2580  if (wev->delayed || r->aio) {
2582  "http writer delayed");
2583 
2584  if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
2585  ngx_http_close_request(r, 0);
2586  }
2587 
2588  return;
2589  }
2590 
2591  rc = ngx_http_output_filter(r, NULL);
2592 
2594  "http writer output filter: %d, \"%V?%V\"",
2595  rc, &r->uri, &r->args);
2596 
2597  if (rc == NGX_ERROR) {
2599  return;
2600  }
2601 
2602  if (r->buffered || r->postponed || (r == r->main && c->buffered)) {
2603 
2604  if (!wev->delayed) {
2605  ngx_add_timer(wev, clcf->send_timeout);
2606  }
2607 
2608  if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
2609  ngx_http_close_request(r, 0);
2610  }
2611 
2612  return;
2613  }
2614 
2616  "http writer done: \"%V?%V\"", &r->uri, &r->args);
2617 
2619 
2621 }
2622 
2623 
2624 static void
2625 ngx_http_request_finalizer(ngx_http_request_t *r)
2626 {
2628  "http finalizer done: \"%V?%V\"", &r->uri, &r->args);
2629 
2631 }
2632 
2633 
2634 void
2636 {
2638  "http reading blocked");
2639 
2640  /* aio does not call this handler */
2641 
2643  && r->connection->read->active)
2644  {
2646  ngx_http_close_request(r, 0);
2647  }
2648  }
2649 }
2650 
2651 
2652 void
2654 {
2655  int n;
2656  char buf[1];
2657  ngx_err_t err;
2658  ngx_event_t *rev;
2659  ngx_connection_t *c;
2660 
2661  c = r->connection;
2662  rev = c->read;
2663 
2664  ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http test reading");
2665 
2666 #if (NGX_HTTP_SPDY)
2667 
2668  if (r->spdy_stream) {
2669  if (c->error) {
2670  err = 0;
2671  goto closed;
2672  }
2673 
2674  return;
2675  }
2676 
2677 #endif
2678 
2679 #if (NGX_HAVE_KQUEUE)
2680 
2682 
2683  if (!rev->pending_eof) {
2684  return;
2685  }
2686 
2687  rev->eof = 1;
2688  c->error = 1;
2689  err = rev->kq_errno;
2690 
2691  goto closed;
2692  }
2693 
2694 #endif
2695 
2696  n = recv(c->fd, buf, 1, MSG_PEEK);
2697 
2698  if (n == 0) {
2699  rev->eof = 1;
2700  c->error = 1;
2701  err = 0;
2702 
2703  goto closed;
2704 
2705  } else if (n == -1) {
2706  err = ngx_socket_errno;
2707 
2708  if (err != NGX_EAGAIN) {
2709  rev->eof = 1;
2710  c->error = 1;
2711 
2712  goto closed;
2713  }
2714  }
2715 
2716  /* aio does not call this handler */
2717 
2718  if ((ngx_event_flags & NGX_USE_LEVEL_EVENT) && rev->active) {
2719 
2720  if (ngx_del_event(rev, NGX_READ_EVENT, 0) != NGX_OK) {
2721  ngx_http_close_request(r, 0);
2722  }
2723  }
2724 
2725  return;
2726 
2727 closed:
2728 
2729  if (err) {
2730  rev->error = 1;
2731  }
2732 
2733  ngx_log_error(NGX_LOG_INFO, c->log, err,
2734  "client prematurely closed connection");
2735 
2737 }
2738 
2739 
2740 static void
2741 ngx_http_set_keepalive(ngx_http_request_t *r)
2742 {
2743  int tcp_nodelay;
2744  ngx_int_t i;
2745  ngx_buf_t *b, *f;
2746  ngx_event_t *rev, *wev;
2747  ngx_connection_t *c;
2751 
2752  c = r->connection;
2753  rev = c->read;
2754 
2756 
2757  ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "set http keepalive handler");
2758 
2759  if (r->discard_body) {
2761  r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000);
2762  ngx_add_timer(rev, clcf->lingering_timeout);
2763  return;
2764  }
2765 
2766  c->log->action = "closing request";
2767 
2768  hc = r->http_connection;
2769  b = r->header_in;
2770 
2771  if (b->pos < b->last) {
2772 
2773  /* the pipelined request */
2774 
2775  if (b != c->buffer) {
2776 
2777  /*
2778  * If the large header buffers were allocated while the previous
2779  * request processing then we do not use c->buffer for
2780  * the pipelined request (see ngx_http_create_request()).
2781  *
2782  * Now we would move the large header buffers to the free list.
2783  */
2784 
2786 
2787  if (hc->free == NULL) {
2788  hc->free = ngx_palloc(c->pool,
2789  cscf->large_client_header_buffers.num * sizeof(ngx_buf_t *));
2790 
2791  if (hc->free == NULL) {
2792  ngx_http_close_request(r, 0);
2793  return;
2794  }
2795  }
2796 
2797  for (i = 0; i < hc->nbusy - 1; i++) {
2798  f = hc->busy[i];
2799  hc->free[hc->nfree++] = f;
2800  f->pos = f->start;
2801  f->last = f->start;
2802  }
2803 
2804  hc->busy[0] = b;
2805  hc->nbusy = 1;
2806  }
2807  }
2808 
2809  /* guard against recursive call from ngx_http_finalize_connection() */
2810  r->keepalive = 0;
2811 
2812  ngx_http_free_request(r, 0);
2813 
2814  c->data = hc;
2815 
2816  if (ngx_handle_read_event(rev, 0) != NGX_OK) {
2818  return;
2819  }
2820 
2821  wev = c->write;
2823 
2824  if (b->pos < b->last) {
2825 
2826  ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "pipelined request");
2827 
2828  c->log->action = "reading client pipelined request line";
2829 
2830  r = ngx_http_create_request(c);
2831  if (r == NULL) {
2833  return;
2834  }
2835 
2836  r->pipeline = 1;
2837 
2838  c->data = r;
2839 
2840  c->sent = 0;
2841  c->destroyed = 0;
2842 
2843  if (rev->timer_set) {
2844  ngx_del_timer(rev);
2845  }
2846 
2847  rev->handler = ngx_http_process_request_line;
2849  return;
2850  }
2851 
2852  /*
2853  * To keep a memory footprint as small as possible for an idle keepalive
2854  * connection we try to free c->buffer's memory if it was allocated outside
2855  * the c->pool. The large header buffers are always allocated outside the
2856  * c->pool and are freed too.
2857  */
2858 
2859  b = c->buffer;
2860 
2861  if (ngx_pfree(c->pool, b->start) == NGX_OK) {
2862 
2863  /*
2864  * the special note for ngx_http_keepalive_handler() that
2865  * c->buffer's memory was freed
2866  */
2867 
2868  b->pos = NULL;
2869 
2870  } else {
2871  b->pos = b->start;
2872  b->last = b->start;
2873  }
2874 
2875  ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc free: %p %d",
2876  hc->free, hc->nfree);
2877 
2878  if (hc->free) {
2879  for (i = 0; i < hc->nfree; i++) {
2880  ngx_pfree(c->pool, hc->free[i]->start);
2881  hc->free[i] = NULL;
2882  }
2883 
2884  hc->nfree = 0;
2885  }
2886 
2887  ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc busy: %p %d",
2888  hc->busy, hc->nbusy);
2889 
2890  if (hc->busy) {
2891  for (i = 0; i < hc->nbusy; i++) {
2892  ngx_pfree(c->pool, hc->busy[i]->start);
2893  hc->busy[i] = NULL;
2894  }
2895 
2896  hc->nbusy = 0;
2897  }
2898 
2899 #if (NGX_HTTP_SSL)
2900  if (c->ssl) {
2902  }
2903 #endif
2904 
2905  rev->handler = ngx_http_keepalive_handler;
2906 
2907  if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
2908  if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) != NGX_OK) {
2910  return;
2911  }
2912  }
2913 
2914  c->log->action = "keepalive";
2915 
2916  if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
2917  if (ngx_tcp_push(c->fd) == -1) {
2920  return;
2921  }
2922 
2924  tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0;
2925 
2926  } else {
2927  tcp_nodelay = 1;
2928  }
2929 
2930  if (tcp_nodelay
2931  && clcf->tcp_nodelay
2933  {
2934  ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
2935 
2936  if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
2937  (const void *) &tcp_nodelay, sizeof(int))
2938  == -1)
2939  {
2940 #if (NGX_SOLARIS)
2941  /* Solaris returns EINVAL if a socket has been shut down */
2943 #endif
2944 
2946  "setsockopt(TCP_NODELAY) failed");
2947 
2950  return;
2951  }
2952 
2954  }
2955 
2956 #if 0
2957  /* if ngx_http_request_t was freed then we need some other place */
2959 #endif
2960 
2961  c->idle = 1;
2963 
2964  ngx_add_timer(rev, clcf->keepalive_timeout);
2965 
2966  if (rev->ready) {
2968  }
2969 }
2970 
2971 
2972 static void
2973 ngx_http_keepalive_handler(ngx_event_t *rev)
2974 {
2975  size_t size;
2976  ssize_t n;
2977  ngx_buf_t *b;
2978  ngx_connection_t *c;
2979 
2980  c = rev->data;
2981 
2982  ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http keepalive handler");
2983 
2984  if (rev->timedout || c->close) {
2986  return;
2987  }
2988 
2989 #if (NGX_HAVE_KQUEUE)
2990 
2992  if (rev->pending_eof) {
2993  c->log->handler = NULL;
2994  ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno,
2995  "kevent() reported that client %V closed "
2996  "keepalive connection", &c->addr_text);
2997 #if (NGX_HTTP_SSL)
2998  if (c->ssl) {
2999  c->ssl->no_send_shutdown = 1;
3000  }
3001 #endif
3003  return;
3004  }
3005  }
3006 
3007 #endif
3008 
3009  b = c->buffer;
3010  size = b->end - b->start;
3011 
3012  if (b->pos == NULL) {
3013 
3014  /*
3015  * The c->buffer's memory was freed by ngx_http_set_keepalive().
3016  * However, the c->buffer->start and c->buffer->end were not changed
3017  * to keep the buffer size.
3018  */
3019 
3020  b->pos = ngx_palloc(c->pool, size);
3021  if (b->pos == NULL) {
3023  return;
3024  }
3025 
3026  b->start = b->pos;
3027  b->last = b->pos;
3028  b->end = b->pos + size;
3029  }
3030 
3031  /*
3032  * MSIE closes a keepalive connection with RST flag
3033  * so we ignore ECONNRESET here.
3034  */
3035 
3038 
3039  n = c->recv(c, b->last, size);
3041 
3042  if (n == NGX_AGAIN) {
3043  if (ngx_handle_read_event(rev, 0) != NGX_OK) {
3045  return;
3046  }
3047 
3048  /*
3049  * Like ngx_http_set_keepalive() we are trying to not hold
3050  * c->buffer's memory for a keepalive connection.
3051  */
3052 
3053  if (ngx_pfree(c->pool, b->start) == NGX_OK) {
3054 
3055  /*
3056  * the special note that c->buffer's memory was freed
3057  */
3058 
3059  b->pos = NULL;
3060  }
3061 
3062  return;
3063  }
3064 
3065  if (n == NGX_ERROR) {
3067  return;
3068  }
3069 
3070  c->log->handler = NULL;
3071 
3072  if (n == 0) {
3074  "client %V closed keepalive connection", &c->addr_text);
3076  return;
3077  }
3078 
3079  b->last += n;
3080 
3081  c->log->handler = ngx_http_log_error;
3082  c->log->action = "reading client request line";
3083 
3084  c->idle = 0;
3086 
3087  c->data = ngx_http_create_request(c);
3088  if (c->data == NULL) {
3090  return;
3091  }
3092 
3093  c->sent = 0;
3094  c->destroyed = 0;
3095 
3096  ngx_del_timer(rev);
3097 
3098  rev->handler = ngx_http_process_request_line;
3099  ngx_http_process_request_line(rev);
3100 }
3101 
3102 
3103 static void
3104 ngx_http_set_lingering_close(ngx_http_request_t *r)
3105 {
3106  ngx_event_t *rev, *wev;
3107  ngx_connection_t *c;
3109 
3110  c = r->connection;
3111 
3113 
3114  rev = c->read;
3115  rev->handler = ngx_http_lingering_close_handler;
3116 
3117  r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000);
3118  ngx_add_timer(rev, clcf->lingering_timeout);
3119 
3120  if (ngx_handle_read_event(rev, 0) != NGX_OK) {
3121  ngx_http_close_request(r, 0);
3122  return;
3123  }
3124 
3125  wev = c->write;
3127 
3128  if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
3129  if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) != NGX_OK) {
3130  ngx_http_close_request(r, 0);
3131  return;
3132  }
3133  }
3134 
3135  if (ngx_shutdown_socket(c->fd, NGX_WRITE_SHUTDOWN) == -1) {
3137  ngx_shutdown_socket_n " failed");
3138  ngx_http_close_request(r, 0);
3139  return;
3140  }
3141 
3142  if (rev->ready) {
3143  ngx_http_lingering_close_handler(rev);
3144  }
3145 }
3146 
3147 
3148 static void
3149 ngx_http_lingering_close_handler(ngx_event_t *rev)
3150 {
3151  ssize_t n;
3152  ngx_msec_t timer;
3153  ngx_connection_t *c;
3154  ngx_http_request_t *r;
3157 
3158  c = rev->data;
3159  r = c->data;
3160 
3162  "http lingering close handler");
3163 
3164  if (rev->timedout) {
3165  ngx_http_close_request(r, 0);
3166  return;
3167  }
3168 
3169  timer = (ngx_msec_t) (r->lingering_time - ngx_time());
3170  if (timer <= 0) {
3171  ngx_http_close_request(r, 0);
3172  return;
3173  }
3174 
3175  do {
3176  n = c->recv(c, buffer, NGX_HTTP_LINGERING_BUFFER_SIZE);
3177 
3178  ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "lingering read: %d", n);
3179 
3180  if (n == NGX_ERROR || n == 0) {
3181  ngx_http_close_request(r, 0);
3182  return;
3183  }
3184 
3185  } while (rev->ready);
3186 
3187  if (ngx_handle_read_event(rev, 0) != NGX_OK) {
3188  ngx_http_close_request(r, 0);
3189  return;
3190  }
3191 
3193 
3194  timer *= 1000;
3195 
3196  if (timer > clcf->lingering_timeout) {
3197  timer = clcf->lingering_timeout;
3198  }
3199 
3200  ngx_add_timer(rev, timer);
3201 }
3202 
3203 
3204 void
3206 {
3207  ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, "http empty handler");
3208 
3209  return;
3210 }
3211 
3212 
3213 void
3215 {
3217  "http request empty handler");
3218 
3219  return;
3220 }
3221 
3222 
3223 ngx_int_t
3225 {
3226  ngx_buf_t *b;
3227  ngx_chain_t out;
3228 
3229  b = ngx_calloc_buf(r->pool);
3230  if (b == NULL) {
3231  return NGX_ERROR;
3232  }
3233 
3234  if (flags & NGX_HTTP_LAST) {
3235 
3236  if (r == r->main && !r->post_action) {
3237  b->last_buf = 1;
3238 
3239  } else {
3240  b->sync = 1;
3241  b->last_in_chain = 1;
3242  }
3243  }
3244 
3245  if (flags & NGX_HTTP_FLUSH) {
3246  b->flush = 1;
3247  }
3248 
3249  out.buf = b;
3250  out.next = NULL;
3251 
3252  return ngx_http_output_filter(r, &out);
3253 }
3254 
3255 
3256 static ngx_int_t
3257 ngx_http_post_action(ngx_http_request_t *r)
3258 {
3260 
3262 
3263  if (clcf->post_action.data == NULL) {
3264  return NGX_DECLINED;
3265  }
3266 
3267  if (r->post_action && r->uri_changes == 0) {
3268  return NGX_DECLINED;
3269  }
3270 
3272  "post action: \"%V\"", &clcf->post_action);
3273 
3274  r->main->count--;
3275 
3277  r->header_only = 1;
3278  r->post_action = 1;
3279 
3281 
3282  if (clcf->post_action.data[0] == '/') {
3283  ngx_http_internal_redirect(r, &clcf->post_action, NULL);
3284 
3285  } else {
3287  }
3288 
3289  return NGX_OK;
3290 }
3291 
3292 
3293 static void
3294 ngx_http_close_request(ngx_http_request_t *r, ngx_int_t rc)
3295 {
3296  ngx_connection_t *c;
3297 
3298  r = r->main;
3299  c = r->connection;
3300 
3302  "http request count:%d blk:%d", r->count, r->blocked);
3303 
3304  if (r->count == 0) {
3305  ngx_log_error(NGX_LOG_ALERT, c->log, 0, "http request count is zero");
3306  }
3307 
3308  r->count--;
3309 
3310  if (r->count || r->blocked) {
3311  return;
3312  }
3313 
3314 #if (NGX_HTTP_SPDY)
3315  if (r->spdy_stream) {
3316  ngx_http_spdy_close_stream(r->spdy_stream, rc);
3317  return;
3318  }
3319 #endif
3320 
3321  ngx_http_free_request(r, rc);
3323 }
3324 
3325 
3326 void
3328 {
3329  ngx_log_t *log;
3330  ngx_pool_t *pool;
3331  struct linger linger;
3332  ngx_http_cleanup_t *cln;
3333  ngx_http_log_ctx_t *ctx;
3335 
3336  log = r->connection->log;
3337 
3338  ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0, "http close request");
3339 
3340  if (r->pool == NULL) {
3341  ngx_log_error(NGX_LOG_ALERT, log, 0, "http request already closed");
3342  return;
3343  }
3344 
3345  for (cln = r->cleanup; cln; cln = cln->next) {
3346  if (cln->handler) {
3347  cln->handler(cln->data);
3348  }
3349  }
3350 
3351 #if (NGX_STAT_STUB)
3352 
3353  if (r->stat_reading) {
3354  (void) ngx_atomic_fetch_add(ngx_stat_reading, -1);
3355  }
3356 
3357  if (r->stat_writing) {
3358  (void) ngx_atomic_fetch_add(ngx_stat_writing, -1);
3359  }
3360 
3361 #endif
3362 
3363  if (rc > 0 && (r->headers_out.status == 0 || r->connection->sent == 0)) {
3364  r->headers_out.status = rc;
3365  }
3366 
3367  log->action = "logging request";
3368 
3369  ngx_http_log_request(r);
3370 
3371  log->action = "closing request";
3372 
3373  if (r->connection->timedout) {
3375 
3376  if (clcf->reset_timedout_connection) {
3377  linger.l_onoff = 1;
3378  linger.l_linger = 0;
3379 
3380  if (setsockopt(r->connection->fd, SOL_SOCKET, SO_LINGER,
3381  (const void *) &linger, sizeof(struct linger)) == -1)
3382  {
3384  "setsockopt(SO_LINGER) failed");
3385  }
3386  }
3387  }
3388 
3389  /* the various request strings were allocated from r->pool */
3390  ctx = log->data;
3391  ctx->request = NULL;
3392 
3393  r->request_line.len = 0;
3394 
3395  r->connection->destroyed = 1;
3396 
3397  /*
3398  * Setting r->pool to NULL will increase probability to catch double close
3399  * of request since the request object is allocated from its own pool.
3400  */
3401 
3402  pool = r->pool;
3403  r->pool = NULL;
3404 
3405  ngx_destroy_pool(pool);
3406 }
3407 
3408 
3409 static void
3410 ngx_http_log_request(ngx_http_request_t *r)
3411 {
3412  ngx_uint_t i, n;
3413  ngx_http_handler_pt *log_handler;
3415 
3417 
3418  log_handler = cmcf->phases[NGX_HTTP_LOG_PHASE].handlers.elts;
3420 
3421  for (i = 0; i < n; i++) {
3422  log_handler[i](r);
3423  }
3424 }
3425 
3426 
3427 void
3429 {
3430  ngx_pool_t *pool;
3431 
3433  "close http connection: %d", c->fd);
3434 
3435 #if (NGX_HTTP_SSL)
3436 
3437  if (c->ssl) {
3438  if (ngx_ssl_shutdown(c) == NGX_AGAIN) {
3439  c->ssl->handler = ngx_http_close_connection;
3440  return;
3441  }
3442  }
3443 
3444 #endif
3445 
3446 #if (NGX_STAT_STUB)
3447  (void) ngx_atomic_fetch_add(ngx_stat_active, -1);
3448 #endif
3449 
3450  c->destroyed = 1;
3451 
3452  pool = c->pool;
3453 
3455 
3456  ngx_destroy_pool(pool);
3457 }
3458 
3459 
3460 static u_char *
3461 ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len)
3462 {
3463  u_char *p;
3464  ngx_http_request_t *r;
3465  ngx_http_log_ctx_t *ctx;
3466 
3467  if (log->action) {
3468  p = ngx_snprintf(buf, len, " while %s", log->action);
3469  len -= p - buf;
3470  buf = p;
3471  }
3472 
3473  ctx = log->data;
3474 
3475  p = ngx_snprintf(buf, len, ", client: %V", &ctx->connection->addr_text);
3476  len -= p - buf;
3477 
3478  r = ctx->request;
3479 
3480  if (r) {
3481  return r->log_handler(r, ctx->current_request, p, len);
3482 
3483  } else {
3484  p = ngx_snprintf(p, len, ", server: %V",
3485  &ctx->connection->listening->addr_text);
3486  }
3487 
3488  return p;
3489 }
3490 
3491 
3492 static u_char *
3493 ngx_http_log_error_handler(ngx_http_request_t *r, ngx_http_request_t *sr,
3494  u_char *buf, size_t len)
3495 {
3496  char *uri_separator;
3497  u_char *p;
3500 
3502 
3503  p = ngx_snprintf(buf, len, ", server: %V", &cscf->server_name);
3504  len -= p - buf;
3505  buf = p;
3506 
3507  if (r->request_line.data == NULL && r->request_start) {
3508  for (p = r->request_start; p < r->header_in->last; p++) {
3509  if (*p == CR || *p == LF) {
3510  break;
3511  }
3512  }
3513 
3514  r->request_line.len = p - r->request_start;
3516  }
3517 
3518  if (r->request_line.len) {
3519  p = ngx_snprintf(buf, len, ", request: \"%V\"", &r->request_line);
3520  len -= p - buf;
3521  buf = p;
3522  }
3523 
3524  if (r != sr) {
3525  p = ngx_snprintf(buf, len, ", subrequest: \"%V\"", &sr->uri);
3526  len -= p - buf;
3527  buf = p;
3528  }
3529 
3530  u = sr->upstream;
3531 
3532  if (u && u->peer.name) {
3533 
3534  uri_separator = "";
3535 
3536 #if (NGX_HAVE_UNIX_DOMAIN)
3537  if (u->peer.sockaddr && u->peer.sockaddr->sa_family == AF_UNIX) {
3538  uri_separator = ":";
3539  }
3540 #endif
3541 
3542  p = ngx_snprintf(buf, len, ", upstream: \"%V%V%s%V\"",
3543  &u->schema, u->peer.name,
3544  uri_separator, &u->uri);
3545  len -= p - buf;
3546  buf = p;
3547  }
3548 
3549  if (r->headers_in.host) {
3550  p = ngx_snprintf(buf, len, ", host: \"%V\"",
3551  &r->headers_in.host->value);
3552  len -= p - buf;
3553  buf = p;
3554  }
3555 
3556  if (r->headers_in.referer) {
3557  p = ngx_snprintf(buf, len, ", referrer: \"%V\"",
3558  &r->headers_in.referer->value);
3559  buf = p;
3560  }
3561 
3562  return buf;
3563 }