src/http/ngx_http_request.c - nginx-1.7.10

Global variables defined

Functions defined

Source code


  1. /*
  2. * Copyright (C) Igor Sysoev
  3. * Copyright (C) Nginx, Inc.
  4. */


  5. #include <ngx_config.h>
  6. #include <ngx_core.h>
  7. #include <ngx_http.h>


  8. static void ngx_http_wait_request_handler(ngx_event_t *ev);
  9. static void ngx_http_process_request_line(ngx_event_t *rev);
  10. static void ngx_http_process_request_headers(ngx_event_t *rev);
  11. static ssize_t ngx_http_read_request_header(ngx_http_request_t *r);
  12. static ngx_int_t ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
  13.     ngx_uint_t request_line);

  14. static ngx_int_t ngx_http_process_header_line(ngx_http_request_t *r,
  15.     ngx_table_elt_t *h, ngx_uint_t offset);
  16. static ngx_int_t ngx_http_process_unique_header_line(ngx_http_request_t *r,
  17.     ngx_table_elt_t *h, ngx_uint_t offset);
  18. static ngx_int_t ngx_http_process_multi_header_lines(ngx_http_request_t *r,
  19.     ngx_table_elt_t *h, ngx_uint_t offset);
  20. static ngx_int_t ngx_http_process_host(ngx_http_request_t *r,
  21.     ngx_table_elt_t *h, ngx_uint_t offset);
  22. static ngx_int_t ngx_http_process_connection(ngx_http_request_t *r,
  23.     ngx_table_elt_t *h, ngx_uint_t offset);
  24. static ngx_int_t ngx_http_process_user_agent(ngx_http_request_t *r,
  25.     ngx_table_elt_t *h, ngx_uint_t offset);

  26. static ngx_int_t ngx_http_validate_host(ngx_str_t *host, ngx_pool_t *pool,
  27.     ngx_uint_t alloc);
  28. static ngx_int_t ngx_http_set_virtual_server(ngx_http_request_t *r,
  29.     ngx_str_t *host);
  30. static ngx_int_t ngx_http_find_virtual_server(ngx_connection_t *c,
  31.     ngx_http_virtual_names_t *virtual_names, ngx_str_t *host,
  32.     ngx_http_request_t *r, ngx_http_core_srv_conf_t **cscfp);

  33. static void ngx_http_request_handler(ngx_event_t *ev);
  34. static void ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc);
  35. static void ngx_http_terminate_handler(ngx_http_request_t *r);
  36. static void ngx_http_finalize_connection(ngx_http_request_t *r);
  37. static ngx_int_t ngx_http_set_write_handler(ngx_http_request_t *r);
  38. static void ngx_http_writer(ngx_http_request_t *r);
  39. static void ngx_http_request_finalizer(ngx_http_request_t *r);

  40. static void ngx_http_set_keepalive(ngx_http_request_t *r);
  41. static void ngx_http_keepalive_handler(ngx_event_t *ev);
  42. static void ngx_http_set_lingering_close(ngx_http_request_t *r);
  43. static void ngx_http_lingering_close_handler(ngx_event_t *ev);
  44. static ngx_int_t ngx_http_post_action(ngx_http_request_t *r);
  45. static void ngx_http_close_request(ngx_http_request_t *r, ngx_int_t error);
  46. static void ngx_http_log_request(ngx_http_request_t *r);

  47. static u_char *ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len);
  48. static u_char *ngx_http_log_error_handler(ngx_http_request_t *r,
  49.     ngx_http_request_t *sr, u_char *buf, size_t len);

  50. #if (NGX_HTTP_SSL)
  51. static void ngx_http_ssl_handshake(ngx_event_t *rev);
  52. static void ngx_http_ssl_handshake_handler(ngx_connection_t *c);
  53. #endif


  54. static char *ngx_http_client_errors[] = {

  55.     /* NGX_HTTP_PARSE_INVALID_METHOD */
  56.     "client sent invalid method",

  57.     /* NGX_HTTP_PARSE_INVALID_REQUEST */
  58.     "client sent invalid request",

  59.     /* NGX_HTTP_PARSE_INVALID_09_METHOD */
  60.     "client sent invalid method in HTTP/0.9 request"
  61. };


  62. ngx_http_header_t  ngx_http_headers_in[] = {
  63.     { ngx_string("Host"), offsetof(ngx_http_headers_in_t, host),
  64.                  ngx_http_process_host },

  65.     { ngx_string("Connection"), offsetof(ngx_http_headers_in_t, connection),
  66.                  ngx_http_process_connection },

  67.     { ngx_string("If-Modified-Since"),
  68.                  offsetof(ngx_http_headers_in_t, if_modified_since),
  69.                  ngx_http_process_unique_header_line },

  70.     { ngx_string("If-Unmodified-Since"),
  71.                  offsetof(ngx_http_headers_in_t, if_unmodified_since),
  72.                  ngx_http_process_unique_header_line },

  73.     { ngx_string("If-Match"),
  74.                  offsetof(ngx_http_headers_in_t, if_match),
  75.                  ngx_http_process_unique_header_line },

  76.     { ngx_string("If-None-Match"),
  77.                  offsetof(ngx_http_headers_in_t, if_none_match),
  78.                  ngx_http_process_unique_header_line },

  79.     { ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent),
  80.                  ngx_http_process_user_agent },

  81.     { ngx_string("Referer"), offsetof(ngx_http_headers_in_t, referer),
  82.                  ngx_http_process_header_line },

  83.     { ngx_string("Content-Length"),
  84.                  offsetof(ngx_http_headers_in_t, content_length),
  85.                  ngx_http_process_unique_header_line },

  86.     { ngx_string("Content-Type"),
  87.                  offsetof(ngx_http_headers_in_t, content_type),
  88.                  ngx_http_process_header_line },

  89.     { ngx_string("Range"), offsetof(ngx_http_headers_in_t, range),
  90.                  ngx_http_process_header_line },

  91.     { ngx_string("If-Range"),
  92.                  offsetof(ngx_http_headers_in_t, if_range),
  93.                  ngx_http_process_unique_header_line },

  94.     { ngx_string("Transfer-Encoding"),
  95.                  offsetof(ngx_http_headers_in_t, transfer_encoding),
  96.                  ngx_http_process_header_line },

  97.     { ngx_string("Expect"),
  98.                  offsetof(ngx_http_headers_in_t, expect),
  99.                  ngx_http_process_unique_header_line },

  100.     { ngx_string("Upgrade"),
  101.                  offsetof(ngx_http_headers_in_t, upgrade),
  102.                  ngx_http_process_header_line },

  103. #if (NGX_HTTP_GZIP)
  104.     { ngx_string("Accept-Encoding"),
  105.                  offsetof(ngx_http_headers_in_t, accept_encoding),
  106.                  ngx_http_process_header_line },

  107.     { ngx_string("Via"), offsetof(ngx_http_headers_in_t, via),
  108.                  ngx_http_process_header_line },
  109. #endif

  110.     { ngx_string("Authorization"),
  111.                  offsetof(ngx_http_headers_in_t, authorization),
  112.                  ngx_http_process_unique_header_line },

  113.     { ngx_string("Keep-Alive"), offsetof(ngx_http_headers_in_t, keep_alive),
  114.                  ngx_http_process_header_line },

  115. #if (NGX_HTTP_X_FORWARDED_FOR)
  116.     { ngx_string("X-Forwarded-For"),
  117.                  offsetof(ngx_http_headers_in_t, x_forwarded_for),
  118.                  ngx_http_process_multi_header_lines },
  119. #endif

  120. #if (NGX_HTTP_REALIP)
  121.     { ngx_string("X-Real-IP"),
  122.                  offsetof(ngx_http_headers_in_t, x_real_ip),
  123.                  ngx_http_process_header_line },
  124. #endif

  125. #if (NGX_HTTP_HEADERS)
  126.     { ngx_string("Accept"), offsetof(ngx_http_headers_in_t, accept),
  127.                  ngx_http_process_header_line },

  128.     { ngx_string("Accept-Language"),
  129.                  offsetof(ngx_http_headers_in_t, accept_language),
  130.                  ngx_http_process_header_line },
  131. #endif

  132. #if (NGX_HTTP_DAV)
  133.     { ngx_string("Depth"), offsetof(ngx_http_headers_in_t, depth),
  134.                  ngx_http_process_header_line },

  135.     { ngx_string("Destination"), offsetof(ngx_http_headers_in_t, destination),
  136.                  ngx_http_process_header_line },

  137.     { ngx_string("Overwrite"), offsetof(ngx_http_headers_in_t, overwrite),
  138.                  ngx_http_process_header_line },

  139.     { ngx_string("Date"), offsetof(ngx_http_headers_in_t, date),
  140.                  ngx_http_process_header_line },
  141. #endif

  142.     { ngx_string("Cookie"), offsetof(ngx_http_headers_in_t, cookies),
  143.                  ngx_http_process_multi_header_lines },

  144.     { ngx_null_string, 0, NULL }
  145. };


  146. void
  147. ngx_http_init_connection(ngx_connection_t *c)
  148. {
  149.     ngx_uint_t              i;
  150.     ngx_event_t            *rev;
  151.     struct sockaddr_in     *sin;
  152.     ngx_http_port_t        *port;
  153.     ngx_http_in_addr_t     *addr;
  154.     ngx_http_log_ctx_t     *ctx;
  155.     ngx_http_connection_t  *hc;
  156. #if (NGX_HAVE_INET6)
  157.     struct sockaddr_in6    *sin6;
  158.     ngx_http_in6_addr_t    *addr6;
  159. #endif

  160.     hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t));
  161.     if (hc == NULL) {
  162.         ngx_http_close_connection(c);
  163.         return;
  164.     }

  165.     c->data = hc;

  166.     /* find the server configuration for the address:port */

  167.     port = c->listening->servers;

  168.     if (port->naddrs > 1) {

  169.         /*
  170.          * there are several addresses on this port and one of them
  171.          * is an "*:port" wildcard so getsockname() in ngx_http_server_addr()
  172.          * is required to determine a server address
  173.          */

  174.         if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) {
  175.             ngx_http_close_connection(c);
  176.             return;
  177.         }

  178.         switch (c->local_sockaddr->sa_family) {

  179. #if (NGX_HAVE_INET6)
  180.         case AF_INET6:
  181.             sin6 = (struct sockaddr_in6 *) c->local_sockaddr;

  182.             addr6 = port->addrs;

  183.             /* the last address is "*" */

  184.             for (i = 0; i < port->naddrs - 1; i++) {
  185.                 if (ngx_memcmp(&addr6[i].addr6, &sin6->sin6_addr, 16) == 0) {
  186.                     break;
  187.                 }
  188.             }

  189.             hc->addr_conf = &addr6[i].conf;

  190.             break;
  191. #endif

  192.         default: /* AF_INET */
  193.             sin = (struct sockaddr_in *) c->local_sockaddr;

  194.             addr = port->addrs;

  195.             /* the last address is "*" */

  196.             for (i = 0; i < port->naddrs - 1; i++) {
  197.                 if (addr[i].addr == sin->sin_addr.s_addr) {
  198.                     break;
  199.                 }
  200.             }

  201.             hc->addr_conf = &addr[i].conf;

  202.             break;
  203.         }

  204.     } else {

  205.         switch (c->local_sockaddr->sa_family) {

  206. #if (NGX_HAVE_INET6)
  207.         case AF_INET6:
  208.             addr6 = port->addrs;
  209.             hc->addr_conf = &addr6[0].conf;
  210.             break;
  211. #endif

  212.         default: /* AF_INET */
  213.             addr = port->addrs;
  214.             hc->addr_conf = &addr[0].conf;
  215.             break;
  216.         }
  217.     }

  218.     /* the default server configuration for the address:port */
  219.     hc->conf_ctx = hc->addr_conf->default_server->ctx;

  220.     ctx = ngx_palloc(c->pool, sizeof(ngx_http_log_ctx_t));
  221.     if (ctx == NULL) {
  222.         ngx_http_close_connection(c);
  223.         return;
  224.     }

  225.     ctx->connection = c;
  226.     ctx->request = NULL;
  227.     ctx->current_request = NULL;

  228.     c->log->connection = c->number;
  229.     c->log->handler = ngx_http_log_error;
  230.     c->log->data = ctx;
  231.     c->log->action = "waiting for request";

  232.     c->log_error = NGX_ERROR_INFO;

  233.     rev = c->read;
  234.     rev->handler = ngx_http_wait_request_handler;
  235.     c->write->handler = ngx_http_empty_handler;

  236. #if (NGX_HTTP_SPDY)
  237.     if (hc->addr_conf->spdy) {
  238.         rev->handler = ngx_http_spdy_init;
  239.     }
  240. #endif

  241. #if (NGX_HTTP_SSL)
  242.     {
  243.     ngx_http_ssl_srv_conf_t  *sscf;

  244.     sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module);

  245.     if (sscf->enable || hc->addr_conf->ssl) {

  246.         c->log->action = "SSL handshaking";

  247.         if (hc->addr_conf->ssl && sscf->ssl.ctx == NULL) {
  248.             ngx_log_error(NGX_LOG_ERR, c->log, 0,
  249.                           "no \"ssl_certificate\" is defined "
  250.                           "in server listening on SSL port");
  251.             ngx_http_close_connection(c);
  252.             return;
  253.         }

  254.         hc->ssl = 1;

  255.         rev->handler = ngx_http_ssl_handshake;
  256.     }
  257.     }
  258. #endif

  259.     if (hc->addr_conf->proxy_protocol) {
  260.         hc->proxy_protocol = 1;
  261.         c->log->action = "reading PROXY protocol";
  262.     }

  263.     if (rev->ready) {
  264.         /* the deferred accept(), rtsig, aio, iocp */

  265.         if (ngx_use_accept_mutex) {
  266.             ngx_post_event(rev, &ngx_posted_events);
  267.             return;
  268.         }

  269.         rev->handler(rev);
  270.         return;
  271.     }

  272.     ngx_add_timer(rev, c->listening->post_accept_timeout);
  273.     ngx_reusable_connection(c, 1);

  274.     if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  275.         ngx_http_close_connection(c);
  276.         return;
  277.     }
  278. }


  279. static void
  280. ngx_http_wait_request_handler(ngx_event_t *rev)
  281. {
  282.     u_char                    *p;
  283.     size_t                     size;
  284.     ssize_t                    n;
  285.     ngx_buf_t                 *b;
  286.     ngx_connection_t          *c;
  287.     ngx_http_connection_t     *hc;
  288.     ngx_http_core_srv_conf_t  *cscf;

  289.     c = rev->data;

  290.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http wait request handler");

  291.     if (rev->timedout) {
  292.         ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
  293.         ngx_http_close_connection(c);
  294.         return;
  295.     }

  296.     if (c->close) {
  297.         ngx_http_close_connection(c);
  298.         return;
  299.     }

  300.     hc = c->data;
  301.     cscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_core_module);

  302.     size = cscf->client_header_buffer_size;

  303.     b = c->buffer;

  304.     if (b == NULL) {
  305.         b = ngx_create_temp_buf(c->pool, size);
  306.         if (b == NULL) {
  307.             ngx_http_close_connection(c);
  308.             return;
  309.         }

  310.         c->buffer = b;

  311.     } else if (b->start == NULL) {

  312.         b->start = ngx_palloc(c->pool, size);
  313.         if (b->start == NULL) {
  314.             ngx_http_close_connection(c);
  315.             return;
  316.         }

  317.         b->pos = b->start;
  318.         b->last = b->start;
  319.         b->end = b->last + size;
  320.     }

  321.     n = c->recv(c, b->last, size);

  322.     if (n == NGX_AGAIN) {

  323.         if (!rev->timer_set) {
  324.             ngx_add_timer(rev, c->listening->post_accept_timeout);
  325.             ngx_reusable_connection(c, 1);
  326.         }

  327.         if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  328.             ngx_http_close_connection(c);
  329.             return;
  330.         }

  331.         /*
  332.          * We are trying to not hold c->buffer's memory for an idle connection.
  333.          */

  334.         if (ngx_pfree(c->pool, b->start) == NGX_OK) {
  335.             b->start = NULL;
  336.         }

  337.         return;
  338.     }

  339.     if (n == NGX_ERROR) {
  340.         ngx_http_close_connection(c);
  341.         return;
  342.     }

  343.     if (n == 0) {
  344.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  345.                       "client closed connection");
  346.         ngx_http_close_connection(c);
  347.         return;
  348.     }

  349.     b->last += n;

  350.     if (hc->proxy_protocol) {
  351.         hc->proxy_protocol = 0;

  352.         p = ngx_proxy_protocol_parse(c, b->pos, b->last);

  353.         if (p == NULL) {
  354.             ngx_http_close_connection(c);
  355.             return;
  356.         }

  357.         b->pos = p;

  358.         if (b->pos == b->last) {
  359.             c->log->action = "waiting for request";
  360.             b->pos = b->start;
  361.             b->last = b->start;
  362.             ngx_post_event(rev, &ngx_posted_events);
  363.             return;
  364.         }
  365.     }

  366.     c->log->action = "reading client request line";

  367.     ngx_reusable_connection(c, 0);

  368.     c->data = ngx_http_create_request(c);
  369.     if (c->data == NULL) {
  370.         ngx_http_close_connection(c);
  371.         return;
  372.     }

  373.     rev->handler = ngx_http_process_request_line;
  374.     ngx_http_process_request_line(rev);
  375. }


  376. ngx_http_request_t *
  377. ngx_http_create_request(ngx_connection_t *c)
  378. {
  379.     ngx_pool_t                 *pool;
  380.     ngx_time_t                 *tp;
  381.     ngx_http_request_t         *r;
  382.     ngx_http_log_ctx_t         *ctx;
  383.     ngx_http_connection_t      *hc;
  384.     ngx_http_core_srv_conf_t   *cscf;
  385.     ngx_http_core_loc_conf_t   *clcf;
  386.     ngx_http_core_main_conf_t  *cmcf;

  387.     c->requests++;

  388.     hc = c->data;

  389.     cscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_core_module);

  390.     pool = ngx_create_pool(cscf->request_pool_size, c->log);
  391.     if (pool == NULL) {
  392.         return NULL;
  393.     }

  394.     r = ngx_pcalloc(pool, sizeof(ngx_http_request_t));
  395.     if (r == NULL) {
  396.         ngx_destroy_pool(pool);
  397.         return NULL;
  398.     }

  399.     r->pool = pool;

  400.     r->http_connection = hc;
  401.     r->signature = NGX_HTTP_MODULE;
  402.     r->connection = c;

  403.     r->main_conf = hc->conf_ctx->main_conf;
  404.     r->srv_conf = hc->conf_ctx->srv_conf;
  405.     r->loc_conf = hc->conf_ctx->loc_conf;

  406.     r->read_event_handler = ngx_http_block_reading;

  407.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  408.     ngx_http_set_connection_log(r->connection, clcf->error_log);

  409.     r->header_in = hc->nbusy ? hc->busy[0] : c->buffer;

  410.     if (ngx_list_init(&r->headers_out.headers, r->pool, 20,
  411.                       sizeof(ngx_table_elt_t))
  412.         != NGX_OK)
  413.     {
  414.         ngx_destroy_pool(r->pool);
  415.         return NULL;
  416.     }

  417.     r->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
  418.     if (r->ctx == NULL) {
  419.         ngx_destroy_pool(r->pool);
  420.         return NULL;
  421.     }

  422.     cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

  423.     r->variables = ngx_pcalloc(r->pool, cmcf->variables.nelts
  424.                                         * sizeof(ngx_http_variable_value_t));
  425.     if (r->variables == NULL) {
  426.         ngx_destroy_pool(r->pool);
  427.         return NULL;
  428.     }

  429. #if (NGX_HTTP_SSL)
  430.     if (c->ssl) {
  431.         r->main_filter_need_in_memory = 1;
  432.     }
  433. #endif

  434.     r->main = r;
  435.     r->count = 1;

  436.     tp = ngx_timeofday();
  437.     r->start_sec = tp->sec;
  438.     r->start_msec = tp->msec;

  439.     r->method = NGX_HTTP_UNKNOWN;
  440.     r->http_version = NGX_HTTP_VERSION_10;

  441.     r->headers_in.content_length_n = -1;
  442.     r->headers_in.keep_alive_n = -1;
  443.     r->headers_out.content_length_n = -1;
  444.     r->headers_out.last_modified_time = -1;

  445.     r->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1;
  446.     r->subrequests = NGX_HTTP_MAX_SUBREQUESTS + 1;

  447.     r->http_state = NGX_HTTP_READING_REQUEST_STATE;

  448.     ctx = c->log->data;
  449.     ctx->request = r;
  450.     ctx->current_request = r;
  451.     r->log_handler = ngx_http_log_error_handler;

  452. #if (NGX_STAT_STUB)
  453.     (void) ngx_atomic_fetch_add(ngx_stat_reading, 1);
  454.     r->stat_reading = 1;
  455.     (void) ngx_atomic_fetch_add(ngx_stat_requests, 1);
  456. #endif

  457.     return r;
  458. }


  459. #if (NGX_HTTP_SSL)

  460. static void
  461. ngx_http_ssl_handshake(ngx_event_t *rev)
  462. {
  463.     u_char                   *p, buf[NGX_PROXY_PROTOCOL_MAX_HEADER + 1];
  464.     size_t                    size;
  465.     ssize_t                   n;
  466.     ngx_err_t                 err;
  467.     ngx_int_t                 rc;
  468.     ngx_connection_t         *c;
  469.     ngx_http_connection_t    *hc;
  470.     ngx_http_ssl_srv_conf_t  *sscf;

  471.     c = rev->data;
  472.     hc = c->data;

  473.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0,
  474.                    "http check ssl handshake");

  475.     if (rev->timedout) {
  476.         ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
  477.         ngx_http_close_connection(c);
  478.         return;
  479.     }

  480.     if (c->close) {
  481.         ngx_http_close_connection(c);
  482.         return;
  483.     }

  484.     size = hc->proxy_protocol ? sizeof(buf) : 1;

  485.     n = recv(c->fd, (char *) buf, size, MSG_PEEK);

  486.     err = ngx_socket_errno;

  487.     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http recv(): %d", n);

  488.     if (n == -1) {
  489.         if (err == NGX_EAGAIN) {

  490.             if (!rev->timer_set) {
  491.                 ngx_add_timer(rev, c->listening->post_accept_timeout);
  492.                 ngx_reusable_connection(c, 1);
  493.             }

  494.             if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  495.                 ngx_http_close_connection(c);
  496.             }

  497.             return;
  498.         }

  499.         ngx_connection_error(c, err, "recv() failed");
  500.         ngx_http_close_connection(c);

  501.         return;
  502.     }

  503.     if (hc->proxy_protocol) {
  504.         hc->proxy_protocol = 0;

  505.         p = ngx_proxy_protocol_parse(c, buf, buf + n);

  506.         if (p == NULL) {
  507.             ngx_http_close_connection(c);
  508.             return;
  509.         }

  510.         size = p - buf;

  511.         if (c->recv(c, buf, size) != (ssize_t) size) {
  512.             ngx_http_close_connection(c);
  513.             return;
  514.         }

  515.         c->log->action = "SSL handshaking";

  516.         if (n == (ssize_t) size) {
  517.             ngx_post_event(rev, &ngx_posted_events);
  518.             return;
  519.         }

  520.         n = 1;
  521.         buf[0] = *p;
  522.     }

  523.     if (n == 1) {
  524.         if (buf[0] & 0x80 /* SSLv2 */ || buf[0] == 0x16 /* SSLv3/TLSv1 */) {
  525.             ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0,
  526.                            "https ssl handshake: 0x%02Xd", buf[0]);

  527.             sscf = ngx_http_get_module_srv_conf(hc->conf_ctx,
  528.                                                 ngx_http_ssl_module);

  529.             if (ngx_ssl_create_connection(&sscf->ssl, c, NGX_SSL_BUFFER)
  530.                 != NGX_OK)
  531.             {
  532.                 ngx_http_close_connection(c);
  533.                 return;
  534.             }

  535.             rc = ngx_ssl_handshake(c);

  536.             if (rc == NGX_AGAIN) {

  537.                 if (!rev->timer_set) {
  538.                     ngx_add_timer(rev, c->listening->post_accept_timeout);
  539.                 }

  540.                 ngx_reusable_connection(c, 0);

  541.                 c->ssl->handler = ngx_http_ssl_handshake_handler;
  542.                 return;
  543.             }

  544.             ngx_http_ssl_handshake_handler(c);

  545.             return;
  546.         }

  547.         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "plain http");

  548.         c->log->action = "waiting for request";

  549.         rev->handler = ngx_http_wait_request_handler;
  550.         ngx_http_wait_request_handler(rev);

  551.         return;
  552.     }

  553.     ngx_log_error(NGX_LOG_INFO, c->log, 0, "client closed connection");
  554.     ngx_http_close_connection(c);
  555. }


  556. static void
  557. ngx_http_ssl_handshake_handler(ngx_connection_t *c)
  558. {
  559.     if (c->ssl->handshaked) {

  560.         /*
  561.          * The majority of browsers do not send the "close notify" alert.
  562.          * Among them are MSIE, old Mozilla, Netscape 4, Konqueror,
  563.          * and Links.  And what is more, MSIE ignores the server's alert.
  564.          *
  565.          * Opera and recent Mozilla send the alert.
  566.          */

  567.         c->ssl->no_wait_shutdown = 1;

  568. #if (NGX_HTTP_SPDY                                                            \
  569.      && (defined TLSEXT_TYPE_application_layer_protocol_negotiation           \
  570.          || defined TLSEXT_TYPE_next_proto_neg))
  571.         {
  572.         unsigned int             len;
  573.         const unsigned char     *data;
  574.         static const ngx_str_t   spdy = ngx_string(NGX_SPDY_NPN_NEGOTIATED);

  575. #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
  576.         SSL_get0_alpn_selected(c->ssl->connection, &data, &len);

  577. #ifdef TLSEXT_TYPE_next_proto_neg
  578.         if (len == 0) {
  579.             SSL_get0_next_proto_negotiated(c->ssl->connection, &data, &len);
  580.         }
  581. #endif

  582. #else /* TLSEXT_TYPE_next_proto_neg */
  583.         SSL_get0_next_proto_negotiated(c->ssl->connection, &data, &len);
  584. #endif

  585.         if (len == spdy.len && ngx_strncmp(data, spdy.data, spdy.len) == 0) {
  586.             ngx_http_spdy_init(c->read);
  587.             return;
  588.         }
  589.         }
  590. #endif

  591.         c->log->action = "waiting for request";

  592.         c->read->handler = ngx_http_wait_request_handler;
  593.         /* STUB: epoll edge */ c->write->handler = ngx_http_empty_handler;

  594.         ngx_reusable_connection(c, 1);

  595.         ngx_http_wait_request_handler(c->read);

  596.         return;
  597.     }

  598.     if (c->read->timedout) {
  599.         ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
  600.     }

  601.     ngx_http_close_connection(c);
  602. }

  603. #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME

  604. int
  605. ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
  606. {
  607.     ngx_str_t                  host;
  608.     const char                *servername;
  609.     ngx_connection_t          *c;
  610.     ngx_http_connection_t     *hc;
  611.     ngx_http_ssl_srv_conf_t   *sscf;
  612.     ngx_http_core_loc_conf_t  *clcf;
  613.     ngx_http_core_srv_conf_t  *cscf;

  614.     servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name);

  615.     if (servername == NULL) {
  616.         return SSL_TLSEXT_ERR_NOACK;
  617.     }

  618.     c = ngx_ssl_get_connection(ssl_conn);

  619.     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
  620.                    "SSL server name: \"%s\"", servername);

  621.     host.len = ngx_strlen(servername);

  622.     if (host.len == 0) {
  623.         return SSL_TLSEXT_ERR_NOACK;
  624.     }

  625.     host.data = (u_char *) servername;

  626.     if (ngx_http_validate_host(&host, c->pool, 1) != NGX_OK) {
  627.         return SSL_TLSEXT_ERR_NOACK;
  628.     }

  629.     hc = c->data;

  630.     if (ngx_http_find_virtual_server(c, hc->addr_conf->virtual_names, &host,
  631.                                      NULL, &cscf)
  632.         != NGX_OK)
  633.     {
  634.         return SSL_TLSEXT_ERR_NOACK;
  635.     }

  636.     hc->ssl_servername = ngx_palloc(c->pool, sizeof(ngx_str_t));
  637.     if (hc->ssl_servername == NULL) {
  638.         return SSL_TLSEXT_ERR_NOACK;
  639.     }

  640.     *hc->ssl_servername = host;

  641.     hc->conf_ctx = cscf->ctx;

  642.     clcf = ngx_http_get_module_loc_conf(hc->conf_ctx, ngx_http_core_module);

  643.     ngx_http_set_connection_log(c, clcf->error_log);

  644.     sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module);

  645.     if (sscf->ssl.ctx) {
  646.         SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx);

  647.         /*
  648.          * SSL_set_SSL_CTX() only changes certs as of 1.0.0d
  649.          * adjust other things we care about
  650.          */

  651.         SSL_set_verify(ssl_conn, SSL_CTX_get_verify_mode(sscf->ssl.ctx),
  652.                        SSL_CTX_get_verify_callback(sscf->ssl.ctx));

  653.         SSL_set_verify_depth(ssl_conn, SSL_CTX_get_verify_depth(sscf->ssl.ctx));

  654. #ifdef SSL_CTRL_CLEAR_OPTIONS
  655.         /* only in 0.9.8m+ */
  656.         SSL_clear_options(ssl_conn, SSL_get_options(ssl_conn) &
  657.                                     ~SSL_CTX_get_options(sscf->ssl.ctx));
  658. #endif

  659.         SSL_set_options(ssl_conn, SSL_CTX_get_options(sscf->ssl.ctx));
  660.     }

  661.     return SSL_TLSEXT_ERR_OK;
  662. }

  663. #endif

  664. #endif


  665. static void
  666. ngx_http_process_request_line(ngx_event_t *rev)
  667. {
  668.     ssize_t              n;
  669.     ngx_int_t            rc, rv;
  670.     ngx_str_t            host;
  671.     ngx_connection_t    *c;
  672.     ngx_http_request_t  *r;

  673.     c = rev->data;
  674.     r = c->data;

  675.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0,
  676.                    "http process request line");

  677.     if (rev->timedout) {
  678.         ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
  679.         c->timedout = 1;
  680.         ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT);
  681.         return;
  682.     }

  683.     rc = NGX_AGAIN;

  684.     for ( ;; ) {

  685.         if (rc == NGX_AGAIN) {
  686.             n = ngx_http_read_request_header(r);

  687.             if (n == NGX_AGAIN || n == NGX_ERROR) {
  688.                 return;
  689.             }
  690.         }

  691.         rc = ngx_http_parse_request_line(r, r->header_in);

  692.         if (rc == NGX_OK) {

  693.             /* the request line has been parsed successfully */

  694.             r->request_line.len = r->request_end - r->request_start;
  695.             r->request_line.data = r->request_start;
  696.             r->request_length = r->header_in->pos - r->request_start;

  697.             ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
  698.                            "http request line: \"%V\"", &r->request_line);

  699.             r->method_name.len = r->method_end - r->request_start + 1;
  700.             r->method_name.data = r->request_line.data;

  701.             if (r->http_protocol.data) {
  702.                 r->http_protocol.len = r->request_end - r->http_protocol.data;
  703.             }

  704.             if (ngx_http_process_request_uri(r) != NGX_OK) {
  705.                 return;
  706.             }

  707.             if (r->host_start && r->host_end) {

  708.                 host.len = r->host_end - r->host_start;
  709.                 host.data = r->host_start;

  710.                 rc = ngx_http_validate_host(&host, r->pool, 0);

  711.                 if (rc == NGX_DECLINED) {
  712.                     ngx_log_error(NGX_LOG_INFO, c->log, 0,
  713.                                   "client sent invalid host in request line");
  714.                     ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  715.                     return;
  716.                 }

  717.                 if (rc == NGX_ERROR) {
  718.                     ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  719.                     return;
  720.                 }

  721.                 if (ngx_http_set_virtual_server(r, &host) == NGX_ERROR) {
  722.                     return;
  723.                 }

  724.                 r->headers_in.server = host;
  725.             }

  726.             if (r->http_version < NGX_HTTP_VERSION_10) {

  727.                 if (r->headers_in.server.len == 0
  728.                     && ngx_http_set_virtual_server(r, &r->headers_in.server)
  729.                        == NGX_ERROR)
  730.                 {
  731.                     return;
  732.                 }

  733.                 ngx_http_process_request(r);
  734.                 return;
  735.             }


  736.             if (ngx_list_init(&r->headers_in.headers, r->pool, 20,
  737.                               sizeof(ngx_table_elt_t))
  738.                 != NGX_OK)
  739.             {
  740.                 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  741.                 return;
  742.             }

  743.             c->log->action = "reading client request headers";

  744.             rev->handler = ngx_http_process_request_headers;
  745.             ngx_http_process_request_headers(rev);

  746.             return;
  747.         }

  748.         if (rc != NGX_AGAIN) {

  749.             /* there was error while a request line parsing */

  750.             ngx_log_error(NGX_LOG_INFO, c->log, 0,
  751.                           ngx_http_client_errors[rc - NGX_HTTP_CLIENT_ERROR]);
  752.             ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  753.             return;
  754.         }

  755.         /* NGX_AGAIN: a request line parsing is still incomplete */

  756.         if (r->header_in->pos == r->header_in->end) {

  757.             rv = ngx_http_alloc_large_header_buffer(r, 1);

  758.             if (rv == NGX_ERROR) {
  759.                 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  760.                 return;
  761.             }

  762.             if (rv == NGX_DECLINED) {
  763.                 r->request_line.len = r->header_in->end - r->request_start;
  764.                 r->request_line.data = r->request_start;

  765.                 ngx_log_error(NGX_LOG_INFO, c->log, 0,
  766.                               "client sent too long URI");
  767.                 ngx_http_finalize_request(r, NGX_HTTP_REQUEST_URI_TOO_LARGE);
  768.                 return;
  769.             }
  770.         }
  771.     }
  772. }


  773. ngx_int_t
  774. ngx_http_process_request_uri(ngx_http_request_t *r)
  775. {
  776.     ngx_http_core_srv_conf_t  *cscf;

  777.     if (r->args_start) {
  778.         r->uri.len = r->args_start - 1 - r->uri_start;
  779.     } else {
  780.         r->uri.len = r->uri_end - r->uri_start;
  781.     }

  782.     if (r->complex_uri || r->quoted_uri) {

  783.         r->uri.data = ngx_pnalloc(r->pool, r->uri.len + 1);
  784.         if (r->uri.data == NULL) {
  785.             ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  786.             return NGX_ERROR;
  787.         }

  788.         cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);

  789.         if (ngx_http_parse_complex_uri(r, cscf->merge_slashes) != NGX_OK) {
  790.             r->uri.len = 0;

  791.             ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  792.                           "client sent invalid request");
  793.             ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  794.             return NGX_ERROR;
  795.         }

  796.     } else {
  797.         r->uri.data = r->uri_start;
  798.     }

  799.     r->unparsed_uri.len = r->uri_end - r->uri_start;
  800.     r->unparsed_uri.data = r->uri_start;

  801.     r->valid_unparsed_uri = r->space_in_uri ? 0 : 1;

  802.     if (r->uri_ext) {
  803.         if (r->args_start) {
  804.             r->exten.len = r->args_start - 1 - r->uri_ext;
  805.         } else {
  806.             r->exten.len = r->uri_end - r->uri_ext;
  807.         }

  808.         r->exten.data = r->uri_ext;
  809.     }

  810.     if (r->args_start && r->uri_end > r->args_start) {
  811.         r->args.len = r->uri_end - r->args_start;
  812.         r->args.data = r->args_start;
  813.     }

  814. #if (NGX_WIN32)
  815.     {
  816.     u_char  *p, *last;

  817.     p = r->uri.data;
  818.     last = r->uri.data + r->uri.len;

  819.     while (p < last) {

  820.         if (*p++ == ':') {

  821.             /*
  822.              * this check covers "::$data", "::$index_allocation" and
  823.              * ":$i30:$index_allocation"
  824.              */

  825.             if (p < last && *p == '$') {
  826.                 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  827.                               "client sent unsafe win32 URI");
  828.                 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  829.                 return NGX_ERROR;
  830.             }
  831.         }
  832.     }

  833.     p = r->uri.data + r->uri.len - 1;

  834.     while (p > r->uri.data) {

  835.         if (*p == ' ') {
  836.             p--;
  837.             continue;
  838.         }

  839.         if (*p == '.') {
  840.             p--;
  841.             continue;
  842.         }

  843.         break;
  844.     }

  845.     if (p != r->uri.data + r->uri.len - 1) {
  846.         r->uri.len = p + 1 - r->uri.data;
  847.         ngx_http_set_exten(r);
  848.     }

  849.     }
  850. #endif

  851.     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  852.                    "http uri: \"%V\"", &r->uri);

  853.     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  854.                    "http args: \"%V\"", &r->args);

  855.     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  856.                    "http exten: \"%V\"", &r->exten);

  857.     return NGX_OK;
  858. }


  859. static void
  860. ngx_http_process_request_headers(ngx_event_t *rev)
  861. {
  862.     u_char                     *p;
  863.     size_t                      len;
  864.     ssize_t                     n;
  865.     ngx_int_t                   rc, rv;
  866.     ngx_table_elt_t            *h;
  867.     ngx_connection_t           *c;
  868.     ngx_http_header_t          *hh;
  869.     ngx_http_request_t         *r;
  870.     ngx_http_core_srv_conf_t   *cscf;
  871.     ngx_http_core_main_conf_t  *cmcf;

  872.     c = rev->data;
  873.     r = c->data;

  874.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0,
  875.                    "http process request header line");

  876.     if (rev->timedout) {
  877.         ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
  878.         c->timedout = 1;
  879.         ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT);
  880.         return;
  881.     }

  882.     cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

  883.     rc = NGX_AGAIN;

  884.     for ( ;; ) {

  885.         if (rc == NGX_AGAIN) {

  886.             if (r->header_in->pos == r->header_in->end) {

  887.                 rv = ngx_http_alloc_large_header_buffer(r, 0);

  888.                 if (rv == NGX_ERROR) {
  889.                     ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  890.                     return;
  891.                 }

  892.                 if (rv == NGX_DECLINED) {
  893.                     p = r->header_name_start;

  894.                     r->lingering_close = 1;

  895.                     if (p == NULL) {
  896.                         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  897.                                       "client sent too large request");
  898.                         ngx_http_finalize_request(r,
  899.                                             NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
  900.                         return;
  901.                     }

  902.                     len = r->header_in->end - p;

  903.                     if (len > NGX_MAX_ERROR_STR - 300) {
  904.                         len = NGX_MAX_ERROR_STR - 300;
  905.                     }

  906.                     ngx_log_error(NGX_LOG_INFO, c->log, 0,
  907.                                 "client sent too long header line: \"%*s...\"",
  908.                                 len, r->header_name_start);

  909.                     ngx_http_finalize_request(r,
  910.                                             NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
  911.                     return;
  912.                 }
  913.             }

  914.             n = ngx_http_read_request_header(r);

  915.             if (n == NGX_AGAIN || n == NGX_ERROR) {
  916.                 return;
  917.             }
  918.         }

  919.         /* the host header could change the server configuration context */
  920.         cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);

  921.         rc = ngx_http_parse_header_line(r, r->header_in,
  922.                                         cscf->underscores_in_headers);

  923.         if (rc == NGX_OK) {

  924.             r->request_length += r->header_in->pos - r->header_name_start;

  925.             if (r->invalid_header && cscf->ignore_invalid_headers) {

  926.                 /* there was error while a header line parsing */

  927.                 ngx_log_error(NGX_LOG_INFO, c->log, 0,
  928.                               "client sent invalid header line: \"%*s\"",
  929.                               r->header_end - r->header_name_start,
  930.                               r->header_name_start);
  931.                 continue;
  932.             }

  933.             /* a header line has been parsed successfully */

  934.             h = ngx_list_push(&r->headers_in.headers);
  935.             if (h == NULL) {
  936.                 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  937.                 return;
  938.             }

  939.             h->hash = r->header_hash;

  940.             h->key.len = r->header_name_end - r->header_name_start;
  941.             h->key.data = r->header_name_start;
  942.             h->key.data[h->key.len] = '\0';

  943.             h->value.len = r->header_end - r->header_start;
  944.             h->value.data = r->header_start;
  945.             h->value.data[h->value.len] = '\0';

  946.             h->lowcase_key = ngx_pnalloc(r->pool, h->key.len);
  947.             if (h->lowcase_key == NULL) {
  948.                 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  949.                 return;
  950.             }

  951.             if (h->key.len == r->lowcase_index) {
  952.                 ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len);

  953.             } else {
  954.                 ngx_strlow(h->lowcase_key, h->key.data, h->key.len);
  955.             }

  956.             hh = ngx_hash_find(&cmcf->headers_in_hash, h->hash,
  957.                                h->lowcase_key, h->key.len);

  958.             if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
  959.                 return;
  960.             }

  961.             ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  962.                            "http header: \"%V: %V\"",
  963.                            &h->key, &h->value);

  964.             continue;
  965.         }

  966.         if (rc == NGX_HTTP_PARSE_HEADER_DONE) {

  967.             /* a whole header has been parsed successfully */

  968.             ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  969.                            "http header done");

  970.             r->request_length += r->header_in->pos - r->header_name_start;

  971.             r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE;

  972.             rc = ngx_http_process_request_header(r);

  973.             if (rc != NGX_OK) {
  974.                 return;
  975.             }

  976.             ngx_http_process_request(r);

  977.             return;
  978.         }

  979.         if (rc == NGX_AGAIN) {

  980.             /* a header line parsing is still not complete */

  981.             continue;
  982.         }

  983.         /* rc == NGX_HTTP_PARSE_INVALID_HEADER: "\r" is not followed by "\n" */

  984.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  985.                       "client sent invalid header line: \"%*s\\r...\"",
  986.                       r->header_end - r->header_name_start,
  987.                       r->header_name_start);
  988.         ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  989.         return;
  990.     }
  991. }


  992. static ssize_t
  993. ngx_http_read_request_header(ngx_http_request_t *r)
  994. {
  995.     ssize_t                    n;
  996.     ngx_event_t               *rev;
  997.     ngx_connection_t          *c;
  998.     ngx_http_core_srv_conf_t  *cscf;

  999.     c = r->connection;
  1000.     rev = c->read;

  1001.     n = r->header_in->last - r->header_in->pos;

  1002.     if (n > 0) {
  1003.         return n;
  1004.     }

  1005.     if (rev->ready) {
  1006.         n = c->recv(c, r->header_in->last,
  1007.                     r->header_in->end - r->header_in->last);
  1008.     } else {
  1009.         n = NGX_AGAIN;
  1010.     }

  1011.     if (n == NGX_AGAIN) {
  1012.         if (!rev->timer_set) {
  1013.             cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
  1014.             ngx_add_timer(rev, cscf->client_header_timeout);
  1015.         }

  1016.         if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  1017.             ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1018.             return NGX_ERROR;
  1019.         }

  1020.         return NGX_AGAIN;
  1021.     }

  1022.     if (n == 0) {
  1023.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1024.                       "client prematurely closed connection");
  1025.     }

  1026.     if (n == 0 || n == NGX_ERROR) {
  1027.         c->error = 1;
  1028.         c->log->action = "reading client request headers";

  1029.         ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  1030.         return NGX_ERROR;
  1031.     }

  1032.     r->header_in->last += n;

  1033.     return n;
  1034. }


  1035. static ngx_int_t
  1036. ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
  1037.     ngx_uint_t request_line)
  1038. {
  1039.     u_char                    *old, *new;
  1040.     ngx_buf_t                 *b;
  1041.     ngx_http_connection_t     *hc;
  1042.     ngx_http_core_srv_conf_t  *cscf;

  1043.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  1044.                    "http alloc large header buffer");

  1045.     if (request_line && r->state == 0) {

  1046.         /* the client fills up the buffer with "\r\n" */

  1047.         r->header_in->pos = r->header_in->start;
  1048.         r->header_in->last = r->header_in->start;

  1049.         return NGX_OK;
  1050.     }

  1051.     old = request_line ? r->request_start : r->header_name_start;

  1052.     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);

  1053.     if (r->state != 0
  1054.         && (size_t) (r->header_in->pos - old)
  1055.                                      >= cscf->large_client_header_buffers.size)
  1056.     {
  1057.         return NGX_DECLINED;
  1058.     }

  1059.     hc = r->http_connection;

  1060.     if (hc->nfree) {
  1061.         b = hc->free[--hc->nfree];

  1062.         ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  1063.                        "http large header free: %p %uz",
  1064.                        b->pos, b->end - b->last);

  1065.     } else if (hc->nbusy < cscf->large_client_header_buffers.num) {

  1066.         if (hc->busy == NULL) {
  1067.             hc->busy = ngx_palloc(r->connection->pool,
  1068.                   cscf->large_client_header_buffers.num * sizeof(ngx_buf_t *));
  1069.             if (hc->busy == NULL) {
  1070.                 return NGX_ERROR;
  1071.             }
  1072.         }

  1073.         b = ngx_create_temp_buf(r->connection->pool,
  1074.                                 cscf->large_client_header_buffers.size);
  1075.         if (b == NULL) {
  1076.             return NGX_ERROR;
  1077.         }

  1078.         ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  1079.                        "http large header alloc: %p %uz",
  1080.                        b->pos, b->end - b->last);

  1081.     } else {
  1082.         return NGX_DECLINED;
  1083.     }

  1084.     hc->busy[hc->nbusy++] = b;

  1085.     if (r->state == 0) {
  1086.         /*
  1087.          * r->state == 0 means that a header line was parsed successfully
  1088.          * and we do not need to copy incomplete header line and
  1089.          * to relocate the parser header pointers
  1090.          */

  1091.         r->header_in = b;

  1092.         return NGX_OK;
  1093.     }

  1094.     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  1095.                    "http large header copy: %d", r->header_in->pos - old);

  1096.     new = b->start;

  1097.     ngx_memcpy(new, old, r->header_in->pos - old);

  1098.     b->pos = new + (r->header_in->pos - old);
  1099.     b->last = new + (r->header_in->pos - old);

  1100.     if (request_line) {
  1101.         r->request_start = new;

  1102.         if (r->request_end) {
  1103.             r->request_end = new + (r->request_end - old);
  1104.         }

  1105.         r->method_end = new + (r->method_end - old);

  1106.         r->uri_start = new + (r->uri_start - old);
  1107.         r->uri_end = new + (r->uri_end - old);

  1108.         if (r->schema_start) {
  1109.             r->schema_start = new + (r->schema_start - old);
  1110.             r->schema_end = new + (r->schema_end - old);
  1111.         }

  1112.         if (r->host_start) {
  1113.             r->host_start = new + (r->host_start - old);
  1114.             if (r->host_end) {
  1115.                 r->host_end = new + (r->host_end - old);
  1116.             }
  1117.         }

  1118.         if (r->port_start) {
  1119.             r->port_start = new + (r->port_start - old);
  1120.             r->port_end = new + (r->port_end - old);
  1121.         }

  1122.         if (r->uri_ext) {
  1123.             r->uri_ext = new + (r->uri_ext - old);
  1124.         }

  1125.         if (r->args_start) {
  1126.             r->args_start = new + (r->args_start - old);
  1127.         }

  1128.         if (r->http_protocol.data) {
  1129.             r->http_protocol.data = new + (r->http_protocol.data - old);
  1130.         }

  1131.     } else {
  1132.         r->header_name_start = new;
  1133.         r->header_name_end = new + (r->header_name_end - old);
  1134.         r->header_start = new + (r->header_start - old);
  1135.         r->header_end = new + (r->header_end - old);
  1136.     }

  1137.     r->header_in = b;

  1138.     return NGX_OK;
  1139. }


  1140. static ngx_int_t
  1141. ngx_http_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
  1142.     ngx_uint_t offset)
  1143. {
  1144.     ngx_table_elt_t  **ph;

  1145.     ph = (ngx_table_elt_t **) ((char *) &r->headers_in + offset);

  1146.     if (*ph == NULL) {
  1147.         *ph = h;
  1148.     }

  1149.     return NGX_OK;
  1150. }


  1151. static ngx_int_t
  1152. ngx_http_process_unique_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
  1153.     ngx_uint_t offset)
  1154. {
  1155.     ngx_table_elt_t  **ph;

  1156.     ph = (ngx_table_elt_t **) ((char *) &r->headers_in + offset);

  1157.     if (*ph == NULL) {
  1158.         *ph = h;
  1159.         return NGX_OK;
  1160.     }

  1161.     ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1162.                   "client sent duplicate header line: \"%V: %V\", "
  1163.                   "previous value: \"%V: %V\"",
  1164.                   &h->key, &h->value, &(*ph)->key, &(*ph)->value);

  1165.     ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);

  1166.     return NGX_ERROR;
  1167. }


  1168. static ngx_int_t
  1169. ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h,
  1170.     ngx_uint_t offset)
  1171. {
  1172.     ngx_int_t  rc;
  1173.     ngx_str_t  host;

  1174.     if (r->headers_in.host == NULL) {
  1175.         r->headers_in.host = h;
  1176.     }

  1177.     host = h->value;

  1178.     rc = ngx_http_validate_host(&host, r->pool, 0);

  1179.     if (rc == NGX_DECLINED) {
  1180.         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1181.                       "client sent invalid host header");
  1182.         ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  1183.         return NGX_ERROR;
  1184.     }

  1185.     if (rc == NGX_ERROR) {
  1186.         ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1187.         return NGX_ERROR;
  1188.     }

  1189.     if (r->headers_in.server.len) {
  1190.         return NGX_OK;
  1191.     }

  1192.     if (ngx_http_set_virtual_server(r, &host) == NGX_ERROR) {
  1193.         return NGX_ERROR;
  1194.     }

  1195.     r->headers_in.server = host;

  1196.     return NGX_OK;
  1197. }


  1198. static ngx_int_t
  1199. ngx_http_process_connection(ngx_http_request_t *r, ngx_table_elt_t *h,
  1200.     ngx_uint_t offset)
  1201. {
  1202.     if (ngx_strcasestrn(h->value.data, "close", 5 - 1)) {
  1203.         r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE;

  1204.     } else if (ngx_strcasestrn(h->value.data, "keep-alive", 10 - 1)) {
  1205.         r->headers_in.connection_type = NGX_HTTP_CONNECTION_KEEP_ALIVE;
  1206.     }

  1207.     return NGX_OK;
  1208. }


  1209. static ngx_int_t
  1210. ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h,
  1211.     ngx_uint_t offset)
  1212. {
  1213.     u_char  *user_agent, *msie;

  1214.     if (r->headers_in.user_agent) {
  1215.         return NGX_OK;
  1216.     }

  1217.     r->headers_in.user_agent = h;

  1218.     /* check some widespread browsers while the header is in CPU cache */

  1219.     user_agent = h->value.data;

  1220.     msie = ngx_strstrn(user_agent, "MSIE ", 5 - 1);

  1221.     if (msie && msie + 7 < user_agent + h->value.len) {

  1222.         r->headers_in.msie = 1;

  1223.         if (msie[6] == '.') {

  1224.             switch (msie[5]) {
  1225.             case '4':
  1226.             case '5':
  1227.                 r->headers_in.msie6 = 1;
  1228.                 break;
  1229.             case '6':
  1230.                 if (ngx_strstrn(msie + 8, "SV1", 3 - 1) == NULL) {
  1231.                     r->headers_in.msie6 = 1;
  1232.                 }
  1233.                 break;
  1234.             }
  1235.         }

  1236. #if 0
  1237.         /* MSIE ignores the SSL "close notify" alert */
  1238.         if (c->ssl) {
  1239.             c->ssl->no_send_shutdown = 1;
  1240.         }
  1241. #endif
  1242.     }

  1243.     if (ngx_strstrn(user_agent, "Opera", 5 - 1)) {
  1244.         r->headers_in.opera = 1;
  1245.         r->headers_in.msie = 0;
  1246.         r->headers_in.msie6 = 0;
  1247.     }

  1248.     if (!r->headers_in.msie && !r->headers_in.opera) {

  1249.         if (ngx_strstrn(user_agent, "Gecko/", 6 - 1)) {
  1250.             r->headers_in.gecko = 1;

  1251.         } else if (ngx_strstrn(user_agent, "Chrome/", 7 - 1)) {
  1252.             r->headers_in.chrome = 1;

  1253.         } else if (ngx_strstrn(user_agent, "Safari/", 7 - 1)
  1254.                    && ngx_strstrn(user_agent, "Mac OS X", 8 - 1))
  1255.         {
  1256.             r->headers_in.safari = 1;

  1257.         } else if (ngx_strstrn(user_agent, "Konqueror", 9 - 1)) {
  1258.             r->headers_in.konqueror = 1;
  1259.         }
  1260.     }

  1261.     return NGX_OK;
  1262. }


  1263. static ngx_int_t
  1264. ngx_http_process_multi_header_lines(ngx_http_request_t *r, ngx_table_elt_t *h,
  1265.     ngx_uint_t offset)
  1266. {
  1267.     ngx_array_t       *headers;
  1268.     ngx_table_elt_t  **ph;

  1269.     headers = (ngx_array_t *) ((char *) &r->headers_in + offset);

  1270.     if (headers->elts == NULL) {
  1271.         if (ngx_array_init(headers, r->pool, 1, sizeof(ngx_table_elt_t *))
  1272.             != NGX_OK)
  1273.         {
  1274.             ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1275.             return NGX_ERROR;
  1276.         }
  1277.     }

  1278.     ph = ngx_array_push(headers);
  1279.     if (ph == NULL) {
  1280.         ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1281.         return NGX_ERROR;
  1282.     }

  1283.     *ph = h;
  1284.     return NGX_OK;
  1285. }


  1286. ngx_int_t
  1287. ngx_http_process_request_header(ngx_http_request_t *r)
  1288. {
  1289.     if (r->headers_in.server.len == 0
  1290.         && ngx_http_set_virtual_server(r, &r->headers_in.server)
  1291.            == NGX_ERROR)
  1292.     {
  1293.         return NGX_ERROR;
  1294.     }

  1295.     if (r->headers_in.host == NULL && r->http_version > NGX_HTTP_VERSION_10) {
  1296.         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1297.                    "client sent HTTP/1.1 request without \"Host\" header");
  1298.         ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  1299.         return NGX_ERROR;
  1300.     }

  1301.     if (r->headers_in.content_length) {
  1302.         r->headers_in.content_length_n =
  1303.                             ngx_atoof(r->headers_in.content_length->value.data,
  1304.                                       r->headers_in.content_length->value.len);

  1305.         if (r->headers_in.content_length_n == NGX_ERROR) {
  1306.             ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1307.                           "client sent invalid \"Content-Length\" header");
  1308.             ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  1309.             return NGX_ERROR;
  1310.         }
  1311.     }

  1312.     if (r->method & NGX_HTTP_TRACE) {
  1313.         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1314.                       "client sent TRACE method");
  1315.         ngx_http_finalize_request(r, NGX_HTTP_NOT_ALLOWED);
  1316.         return NGX_ERROR;
  1317.     }

  1318.     if (r->headers_in.transfer_encoding) {
  1319.         if (r->headers_in.transfer_encoding->value.len == 7
  1320.             && ngx_strncasecmp(r->headers_in.transfer_encoding->value.data,
  1321.                                (u_char *) "chunked", 7) == 0)
  1322.         {
  1323.             r->headers_in.content_length = NULL;
  1324.             r->headers_in.content_length_n = -1;
  1325.             r->headers_in.chunked = 1;

  1326.         } else if (r->headers_in.transfer_encoding->value.len != 8
  1327.             || ngx_strncasecmp(r->headers_in.transfer_encoding->value.data,
  1328.                                (u_char *) "identity", 8) != 0)
  1329.         {
  1330.             ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1331.                           "client sent unknown \"Transfer-Encoding\": \"%V\"",
  1332.                           &r->headers_in.transfer_encoding->value);
  1333.             ngx_http_finalize_request(r, NGX_HTTP_NOT_IMPLEMENTED);
  1334.             return NGX_ERROR;
  1335.         }
  1336.     }

  1337.     if (r->headers_in.connection_type == NGX_HTTP_CONNECTION_KEEP_ALIVE) {
  1338.         if (r->headers_in.keep_alive) {
  1339.             r->headers_in.keep_alive_n =
  1340.                             ngx_atotm(r->headers_in.keep_alive->value.data,
  1341.                                       r->headers_in.keep_alive->value.len);
  1342.         }
  1343.     }

  1344.     return NGX_OK;
  1345. }


  1346. void
  1347. ngx_http_process_request(ngx_http_request_t *r)
  1348. {
  1349.     ngx_connection_t  *c;

  1350.     c = r->connection;

  1351. #if (NGX_HTTP_SSL)

  1352.     if (r->http_connection->ssl) {
  1353.         long                      rc;
  1354.         X509                     *cert;
  1355.         ngx_http_ssl_srv_conf_t  *sscf;

  1356.         if (c->ssl == NULL) {
  1357.             ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1358.                           "client sent plain HTTP request to HTTPS port");
  1359.             ngx_http_finalize_request(r, NGX_HTTP_TO_HTTPS);
  1360.             return;
  1361.         }

  1362.         sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);

  1363.         if (sscf->verify) {
  1364.             rc = SSL_get_verify_result(c->ssl->connection);

  1365.             if (rc != X509_V_OK
  1366.                 && (sscf->verify != 3 || !ngx_ssl_verify_error_optional(rc)))
  1367.             {
  1368.                 ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1369.                               "client SSL certificate verify error: (%l:%s)",
  1370.                               rc, X509_verify_cert_error_string(rc));

  1371.                 ngx_ssl_remove_cached_session(sscf->ssl.ctx,
  1372.                                        (SSL_get0_session(c->ssl->connection)));

  1373.                 ngx_http_finalize_request(r, NGX_HTTPS_CERT_ERROR);
  1374.                 return;
  1375.             }

  1376.             if (sscf->verify == 1) {
  1377.                 cert = SSL_get_peer_certificate(c->ssl->connection);

  1378.                 if (cert == NULL) {
  1379.                     ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1380.                                   "client sent no required SSL certificate");

  1381.                     ngx_ssl_remove_cached_session(sscf->ssl.ctx,
  1382.                                        (SSL_get0_session(c->ssl->connection)));

  1383.                     ngx_http_finalize_request(r, NGX_HTTPS_NO_CERT);
  1384.                     return;
  1385.                 }

  1386.                 X509_free(cert);
  1387.             }
  1388.         }
  1389.     }

  1390. #endif

  1391.     if (c->read->timer_set) {
  1392.         ngx_del_timer(c->read);
  1393.     }

  1394. #if (NGX_STAT_STUB)
  1395.     (void) ngx_atomic_fetch_add(ngx_stat_reading, -1);
  1396.     r->stat_reading = 0;
  1397.     (void) ngx_atomic_fetch_add(ngx_stat_writing, 1);
  1398.     r->stat_writing = 1;
  1399. #endif

  1400.     c->read->handler = ngx_http_request_handler;
  1401.     c->write->handler = ngx_http_request_handler;
  1402.     r->read_event_handler = ngx_http_block_reading;

  1403.     ngx_http_handler(r);

  1404.     ngx_http_run_posted_requests(c);
  1405. }


  1406. static ngx_int_t
  1407. ngx_http_validate_host(ngx_str_t *host, ngx_pool_t *pool, ngx_uint_t alloc)
  1408. {
  1409.     u_char  *h, ch;
  1410.     size_t   i, dot_pos, host_len;

  1411.     enum {
  1412.         sw_usual = 0,
  1413.         sw_literal,
  1414.         sw_rest
  1415.     } state;

  1416.     dot_pos = host->len;
  1417.     host_len = host->len;

  1418.     h = host->data;

  1419.     state = sw_usual;

  1420.     for (i = 0; i < host->len; i++) {
  1421.         ch = h[i];

  1422.         switch (ch) {

  1423.         case '.':
  1424.             if (dot_pos == i - 1) {
  1425.                 return NGX_DECLINED;
  1426.             }
  1427.             dot_pos = i;
  1428.             break;

  1429.         case ':':
  1430.             if (state == sw_usual) {
  1431.                 host_len = i;
  1432.                 state = sw_rest;
  1433.             }
  1434.             break;

  1435.         case '[':
  1436.             if (i == 0) {
  1437.                 state = sw_literal;
  1438.             }
  1439.             break;

  1440.         case ']':
  1441.             if (state == sw_literal) {
  1442.                 host_len = i + 1;
  1443.                 state = sw_rest;
  1444.             }
  1445.             break;

  1446.         case '\0':
  1447.             return NGX_DECLINED;

  1448.         default:

  1449.             if (ngx_path_separator(ch)) {
  1450.                 return NGX_DECLINED;
  1451.             }

  1452.             if (ch >= 'A' && ch <= 'Z') {
  1453.                 alloc = 1;
  1454.             }

  1455.             break;
  1456.         }
  1457.     }

  1458.     if (dot_pos == host_len - 1) {
  1459.         host_len--;
  1460.     }

  1461.     if (host_len == 0) {
  1462.         return NGX_DECLINED;
  1463.     }

  1464.     if (alloc) {
  1465.         host->data = ngx_pnalloc(pool, host_len);
  1466.         if (host->data == NULL) {
  1467.             return NGX_ERROR;
  1468.         }

  1469.         ngx_strlow(host->data, h, host_len);
  1470.     }

  1471.     host->len = host_len;

  1472.     return NGX_OK;
  1473. }


  1474. static ngx_int_t
  1475. ngx_http_set_virtual_server(ngx_http_request_t *r, ngx_str_t *host)
  1476. {
  1477.     ngx_int_t                  rc;
  1478.     ngx_http_connection_t     *hc;
  1479.     ngx_http_core_loc_conf_t  *clcf;
  1480.     ngx_http_core_srv_conf_t  *cscf;

  1481. #if (NGX_SUPPRESS_WARN)
  1482.     cscf = NULL;
  1483. #endif

  1484.     hc = r->http_connection;

  1485. #if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)

  1486.     if (hc->ssl_servername) {
  1487.         if (hc->ssl_servername->len == host->len
  1488.             && ngx_strncmp(hc->ssl_servername->data,
  1489.                            host->data, host->len) == 0)
  1490.         {
  1491. #if (NGX_PCRE)
  1492.             if (hc->ssl_servername_regex
  1493.                 && ngx_http_regex_exec(r, hc->ssl_servername_regex,
  1494.                                           hc->ssl_servername) != NGX_OK)
  1495.             {
  1496.                 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1497.                 return NGX_ERROR;
  1498.             }
  1499. #endif
  1500.             return NGX_OK;
  1501.         }
  1502.     }

  1503. #endif

  1504.     rc = ngx_http_find_virtual_server(r->connection,
  1505.                                       hc->addr_conf->virtual_names,
  1506.                                       host, r, &cscf);

  1507.     if (rc == NGX_ERROR) {
  1508.         ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1509.         return NGX_ERROR;
  1510.     }

  1511. #if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)

  1512.     if (hc->ssl_servername) {
  1513.         ngx_http_ssl_srv_conf_t  *sscf;

  1514.         if (rc == NGX_DECLINED) {
  1515.             cscf = hc->addr_conf->default_server;
  1516.             rc = NGX_OK;
  1517.         }

  1518.         sscf = ngx_http_get_module_srv_conf(cscf->ctx, ngx_http_ssl_module);

  1519.         if (sscf->verify) {
  1520.             ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1521.                           "client attempted to request the server name "
  1522.                           "different from that one was negotiated");
  1523.             ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  1524.             return NGX_ERROR;
  1525.         }
  1526.     }

  1527. #endif

  1528.     if (rc == NGX_DECLINED) {
  1529.         return NGX_OK;
  1530.     }

  1531.     r->srv_conf = cscf->ctx->srv_conf;
  1532.     r->loc_conf = cscf->ctx->loc_conf;

  1533.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  1534.     ngx_http_set_connection_log(r->connection, clcf->error_log);

  1535.     return NGX_OK;
  1536. }


  1537. static ngx_int_t
  1538. ngx_http_find_virtual_server(ngx_connection_t *c,
  1539.     ngx_http_virtual_names_t *virtual_names, ngx_str_t *host,
  1540.     ngx_http_request_t *r, ngx_http_core_srv_conf_t **cscfp)
  1541. {
  1542.     ngx_http_core_srv_conf_t  *cscf;

  1543.     if (virtual_names == NULL) {
  1544.         return NGX_DECLINED;
  1545.     }

  1546.     cscf = ngx_hash_find_combined(&virtual_names->names,
  1547.                                   ngx_hash_key(host->data, host->len),
  1548.                                   host->data, host->len);

  1549.     if (cscf) {
  1550.         *cscfp = cscf;
  1551.         return NGX_OK;
  1552.     }

  1553. #if (NGX_PCRE)

  1554.     if (host->len && virtual_names->nregex) {
  1555.         ngx_int_t                n;
  1556.         ngx_uint_t               i;
  1557.         ngx_http_server_name_t  *sn;

  1558.         sn = virtual_names->regex;

  1559. #if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)

  1560.         if (r == NULL) {
  1561.             ngx_http_connection_t  *hc;

  1562.             for (i = 0; i < virtual_names->nregex; i++) {

  1563.                 n = ngx_regex_exec(sn[i].regex->regex, host, NULL, 0);

  1564.                 if (n == NGX_REGEX_NO_MATCHED) {
  1565.                     continue;
  1566.                 }

  1567.                 if (n >= 0) {
  1568.                     hc = c->data;
  1569.                     hc->ssl_servername_regex = sn[i].regex;

  1570.                     *cscfp = sn[i].server;
  1571.                     return NGX_OK;
  1572.                 }

  1573.                 ngx_log_error(NGX_LOG_ALERT, c->log, 0,
  1574.                               ngx_regex_exec_n " failed: %i "
  1575.                               "on \"%V\" using \"%V\"",
  1576.                               n, host, &sn[i].regex->name);

  1577.                 return NGX_ERROR;
  1578.             }

  1579.             return NGX_DECLINED;
  1580.         }

  1581. #endif /* NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME */

  1582.         for (i = 0; i < virtual_names->nregex; i++) {

  1583.             n = ngx_http_regex_exec(r, sn[i].regex, host);

  1584.             if (n == NGX_DECLINED) {
  1585.                 continue;
  1586.             }

  1587.             if (n == NGX_OK) {
  1588.                 *cscfp = sn[i].server;
  1589.                 return NGX_OK;
  1590.             }

  1591.             return NGX_ERROR;
  1592.         }
  1593.     }

  1594. #endif /* NGX_PCRE */

  1595.     return NGX_DECLINED;
  1596. }


  1597. static void
  1598. ngx_http_request_handler(ngx_event_t *ev)
  1599. {
  1600.     ngx_connection_t    *c;
  1601.     ngx_http_request_t  *r;

  1602.     c = ev->data;
  1603.     r = c->data;

  1604.     ngx_http_set_log_request(c->log, r);

  1605.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
  1606.                    "http run request: \"%V?%V\"", &r->uri, &r->args);

  1607.     if (ev->write) {
  1608.         r->write_event_handler(r);

  1609.     } else {
  1610.         r->read_event_handler(r);
  1611.     }

  1612.     ngx_http_run_posted_requests(c);
  1613. }


  1614. void
  1615. ngx_http_run_posted_requests(ngx_connection_t *c)
  1616. {
  1617.     ngx_http_request_t         *r;
  1618.     ngx_http_posted_request_t  *pr;

  1619.     for ( ;; ) {

  1620.         if (c->destroyed) {
  1621.             return;
  1622.         }

  1623.         r = c->data;
  1624.         pr = r->main->posted_requests;

  1625.         if (pr == NULL) {
  1626.             return;
  1627.         }

  1628.         r->main->posted_requests = pr->next;

  1629.         r = pr->request;

  1630.         ngx_http_set_log_request(c->log, r);

  1631.         ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
  1632.                        "http posted request: \"%V?%V\"", &r->uri, &r->args);

  1633.         r->write_event_handler(r);
  1634.     }
  1635. }


  1636. ngx_int_t
  1637. ngx_http_post_request(ngx_http_request_t *r, ngx_http_posted_request_t *pr)
  1638. {
  1639.     ngx_http_posted_request_t  **p;

  1640.     if (pr == NULL) {
  1641.         pr = ngx_palloc(r->pool, sizeof(ngx_http_posted_request_t));
  1642.         if (pr == NULL) {
  1643.             return NGX_ERROR;
  1644.         }
  1645.     }

  1646.     pr->request = r;
  1647.     pr->next = NULL;

  1648.     for (p = &r->main->posted_requests; *p; p = &(*p)->next) { /* void */ }

  1649.     *p = pr;

  1650.     return NGX_OK;
  1651. }


  1652. void
  1653. ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
  1654. {
  1655.     ngx_connection_t          *c;
  1656.     ngx_http_request_t        *pr;
  1657.     ngx_http_core_loc_conf_t  *clcf;

  1658.     c = r->connection;

  1659.     ngx_log_debug5(NGX_LOG_DEBUG_HTTP, c->log, 0,
  1660.                    "http finalize request: %d, \"%V?%V\" a:%d, c:%d",
  1661.                    rc, &r->uri, &r->args, r == c->data, r->main->count);

  1662.     if (rc == NGX_DONE) {
  1663.         ngx_http_finalize_connection(r);
  1664.         return;
  1665.     }

  1666.     if (rc == NGX_OK && r->filter_finalize) {
  1667.         c->error = 1;
  1668.     }

  1669.     if (rc == NGX_DECLINED) {
  1670.         r->content_handler = NULL;
  1671.         r->write_event_handler = ngx_http_core_run_phases;
  1672.         ngx_http_core_run_phases(r);
  1673.         return;
  1674.     }

  1675.     if (r != r->main && r->post_subrequest) {
  1676.         rc = r->post_subrequest->handler(r, r->post_subrequest->data, rc);
  1677.     }

  1678.     if (rc == NGX_ERROR
  1679.         || rc == NGX_HTTP_REQUEST_TIME_OUT
  1680.         || rc == NGX_HTTP_CLIENT_CLOSED_REQUEST
  1681.         || c->error)
  1682.     {
  1683.         if (ngx_http_post_action(r) == NGX_OK) {
  1684.             return;
  1685.         }

  1686.         if (r->main->blocked) {
  1687.             r->write_event_handler = ngx_http_request_finalizer;
  1688.         }

  1689.         ngx_http_terminate_request(r, rc);
  1690.         return;
  1691.     }

  1692.     if (rc >= NGX_HTTP_SPECIAL_RESPONSE
  1693.         || rc == NGX_HTTP_CREATED
  1694.         || rc == NGX_HTTP_NO_CONTENT)
  1695.     {
  1696.         if (rc == NGX_HTTP_CLOSE) {
  1697.             ngx_http_terminate_request(r, rc);
  1698.             return;
  1699.         }

  1700.         if (r == r->main) {
  1701.             if (c->read->timer_set) {
  1702.                 ngx_del_timer(c->read);
  1703.             }

  1704.             if (c->write->timer_set) {
  1705.                 ngx_del_timer(c->write);
  1706.             }
  1707.         }

  1708.         c->read->handler = ngx_http_request_handler;
  1709.         c->write->handler = ngx_http_request_handler;

  1710.         ngx_http_finalize_request(r, ngx_http_special_response_handler(r, rc));
  1711.         return;
  1712.     }

  1713.     if (r != r->main) {

  1714.         if (r->buffered || r->postponed) {

  1715.             if (ngx_http_set_write_handler(r) != NGX_OK) {
  1716.                 ngx_http_terminate_request(r, 0);
  1717.             }

  1718.             return;
  1719.         }

  1720.         pr = r->parent;

  1721.         if (r == c->data) {

  1722.             r->main->count--;
  1723.             r->main->subrequests++;

  1724.             if (!r->logged) {

  1725.                 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  1726.                 if (clcf->log_subrequest) {
  1727.                     ngx_http_log_request(r);
  1728.                 }

  1729.                 r->logged = 1;

  1730.             } else {
  1731.                 ngx_log_error(NGX_LOG_ALERT, c->log, 0,
  1732.                               "subrequest: \"%V?%V\" logged again",
  1733.                               &r->uri, &r->args);
  1734.             }

  1735.             r->done = 1;

  1736.             if (pr->postponed && pr->postponed->request == r) {
  1737.                 pr->postponed = pr->postponed->next;
  1738.             }

  1739.             c->data = pr;

  1740.         } else {

  1741.             ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
  1742.                            "http finalize non-active request: \"%V?%V\"",
  1743.                            &r->uri, &r->args);

  1744.             r->write_event_handler = ngx_http_request_finalizer;

  1745.             if (r->waited) {
  1746.                 r->done = 1;
  1747.             }
  1748.         }

  1749.         if (ngx_http_post_request(pr, NULL) != NGX_OK) {
  1750.             r->main->count++;
  1751.             ngx_http_terminate_request(r, 0);
  1752.             return;
  1753.         }

  1754.         ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
  1755.                        "http wake parent request: \"%V?%V\"",
  1756.                        &pr->uri, &pr->args);

  1757.         return;
  1758.     }

  1759.     if (r->buffered || c->buffered || r->postponed || r->blocked) {

  1760.         if (ngx_http_set_write_handler(r) != NGX_OK) {
  1761.             ngx_http_terminate_request(r, 0);
  1762.         }

  1763.         return;
  1764.     }

  1765.     if (r != c->data) {
  1766.         ngx_log_error(NGX_LOG_ALERT, c->log, 0,
  1767.                       "http finalize non-active request: \"%V?%V\"",
  1768.                       &r->uri, &r->args);
  1769.         return;
  1770.     }

  1771.     r->done = 1;
  1772.     r->write_event_handler = ngx_http_request_empty_handler;

  1773.     if (!r->post_action) {
  1774.         r->request_complete = 1;
  1775.     }

  1776.     if (ngx_http_post_action(r) == NGX_OK) {
  1777.         return;
  1778.     }

  1779.     if (c->read->timer_set) {
  1780.         ngx_del_timer(c->read);
  1781.     }

  1782.     if (c->write->timer_set) {
  1783.         c->write->delayed = 0;
  1784.         ngx_del_timer(c->write);
  1785.     }

  1786.     if (c->read->eof) {
  1787.         ngx_http_close_request(r, 0);
  1788.         return;
  1789.     }

  1790.     ngx_http_finalize_connection(r);
  1791. }


  1792. static void
  1793. ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc)
  1794. {
  1795.     ngx_http_cleanup_t    *cln;
  1796.     ngx_http_request_t    *mr;
  1797.     ngx_http_ephemeral_t  *e;

  1798.     mr = r->main;

  1799.     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  1800.                    "http terminate request count:%d", mr->count);

  1801.     if (rc > 0 && (mr->headers_out.status == 0 || mr->connection->sent == 0)) {
  1802.         mr->headers_out.status = rc;
  1803.     }

  1804.     cln = mr->cleanup;
  1805.     mr->cleanup = NULL;

  1806.     while (cln) {
  1807.         if (cln->handler) {
  1808.             cln->handler(cln->data);
  1809.         }

  1810.         cln = cln->next;
  1811.     }

  1812.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  1813.                    "http terminate cleanup count:%d blk:%d",
  1814.                    mr->count, mr->blocked);

  1815.     if (mr->write_event_handler) {

  1816.         if (mr->blocked) {
  1817.             return;
  1818.         }

  1819.         e = ngx_http_ephemeral(mr);
  1820.         mr->posted_requests = NULL;
  1821.         mr->write_event_handler = ngx_http_terminate_handler;
  1822.         (void) ngx_http_post_request(mr, &e->terminal_posted_request);
  1823.         return;
  1824.     }

  1825.     ngx_http_close_request(mr, rc);
  1826. }


  1827. static void
  1828. ngx_http_terminate_handler(ngx_http_request_t *r)
  1829. {
  1830.     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  1831.                    "http terminate handler count:%d", r->count);

  1832.     r->count = 1;

  1833.     ngx_http_close_request(r, 0);
  1834. }


  1835. static void
  1836. ngx_http_finalize_connection(ngx_http_request_t *r)
  1837. {
  1838.     ngx_http_core_loc_conf_t  *clcf;

  1839. #if (NGX_HTTP_SPDY)
  1840.     if (r->spdy_stream) {
  1841.         ngx_http_close_request(r, 0);
  1842.         return;
  1843.     }
  1844. #endif

  1845.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  1846.     if (r->main->count != 1) {

  1847.         if (r->discard_body) {
  1848.             r->read_event_handler = ngx_http_discarded_request_body_handler;
  1849.             ngx_add_timer(r->connection->read, clcf->lingering_timeout);

  1850.             if (r->lingering_time == 0) {
  1851.                 r->lingering_time = ngx_time()
  1852.                                       + (time_t) (clcf->lingering_time / 1000);
  1853.             }
  1854.         }

  1855.         ngx_http_close_request(r, 0);
  1856.         return;
  1857.     }

  1858.     if (!ngx_terminate
  1859.          && !ngx_exiting
  1860.          && r->keepalive
  1861.          && clcf->keepalive_timeout > 0)
  1862.     {
  1863.         ngx_http_set_keepalive(r);
  1864.         return;
  1865.     }

  1866.     if (clcf->lingering_close == NGX_HTTP_LINGERING_ALWAYS
  1867.         || (clcf->lingering_close == NGX_HTTP_LINGERING_ON
  1868.             && (r->lingering_close
  1869.                 || r->header_in->pos < r->header_in->last
  1870.                 || r->connection->read->ready)))
  1871.     {
  1872.         ngx_http_set_lingering_close(r);
  1873.         return;
  1874.     }

  1875.     ngx_http_close_request(r, 0);
  1876. }


  1877. static ngx_int_t
  1878. ngx_http_set_write_handler(ngx_http_request_t *r)
  1879. {
  1880.     ngx_event_t               *wev;
  1881.     ngx_http_core_loc_conf_t  *clcf;

  1882.     r->http_state = NGX_HTTP_WRITING_REQUEST_STATE;

  1883.     r->read_event_handler = r->discard_body ?
  1884.                                 ngx_http_discarded_request_body_handler:
  1885.                                 ngx_http_test_reading;
  1886.     r->write_event_handler = ngx_http_writer;

  1887. #if (NGX_HTTP_SPDY)
  1888.     if (r->spdy_stream) {
  1889.         return NGX_OK;
  1890.     }
  1891. #endif

  1892.     wev = r->connection->write;

  1893.     if (wev->ready && wev->delayed) {
  1894.         return NGX_OK;
  1895.     }

  1896.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
  1897.     if (!wev->delayed) {
  1898.         ngx_add_timer(wev, clcf->send_timeout);
  1899.     }

  1900.     if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
  1901.         ngx_http_close_request(r, 0);
  1902.         return NGX_ERROR;
  1903.     }

  1904.     return NGX_OK;
  1905. }


  1906. static void
  1907. ngx_http_writer(ngx_http_request_t *r)
  1908. {
  1909.     int                        rc;
  1910.     ngx_event_t               *wev;
  1911.     ngx_connection_t          *c;
  1912.     ngx_http_core_loc_conf_t  *clcf;

  1913.     c = r->connection;
  1914.     wev = c->write;

  1915.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, wev->log, 0,
  1916.                    "http writer handler: \"%V?%V\"", &r->uri, &r->args);

  1917.     clcf = ngx_http_get_module_loc_conf(r->main, ngx_http_core_module);

  1918.     if (wev->timedout) {
  1919.         if (!wev->delayed) {
  1920.             ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
  1921.                           "client timed out");
  1922.             c->timedout = 1;

  1923.             ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT);
  1924.             return;
  1925.         }

  1926.         wev->timedout = 0;
  1927.         wev->delayed = 0;

  1928.         if (!wev->ready) {
  1929.             ngx_add_timer(wev, clcf->send_timeout);

  1930.             if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
  1931.                 ngx_http_close_request(r, 0);
  1932.             }

  1933.             return;
  1934.         }

  1935.     }

  1936.     if (wev->delayed || r->aio) {
  1937.         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0,
  1938.                        "http writer delayed");

  1939.         if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
  1940.             ngx_http_close_request(r, 0);
  1941.         }

  1942.         return;
  1943.     }

  1944.     rc = ngx_http_output_filter(r, NULL);

  1945.     ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
  1946.                    "http writer output filter: %d, \"%V?%V\"",
  1947.                    rc, &r->uri, &r->args);

  1948.     if (rc == NGX_ERROR) {
  1949.         ngx_http_finalize_request(r, rc);
  1950.         return;
  1951.     }

  1952.     if (r->buffered || r->postponed || (r == r->main && c->buffered)) {

  1953. #if (NGX_HTTP_SPDY)
  1954.         if (r->spdy_stream) {
  1955.             return;
  1956.         }
  1957. #endif

  1958.         if (!wev->delayed) {
  1959.             ngx_add_timer(wev, clcf->send_timeout);
  1960.         }

  1961.         if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
  1962.             ngx_http_close_request(r, 0);
  1963.         }

  1964.         return;
  1965.     }

  1966.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, wev->log, 0,
  1967.                    "http writer done: \"%V?%V\"", &r->uri, &r->args);

  1968.     r->write_event_handler = ngx_http_request_empty_handler;

  1969.     ngx_http_finalize_request(r, rc);
  1970. }


  1971. static void
  1972. ngx_http_request_finalizer(ngx_http_request_t *r)
  1973. {
  1974.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  1975.                    "http finalizer done: \"%V?%V\"", &r->uri, &r->args);

  1976.     ngx_http_finalize_request(r, 0);
  1977. }


  1978. void
  1979. ngx_http_block_reading(ngx_http_request_t *r)
  1980. {
  1981.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  1982.                    "http reading blocked");

  1983.     /* aio does not call this handler */

  1984.     if ((ngx_event_flags & NGX_USE_LEVEL_EVENT)
  1985.         && r->connection->read->active)
  1986.     {
  1987.         if (ngx_del_event(r->connection->read, NGX_READ_EVENT, 0) != NGX_OK) {
  1988.             ngx_http_close_request(r, 0);
  1989.         }
  1990.     }
  1991. }


  1992. void
  1993. ngx_http_test_reading(ngx_http_request_t *r)
  1994. {
  1995.     int                n;
  1996.     char               buf[1];
  1997.     ngx_err_t          err;
  1998.     ngx_event_t       *rev;
  1999.     ngx_connection_t  *c;

  2000.     c = r->connection;
  2001.     rev = c->read;

  2002.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http test reading");

  2003. #if (NGX_HTTP_SPDY)

  2004.     if (r->spdy_stream) {
  2005.         if (c->error) {
  2006.             err = 0;
  2007.             goto closed;
  2008.         }

  2009.         return;
  2010.     }

  2011. #endif

  2012. #if (NGX_HAVE_KQUEUE)

  2013.     if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {

  2014.         if (!rev->pending_eof) {
  2015.             return;
  2016.         }

  2017.         rev->eof = 1;
  2018.         c->error = 1;
  2019.         err = rev->kq_errno;

  2020.         goto closed;
  2021.     }

  2022. #endif

  2023. #if (NGX_HAVE_EPOLLRDHUP)

  2024.     if ((ngx_event_flags & NGX_USE_EPOLL_EVENT) && rev->pending_eof) {
  2025.         socklen_t  len;

  2026.         rev->eof = 1;
  2027.         c->error = 1;

  2028.         err = 0;
  2029.         len = sizeof(ngx_err_t);

  2030.         /*
  2031.          * BSDs and Linux return 0 and set a pending error in err
  2032.          * Solaris returns -1 and sets errno
  2033.          */

  2034.         if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len)
  2035.             == -1)
  2036.         {
  2037.             err = ngx_socket_errno;
  2038.         }

  2039.         goto closed;
  2040.     }

  2041. #endif

  2042.     n = recv(c->fd, buf, 1, MSG_PEEK);

  2043.     if (n == 0) {
  2044.         rev->eof = 1;
  2045.         c->error = 1;
  2046.         err = 0;

  2047.         goto closed;

  2048.     } else if (n == -1) {
  2049.         err = ngx_socket_errno;

  2050.         if (err != NGX_EAGAIN) {
  2051.             rev->eof = 1;
  2052.             c->error = 1;

  2053.             goto closed;
  2054.         }
  2055.     }

  2056.     /* aio does not call this handler */

  2057.     if ((ngx_event_flags & NGX_USE_LEVEL_EVENT) && rev->active) {

  2058.         if (ngx_del_event(rev, NGX_READ_EVENT, 0) != NGX_OK) {
  2059.             ngx_http_close_request(r, 0);
  2060.         }
  2061.     }

  2062.     return;

  2063. closed:

  2064.     if (err) {
  2065.         rev->error = 1;
  2066.     }

  2067.     ngx_log_error(NGX_LOG_INFO, c->log, err,
  2068.                   "client prematurely closed connection");

  2069.     ngx_http_finalize_request(r, NGX_HTTP_CLIENT_CLOSED_REQUEST);
  2070. }


  2071. static void
  2072. ngx_http_set_keepalive(ngx_http_request_t *r)
  2073. {
  2074.     int                        tcp_nodelay;
  2075.     ngx_int_t                  i;
  2076.     ngx_buf_t                 *b, *f;
  2077.     ngx_event_t               *rev, *wev;
  2078.     ngx_connection_t          *c;
  2079.     ngx_http_connection_t     *hc;
  2080.     ngx_http_core_srv_conf_t  *cscf;
  2081.     ngx_http_core_loc_conf_t  *clcf;

  2082.     c = r->connection;
  2083.     rev = c->read;

  2084.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  2085.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "set http keepalive handler");

  2086.     if (r->discard_body) {
  2087.         r->write_event_handler = ngx_http_request_empty_handler;
  2088.         r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000);
  2089.         ngx_add_timer(rev, clcf->lingering_timeout);
  2090.         return;
  2091.     }

  2092.     c->log->action = "closing request";

  2093.     hc = r->http_connection;
  2094.     b = r->header_in;

  2095.     if (b->pos < b->last) {

  2096.         /* the pipelined request */

  2097.         if (b != c->buffer) {

  2098.             /*
  2099.              * If the large header buffers were allocated while the previous
  2100.              * request processing then we do not use c->buffer for
  2101.              * the pipelined request (see ngx_http_create_request()).
  2102.              *
  2103.              * Now we would move the large header buffers to the free list.
  2104.              */

  2105.             cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);

  2106.             if (hc->free == NULL) {
  2107.                 hc->free = ngx_palloc(c->pool,
  2108.                   cscf->large_client_header_buffers.num * sizeof(ngx_buf_t *));

  2109.                 if (hc->free == NULL) {
  2110.                     ngx_http_close_request(r, 0);
  2111.                     return;
  2112.                 }
  2113.             }

  2114.             for (i = 0; i < hc->nbusy - 1; i++) {
  2115.                 f = hc->busy[i];
  2116.                 hc->free[hc->nfree++] = f;
  2117.                 f->pos = f->start;
  2118.                 f->last = f->start;
  2119.             }

  2120.             hc->busy[0] = b;
  2121.             hc->nbusy = 1;
  2122.         }
  2123.     }

  2124.     /* guard against recursive call from ngx_http_finalize_connection() */
  2125.     r->keepalive = 0;

  2126.     ngx_http_free_request(r, 0);

  2127.     c->data = hc;

  2128.     if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  2129.         ngx_http_close_connection(c);
  2130.         return;
  2131.     }

  2132.     wev = c->write;
  2133.     wev->handler = ngx_http_empty_handler;

  2134.     if (b->pos < b->last) {

  2135.         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "pipelined request");

  2136.         c->log->action = "reading client pipelined request line";

  2137.         r = ngx_http_create_request(c);
  2138.         if (r == NULL) {
  2139.             ngx_http_close_connection(c);
  2140.             return;
  2141.         }

  2142.         r->pipeline = 1;

  2143.         c->data = r;

  2144.         c->sent = 0;
  2145.         c->destroyed = 0;

  2146.         if (rev->timer_set) {
  2147.             ngx_del_timer(rev);
  2148.         }

  2149.         rev->handler = ngx_http_process_request_line;
  2150.         ngx_post_event(rev, &ngx_posted_events);
  2151.         return;
  2152.     }

  2153.     /*
  2154.      * To keep a memory footprint as small as possible for an idle keepalive
  2155.      * connection we try to free c->buffer's memory if it was allocated outside
  2156.      * the c->pool.  The large header buffers are always allocated outside the
  2157.      * c->pool and are freed too.
  2158.      */

  2159.     b = c->buffer;

  2160.     if (ngx_pfree(c->pool, b->start) == NGX_OK) {

  2161.         /*
  2162.          * the special note for ngx_http_keepalive_handler() that
  2163.          * c->buffer's memory was freed
  2164.          */

  2165.         b->pos = NULL;

  2166.     } else {
  2167.         b->pos = b->start;
  2168.         b->last = b->start;
  2169.     }

  2170.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc free: %p %d",
  2171.                    hc->free, hc->nfree);

  2172.     if (hc->free) {
  2173.         for (i = 0; i < hc->nfree; i++) {
  2174.             ngx_pfree(c->pool, hc->free[i]->start);
  2175.             hc->free[i] = NULL;
  2176.         }

  2177.         hc->nfree = 0;
  2178.     }

  2179.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc busy: %p %d",
  2180.                    hc->busy, hc->nbusy);

  2181.     if (hc->busy) {
  2182.         for (i = 0; i < hc->nbusy; i++) {
  2183.             ngx_pfree(c->pool, hc->busy[i]->start);
  2184.             hc->busy[i] = NULL;
  2185.         }

  2186.         hc->nbusy = 0;
  2187.     }

  2188. #if (NGX_HTTP_SSL)
  2189.     if (c->ssl) {
  2190.         ngx_ssl_free_buffer(c);
  2191.     }
  2192. #endif

  2193.     rev->handler = ngx_http_keepalive_handler;

  2194.     if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
  2195.         if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) != NGX_OK) {
  2196.             ngx_http_close_connection(c);
  2197.             return;
  2198.         }
  2199.     }

  2200.     c->log->action = "keepalive";

  2201.     if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
  2202.         if (ngx_tcp_push(c->fd) == -1) {
  2203.             ngx_connection_error(c, ngx_socket_errno, ngx_tcp_push_n " failed");
  2204.             ngx_http_close_connection(c);
  2205.             return;
  2206.         }

  2207.         c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
  2208.         tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0;

  2209.     } else {
  2210.         tcp_nodelay = 1;
  2211.     }

  2212.     if (tcp_nodelay
  2213.         && clcf->tcp_nodelay
  2214.         && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET)
  2215.     {
  2216.         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");

  2217.         if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
  2218.                        (const void *) &tcp_nodelay, sizeof(int))
  2219.             == -1)
  2220.         {
  2221. #if (NGX_SOLARIS)
  2222.             /* Solaris returns EINVAL if a socket has been shut down */
  2223.             c->log_error = NGX_ERROR_IGNORE_EINVAL;
  2224. #endif

  2225.             ngx_connection_error(c, ngx_socket_errno,
  2226.                                  "setsockopt(TCP_NODELAY) failed");

  2227.             c->log_error = NGX_ERROR_INFO;
  2228.             ngx_http_close_connection(c);
  2229.             return;
  2230.         }

  2231.         c->tcp_nodelay = NGX_TCP_NODELAY_SET;
  2232.     }

  2233. #if 0
  2234.     /* if ngx_http_request_t was freed then we need some other place */
  2235.     r->http_state = NGX_HTTP_KEEPALIVE_STATE;
  2236. #endif

  2237.     c->idle = 1;
  2238.     ngx_reusable_connection(c, 1);

  2239.     ngx_add_timer(rev, clcf->keepalive_timeout);

  2240.     if (rev->ready) {
  2241.         ngx_post_event(rev, &ngx_posted_events);
  2242.     }
  2243. }


  2244. static void
  2245. ngx_http_keepalive_handler(ngx_event_t *rev)
  2246. {
  2247.     size_t             size;
  2248.     ssize_t            n;
  2249.     ngx_buf_t         *b;
  2250.     ngx_connection_t  *c;

  2251.     c = rev->data;

  2252.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http keepalive handler");

  2253.     if (rev->timedout || c->close) {
  2254.         ngx_http_close_connection(c);
  2255.         return;
  2256.     }

  2257. #if (NGX_HAVE_KQUEUE)

  2258.     if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
  2259.         if (rev->pending_eof) {
  2260.             c->log->handler = NULL;
  2261.             ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno,
  2262.                           "kevent() reported that client %V closed "
  2263.                           "keepalive connection", &c->addr_text);
  2264. #if (NGX_HTTP_SSL)
  2265.             if (c->ssl) {
  2266.                 c->ssl->no_send_shutdown = 1;
  2267.             }
  2268. #endif
  2269.             ngx_http_close_connection(c);
  2270.             return;
  2271.         }
  2272.     }

  2273. #endif

  2274.     b = c->buffer;
  2275.     size = b->end - b->start;

  2276.     if (b->pos == NULL) {

  2277.         /*
  2278.          * The c->buffer's memory was freed by ngx_http_set_keepalive().
  2279.          * However, the c->buffer->start and c->buffer->end were not changed
  2280.          * to keep the buffer size.
  2281.          */

  2282.         b->pos = ngx_palloc(c->pool, size);
  2283.         if (b->pos == NULL) {
  2284.             ngx_http_close_connection(c);
  2285.             return;
  2286.         }

  2287.         b->start = b->pos;
  2288.         b->last = b->pos;
  2289.         b->end = b->pos + size;
  2290.     }

  2291.     /*
  2292.      * MSIE closes a keepalive connection with RST flag
  2293.      * so we ignore ECONNRESET here.
  2294.      */

  2295.     c->log_error = NGX_ERROR_IGNORE_ECONNRESET;
  2296.     ngx_set_socket_errno(0);

  2297.     n = c->recv(c, b->last, size);
  2298.     c->log_error = NGX_ERROR_INFO;

  2299.     if (n == NGX_AGAIN) {
  2300.         if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  2301.             ngx_http_close_connection(c);
  2302.             return;
  2303.         }

  2304.         /*
  2305.          * Like ngx_http_set_keepalive() we are trying to not hold
  2306.          * c->buffer's memory for a keepalive connection.
  2307.          */

  2308.         if (ngx_pfree(c->pool, b->start) == NGX_OK) {

  2309.             /*
  2310.              * the special note that c->buffer's memory was freed
  2311.              */

  2312.             b->pos = NULL;
  2313.         }

  2314.         return;
  2315.     }

  2316.     if (n == NGX_ERROR) {
  2317.         ngx_http_close_connection(c);
  2318.         return;
  2319.     }

  2320.     c->log->handler = NULL;

  2321.     if (n == 0) {
  2322.         ngx_log_error(NGX_LOG_INFO, c->log, ngx_socket_errno,
  2323.                       "client %V closed keepalive connection", &c->addr_text);
  2324.         ngx_http_close_connection(c);
  2325.         return;
  2326.     }

  2327.     b->last += n;

  2328.     c->log->handler = ngx_http_log_error;
  2329.     c->log->action = "reading client request line";

  2330.     c->idle = 0;
  2331.     ngx_reusable_connection(c, 0);

  2332.     c->data = ngx_http_create_request(c);
  2333.     if (c->data == NULL) {
  2334.         ngx_http_close_connection(c);
  2335.         return;
  2336.     }

  2337.     c->sent = 0;
  2338.     c->destroyed = 0;

  2339.     ngx_del_timer(rev);

  2340.     rev->handler = ngx_http_process_request_line;
  2341.     ngx_http_process_request_line(rev);
  2342. }


  2343. static void
  2344. ngx_http_set_lingering_close(ngx_http_request_t *r)
  2345. {
  2346.     ngx_event_t               *rev, *wev;
  2347.     ngx_connection_t          *c;
  2348.     ngx_http_core_loc_conf_t  *clcf;

  2349.     c = r->connection;

  2350.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  2351.     rev = c->read;
  2352.     rev->handler = ngx_http_lingering_close_handler;

  2353.     r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000);
  2354.     ngx_add_timer(rev, clcf->lingering_timeout);

  2355.     if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  2356.         ngx_http_close_request(r, 0);
  2357.         return;
  2358.     }

  2359.     wev = c->write;
  2360.     wev->handler = ngx_http_empty_handler;

  2361.     if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
  2362.         if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) != NGX_OK) {
  2363.             ngx_http_close_request(r, 0);
  2364.             return;
  2365.         }
  2366.     }

  2367.     if (ngx_shutdown_socket(c->fd, NGX_WRITE_SHUTDOWN) == -1) {
  2368.         ngx_connection_error(c, ngx_socket_errno,
  2369.                              ngx_shutdown_socket_n " failed");
  2370.         ngx_http_close_request(r, 0);
  2371.         return;
  2372.     }

  2373.     if (rev->ready) {
  2374.         ngx_http_lingering_close_handler(rev);
  2375.     }
  2376. }


  2377. static void
  2378. ngx_http_lingering_close_handler(ngx_event_t *rev)
  2379. {
  2380.     ssize_t                    n;
  2381.     ngx_msec_t                 timer;
  2382.     ngx_connection_t          *c;
  2383.     ngx_http_request_t        *r;
  2384.     ngx_http_core_loc_conf_t  *clcf;
  2385.     u_char                     buffer[NGX_HTTP_LINGERING_BUFFER_SIZE];

  2386.     c = rev->data;
  2387.     r = c->data;

  2388.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
  2389.                    "http lingering close handler");

  2390.     if (rev->timedout) {
  2391.         ngx_http_close_request(r, 0);
  2392.         return;
  2393.     }

  2394.     timer = (ngx_msec_t) r->lingering_time - (ngx_msec_t) ngx_time();
  2395.     if ((ngx_msec_int_t) timer <= 0) {
  2396.         ngx_http_close_request(r, 0);
  2397.         return;
  2398.     }

  2399.     do {
  2400.         n = c->recv(c, buffer, NGX_HTTP_LINGERING_BUFFER_SIZE);

  2401.         ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "lingering read: %d", n);

  2402.         if (n == NGX_ERROR || n == 0) {
  2403.             ngx_http_close_request(r, 0);
  2404.             return;
  2405.         }

  2406.     } while (rev->ready);

  2407.     if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  2408.         ngx_http_close_request(r, 0);
  2409.         return;
  2410.     }

  2411.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  2412.     timer *= 1000;

  2413.     if (timer > clcf->lingering_timeout) {
  2414.         timer = clcf->lingering_timeout;
  2415.     }

  2416.     ngx_add_timer(rev, timer);
  2417. }


  2418. void
  2419. ngx_http_empty_handler(ngx_event_t *wev)
  2420. {
  2421.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, "http empty handler");

  2422.     return;
  2423. }


  2424. void
  2425. ngx_http_request_empty_handler(ngx_http_request_t *r)
  2426. {
  2427.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  2428.                    "http request empty handler");

  2429.     return;
  2430. }


  2431. ngx_int_t
  2432. ngx_http_send_special(ngx_http_request_t *r, ngx_uint_t flags)
  2433. {
  2434.     ngx_buf_t    *b;
  2435.     ngx_chain_t   out;

  2436.     b = ngx_calloc_buf(r->pool);
  2437.     if (b == NULL) {
  2438.         return NGX_ERROR;
  2439.     }

  2440.     if (flags & NGX_HTTP_LAST) {

  2441.         if (r == r->main && !r->post_action) {
  2442.             b->last_buf = 1;

  2443.         } else {
  2444.             b->sync = 1;
  2445.             b->last_in_chain = 1;
  2446.         }
  2447.     }

  2448.     if (flags & NGX_HTTP_FLUSH) {
  2449.         b->flush = 1;
  2450.     }

  2451.     out.buf = b;
  2452.     out.next = NULL;

  2453.     return ngx_http_output_filter(r, &out);
  2454. }


  2455. static ngx_int_t
  2456. ngx_http_post_action(ngx_http_request_t *r)
  2457. {
  2458.     ngx_http_core_loc_conf_t  *clcf;

  2459.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  2460.     if (clcf->post_action.data == NULL) {
  2461.         return NGX_DECLINED;
  2462.     }

  2463.     if (r->post_action && r->uri_changes == 0) {
  2464.         return NGX_DECLINED;
  2465.     }

  2466.     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  2467.                    "post action: \"%V\"", &clcf->post_action);

  2468.     r->main->count--;

  2469.     r->http_version = NGX_HTTP_VERSION_9;
  2470.     r->header_only = 1;
  2471.     r->post_action = 1;

  2472.     r->read_event_handler = ngx_http_block_reading;

  2473.     if (clcf->post_action.data[0] == '/') {
  2474.         ngx_http_internal_redirect(r, &clcf->post_action, NULL);

  2475.     } else {
  2476.         ngx_http_named_location(r, &clcf->post_action);
  2477.     }

  2478.     return NGX_OK;
  2479. }


  2480. static void
  2481. ngx_http_close_request(ngx_http_request_t *r, ngx_int_t rc)
  2482. {
  2483.     ngx_connection_t  *c;

  2484.     r = r->main;
  2485.     c = r->connection;

  2486.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
  2487.                    "http request count:%d blk:%d", r->count, r->blocked);

  2488.     if (r->count == 0) {
  2489.         ngx_log_error(NGX_LOG_ALERT, c->log, 0, "http request count is zero");
  2490.     }

  2491.     r->count--;

  2492.     if (r->count || r->blocked) {
  2493.         return;
  2494.     }

  2495. #if (NGX_HTTP_SPDY)
  2496.     if (r->spdy_stream) {
  2497.         ngx_http_spdy_close_stream(r->spdy_stream, rc);
  2498.         return;
  2499.     }
  2500. #endif

  2501.     ngx_http_free_request(r, rc);
  2502.     ngx_http_close_connection(c);
  2503. }


  2504. void
  2505. ngx_http_free_request(ngx_http_request_t *r, ngx_int_t rc)
  2506. {
  2507.     ngx_log_t                 *log;
  2508.     ngx_pool_t                *pool;
  2509.     struct linger              linger;
  2510.     ngx_http_cleanup_t        *cln;
  2511.     ngx_http_log_ctx_t        *ctx;
  2512.     ngx_http_core_loc_conf_t  *clcf;

  2513.     log = r->connection->log;

  2514.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0, "http close request");

  2515.     if (r->pool == NULL) {
  2516.         ngx_log_error(NGX_LOG_ALERT, log, 0, "http request already closed");
  2517.         return;
  2518.     }

  2519.     cln = r->cleanup;
  2520.     r->cleanup = NULL;

  2521.     while (cln) {
  2522.         if (cln->handler) {
  2523.             cln->handler(cln->data);
  2524.         }

  2525.         cln = cln->next;
  2526.     }

  2527. #if (NGX_STAT_STUB)

  2528.     if (r->stat_reading) {
  2529.         (void) ngx_atomic_fetch_add(ngx_stat_reading, -1);
  2530.     }

  2531.     if (r->stat_writing) {
  2532.         (void) ngx_atomic_fetch_add(ngx_stat_writing, -1);
  2533.     }

  2534. #endif

  2535.     if (rc > 0 && (r->headers_out.status == 0 || r->connection->sent == 0)) {
  2536.         r->headers_out.status = rc;
  2537.     }

  2538.     log->action = "logging request";

  2539.     ngx_http_log_request(r);

  2540.     log->action = "closing request";

  2541.     if (r->connection->timedout) {
  2542.         clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  2543.         if (clcf->reset_timedout_connection) {
  2544.             linger.l_onoff = 1;
  2545.             linger.l_linger = 0;

  2546.             if (setsockopt(r->connection->fd, SOL_SOCKET, SO_LINGER,
  2547.                            (const void *) &linger, sizeof(struct linger)) == -1)
  2548.             {
  2549.                 ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno,
  2550.                               "setsockopt(SO_LINGER) failed");
  2551.             }
  2552.         }
  2553.     }

  2554.     /* the various request strings were allocated from r->pool */
  2555.     ctx = log->data;
  2556.     ctx->request = NULL;

  2557.     r->request_line.len = 0;

  2558.     r->connection->destroyed = 1;

  2559.     /*
  2560.      * Setting r->pool to NULL will increase probability to catch double close
  2561.      * of request since the request object is allocated from its own pool.
  2562.      */

  2563.     pool = r->pool;
  2564.     r->pool = NULL;

  2565.     ngx_destroy_pool(pool);
  2566. }


  2567. static void
  2568. ngx_http_log_request(ngx_http_request_t *r)
  2569. {
  2570.     ngx_uint_t                  i, n;
  2571.     ngx_http_handler_pt        *log_handler;
  2572.     ngx_http_core_main_conf_t  *cmcf;

  2573.     cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

  2574.     log_handler = cmcf->phases[NGX_HTTP_LOG_PHASE].handlers.elts;
  2575.     n = cmcf->phases[NGX_HTTP_LOG_PHASE].handlers.nelts;

  2576.     for (i = 0; i < n; i++) {
  2577.         log_handler[i](r);
  2578.     }
  2579. }


  2580. void
  2581. ngx_http_close_connection(ngx_connection_t *c)
  2582. {
  2583.     ngx_pool_t  *pool;

  2584.     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
  2585.                    "close http connection: %d", c->fd);

  2586. #if (NGX_HTTP_SSL)

  2587.     if (c->ssl) {
  2588.         if (ngx_ssl_shutdown(c) == NGX_AGAIN) {
  2589.             c->ssl->handler = ngx_http_close_connection;
  2590.             return;
  2591.         }
  2592.     }

  2593. #endif

  2594. #if (NGX_STAT_STUB)
  2595.     (void) ngx_atomic_fetch_add(ngx_stat_active, -1);
  2596. #endif

  2597.     c->destroyed = 1;

  2598.     pool = c->pool;

  2599.     ngx_close_connection(c);

  2600.     ngx_destroy_pool(pool);
  2601. }


  2602. static u_char *
  2603. ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len)
  2604. {
  2605.     u_char              *p;
  2606.     ngx_http_request_t  *r;
  2607.     ngx_http_log_ctx_t  *ctx;

  2608.     if (log->action) {
  2609.         p = ngx_snprintf(buf, len, " while %s", log->action);
  2610.         len -= p - buf;
  2611.         buf = p;
  2612.     }

  2613.     ctx = log->data;

  2614.     p = ngx_snprintf(buf, len, ", client: %V", &ctx->connection->addr_text);
  2615.     len -= p - buf;

  2616.     r = ctx->request;

  2617.     if (r) {
  2618.         return r->log_handler(r, ctx->current_request, p, len);

  2619.     } else {
  2620.         p = ngx_snprintf(p, len, ", server: %V",
  2621.                          &ctx->connection->listening->addr_text);
  2622.     }

  2623.     return p;
  2624. }


  2625. static u_char *
  2626. ngx_http_log_error_handler(ngx_http_request_t *r, ngx_http_request_t *sr,
  2627.     u_char *buf, size_t len)
  2628. {
  2629.     char                      *uri_separator;
  2630.     u_char                    *p;
  2631.     ngx_http_upstream_t       *u;
  2632.     ngx_http_core_srv_conf_t  *cscf;

  2633.     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);

  2634.     p = ngx_snprintf(buf, len, ", server: %V", &cscf->server_name);
  2635.     len -= p - buf;
  2636.     buf = p;

  2637.     if (r->request_line.data == NULL && r->request_start) {
  2638.         for (p = r->request_start; p < r->header_in->last; p++) {
  2639.             if (*p == CR || *p == LF) {
  2640.                 break;
  2641.             }
  2642.         }

  2643.         r->request_line.len = p - r->request_start;
  2644.         r->request_line.data = r->request_start;
  2645.     }

  2646.     if (r->request_line.len) {
  2647.         p = ngx_snprintf(buf, len, ", request: \"%V\"", &r->request_line);
  2648.         len -= p - buf;
  2649.         buf = p;
  2650.     }

  2651.     if (r != sr) {
  2652.         p = ngx_snprintf(buf, len, ", subrequest: \"%V\"", &sr->uri);
  2653.         len -= p - buf;
  2654.         buf = p;
  2655.     }

  2656.     u = sr->upstream;

  2657.     if (u && u->peer.name) {

  2658.         uri_separator = "";

  2659. #if (NGX_HAVE_UNIX_DOMAIN)
  2660.         if (u->peer.sockaddr && u->peer.sockaddr->sa_family == AF_UNIX) {
  2661.             uri_separator = ":";
  2662.         }
  2663. #endif

  2664.         p = ngx_snprintf(buf, len, ", upstream: \"%V%V%s%V\"",
  2665.                          &u->schema, u->peer.name,
  2666.                          uri_separator, &u->uri);
  2667.         len -= p - buf;
  2668.         buf = p;
  2669.     }

  2670.     if (r->headers_in.host) {
  2671.         p = ngx_snprintf(buf, len, ", host: \"%V\"",
  2672.                          &r->headers_in.host->value);
  2673.         len -= p - buf;
  2674.         buf = p;
  2675.     }

  2676.     if (r->headers_in.referer) {
  2677.         p = ngx_snprintf(buf, len, ", referrer: \"%V\"",
  2678.                          &r->headers_in.referer->value);
  2679.         buf = p;
  2680.     }

  2681.     return buf;
  2682. }