src/http/ngx_http_request.c - nginx

Global variables defined

Data types 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 ngx_http_request_t *ngx_http_alloc_request(ngx_connection_t *c);
  10. static void ngx_http_process_request_line(ngx_event_t *rev);
  11. static void ngx_http_process_request_headers(ngx_event_t *rev);
  12. static ssize_t ngx_http_read_request_header(ngx_http_request_t *r);
  13. static ngx_int_t ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
  14.     ngx_uint_t request_line);

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

  27. static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r);
  28. static ngx_int_t ngx_http_find_virtual_server(ngx_connection_t *c,
  29.     ngx_http_virtual_names_t *virtual_names, ngx_str_t *host,
  30.     ngx_http_request_t *r, ngx_http_core_srv_conf_t **cscfp);

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

  38. static void ngx_http_set_keepalive(ngx_http_request_t *r);
  39. static void ngx_http_keepalive_handler(ngx_event_t *ev);
  40. static void ngx_http_set_lingering_close(ngx_connection_t *c);
  41. static void ngx_http_lingering_close_handler(ngx_event_t *ev);
  42. static ngx_int_t ngx_http_post_action(ngx_http_request_t *r);
  43. static void ngx_http_log_request(ngx_http_request_t *r);

  44. static u_char *ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len);
  45. static u_char *ngx_http_log_error_handler(ngx_http_request_t *r,
  46.     ngx_http_request_t *sr, u_char *buf, size_t len);

  47. #if (NGX_HTTP_SSL)
  48. static void ngx_http_ssl_handshake(ngx_event_t *rev);
  49. static void ngx_http_ssl_handshake_handler(ngx_connection_t *c);
  50. #endif


  51. static char *ngx_http_client_errors[] = {

  52.     /* NGX_HTTP_PARSE_INVALID_METHOD */
  53.     "client sent invalid method",

  54.     /* NGX_HTTP_PARSE_INVALID_REQUEST */
  55.     "client sent invalid request",

  56.     /* NGX_HTTP_PARSE_INVALID_VERSION */
  57.     "client sent invalid version",

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


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

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

  66.     { ngx_string("Proxy-Connection"), 0,
  67.                  ngx_http_process_proxy_connection },

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

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

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

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

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

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

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

  87.     { ngx_string("Content-Range"),
  88.                  offsetof(ngx_http_headers_in_t, content_range),
  89.                  ngx_http_process_unique_header_line },

  90.     { ngx_string("Content-Type"),
  91.                  offsetof(ngx_http_headers_in_t, content_type),
  92.                  ngx_http_process_header_line },

  93.     { ngx_string("Range"), offsetof(ngx_http_headers_in_t, range),
  94.                  ngx_http_process_header_line },

  95.     { ngx_string("If-Range"),
  96.                  offsetof(ngx_http_headers_in_t, if_range),
  97.                  ngx_http_process_unique_header_line },

  98.     { ngx_string("Transfer-Encoding"),
  99.                  offsetof(ngx_http_headers_in_t, transfer_encoding),
  100.                  ngx_http_process_unique_header_line },

  101.     { ngx_string("TE"),
  102.                  offsetof(ngx_http_headers_in_t, te),
  103.                  ngx_http_process_header_line },

  104.     { ngx_string("Expect"),
  105.                  offsetof(ngx_http_headers_in_t, expect),
  106.                  ngx_http_process_unique_header_line },

  107.     { ngx_string("Upgrade"),
  108.                  offsetof(ngx_http_headers_in_t, upgrade),
  109.                  ngx_http_process_header_line },

  110. #if (NGX_HTTP_GZIP || NGX_HTTP_HEADERS)
  111.     { ngx_string("Accept-Encoding"),
  112.                  offsetof(ngx_http_headers_in_t, accept_encoding),
  113.                  ngx_http_process_header_line },

  114.     { ngx_string("Via"), offsetof(ngx_http_headers_in_t, via),
  115.                  ngx_http_process_header_line },
  116. #endif

  117.     { ngx_string("Authorization"),
  118.                  offsetof(ngx_http_headers_in_t, authorization),
  119.                  ngx_http_process_unique_header_line },

  120.     { ngx_string("Proxy-Authorization"),
  121.                  offsetof(ngx_http_headers_in_t, proxy_authorization),
  122.                  ngx_http_process_unique_header_line },

  123.     { ngx_string("Keep-Alive"), offsetof(ngx_http_headers_in_t, keep_alive),
  124.                  ngx_http_process_header_line },

  125. #if (NGX_HTTP_X_FORWARDED_FOR)
  126.     { ngx_string("X-Forwarded-For"),
  127.                  offsetof(ngx_http_headers_in_t, x_forwarded_for),
  128.                  ngx_http_process_header_line },
  129. #endif

  130. #if (NGX_HTTP_REALIP)
  131.     { ngx_string("X-Real-IP"),
  132.                  offsetof(ngx_http_headers_in_t, x_real_ip),
  133.                  ngx_http_process_header_line },
  134. #endif

  135. #if (NGX_HTTP_HEADERS)
  136.     { ngx_string("Accept"), offsetof(ngx_http_headers_in_t, accept),
  137.                  ngx_http_process_header_line },

  138.     { ngx_string("Accept-Language"),
  139.                  offsetof(ngx_http_headers_in_t, accept_language),
  140.                  ngx_http_process_header_line },
  141. #endif

  142. #if (NGX_HTTP_DAV)
  143.     { ngx_string("Depth"), offsetof(ngx_http_headers_in_t, depth),
  144.                  ngx_http_process_header_line },

  145.     { ngx_string("Destination"), offsetof(ngx_http_headers_in_t, destination),
  146.                  ngx_http_process_header_line },

  147.     { ngx_string("Overwrite"), offsetof(ngx_http_headers_in_t, overwrite),
  148.                  ngx_http_process_header_line },

  149.     { ngx_string("Date"), offsetof(ngx_http_headers_in_t, date),
  150.                  ngx_http_process_header_line },
  151. #endif

  152.     { ngx_string("Cookie"), offsetof(ngx_http_headers_in_t, cookie),
  153.                  ngx_http_process_header_line },

  154.     { ngx_null_string, 0, NULL }
  155. };


  156. void
  157. ngx_http_init_connection(ngx_connection_t *c)
  158. {
  159.     ngx_uint_t                 i;
  160.     ngx_event_t               *rev;
  161.     struct sockaddr_in        *sin;
  162.     ngx_http_port_t           *port;
  163.     ngx_http_in_addr_t        *addr;
  164.     ngx_http_log_ctx_t        *ctx;
  165.     ngx_http_connection_t     *hc;
  166.     ngx_http_core_srv_conf_t  *cscf;
  167. #if (NGX_HAVE_INET6)
  168.     struct sockaddr_in6       *sin6;
  169.     ngx_http_in6_addr_t       *addr6;
  170. #endif

  171.     hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t));
  172.     if (hc == NULL) {
  173.         ngx_http_close_connection(c);
  174.         return;
  175.     }

  176.     c->data = hc;

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

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

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

  180.         /*
  181.          * there are several addresses on this port and one of them
  182.          * is an "*:port" wildcard so getsockname() in ngx_http_server_addr()
  183.          * is required to determine a server address
  184.          */

  185.         if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) {
  186.             ngx_http_close_connection(c);
  187.             return;
  188.         }

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

  190. #if (NGX_HAVE_INET6)
  191.         case AF_INET6:
  192.             sin6 = (struct sockaddr_in6 *) c->local_sockaddr;

  193.             addr6 = port->addrs;

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

  195.             for (i = 0; i < port->naddrs - 1; i++) {
  196.                 if (ngx_memcmp(&addr6[i].addr6, &sin6->sin6_addr, 16) == 0) {
  197.                     break;
  198.                 }
  199.             }

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

  201.             break;
  202. #endif

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

  205.             addr = port->addrs;

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

  207.             for (i = 0; i < port->naddrs - 1; i++) {
  208.                 if (addr[i].addr == sin->sin_addr.s_addr) {
  209.                     break;
  210.                 }
  211.             }

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

  213.             break;
  214.         }

  215.     } else {

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

  217. #if (NGX_HAVE_INET6)
  218.         case AF_INET6:
  219.             addr6 = port->addrs;
  220.             hc->addr_conf = &addr6[0].conf;
  221.             break;
  222. #endif

  223.         default: /* AF_INET */
  224.             addr = port->addrs;
  225.             hc->addr_conf = &addr[0].conf;
  226.             break;
  227.         }
  228.     }

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

  231.     ctx = ngx_palloc(c->pool, sizeof(ngx_http_log_ctx_t));
  232.     if (ctx == NULL) {
  233.         ngx_http_close_connection(c);
  234.         return;
  235.     }

  236.     ctx->connection = c;
  237.     ctx->request = NULL;
  238.     ctx->current_request = NULL;

  239.     c->log->connection = c->number;
  240.     c->log->handler = ngx_http_log_error;
  241.     c->log->data = ctx;
  242.     c->log->action = "waiting for request";

  243.     c->log_error = NGX_ERROR_INFO;

  244.     rev = c->read;
  245.     rev->handler = ngx_http_wait_request_handler;
  246.     c->write->handler = ngx_http_empty_handler;

  247. #if (NGX_HTTP_V3)
  248.     if (hc->addr_conf->quic) {
  249.         ngx_http_v3_init_stream(c);
  250.         return;
  251.     }
  252. #endif

  253. #if (NGX_HTTP_SSL)
  254.     if (hc->addr_conf->ssl) {
  255.         hc->ssl = 1;
  256.         c->log->action = "SSL handshaking";
  257.         rev->handler = ngx_http_ssl_handshake;
  258.     }
  259. #endif

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

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

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

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

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

  274.     ngx_add_timer(rev, cscf->client_header_timeout);
  275.     ngx_reusable_connection(c, 1);

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


  281. static void
  282. ngx_http_wait_request_handler(ngx_event_t *rev)
  283. {
  284.     u_char                    *p;
  285.     size_t                     size;
  286.     ssize_t                    n;
  287.     ngx_buf_t                 *b;
  288.     ngx_connection_t          *c;
  289.     ngx_http_connection_t     *hc;
  290. #if (NGX_HTTP_V2)
  291.     ngx_http_v2_srv_conf_t    *h2scf;
  292. #endif
  293.     ngx_http_core_srv_conf_t  *cscf;

  294.     c = rev->data;

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

  296.     if (rev->timedout) {
  297.         ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
  298.         ngx_http_close_connection(c);
  299.         return;
  300.     }

  301.     if (c->close) {
  302.         ngx_http_close_connection(c);
  303.         return;
  304.     }

  305.     hc = c->data;
  306.     cscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_core_module);

  307.     size = cscf->client_header_buffer_size;

  308.     b = c->buffer;

  309.     if (b == NULL) {
  310.         b = ngx_create_temp_buf(c->pool, size);
  311.         if (b == NULL) {
  312.             ngx_http_close_connection(c);
  313.             return;
  314.         }

  315.         c->buffer = b;

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

  317.         b->start = ngx_palloc(c->pool, size);
  318.         if (b->start == NULL) {
  319.             ngx_http_close_connection(c);
  320.             return;
  321.         }

  322.         b->pos = b->start;
  323.         b->last = b->start;
  324.         b->end = b->last + size;
  325.     }

  326.     size = b->end - b->last;

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

  328.     if (n == NGX_AGAIN) {

  329.         if (!rev->timer_set) {
  330.             ngx_add_timer(rev, cscf->client_header_timeout);
  331.             ngx_reusable_connection(c, 1);
  332.         }

  333.         if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  334.             ngx_http_close_connection(c);
  335.             return;
  336.         }

  337.         if (b->pos == b->last) {

  338.             /*
  339.              * We are trying to not hold c->buffer's memory for an
  340.              * idle connection.
  341.              */

  342.             if (ngx_pfree(c->pool, b->start) == NGX_OK) {
  343.                 b->start = NULL;
  344.             }
  345.         }

  346.         return;
  347.     }

  348.     if (n == NGX_ERROR) {
  349.         ngx_http_close_connection(c);
  350.         return;
  351.     }

  352.     if (n == 0) {
  353.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  354.                       "client closed connection");
  355.         ngx_http_close_connection(c);
  356.         return;
  357.     }

  358.     b->last += n;

  359.     if (hc->proxy_protocol) {
  360.         hc->proxy_protocol = 0;

  361.         p = ngx_proxy_protocol_read(c, b->pos, b->last);

  362.         if (p == NULL) {
  363.             ngx_http_close_connection(c);
  364.             return;
  365.         }

  366.         b->pos = p;

  367.         if (b->pos == b->last) {
  368.             c->log->action = "waiting for request";
  369.             b->pos = b->start;
  370.             b->last = b->start;
  371.             ngx_post_event(rev, &ngx_posted_events);
  372.             return;
  373.         }
  374.     }

  375. #if (NGX_HTTP_V2)

  376.     h2scf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_v2_module);

  377.     if (!hc->ssl && (h2scf->enable || hc->addr_conf->http2)) {

  378.         size = ngx_min(sizeof(NGX_HTTP_V2_PREFACE) - 1,
  379.                        (size_t) (b->last - b->pos));

  380.         if (ngx_memcmp(b->pos, NGX_HTTP_V2_PREFACE, size) == 0) {

  381.             if (size == sizeof(NGX_HTTP_V2_PREFACE) - 1) {
  382.                 ngx_http_v2_init(rev);
  383.                 return;
  384.             }

  385.             ngx_post_event(rev, &ngx_posted_events);
  386.             return;
  387.         }
  388.     }

  389. #endif

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

  391.     ngx_reusable_connection(c, 0);

  392.     c->data = ngx_http_create_request(c);
  393.     if (c->data == NULL) {
  394.         ngx_http_close_connection(c);
  395.         return;
  396.     }

  397.     rev->handler = ngx_http_process_request_line;
  398.     ngx_http_process_request_line(rev);
  399. }


  400. ngx_http_request_t *
  401. ngx_http_create_request(ngx_connection_t *c)
  402. {
  403.     ngx_http_request_t        *r;
  404.     ngx_http_log_ctx_t        *ctx;
  405.     ngx_http_core_loc_conf_t  *clcf;

  406.     r = ngx_http_alloc_request(c);
  407.     if (r == NULL) {
  408.         return NULL;
  409.     }

  410.     c->requests++;

  411.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  412.     ngx_set_connection_log(c, clcf->error_log);

  413.     ctx = c->log->data;
  414.     ctx->request = r;
  415.     ctx->current_request = r;

  416. #if (NGX_STAT_STUB)
  417.     (void) ngx_atomic_fetch_add(ngx_stat_reading, 1);
  418.     r->stat_reading = 1;
  419.     (void) ngx_atomic_fetch_add(ngx_stat_requests, 1);
  420. #endif

  421.     return r;
  422. }


  423. static ngx_http_request_t *
  424. ngx_http_alloc_request(ngx_connection_t *c)
  425. {
  426.     ngx_pool_t                 *pool;
  427.     ngx_time_t                 *tp;
  428.     ngx_http_request_t         *r;
  429.     ngx_http_connection_t      *hc;
  430.     ngx_http_core_srv_conf_t   *cscf;
  431.     ngx_http_core_main_conf_t  *cmcf;

  432.     hc = c->data;

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

  434.     pool = ngx_create_pool(cscf->request_pool_size, c->log);
  435.     if (pool == NULL) {
  436.         return NULL;
  437.     }

  438.     r = ngx_pcalloc(pool, sizeof(ngx_http_request_t));
  439.     if (r == NULL) {
  440.         ngx_destroy_pool(pool);
  441.         return NULL;
  442.     }

  443.     r->pool = pool;

  444.     r->http_connection = hc;
  445.     r->signature = NGX_HTTP_MODULE;
  446.     r->connection = c;

  447.     r->main_conf = hc->conf_ctx->main_conf;
  448.     r->srv_conf = hc->conf_ctx->srv_conf;
  449.     r->loc_conf = hc->conf_ctx->loc_conf;

  450.     r->read_event_handler = ngx_http_block_reading;

  451.     r->header_in = hc->busy ? hc->busy->buf : c->buffer;

  452.     if (ngx_list_init(&r->headers_out.headers, r->pool, 20,
  453.                       sizeof(ngx_table_elt_t))
  454.         != NGX_OK)
  455.     {
  456.         ngx_destroy_pool(r->pool);
  457.         return NULL;
  458.     }

  459.     if (ngx_list_init(&r->headers_out.trailers, r->pool, 4,
  460.                       sizeof(ngx_table_elt_t))
  461.         != NGX_OK)
  462.     {
  463.         ngx_destroy_pool(r->pool);
  464.         return NULL;
  465.     }

  466.     r->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
  467.     if (r->ctx == NULL) {
  468.         ngx_destroy_pool(r->pool);
  469.         return NULL;
  470.     }

  471.     cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

  472.     r->variables = ngx_pcalloc(r->pool, cmcf->variables.nelts
  473.                                         * sizeof(ngx_http_variable_value_t));
  474.     if (r->variables == NULL) {
  475.         ngx_destroy_pool(r->pool);
  476.         return NULL;
  477.     }

  478. #if (NGX_HTTP_SSL)
  479.     if (c->ssl && !c->ssl->sendfile) {
  480.         r->main_filter_need_in_memory = 1;
  481.     }
  482. #endif

  483.     r->main = r;
  484.     r->count = 1;

  485.     tp = ngx_timeofday();
  486.     r->start_sec = tp->sec;
  487.     r->start_msec = tp->msec;

  488.     r->method = NGX_HTTP_UNKNOWN;
  489.     r->http_version = NGX_HTTP_VERSION_10;

  490.     r->headers_in.content_length_n = -1;
  491.     r->headers_in.keep_alive_n = -1;
  492.     r->headers_out.content_length_n = -1;
  493.     r->headers_out.last_modified_time = -1;

  494.     r->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1;
  495.     r->subrequests = NGX_HTTP_MAX_SUBREQUESTS + 1;

  496.     r->http_state = NGX_HTTP_READING_REQUEST_STATE;

  497.     r->log_handler = ngx_http_log_error_handler;

  498.     return r;
  499. }


  500. #if (NGX_HTTP_SSL)

  501. static void
  502. ngx_http_ssl_handshake(ngx_event_t *rev)
  503. {
  504.     u_char                    *p, buf[NGX_PROXY_PROTOCOL_MAX_HEADER + 1];
  505.     size_t                     size;
  506.     ssize_t                    n;
  507.     ngx_err_t                  err;
  508.     ngx_int_t                  rc;
  509.     ngx_connection_t          *c;
  510.     ngx_http_connection_t     *hc;
  511.     ngx_http_ssl_srv_conf_t   *sscf;
  512.     ngx_http_core_loc_conf_t  *clcf;
  513.     ngx_http_core_srv_conf_t  *cscf;

  514.     c = rev->data;
  515.     hc = c->data;

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

  518.     if (rev->timedout) {
  519.         ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
  520.         ngx_http_close_connection(c);
  521.         return;
  522.     }

  523.     if (c->close) {
  524.         ngx_http_close_connection(c);
  525.         return;
  526.     }

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

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

  529.     err = ngx_socket_errno;

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

  531.     if (n == -1) {
  532.         if (err == NGX_EAGAIN) {
  533.             rev->ready = 0;

  534.             if (!rev->timer_set) {
  535.                 cscf = ngx_http_get_module_srv_conf(hc->conf_ctx,
  536.                                                     ngx_http_core_module);
  537.                 ngx_add_timer(rev, cscf->client_header_timeout);
  538.                 ngx_reusable_connection(c, 1);
  539.             }

  540.             if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  541.                 ngx_http_close_connection(c);
  542.             }

  543.             return;
  544.         }

  545.         ngx_connection_error(c, err, "recv() failed");
  546.         ngx_http_close_connection(c);

  547.         return;
  548.     }

  549.     if (hc->proxy_protocol) {
  550.         hc->proxy_protocol = 0;

  551.         p = ngx_proxy_protocol_read(c, buf, buf + n);

  552.         if (p == NULL) {
  553.             ngx_http_close_connection(c);
  554.             return;
  555.         }

  556.         size = p - buf;

  557.         if (c->recv(c, buf, size) != (ssize_t) size) {
  558.             ngx_http_close_connection(c);
  559.             return;
  560.         }

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

  562.         if (n == (ssize_t) size) {
  563.             ngx_post_event(rev, &ngx_posted_events);
  564.             return;
  565.         }

  566.         n = 1;
  567.         buf[0] = *p;
  568.     }

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

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

  575.             if (clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) {
  576.                 ngx_http_close_connection(c);
  577.                 return;
  578.             }

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

  581.             if (ngx_ssl_create_connection(&sscf->ssl, c, NGX_SSL_BUFFER)
  582.                 != NGX_OK)
  583.             {
  584.                 ngx_http_close_connection(c);
  585.                 return;
  586.             }

  587.             ngx_reusable_connection(c, 0);

  588.             rc = ngx_ssl_handshake(c);

  589.             if (rc == NGX_AGAIN) {

  590.                 if (!rev->timer_set) {
  591.                     cscf = ngx_http_get_module_srv_conf(hc->conf_ctx,
  592.                                                         ngx_http_core_module);
  593.                     ngx_add_timer(rev, cscf->client_header_timeout);
  594.                 }

  595.                 c->ssl->handler = ngx_http_ssl_handshake_handler;
  596.                 return;
  597.             }

  598.             ngx_http_ssl_handshake_handler(c);

  599.             return;
  600.         }

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

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

  603.         rev->handler = ngx_http_wait_request_handler;
  604.         ngx_http_wait_request_handler(rev);

  605.         return;
  606.     }

  607.     ngx_log_error(NGX_LOG_INFO, c->log, 0, "client closed connection");
  608.     ngx_http_close_connection(c);
  609. }


  610. static void
  611. ngx_http_ssl_handshake_handler(ngx_connection_t *c)
  612. {
  613.     if (c->ssl->handshaked) {

  614.         /*
  615.          * The majority of browsers do not send the "close notify" alert.
  616.          * Among them are MSIE, old Mozilla, Netscape 4, Konqueror,
  617.          * and Links.  And what is more, MSIE ignores the server's alert.
  618.          *
  619.          * Opera and recent Mozilla send the alert.
  620.          */

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

  622. #if (NGX_HTTP_V2                                                              \
  623.      && defined TLSEXT_TYPE_application_layer_protocol_negotiation)
  624.         {
  625.         unsigned int             len;
  626.         const unsigned char     *data;
  627.         ngx_http_connection_t   *hc;
  628.         ngx_http_v2_srv_conf_t  *h2scf;

  629.         hc = c->data;

  630.         h2scf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_v2_module);

  631.         if (h2scf->enable || hc->addr_conf->http2) {

  632.             SSL_get0_alpn_selected(c->ssl->connection, &data, &len);

  633.             if (len == 2 && data[0] == 'h' && data[1] == '2') {
  634.                 ngx_http_v2_init(c->read);
  635.                 return;
  636.             }
  637.         }
  638.         }
  639. #endif

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

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

  643.         ngx_reusable_connection(c, 1);

  644.         ngx_http_wait_request_handler(c->read);

  645.         return;
  646.     }

  647.     if (c->read->timedout) {
  648.         ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
  649.     }

  650.     ngx_http_close_connection(c);
  651. }


  652. #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME

  653. int
  654. ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
  655. {
  656.     ngx_int_t                  rc;
  657.     ngx_str_t                  host;
  658.     const char                *servername;
  659.     ngx_connection_t          *c;
  660.     ngx_http_connection_t     *hc;
  661.     ngx_http_ssl_srv_conf_t   *sscf;
  662.     ngx_http_core_loc_conf_t  *clcf;
  663.     ngx_http_core_srv_conf_t  *cscf;

  664.     c = ngx_ssl_get_connection(ssl_conn);

  665.     if (c->ssl->handshaked) {
  666.         *ad = SSL_AD_NO_RENEGOTIATION;
  667.         return SSL_TLSEXT_ERR_ALERT_FATAL;
  668.     }

  669.     if (c->ssl->sni_accepted) {
  670.         return SSL_TLSEXT_ERR_OK;
  671.     }

  672.     if (c->ssl->handshake_rejected) {
  673.         *ad = SSL_AD_UNRECOGNIZED_NAME;
  674.         return SSL_TLSEXT_ERR_ALERT_FATAL;
  675.     }

  676.     hc = c->data;

  677.     if (arg != NULL) {
  678.         host = *(ngx_str_t *) arg;

  679.         if (host.data == NULL) {
  680.             ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
  681.                            "SSL server name: null");
  682.             goto done;
  683.         }

  684.     } else {
  685.         servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name);

  686.         if (servername == NULL) {
  687.             ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
  688.                            "SSL server name: null");
  689.             goto done;
  690.         }

  691.         host.len = ngx_strlen(servername);
  692.         host.data = (u_char *) servername;
  693.     }

  694.     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
  695.                    "SSL server name: \"%V\"", &host);

  696.     if (host.len == 0) {
  697.         goto done;
  698.     }

  699.     rc = ngx_http_validate_host(&host, NULL, c->pool, 1);

  700.     if (rc == NGX_ERROR) {
  701.         goto error;
  702.     }

  703.     if (rc == NGX_DECLINED) {
  704.         goto done;
  705.     }

  706.     rc = ngx_http_find_virtual_server(c, hc->addr_conf->virtual_names, &host,
  707.                                       NULL, &cscf);

  708.     if (rc == NGX_ERROR) {
  709.         goto error;
  710.     }

  711.     if (rc == NGX_DECLINED) {
  712.         goto done;
  713.     }

  714.     hc->ssl_servername = ngx_palloc(c->pool, sizeof(ngx_str_t));
  715.     if (hc->ssl_servername == NULL) {
  716.         goto error;
  717.     }

  718.     *hc->ssl_servername = host;

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

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

  721.     ngx_set_connection_log(c, clcf->error_log);

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

  723.     c->ssl->buffer_size = sscf->buffer_size;

  724.     if (sscf->ssl.ctx) {
  725.         if (SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx) == NULL) {
  726.             goto error;
  727.         }

  728.         /*
  729.          * SSL_set_SSL_CTX() only changes certs as of 1.0.0d
  730.          * adjust other things we care about
  731.          */

  732.         SSL_set_verify(ssl_conn, SSL_CTX_get_verify_mode(sscf->ssl.ctx),
  733.                        SSL_CTX_get_verify_callback(sscf->ssl.ctx));

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

  735. #if OPENSSL_VERSION_NUMBER >= 0x009080dfL
  736.         /* only in 0.9.8m+ */
  737.         SSL_clear_options(ssl_conn, SSL_get_options(ssl_conn) &
  738.                                     ~SSL_CTX_get_options(sscf->ssl.ctx));
  739. #endif

  740.         SSL_set_options(ssl_conn, SSL_CTX_get_options(sscf->ssl.ctx));

  741. #ifdef SSL_OP_NO_RENEGOTIATION
  742.         SSL_set_options(ssl_conn, SSL_OP_NO_RENEGOTIATION);
  743. #endif

  744. #ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT
  745. #if (NGX_HTTP_V3)
  746.         if (c->listening->quic) {
  747.             SSL_clear_options(ssl_conn, SSL_OP_ENABLE_MIDDLEBOX_COMPAT);
  748.         }
  749. #endif
  750. #endif
  751.     }

  752. done:

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

  754.     if (sscf->reject_handshake) {
  755.         c->ssl->handshake_rejected = 1;
  756.         *ad = SSL_AD_UNRECOGNIZED_NAME;
  757.         return SSL_TLSEXT_ERR_ALERT_FATAL;
  758.     }

  759.     c->ssl->sni_accepted = 1;
  760.     return SSL_TLSEXT_ERR_OK;

  761. error:

  762.     *ad = SSL_AD_INTERNAL_ERROR;
  763.     return SSL_TLSEXT_ERR_ALERT_FATAL;
  764. }

  765. #endif


  766. #ifdef SSL_R_CERT_CB_ERROR

  767. int
  768. ngx_http_ssl_certificate(ngx_ssl_conn_t *ssl_conn, void *arg)
  769. {
  770.     ngx_str_t                  cert, key;
  771.     ngx_uint_t                 i, nelts;
  772.     ngx_connection_t          *c;
  773.     ngx_http_request_t        *r;
  774.     ngx_http_ssl_srv_conf_t   *sscf;
  775.     ngx_http_complex_value_t  *certs, *keys;

  776.     c = ngx_ssl_get_connection(ssl_conn);

  777.     if (c->ssl->handshaked) {
  778.         return 0;
  779.     }

  780.     r = ngx_http_alloc_request(c);
  781.     if (r == NULL) {
  782.         return 0;
  783.     }

  784.     r->logged = 1;

  785.     sscf = arg;

  786.     nelts = sscf->certificate_values->nelts;
  787.     certs = sscf->certificate_values->elts;
  788.     keys = sscf->certificate_key_values->elts;

  789.     for (i = 0; i < nelts; i++) {

  790.         if (ngx_http_complex_value(r, &certs[i], &cert) != NGX_OK) {
  791.             goto failed;
  792.         }

  793.         ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
  794.                        "ssl cert: \"%s\"", cert.data);

  795.         if (ngx_http_complex_value(r, &keys[i], &key) != NGX_OK) {
  796.             goto failed;
  797.         }

  798.         ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
  799.                        "ssl key: \"%s\"", key.data);

  800.         if (ngx_ssl_connection_certificate(c, r->pool, &cert, &key,
  801.                                            sscf->certificate_cache,
  802.                                            sscf->passwords)
  803.             != NGX_OK)
  804.         {
  805.             goto failed;
  806.         }
  807.     }

  808.     ngx_http_free_request(r, 0);
  809.     c->log->action = "SSL handshaking";
  810.     c->destroyed = 0;
  811.     return 1;

  812. failed:

  813.     ngx_http_free_request(r, 0);
  814.     c->log->action = "SSL handshaking";
  815.     c->destroyed = 0;
  816.     return 0;
  817. }

  818. #endif

  819. #endif


  820. static void
  821. ngx_http_process_request_line(ngx_event_t *rev)
  822. {
  823.     ssize_t              n;
  824.     ngx_int_t            rc, rv;
  825.     ngx_str_t            host;
  826.     in_port_t            port;
  827.     ngx_connection_t    *c;
  828.     ngx_http_request_t  *r;

  829.     c = rev->data;
  830.     r = c->data;

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

  833.     if (rev->timedout) {
  834.         ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
  835.         c->timedout = 1;
  836.         ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT);
  837.         return;
  838.     }

  839.     rc = NGX_AGAIN;

  840.     for ( ;; ) {

  841.         if (rc == NGX_AGAIN) {
  842.             n = ngx_http_read_request_header(r);

  843.             if (n == NGX_AGAIN || n == NGX_ERROR) {
  844.                 break;
  845.             }
  846.         }

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

  848.         if (rc == NGX_OK) {

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

  850.             r->request_line.len = r->request_end - r->request_start;
  851.             r->request_line.data = r->request_start;
  852.             r->request_length = r->header_in->pos - r->request_start;

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

  855.             r->method_name.len = r->method_end - r->request_start + 1;
  856.             r->method_name.data = r->request_line.data;

  857.             if (r->http_protocol.data) {
  858.                 r->http_protocol.len = r->request_end - r->http_protocol.data;
  859.             }

  860.             if (ngx_http_process_request_uri(r) != NGX_OK) {
  861.                 break;
  862.             }

  863.             if (r->schema_end) {
  864.                 r->schema.len = r->schema_end - r->schema_start;
  865.                 r->schema.data = r->schema_start;
  866.             }

  867.             if (r->host_end) {

  868.                 host.len = r->host_end - r->host_start;
  869.                 host.data = r->host_start;

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

  871.                 if (rc == NGX_DECLINED) {
  872.                     ngx_log_error(NGX_LOG_INFO, c->log, 0,
  873.                                   "client sent invalid host in request line");
  874.                     ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  875.                     break;
  876.                 }

  877.                 if (rc == NGX_ERROR) {
  878.                     ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  879.                     break;
  880.                 }

  881.                 if (ngx_http_set_virtual_server(r, &host) == NGX_ERROR) {
  882.                     break;
  883.                 }

  884.                 r->headers_in.server = host;
  885.                 r->port = port;
  886.             }

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

  888.                 if (r->headers_in.server.len == 0
  889.                     && ngx_http_set_virtual_server(r, &r->headers_in.server)
  890.                        == NGX_ERROR)
  891.                 {
  892.                     break;
  893.                 }

  894.                 ngx_http_process_request(r);
  895.                 break;
  896.             }


  897.             if (ngx_list_init(&r->headers_in.headers, r->pool, 20,
  898.                               sizeof(ngx_table_elt_t))
  899.                 != NGX_OK)
  900.             {
  901.                 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  902.                 break;
  903.             }

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

  905.             rev->handler = ngx_http_process_request_headers;
  906.             ngx_http_process_request_headers(rev);

  907.             break;
  908.         }

  909.         if (rc != NGX_AGAIN) {

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

  911.             ngx_log_error(NGX_LOG_INFO, c->log, 0,
  912.                           ngx_http_client_errors[rc - NGX_HTTP_CLIENT_ERROR]);

  913.             if (rc == NGX_HTTP_PARSE_INVALID_VERSION) {
  914.                 ngx_http_finalize_request(r, NGX_HTTP_VERSION_NOT_SUPPORTED);

  915.             } else {
  916.                 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  917.             }

  918.             break;
  919.         }

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

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

  922.             rv = ngx_http_alloc_large_header_buffer(r, 1);

  923.             if (rv == NGX_ERROR) {
  924.                 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  925.                 break;
  926.             }

  927.             if (rv == NGX_DECLINED) {
  928.                 r->request_line.len = r->header_in->end - r->request_start;
  929.                 r->request_line.data = r->request_start;

  930.                 ngx_log_error(NGX_LOG_INFO, c->log, 0,
  931.                               "client sent too long URI");
  932.                 ngx_http_finalize_request(r, NGX_HTTP_REQUEST_URI_TOO_LARGE);
  933.                 break;
  934.             }
  935.         }
  936.     }

  937.     ngx_http_run_posted_requests(c);
  938. }


  939. ngx_int_t
  940. ngx_http_process_request_uri(ngx_http_request_t *r)
  941. {
  942.     ngx_http_core_srv_conf_t  *cscf;

  943.     if (r->args_start) {
  944.         r->uri.len = r->args_start - 1 - r->uri_start;
  945.     } else {
  946.         r->uri.len = r->uri_end - r->uri_start;
  947.     }

  948.     if (r->complex_uri || r->quoted_uri || r->empty_path_in_uri) {

  949.         if (r->empty_path_in_uri) {
  950.             r->uri.len++;
  951.         }

  952.         r->uri.data = ngx_pnalloc(r->pool, r->uri.len);
  953.         if (r->uri.data == NULL) {
  954.             ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  955.             return NGX_ERROR;
  956.         }

  957.         cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);

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

  960.             ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  961.                           "client sent invalid request");
  962.             ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  963.             return NGX_ERROR;
  964.         }

  965.     } else {
  966.         r->uri.data = r->uri_start;
  967.     }

  968.     r->unparsed_uri.len = r->uri_end - r->uri_start;
  969.     r->unparsed_uri.data = r->uri_start;

  970.     r->valid_unparsed_uri = r->empty_path_in_uri ? 0 : 1;

  971.     if (r->uri_ext) {
  972.         if (r->args_start) {
  973.             r->exten.len = r->args_start - 1 - r->uri_ext;
  974.         } else {
  975.             r->exten.len = r->uri_end - r->uri_ext;
  976.         }

  977.         r->exten.data = r->uri_ext;
  978.     }

  979.     if (r->args_start && r->uri_end > r->args_start) {
  980.         r->args.len = r->uri_end - r->args_start;
  981.         r->args.data = r->args_start;
  982.     }

  983. #if (NGX_WIN32)
  984.     {
  985.     u_char  *p, *last;

  986.     p = r->uri.data;
  987.     last = r->uri.data + r->uri.len;

  988.     while (p < last) {

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

  990.             /*
  991.              * this check covers "::$data", "::$index_allocation" and
  992.              * ":$i30:$index_allocation"
  993.              */

  994.             if (p < last && *p == '$') {
  995.                 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  996.                               "client sent unsafe win32 URI");
  997.                 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  998.                 return NGX_ERROR;
  999.             }
  1000.         }
  1001.     }

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

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

  1004.         if (*p == ' ') {
  1005.             p--;
  1006.             continue;
  1007.         }

  1008.         if (*p == '.') {
  1009.             p--;
  1010.             continue;
  1011.         }

  1012.         break;
  1013.     }

  1014.     if (p != r->uri.data + r->uri.len - 1) {
  1015.         r->uri.len = p + 1 - r->uri.data;
  1016.         ngx_http_set_exten(r);
  1017.     }

  1018.     }
  1019. #endif

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

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

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

  1026.     return NGX_OK;
  1027. }


  1028. static void
  1029. ngx_http_process_request_headers(ngx_event_t *rev)
  1030. {
  1031.     u_char                     *p;
  1032.     size_t                      len;
  1033.     ssize_t                     n;
  1034.     ngx_int_t                   rc, rv;
  1035.     ngx_table_elt_t            *h;
  1036.     ngx_connection_t           *c;
  1037.     ngx_http_header_t          *hh;
  1038.     ngx_http_request_t         *r;
  1039.     ngx_http_core_srv_conf_t   *cscf;
  1040.     ngx_http_core_main_conf_t  *cmcf;

  1041.     c = rev->data;
  1042.     r = c->data;

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

  1045.     if (rev->timedout) {
  1046.         ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
  1047.         c->timedout = 1;
  1048.         ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT);
  1049.         return;
  1050.     }

  1051.     cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

  1052.     rc = NGX_AGAIN;

  1053.     for ( ;; ) {

  1054.         if (rc == NGX_AGAIN) {

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

  1056.                 rv = ngx_http_alloc_large_header_buffer(r, 0);

  1057.                 if (rv == NGX_ERROR) {
  1058.                     ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1059.                     break;
  1060.                 }

  1061.                 if (rv == NGX_DECLINED) {
  1062.                     p = r->header_name_start;

  1063.                     r->lingering_close = 1;

  1064.                     if (p == NULL) {
  1065.                         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1066.                                       "client sent too large request");
  1067.                         ngx_http_finalize_request(r,
  1068.                                             NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
  1069.                         break;
  1070.                     }

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

  1072.                     if (len > NGX_MAX_ERROR_STR - 300) {
  1073.                         len = NGX_MAX_ERROR_STR - 300;
  1074.                     }

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

  1078.                     ngx_http_finalize_request(r,
  1079.                                             NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
  1080.                     break;
  1081.                 }
  1082.             }

  1083.             n = ngx_http_read_request_header(r);

  1084.             if (n == NGX_AGAIN || n == NGX_ERROR) {
  1085.                 break;
  1086.             }
  1087.         }

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

  1090.         rc = ngx_http_parse_header_line(r, r->header_in,
  1091.                                         cscf->underscores_in_headers);

  1092.         if (rc == NGX_OK) {

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

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

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

  1096.                 ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1097.                               "client sent invalid header line: \"%*s\"",
  1098.                               r->header_end - r->header_name_start,
  1099.                               r->header_name_start);
  1100.                 continue;
  1101.             }

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

  1103.             if (r->headers_in.count++ >= cscf->max_headers) {
  1104.                 r->lingering_close = 1;
  1105.                 ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1106.                               "client sent too many header lines");
  1107.                 ngx_http_finalize_request(r,
  1108.                                           NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
  1109.                 break;
  1110.             }

  1111.             h = ngx_list_push(&r->headers_in.headers);
  1112.             if (h == NULL) {
  1113.                 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1114.                 break;
  1115.             }

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

  1117.             h->key.len = r->header_name_end - r->header_name_start;
  1118.             h->key.data = r->header_name_start;
  1119.             h->key.data[h->key.len] = '\0';

  1120.             h->value.len = r->header_end - r->header_start;
  1121.             h->value.data = r->header_start;
  1122.             h->value.data[h->value.len] = '\0';

  1123.             h->lowcase_key = ngx_pnalloc(r->pool, h->key.len);
  1124.             if (h->lowcase_key == NULL) {
  1125.                 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1126.                 break;
  1127.             }

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

  1130.             } else {
  1131.                 ngx_strlow(h->lowcase_key, h->key.data, h->key.len);
  1132.             }

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

  1135.             if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
  1136.                 break;
  1137.             }

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

  1141.             continue;
  1142.         }

  1143.         if (rc == NGX_HTTP_PARSE_HEADER_DONE) {

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

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

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

  1148.             r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE;

  1149.             rc = ngx_http_process_request_header(r);

  1150.             if (rc != NGX_OK) {
  1151.                 break;
  1152.             }

  1153.             ngx_http_process_request(r);

  1154.             break;
  1155.         }

  1156.         if (rc == NGX_AGAIN) {

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

  1158.             continue;
  1159.         }

  1160.         /* rc == NGX_HTTP_PARSE_INVALID_HEADER */

  1161.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1162.                       "client sent invalid header line: \"%*s\\x%02xd...\"",
  1163.                       r->header_end - r->header_name_start,
  1164.                       r->header_name_start, *r->header_end);

  1165.         ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  1166.         break;
  1167.     }

  1168.     ngx_http_run_posted_requests(c);
  1169. }


  1170. static ssize_t
  1171. ngx_http_read_request_header(ngx_http_request_t *r)
  1172. {
  1173.     ssize_t                    n;
  1174.     ngx_event_t               *rev;
  1175.     ngx_connection_t          *c;
  1176.     ngx_http_core_srv_conf_t  *cscf;

  1177.     c = r->connection;
  1178.     rev = c->read;

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

  1180.     if (n > 0) {
  1181.         return n;
  1182.     }

  1183.     if (rev->ready) {
  1184.         n = c->recv(c, r->header_in->last,
  1185.                     r->header_in->end - r->header_in->last);
  1186.     } else {
  1187.         n = NGX_AGAIN;
  1188.     }

  1189.     if (n == NGX_AGAIN) {
  1190.         if (!rev->timer_set) {
  1191.             cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
  1192.             ngx_add_timer(rev, cscf->client_header_timeout);
  1193.         }

  1194.         if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  1195.             ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1196.             return NGX_ERROR;
  1197.         }

  1198.         return NGX_AGAIN;
  1199.     }

  1200.     if (n == 0) {
  1201.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1202.                       "client prematurely closed connection");
  1203.     }

  1204.     if (n == 0 || n == NGX_ERROR) {
  1205.         c->error = 1;
  1206.         c->log->action = "reading client request headers";

  1207.         ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  1208.         return NGX_ERROR;
  1209.     }

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

  1211.     return n;
  1212. }


  1213. static ngx_int_t
  1214. ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
  1215.     ngx_uint_t request_line)
  1216. {
  1217.     u_char                    *old, *new;
  1218.     ngx_buf_t                 *b;
  1219.     ngx_chain_t               *cl;
  1220.     ngx_http_connection_t     *hc;
  1221.     ngx_http_core_srv_conf_t  *cscf;

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

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

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

  1226.         r->header_in->pos = r->header_in->start;
  1227.         r->header_in->last = r->header_in->start;

  1228.         return NGX_OK;
  1229.     }

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

  1231.     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);

  1232.     if (r->state != 0
  1233.         && (size_t) (r->header_in->pos - old)
  1234.                                      >= cscf->large_client_header_buffers.size)
  1235.     {
  1236.         return NGX_DECLINED;
  1237.     }

  1238.     hc = r->http_connection;

  1239.     if (hc->free) {
  1240.         cl = hc->free;
  1241.         hc->free = cl->next;

  1242.         b = cl->buf;

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

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

  1247.         b = ngx_create_temp_buf(r->connection->pool,
  1248.                                 cscf->large_client_header_buffers.size);
  1249.         if (b == NULL) {
  1250.             return NGX_ERROR;
  1251.         }

  1252.         cl = ngx_alloc_chain_link(r->connection->pool);
  1253.         if (cl == NULL) {
  1254.             return NGX_ERROR;
  1255.         }

  1256.         cl->buf = b;

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

  1260.     } else {
  1261.         return NGX_DECLINED;
  1262.     }

  1263.     cl->next = hc->busy;
  1264.     hc->busy = cl;
  1265.     hc->nbusy++;

  1266.     if (r->state == 0) {
  1267.         /*
  1268.          * r->state == 0 means that a header line was parsed successfully
  1269.          * and we do not need to copy incomplete header line and
  1270.          * to relocate the parser header pointers
  1271.          */

  1272.         r->header_in = b;

  1273.         return NGX_OK;
  1274.     }

  1275.     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  1276.                    "http large header copy: %uz", r->header_in->pos - old);

  1277.     if (r->header_in->pos - old > b->end - b->start) {
  1278.         ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
  1279.                       "too large header to copy");
  1280.         return NGX_ERROR;
  1281.     }

  1282.     new = b->start;

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

  1284.     b->pos = new + (r->header_in->pos - old);
  1285.     b->last = new + (r->header_in->pos - old);

  1286.     if (request_line) {
  1287.         r->request_start = new;

  1288.         if (r->request_end) {
  1289.             r->request_end = new + (r->request_end - old);
  1290.         }

  1291.         if (r->method_end) {
  1292.             r->method_end = new + (r->method_end - old);
  1293.         }

  1294.         if (r->uri_start) {
  1295.             r->uri_start = new + (r->uri_start - old);
  1296.         }

  1297.         if (r->uri_end) {
  1298.             r->uri_end = new + (r->uri_end - old);
  1299.         }

  1300.         if (r->schema_start) {
  1301.             r->schema_start = new + (r->schema_start - old);
  1302.             if (r->schema_end) {
  1303.                 r->schema_end = new + (r->schema_end - old);
  1304.             }
  1305.         }

  1306.         if (r->host_start) {
  1307.             r->host_start = new + (r->host_start - old);
  1308.             if (r->host_end) {
  1309.                 r->host_end = new + (r->host_end - old);
  1310.             }
  1311.         }

  1312.         if (r->uri_ext) {
  1313.             r->uri_ext = new + (r->uri_ext - old);
  1314.         }

  1315.         if (r->args_start) {
  1316.             r->args_start = new + (r->args_start - old);
  1317.         }

  1318.         if (r->http_protocol.data) {
  1319.             r->http_protocol.data = new + (r->http_protocol.data - old);
  1320.         }

  1321.     } else {
  1322.         r->header_name_start = new;

  1323.         if (r->header_name_end) {
  1324.             r->header_name_end = new + (r->header_name_end - old);
  1325.         }

  1326.         if (r->header_start) {
  1327.             r->header_start = new + (r->header_start - old);
  1328.         }

  1329.         if (r->header_end) {
  1330.             r->header_end = new + (r->header_end - old);
  1331.         }
  1332.     }

  1333.     r->header_in = b;

  1334.     return NGX_OK;
  1335. }


  1336. static ngx_int_t
  1337. ngx_http_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
  1338.     ngx_uint_t offset)
  1339. {
  1340.     ngx_table_elt_t  **ph;

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

  1342.     while (*ph) { ph = &(*ph)->next; }

  1343.     *ph = h;
  1344.     h->next = NULL;

  1345.     return NGX_OK;
  1346. }


  1347. static ngx_int_t
  1348. ngx_http_process_unique_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
  1349.     ngx_uint_t offset)
  1350. {
  1351.     ngx_table_elt_t  **ph;

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

  1353.     if (*ph == NULL) {
  1354.         *ph = h;
  1355.         h->next = NULL;
  1356.         return NGX_OK;
  1357.     }

  1358.     ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1359.                   "client sent duplicate header line: \"%V: %V\", "
  1360.                   "previous value: \"%V: %V\"",
  1361.                   &h->key, &h->value, &(*ph)->key, &(*ph)->value);

  1362.     ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);

  1363.     return NGX_ERROR;
  1364. }


  1365. static ngx_int_t
  1366. ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h,
  1367.     ngx_uint_t offset)
  1368. {
  1369.     ngx_int_t  rc;
  1370.     ngx_str_t  host;
  1371.     in_port_t  port;

  1372.     if (r->headers_in.host) {
  1373.         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1374.                       "client sent duplicate host header: \"%V: %V\", "
  1375.                       "previous value: \"%V: %V\"",
  1376.                       &h->key, &h->value, &r->headers_in.host->key,
  1377.                       &r->headers_in.host->value);
  1378.         ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  1379.         return NGX_ERROR;
  1380.     }

  1381.     r->headers_in.host = h;
  1382.     h->next = NULL;

  1383.     host = h->value;

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

  1385.     if (rc == NGX_DECLINED) {
  1386.         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1387.                       "client sent invalid host header");
  1388.         ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  1389.         return NGX_ERROR;
  1390.     }

  1391.     if (rc == NGX_ERROR) {
  1392.         ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1393.         return NGX_ERROR;
  1394.     }

  1395.     if (r->headers_in.server.len) {
  1396.         return NGX_OK;
  1397.     }

  1398.     if (ngx_http_set_virtual_server(r, &host) == NGX_ERROR) {
  1399.         return NGX_ERROR;
  1400.     }

  1401.     r->headers_in.server = host;
  1402.     r->port = port;

  1403.     return NGX_OK;
  1404. }


  1405. static ngx_int_t
  1406. ngx_http_process_connection(ngx_http_request_t *r, ngx_table_elt_t *h,
  1407.     ngx_uint_t offset)
  1408. {
  1409.     if (ngx_http_process_header_line(r, h, offset) != NGX_OK) {
  1410.         return NGX_ERROR;
  1411.     }

  1412.     if (ngx_strcasestrn(h->value.data, "close", 5 - 1)) {
  1413.         r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE;

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

  1417.     return NGX_OK;
  1418. }


  1419. static ngx_int_t
  1420. ngx_http_process_proxy_connection(ngx_http_request_t *r, ngx_table_elt_t *h,
  1421.     ngx_uint_t offset)
  1422. {
  1423.     if (r->http_version >= NGX_HTTP_VERSION_20) {
  1424.         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1425.                       "client sent \"Proxy-Connection\" header");
  1426.         ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  1427.         return NGX_ERROR;
  1428.     }

  1429.     return NGX_OK;
  1430. }


  1431. static ngx_int_t
  1432. ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h,
  1433.     ngx_uint_t offset)
  1434. {
  1435.     u_char  *user_agent, *msie;

  1436.     if (ngx_http_process_header_line(r, h, offset) != NGX_OK) {
  1437.         return NGX_ERROR;
  1438.     }

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

  1440.     user_agent = h->value.data;

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

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

  1443.         r->headers_in.msie = 1;

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

  1445.             switch (msie[5]) {
  1446.             case '4':
  1447.             case '5':
  1448.                 r->headers_in.msie6 = 1;
  1449.                 break;
  1450.             case '6':
  1451.                 if (ngx_strstrn(msie + 8, "SV1", 3 - 1) == NULL) {
  1452.                     r->headers_in.msie6 = 1;
  1453.                 }
  1454.                 break;
  1455.             }
  1456.         }

  1457. #if 0
  1458.         /* MSIE ignores the SSL "close notify" alert */
  1459.         if (c->ssl) {
  1460.             c->ssl->no_send_shutdown = 1;
  1461.         }
  1462. #endif
  1463.     }

  1464.     if (ngx_strstrn(user_agent, "Opera", 5 - 1)) {
  1465.         r->headers_in.opera = 1;
  1466.         r->headers_in.msie = 0;
  1467.         r->headers_in.msie6 = 0;
  1468.     }

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

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

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

  1474.         } else if (ngx_strstrn(user_agent, "Safari/", 7 - 1)
  1475.                    && ngx_strstrn(user_agent, "Mac OS X", 8 - 1))
  1476.         {
  1477.             r->headers_in.safari = 1;

  1478.         } else if (ngx_strstrn(user_agent, "Konqueror", 9 - 1)) {
  1479.             r->headers_in.konqueror = 1;
  1480.         }
  1481.     }

  1482.     return NGX_OK;
  1483. }


  1484. static ngx_int_t
  1485. ngx_http_process_request_header(ngx_http_request_t *r)
  1486. {
  1487.     ngx_http_core_srv_conf_t  *cscf;

  1488.     if (r->headers_in.server.len == 0
  1489.         && ngx_http_set_virtual_server(r, &r->headers_in.server)
  1490.            == NGX_ERROR)
  1491.     {
  1492.         return NGX_ERROR;
  1493.     }

  1494.     if (r->headers_in.host == NULL && r->http_version > NGX_HTTP_VERSION_10) {
  1495.         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1496.                    "client sent HTTP/1.1 request without \"Host\" header");
  1497.         ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  1498.         return NGX_ERROR;
  1499.     }

  1500.     if (r->headers_in.content_length) {
  1501.         r->headers_in.content_length_n =
  1502.                             ngx_atoof(r->headers_in.content_length->value.data,
  1503.                                       r->headers_in.content_length->value.len);

  1504.         if (r->headers_in.content_length_n == NGX_ERROR) {
  1505.             ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1506.                           "client sent invalid \"Content-Length\" header");
  1507.             ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  1508.             return NGX_ERROR;
  1509.         }
  1510.     }

  1511.     if (r->headers_in.transfer_encoding) {
  1512.         if (r->http_version < NGX_HTTP_VERSION_11) {
  1513.             ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1514.                           "client sent HTTP/1.0 request with "
  1515.                           "\"Transfer-Encoding\" header");
  1516.             ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  1517.             return NGX_ERROR;
  1518.         }

  1519.         if (r->headers_in.transfer_encoding->value.len == 7
  1520.             && ngx_strncasecmp(r->headers_in.transfer_encoding->value.data,
  1521.                                (u_char *) "chunked", 7) == 0)
  1522.         {
  1523.             if (r->headers_in.content_length) {
  1524.                 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1525.                               "client sent \"Content-Length\" and "
  1526.                               "\"Transfer-Encoding\" headers "
  1527.                               "at the same time");
  1528.                 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  1529.                 return NGX_ERROR;
  1530.             }

  1531.             r->headers_in.chunked = 1;

  1532.         } else {
  1533.             ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1534.                           "client sent unknown \"Transfer-Encoding\": \"%V\"",
  1535.                           &r->headers_in.transfer_encoding->value);
  1536.             ngx_http_finalize_request(r, NGX_HTTP_NOT_IMPLEMENTED);
  1537.             return NGX_ERROR;
  1538.         }
  1539.     }

  1540.     if (r->headers_in.connection_type == NGX_HTTP_CONNECTION_KEEP_ALIVE) {
  1541.         if (r->headers_in.keep_alive) {
  1542.             r->headers_in.keep_alive_n =
  1543.                             ngx_atotm(r->headers_in.keep_alive->value.data,
  1544.                                       r->headers_in.keep_alive->value.len);
  1545.         }
  1546.     }

  1547.     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);

  1548.     if (r->method == NGX_HTTP_CONNECT
  1549.         && (r->http_version != NGX_HTTP_VERSION_11 || !cscf->allow_connect))
  1550.     {
  1551.         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1552.                       "client sent CONNECT method");
  1553.         ngx_http_finalize_request(r, NGX_HTTP_NOT_ALLOWED);
  1554.         return NGX_ERROR;
  1555.     }

  1556.     if (r->method == NGX_HTTP_TRACE) {
  1557.         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1558.                       "client sent TRACE method");
  1559.         ngx_http_finalize_request(r, NGX_HTTP_NOT_ALLOWED);
  1560.         return NGX_ERROR;
  1561.     }

  1562.     return NGX_OK;
  1563. }


  1564. void
  1565. ngx_http_process_request(ngx_http_request_t *r)
  1566. {
  1567.     ngx_connection_t  *c;

  1568.     c = r->connection;

  1569. #if (NGX_HTTP_SSL)

  1570.     if (r->http_connection->ssl) {
  1571.         long                      rc;
  1572.         X509                     *cert;
  1573.         const char               *s;
  1574.         ngx_http_ssl_srv_conf_t  *sscf;

  1575.         if (c->ssl == NULL) {
  1576.             ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1577.                           "client sent plain HTTP request to HTTPS port");
  1578.             ngx_http_finalize_request(r, NGX_HTTP_TO_HTTPS);
  1579.             return;
  1580.         }

  1581.         sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);

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

  1584.             if (rc != X509_V_OK
  1585.                 && (sscf->verify != 3 || !ngx_ssl_verify_error_optional(rc)))
  1586.             {
  1587.                 ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1588.                               "client SSL certificate verify error: (%l:%s)",
  1589.                               rc, X509_verify_cert_error_string(rc));

  1590.                 ngx_ssl_remove_cached_session(c->ssl->session_ctx,
  1591.                                        (SSL_get0_session(c->ssl->connection)));

  1592.                 ngx_http_finalize_request(r, NGX_HTTPS_CERT_ERROR);
  1593.                 return;
  1594.             }

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

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

  1600.                     ngx_ssl_remove_cached_session(c->ssl->session_ctx,
  1601.                                        (SSL_get0_session(c->ssl->connection)));

  1602.                     ngx_http_finalize_request(r, NGX_HTTPS_NO_CERT);
  1603.                     return;
  1604.                 }

  1605.                 X509_free(cert);
  1606.             }

  1607.             if (ngx_ssl_ocsp_get_status(c, &s) != NGX_OK) {
  1608.                 ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1609.                               "client SSL certificate verify error: %s", s);

  1610.                 ngx_ssl_remove_cached_session(c->ssl->session_ctx,
  1611.                                        (SSL_get0_session(c->ssl->connection)));

  1612.                 ngx_http_finalize_request(r, NGX_HTTPS_CERT_ERROR);
  1613.                 return;
  1614.             }
  1615.         }
  1616.     }

  1617. #endif

  1618.     if (c->read->timer_set) {
  1619.         ngx_del_timer(c->read);
  1620.     }

  1621. #if (NGX_STAT_STUB)
  1622.     (void) ngx_atomic_fetch_add(ngx_stat_reading, -1);
  1623.     r->stat_reading = 0;
  1624.     (void) ngx_atomic_fetch_add(ngx_stat_writing, 1);
  1625.     r->stat_writing = 1;
  1626. #endif

  1627.     c->read->handler = ngx_http_request_handler;
  1628.     c->write->handler = ngx_http_request_handler;
  1629.     r->read_event_handler = ngx_http_block_reading;

  1630.     ngx_http_handler(r);
  1631. }


  1632. ngx_int_t
  1633. ngx_http_validate_host(ngx_str_t *host, in_port_t *portp, ngx_pool_t *pool,
  1634.     ngx_uint_t alloc)
  1635. {
  1636.     u_char     *h, ch;
  1637.     size_t      i, dot_pos, host_len;
  1638.     ngx_int_t   port;

  1639.     enum {
  1640.         sw_host_start = 0,
  1641.         sw_host,
  1642.         sw_host_ip_literal,
  1643.         sw_host_end,
  1644.         sw_port,
  1645.     } state;

  1646.     dot_pos = host->len;
  1647.     host_len = host->len;
  1648.     port = 0;

  1649.     h = host->data;

  1650.     state = sw_host_start;

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

  1653.         switch (state) {

  1654.         case sw_host_start:

  1655.             if (ch == '[') {
  1656.                 state = sw_host_ip_literal;
  1657.                 break;
  1658.             }

  1659.             state = sw_host;

  1660.             /* fall through */

  1661.         case sw_host:

  1662.             if (ch >= 'A' && ch <= 'Z') {
  1663.                 alloc = 1;
  1664.                 break;
  1665.             }

  1666.             if (ch >= 'a' && ch <= 'z') {
  1667.                 break;
  1668.             }

  1669.             if (ch >= '0' && ch <= '9') {
  1670.                 break;
  1671.             }

  1672.             switch (ch) {
  1673.             case ':':
  1674.                 host_len = i;
  1675.                 state = sw_port;
  1676.                 break;
  1677.             case '-':
  1678.                 break;
  1679.             case '.':
  1680.                 if (dot_pos == i - 1) {
  1681.                     return NGX_DECLINED;
  1682.                 }
  1683.                 dot_pos = i;
  1684.                 break;
  1685.             case '_':
  1686.             case '~':
  1687.                 /* unreserved */
  1688.                 break;
  1689.             case '!':
  1690.             case '$':
  1691.             case '&':
  1692.             case '\'':
  1693.             case '(':
  1694.             case ')':
  1695.             case '*':
  1696.             case '+':
  1697.             case ',':
  1698.             case ';':
  1699.             case '=':
  1700.                 /* sub-delims */
  1701.                 break;
  1702.             case '%':
  1703.                 /* pct-encoded */
  1704.                 break;
  1705.             default:
  1706.                 return NGX_DECLINED;
  1707.             }
  1708.             break;

  1709.         case sw_host_ip_literal:

  1710.             if (ch >= 'A' && ch <= 'Z') {
  1711.                 alloc = 1;
  1712.                 break;
  1713.             }

  1714.             if (ch >= 'a' && ch <= 'z') {
  1715.                 break;
  1716.             }

  1717.             if (ch >= '0' && ch <= '9') {
  1718.                 break;
  1719.             }

  1720.             switch (ch) {
  1721.             case ':':
  1722.                 break;
  1723.             case ']':
  1724.                 host_len = i + 1;
  1725.                 state = sw_host_end;
  1726.                 break;
  1727.             case '-':
  1728.                 break;
  1729.             case '.':
  1730.                 if (dot_pos == i - 1) {
  1731.                     return NGX_DECLINED;
  1732.                 }
  1733.                 dot_pos = i;
  1734.                 break;
  1735.             case '_':
  1736.             case '~':
  1737.                 /* unreserved */
  1738.                 break;
  1739.             case '!':
  1740.             case '$':
  1741.             case '&':
  1742.             case '\'':
  1743.             case '(':
  1744.             case ')':
  1745.             case '*':
  1746.             case '+':
  1747.             case ',':
  1748.             case ';':
  1749.             case '=':
  1750.                 /* sub-delims */
  1751.                 break;
  1752.             default:
  1753.                 return NGX_DECLINED;
  1754.             }
  1755.             break;

  1756.         case sw_host_end:

  1757.             if (ch == ':') {
  1758.                 state = sw_port;
  1759.                 break;
  1760.             }
  1761.             return NGX_DECLINED;

  1762.         case sw_port:

  1763.             if (ch >= '0' && ch <= '9') {
  1764.                 if (port >= 6553 && (port > 6553 || (ch - '0') > 5)) {
  1765.                     return NGX_DECLINED;
  1766.                 }

  1767.                 port = port * 10 + (ch - '0');
  1768.                 break;
  1769.             }
  1770.             return NGX_DECLINED;
  1771.         }
  1772.     }

  1773.     if (state == sw_host_ip_literal) {
  1774.         return NGX_DECLINED;
  1775.     }

  1776.     if (dot_pos == host_len - 1) {
  1777.         host_len--;
  1778.     }

  1779.     if (host_len == 0) {
  1780.         return NGX_DECLINED;
  1781.     }

  1782.     if (alloc) {
  1783.         host->data = ngx_pnalloc(pool, host_len);
  1784.         if (host->data == NULL) {
  1785.             return NGX_ERROR;
  1786.         }

  1787.         ngx_strlow(host->data, h, host_len);
  1788.     }

  1789.     host->len = host_len;

  1790.     if (portp) {
  1791.         *portp = port;
  1792.     }

  1793.     return NGX_OK;
  1794. }


  1795. ngx_int_t
  1796. ngx_http_set_virtual_server(ngx_http_request_t *r, ngx_str_t *host)
  1797. {
  1798.     ngx_int_t                  rc;
  1799.     ngx_http_connection_t     *hc;
  1800.     ngx_http_core_loc_conf_t  *clcf;
  1801.     ngx_http_core_srv_conf_t  *cscf;

  1802. #if (NGX_SUPPRESS_WARN)
  1803.     cscf = NULL;
  1804. #endif

  1805.     hc = r->http_connection;

  1806. #if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)

  1807.     if (hc->ssl_servername) {
  1808.         if (hc->ssl_servername->len == host->len
  1809.             && ngx_strncmp(hc->ssl_servername->data,
  1810.                            host->data, host->len) == 0)
  1811.         {
  1812. #if (NGX_PCRE)
  1813.             if (hc->ssl_servername_regex
  1814.                 && ngx_http_regex_exec(r, hc->ssl_servername_regex,
  1815.                                           hc->ssl_servername) != NGX_OK)
  1816.             {
  1817.                 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1818.                 return NGX_ERROR;
  1819.             }
  1820. #endif
  1821.             return NGX_OK;
  1822.         }
  1823.     }

  1824. #endif

  1825.     rc = ngx_http_find_virtual_server(r->connection,
  1826.                                       hc->addr_conf->virtual_names,
  1827.                                       host, r, &cscf);

  1828.     if (rc == NGX_ERROR) {
  1829.         ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1830.         return NGX_ERROR;
  1831.     }

  1832. #if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)

  1833.     if (hc->ssl_servername) {
  1834.         ngx_http_ssl_srv_conf_t  *sscf;

  1835.         if (rc == NGX_DECLINED) {
  1836.             cscf = hc->addr_conf->default_server;
  1837.             rc = NGX_OK;
  1838.         }

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

  1840.         if (sscf->verify) {
  1841.             ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1842.                           "client attempted to request the server name "
  1843.                           "different from the one that was negotiated");
  1844.             ngx_http_finalize_request(r, NGX_HTTP_MISDIRECTED_REQUEST);
  1845.             return NGX_ERROR;
  1846.         }
  1847.     }

  1848. #endif

  1849.     if (rc == NGX_DECLINED) {
  1850.         return NGX_OK;
  1851.     }

  1852.     r->srv_conf = cscf->ctx->srv_conf;
  1853.     r->loc_conf = cscf->ctx->loc_conf;

  1854.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  1855.     ngx_set_connection_log(r->connection, clcf->error_log);

  1856.     return NGX_OK;
  1857. }


  1858. static ngx_int_t
  1859. ngx_http_find_virtual_server(ngx_connection_t *c,
  1860.     ngx_http_virtual_names_t *virtual_names, ngx_str_t *host,
  1861.     ngx_http_request_t *r, ngx_http_core_srv_conf_t **cscfp)
  1862. {
  1863.     ngx_http_core_srv_conf_t  *cscf;

  1864.     if (virtual_names == NULL) {
  1865.         return NGX_DECLINED;
  1866.     }

  1867.     cscf = ngx_hash_find_combined(&virtual_names->names,
  1868.                                   ngx_hash_key(host->data, host->len),
  1869.                                   host->data, host->len);

  1870.     if (cscf) {
  1871.         *cscfp = cscf;
  1872.         return NGX_OK;
  1873.     }

  1874. #if (NGX_PCRE)

  1875.     if (host->len && virtual_names->nregex) {
  1876.         ngx_int_t                n;
  1877.         ngx_uint_t               i;
  1878.         ngx_http_server_name_t  *sn;

  1879.         sn = virtual_names->regex;

  1880. #if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)

  1881.         if (r == NULL) {
  1882.             ngx_http_connection_t  *hc;

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

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

  1885.                 if (n == NGX_REGEX_NO_MATCHED) {
  1886.                     continue;
  1887.                 }

  1888.                 if (n >= 0) {
  1889.                     hc = c->data;
  1890.                     hc->ssl_servername_regex = sn[i].regex;

  1891.                     *cscfp = sn[i].server;
  1892.                     return NGX_OK;
  1893.                 }

  1894.                 ngx_log_error(NGX_LOG_ALERT, c->log, 0,
  1895.                               ngx_regex_exec_n " failed: %i "
  1896.                               "on \"%V\" using \"%V\"",
  1897.                               n, host, &sn[i].regex->name);

  1898.                 return NGX_ERROR;
  1899.             }

  1900.             return NGX_DECLINED;
  1901.         }

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

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

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

  1905.             if (n == NGX_DECLINED) {
  1906.                 continue;
  1907.             }

  1908.             if (n == NGX_OK) {
  1909.                 *cscfp = sn[i].server;
  1910.                 return NGX_OK;
  1911.             }

  1912.             return NGX_ERROR;
  1913.         }
  1914.     }

  1915. #endif /* NGX_PCRE */

  1916.     return NGX_DECLINED;
  1917. }


  1918. static void
  1919. ngx_http_request_handler(ngx_event_t *ev)
  1920. {
  1921.     ngx_connection_t    *c;
  1922.     ngx_http_request_t  *r;

  1923.     c = ev->data;
  1924.     r = c->data;

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

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

  1928.     if (c->close) {
  1929.         r->main->count++;
  1930.         ngx_http_terminate_request(r, 0);
  1931.         ngx_http_run_posted_requests(c);
  1932.         return;
  1933.     }

  1934.     if (ev->delayed && ev->timedout) {
  1935.         ev->delayed = 0;
  1936.         ev->timedout = 0;
  1937.     }

  1938.     if (ev->write) {
  1939.         r->write_event_handler(r);

  1940.     } else {
  1941.         r->read_event_handler(r);
  1942.     }

  1943.     ngx_http_run_posted_requests(c);
  1944. }


  1945. void
  1946. ngx_http_run_posted_requests(ngx_connection_t *c)
  1947. {
  1948.     ngx_http_request_t         *r;
  1949.     ngx_http_posted_request_t  *pr;

  1950.     for ( ;; ) {

  1951.         if (c->destroyed) {
  1952.             return;
  1953.         }

  1954.         r = c->data;
  1955.         pr = r->main->posted_requests;

  1956.         if (pr == NULL) {
  1957.             return;
  1958.         }

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

  1960.         r = pr->request;

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

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

  1964.         r->write_event_handler(r);
  1965.     }
  1966. }


  1967. ngx_int_t
  1968. ngx_http_post_request(ngx_http_request_t *r, ngx_http_posted_request_t *pr)
  1969. {
  1970.     ngx_http_posted_request_t  **p;

  1971.     if (pr == NULL) {
  1972.         pr = ngx_palloc(r->pool, sizeof(ngx_http_posted_request_t));
  1973.         if (pr == NULL) {
  1974.             return NGX_ERROR;
  1975.         }
  1976.     }

  1977.     pr->request = r;
  1978.     pr->next = NULL;

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

  1980.     *p = pr;

  1981.     return NGX_OK;
  1982. }


  1983. void
  1984. ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
  1985. {
  1986.     ngx_connection_t          *c;
  1987.     ngx_http_request_t        *pr;
  1988.     ngx_http_core_loc_conf_t  *clcf;

  1989.     c = r->connection;

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

  1993.     if (rc == NGX_DONE) {
  1994.         ngx_http_finalize_connection(r);
  1995.         return;
  1996.     }

  1997.     if (rc == NGX_OK && r->filter_finalize) {
  1998.         c->error = 1;
  1999.     }

  2000.     if (rc == NGX_DECLINED) {
  2001.         r->content_handler = NULL;
  2002.         r->write_event_handler = ngx_http_core_run_phases;
  2003.         ngx_http_core_run_phases(r);
  2004.         return;
  2005.     }

  2006.     if (r != r->main && r->post_subrequest) {
  2007.         rc = r->post_subrequest->handler(r, r->post_subrequest->data, rc);
  2008.     }

  2009.     if (rc == NGX_ERROR
  2010.         || rc == NGX_HTTP_REQUEST_TIME_OUT
  2011.         || rc == NGX_HTTP_CLIENT_CLOSED_REQUEST
  2012.         || c->error)
  2013.     {
  2014.         if (ngx_http_post_action(r) == NGX_OK) {
  2015.             return;
  2016.         }

  2017.         ngx_http_terminate_request(r, rc);
  2018.         return;
  2019.     }

  2020.     if (rc >= NGX_HTTP_SPECIAL_RESPONSE
  2021.         || rc == NGX_HTTP_CREATED
  2022.         || rc == NGX_HTTP_NO_CONTENT)
  2023.     {
  2024.         if (rc == NGX_HTTP_CLOSE) {
  2025.             c->timedout = 1;
  2026.             ngx_http_terminate_request(r, rc);
  2027.             return;
  2028.         }

  2029.         if (r == r->main) {
  2030.             if (c->read->timer_set) {
  2031.                 ngx_del_timer(c->read);
  2032.             }

  2033.             if (c->write->timer_set) {
  2034.                 ngx_del_timer(c->write);
  2035.             }
  2036.         }

  2037.         c->read->handler = ngx_http_request_handler;
  2038.         c->write->handler = ngx_http_request_handler;

  2039.         ngx_http_finalize_request(r, ngx_http_special_response_handler(r, rc));
  2040.         return;
  2041.     }

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

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

  2044.             if (ngx_http_set_write_handler(r) != NGX_OK) {
  2045.                 ngx_http_terminate_request(r, 0);
  2046.             }

  2047.             return;
  2048.         }

  2049.         pr = r->parent;

  2050.         if (r == c->data || r->background) {

  2051.             if (!r->logged) {

  2052.                 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  2053.                 if (clcf->log_subrequest) {
  2054.                     ngx_http_log_request(r);
  2055.                 }

  2056.                 r->logged = 1;

  2057.             } else {
  2058.                 ngx_log_error(NGX_LOG_ALERT, c->log, 0,
  2059.                               "subrequest: \"%V?%V\" logged again",
  2060.                               &r->uri, &r->args);
  2061.             }

  2062.             r->done = 1;

  2063.             if (r->background) {
  2064.                 ngx_http_finalize_connection(r);
  2065.                 return;
  2066.             }

  2067.             r->main->count--;

  2068.             if (pr->postponed && pr->postponed->request == r) {
  2069.                 pr->postponed = pr->postponed->next;
  2070.             }

  2071.             c->data = pr;

  2072.         } else {

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

  2076.             r->write_event_handler = ngx_http_request_finalizer;

  2077.             if (r->waited) {
  2078.                 r->done = 1;
  2079.             }
  2080.         }

  2081.         if (ngx_http_post_request(pr, NULL) != NGX_OK) {
  2082.             r->main->count++;
  2083.             ngx_http_terminate_request(r, 0);
  2084.             return;
  2085.         }

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

  2089.         return;
  2090.     }

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

  2092.         if (ngx_http_set_write_handler(r) != NGX_OK) {
  2093.             ngx_http_terminate_request(r, 0);
  2094.         }

  2095.         return;
  2096.     }

  2097.     if (r != c->data) {
  2098.         ngx_log_error(NGX_LOG_ALERT, c->log, 0,
  2099.                       "http finalize non-active request: \"%V?%V\"",
  2100.                       &r->uri, &r->args);
  2101.         return;
  2102.     }

  2103.     r->done = 1;

  2104.     r->read_event_handler = ngx_http_block_reading;
  2105.     r->write_event_handler = ngx_http_request_empty_handler;

  2106.     if (!r->post_action) {
  2107.         r->request_complete = 1;
  2108.     }

  2109.     if (ngx_http_post_action(r) == NGX_OK) {
  2110.         return;
  2111.     }

  2112.     if (c->read->timer_set) {
  2113.         ngx_del_timer(c->read);
  2114.     }

  2115.     if (c->write->timer_set) {
  2116.         c->write->delayed = 0;
  2117.         ngx_del_timer(c->write);
  2118.     }

  2119.     ngx_http_finalize_connection(r);
  2120. }


  2121. static void
  2122. ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc)
  2123. {
  2124.     ngx_http_cleanup_t    *cln;
  2125.     ngx_http_request_t    *mr;
  2126.     ngx_http_ephemeral_t  *e;

  2127.     mr = r->main;

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

  2130.     mr->terminated = 1;

  2131.     if (rc > 0 && (mr->headers_out.status == 0 || mr->connection->sent == 0)) {
  2132.         mr->headers_out.status = rc;
  2133.     }

  2134.     cln = mr->cleanup;
  2135.     mr->cleanup = NULL;

  2136.     while (cln) {
  2137.         if (cln->handler) {
  2138.             cln->handler(cln->data);
  2139.         }

  2140.         cln = cln->next;
  2141.     }

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

  2145.     if (mr->write_event_handler) {

  2146.         if (mr->blocked) {
  2147.             r = r->connection->data;

  2148.             r->connection->error = 1;
  2149.             r->write_event_handler = ngx_http_request_finalizer;

  2150.             return;
  2151.         }

  2152.         e = ngx_http_ephemeral(mr);
  2153.         mr->posted_requests = NULL;
  2154.         mr->write_event_handler = ngx_http_terminate_handler;
  2155.         (void) ngx_http_post_request(mr, &e->terminal_posted_request);
  2156.         return;
  2157.     }

  2158.     ngx_http_close_request(mr, rc);
  2159. }


  2160. static void
  2161. ngx_http_terminate_handler(ngx_http_request_t *r)
  2162. {
  2163.     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  2164.                    "http terminate handler count:%d", r->count);

  2165.     r->count = 1;

  2166.     ngx_http_close_request(r, 0);
  2167. }


  2168. static void
  2169. ngx_http_finalize_connection(ngx_http_request_t *r)
  2170. {
  2171.     ngx_http_core_loc_conf_t  *clcf;

  2172. #if (NGX_HTTP_V2)
  2173.     if (r->stream) {
  2174.         ngx_http_close_request(r, 0);
  2175.         return;
  2176.     }
  2177. #endif

  2178. #if (NGX_HTTP_V3)
  2179.     if (r->connection->quic) {
  2180.         ngx_http_close_request(r, 0);
  2181.         return;
  2182.     }
  2183. #endif

  2184.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

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

  2186.         if (r->discard_body) {
  2187.             r->read_event_handler = ngx_http_discarded_request_body_handler;
  2188.             ngx_add_timer(r->connection->read, clcf->lingering_timeout);

  2189.             if (r->lingering_time == 0) {
  2190.                 r->lingering_time = ngx_time()
  2191.                                       + (time_t) (clcf->lingering_time / 1000);
  2192.             }
  2193.         }

  2194.         ngx_http_close_request(r, 0);
  2195.         return;
  2196.     }

  2197.     r = r->main;

  2198.     if (r->connection->read->eof) {
  2199.         ngx_http_close_request(r, 0);
  2200.         return;
  2201.     }

  2202.     if (r->reading_body) {
  2203.         r->keepalive = 0;
  2204.         r->lingering_close = 1;
  2205.     }

  2206.     if (r->keepalive
  2207.         && clcf->keepalive_min_timeout > 0)
  2208.     {
  2209.         ngx_http_set_keepalive(r);
  2210.         return;
  2211.     }

  2212.     if (!ngx_terminate
  2213.          && !ngx_exiting
  2214.          && r->keepalive
  2215.          && clcf->keepalive_timeout > 0)
  2216.     {
  2217.         ngx_http_set_keepalive(r);
  2218.         return;
  2219.     }

  2220.     if (clcf->lingering_close == NGX_HTTP_LINGERING_ALWAYS
  2221.         || (clcf->lingering_close == NGX_HTTP_LINGERING_ON
  2222.             && (r->lingering_close
  2223.                 || r->header_in->pos < r->header_in->last
  2224.                 || r->connection->read->ready
  2225.                 || r->connection->pipeline)))
  2226.     {
  2227.         ngx_http_set_lingering_close(r->connection);
  2228.         return;
  2229.     }

  2230.     ngx_http_close_request(r, 0);
  2231. }


  2232. static ngx_int_t
  2233. ngx_http_set_write_handler(ngx_http_request_t *r)
  2234. {
  2235.     ngx_event_t               *wev;
  2236.     ngx_http_core_loc_conf_t  *clcf;

  2237.     r->http_state = NGX_HTTP_WRITING_REQUEST_STATE;

  2238.     r->read_event_handler = r->discard_body ?
  2239.                                 ngx_http_discarded_request_body_handler:
  2240.                                 ngx_http_test_reading;
  2241.     r->write_event_handler = ngx_http_writer;

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

  2243.     if (wev->ready && wev->delayed) {
  2244.         return NGX_OK;
  2245.     }

  2246.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
  2247.     if (!wev->delayed) {
  2248.         ngx_add_timer(wev, clcf->send_timeout);
  2249.     }

  2250.     if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
  2251.         ngx_http_close_request(r, 0);
  2252.         return NGX_ERROR;
  2253.     }

  2254.     return NGX_OK;
  2255. }


  2256. static void
  2257. ngx_http_writer(ngx_http_request_t *r)
  2258. {
  2259.     ngx_int_t                  rc;
  2260.     ngx_event_t               *wev;
  2261.     ngx_connection_t          *c;
  2262.     ngx_http_core_loc_conf_t  *clcf;

  2263.     c = r->connection;
  2264.     wev = c->write;

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

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

  2268.     if (wev->timedout) {
  2269.         ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
  2270.                       "client timed out");
  2271.         c->timedout = 1;

  2272.         ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT);
  2273.         return;
  2274.     }

  2275.     if (wev->delayed || r->aio) {
  2276.         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0,
  2277.                        "http writer delayed");

  2278.         if (!wev->delayed) {
  2279.             ngx_add_timer(wev, clcf->send_timeout);
  2280.         }

  2281.         if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
  2282.             ngx_http_close_request(r, 0);
  2283.         }

  2284.         return;
  2285.     }

  2286.     rc = ngx_http_output_filter(r, NULL);

  2287.     ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
  2288.                    "http writer output filter: %i, \"%V?%V\"",
  2289.                    rc, &r->uri, &r->args);

  2290.     if (rc == NGX_ERROR) {
  2291.         ngx_http_finalize_request(r, rc);
  2292.         return;
  2293.     }

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

  2295.         if (!wev->delayed) {
  2296.             ngx_add_timer(wev, clcf->send_timeout);
  2297.         }

  2298.         if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
  2299.             ngx_http_close_request(r, 0);
  2300.         }

  2301.         return;
  2302.     }

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

  2305.     r->write_event_handler = ngx_http_request_empty_handler;

  2306.     ngx_http_finalize_request(r, rc);
  2307. }


  2308. static void
  2309. ngx_http_request_finalizer(ngx_http_request_t *r)
  2310. {
  2311.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  2312.                    "http finalizer done: \"%V?%V\"", &r->uri, &r->args);

  2313.     ngx_http_finalize_request(r, 0);
  2314. }


  2315. void
  2316. ngx_http_block_reading(ngx_http_request_t *r)
  2317. {
  2318.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  2319.                    "http reading blocked");

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

  2321.     if ((ngx_event_flags & NGX_USE_LEVEL_EVENT)
  2322.         && r->connection->read->active)
  2323.     {
  2324.         if (ngx_del_event(r->connection->read, NGX_READ_EVENT, 0) != NGX_OK) {
  2325.             ngx_http_close_request(r, 0);
  2326.         }
  2327.     }
  2328. }


  2329. void
  2330. ngx_http_test_reading(ngx_http_request_t *r)
  2331. {
  2332.     int                n;
  2333.     char               buf[1];
  2334.     ngx_err_t          err;
  2335.     ngx_event_t       *rev;
  2336.     ngx_connection_t  *c;

  2337.     c = r->connection;
  2338.     rev = c->read;

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

  2340. #if (NGX_HTTP_V2)

  2341.     if (r->stream) {
  2342.         if (c->error) {
  2343.             err = 0;
  2344.             goto closed;
  2345.         }

  2346.         return;
  2347.     }

  2348. #endif

  2349. #if (NGX_HTTP_V3)

  2350.     if (c->quic) {
  2351.         if (rev->error) {
  2352.             c->error = 1;
  2353.             err = 0;
  2354.             goto closed;
  2355.         }

  2356.         return;
  2357.     }

  2358. #endif

  2359. #if (NGX_HAVE_KQUEUE)

  2360.     if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {

  2361.         if (!rev->pending_eof) {
  2362.             return;
  2363.         }

  2364.         rev->eof = 1;
  2365.         c->error = 1;
  2366.         err = rev->kq_errno;

  2367.         goto closed;
  2368.     }

  2369. #endif

  2370. #if (NGX_HAVE_EPOLLRDHUP)

  2371.     if ((ngx_event_flags & NGX_USE_EPOLL_EVENT) && ngx_use_epoll_rdhup) {
  2372.         socklen_t  len;

  2373.         if (!rev->pending_eof) {
  2374.             return;
  2375.         }

  2376.         rev->eof = 1;
  2377.         c->error = 1;

  2378.         err = 0;
  2379.         len = sizeof(ngx_err_t);

  2380.         /*
  2381.          * BSDs and Linux return 0 and set a pending error in err
  2382.          * Solaris returns -1 and sets errno
  2383.          */

  2384.         if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len)
  2385.             == -1)
  2386.         {
  2387.             err = ngx_socket_errno;
  2388.         }

  2389.         goto closed;
  2390.     }

  2391. #endif

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

  2393.     if (n == 0) {
  2394.         rev->eof = 1;
  2395.         c->error = 1;
  2396.         err = 0;

  2397.         goto closed;

  2398.     } else if (n == -1) {
  2399.         err = ngx_socket_errno;

  2400.         if (err != NGX_EAGAIN) {
  2401.             rev->eof = 1;
  2402.             c->error = 1;

  2403.             goto closed;
  2404.         }
  2405.     }

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

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

  2408.         if (ngx_del_event(rev, NGX_READ_EVENT, 0) != NGX_OK) {
  2409.             ngx_http_close_request(r, 0);
  2410.         }
  2411.     }

  2412.     return;

  2413. closed:

  2414.     if (err) {
  2415.         rev->error = 1;
  2416.     }

  2417. #if (NGX_HTTP_SSL)
  2418.     if (c->ssl) {
  2419.         c->ssl->no_send_shutdown = 1;
  2420.     }
  2421. #endif

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

  2424.     ngx_http_finalize_request(r, NGX_HTTP_CLIENT_CLOSED_REQUEST);
  2425. }


  2426. static void
  2427. ngx_http_set_keepalive(ngx_http_request_t *r)
  2428. {
  2429.     int                        tcp_nodelay;
  2430.     ngx_buf_t                 *b, *f;
  2431.     ngx_chain_t               *cl, *ln;
  2432.     ngx_event_t               *rev, *wev;
  2433.     ngx_connection_t          *c;
  2434.     ngx_http_connection_t     *hc;
  2435.     ngx_http_core_loc_conf_t  *clcf;

  2436.     c = r->connection;
  2437.     rev = c->read;

  2438.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

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

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

  2441.     hc = r->http_connection;
  2442.     b = r->header_in;

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

  2444.         /* the pipelined request */

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

  2446.             /*
  2447.              * If the large header buffers were allocated while the previous
  2448.              * request processing then we do not use c->buffer for
  2449.              * the pipelined request (see ngx_http_create_request()).
  2450.              *
  2451.              * Now we would move the large header buffers to the free list.
  2452.              */

  2453.             for (cl = hc->busy; cl; /* void */) {
  2454.                 ln = cl;
  2455.                 cl = cl->next;

  2456.                 if (ln->buf == b) {
  2457.                     ngx_free_chain(c->pool, ln);
  2458.                     continue;
  2459.                 }

  2460.                 f = ln->buf;
  2461.                 f->pos = f->start;
  2462.                 f->last = f->start;

  2463.                 ln->next = hc->free;
  2464.                 hc->free = ln;
  2465.             }

  2466.             cl = ngx_alloc_chain_link(c->pool);
  2467.             if (cl == NULL) {
  2468.                 ngx_http_close_request(r, 0);
  2469.                 return;
  2470.             }

  2471.             cl->buf = b;
  2472.             cl->next = NULL;

  2473.             hc->busy = cl;
  2474.             hc->nbusy = 1;
  2475.         }
  2476.     }

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

  2479.     ngx_http_free_request(r, 0);

  2480.     c->data = hc;

  2481.     if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  2482.         ngx_http_close_connection(c);
  2483.         return;
  2484.     }

  2485.     wev = c->write;
  2486.     wev->handler = ngx_http_empty_handler;

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

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

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

  2490.         r = ngx_http_create_request(c);
  2491.         if (r == NULL) {
  2492.             ngx_http_close_connection(c);
  2493.             return;
  2494.         }

  2495.         r->pipeline = 1;

  2496.         c->data = r;

  2497.         c->sent = 0;
  2498.         c->destroyed = 0;
  2499.         c->pipeline = 1;

  2500.         if (rev->timer_set) {
  2501.             ngx_del_timer(rev);
  2502.         }

  2503.         rev->handler = ngx_http_process_request_line;
  2504.         ngx_post_event(rev, &ngx_posted_events);
  2505.         return;
  2506.     }

  2507.     /*
  2508.      * To keep a memory footprint as small as possible for an idle keepalive
  2509.      * connection we try to free c->buffer's memory if it was allocated outside
  2510.      * the c->pool.  The large header buffers are always allocated outside the
  2511.      * c->pool and are freed too.
  2512.      */

  2513.     b = c->buffer;

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

  2515.         /*
  2516.          * the special note for ngx_http_keepalive_handler() that
  2517.          * c->buffer's memory was freed
  2518.          */

  2519.         b->pos = NULL;

  2520.     } else {
  2521.         b->pos = b->start;
  2522.         b->last = b->start;
  2523.     }

  2524.     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc free: %p",
  2525.                    hc->free);

  2526.     if (hc->free) {
  2527.         for (cl = hc->free; cl; /* void */) {
  2528.             ln = cl;
  2529.             cl = cl->next;
  2530.             ngx_pfree(c->pool, ln->buf->start);
  2531.             ngx_free_chain(c->pool, ln);
  2532.         }

  2533.         hc->free = NULL;
  2534.     }

  2535.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc busy: %p %i",
  2536.                    hc->busy, hc->nbusy);

  2537.     if (hc->busy) {
  2538.         for (cl = hc->busy; cl; /* void */) {
  2539.             ln = cl;
  2540.             cl = cl->next;
  2541.             ngx_pfree(c->pool, ln->buf->start);
  2542.             ngx_free_chain(c->pool, ln);
  2543.         }

  2544.         hc->busy = NULL;
  2545.         hc->nbusy = 0;
  2546.     }

  2547. #if (NGX_HTTP_SSL)
  2548.     if (c->ssl) {
  2549.         ngx_ssl_free_buffer(c);
  2550.     }
  2551. #endif

  2552.     rev->handler = ngx_http_keepalive_handler;

  2553.     if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
  2554.         if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) != NGX_OK) {
  2555.             ngx_http_close_connection(c);
  2556.             return;
  2557.         }
  2558.     }

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

  2560.     if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
  2561.         if (ngx_tcp_push(c->fd) == -1) {
  2562.             ngx_connection_error(c, ngx_socket_errno, ngx_tcp_push_n " failed");
  2563.             ngx_http_close_connection(c);
  2564.             return;
  2565.         }

  2566.         c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
  2567.         tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0;

  2568.     } else {
  2569.         tcp_nodelay = 1;
  2570.     }

  2571.     if (tcp_nodelay && clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) {
  2572.         ngx_http_close_connection(c);
  2573.         return;
  2574.     }

  2575. #if 0
  2576.     /* if ngx_http_request_t was freed then we need some other place */
  2577.     r->http_state = NGX_HTTP_KEEPALIVE_STATE;
  2578. #endif

  2579.     if (clcf->keepalive_min_timeout == 0) {
  2580.         c->idle = 1;
  2581.         ngx_reusable_connection(c, 1);
  2582.     }

  2583.     if (clcf->keepalive_min_timeout > 0
  2584.         && clcf->keepalive_timeout > clcf->keepalive_min_timeout)
  2585.     {
  2586.         hc->keepalive_timeout = clcf->keepalive_timeout
  2587.                                 - clcf->keepalive_min_timeout;

  2588.     } else {
  2589.         hc->keepalive_timeout = 0;
  2590.     }

  2591.     ngx_add_timer(rev, clcf->keepalive_timeout - hc->keepalive_timeout);

  2592.     if (rev->ready) {
  2593.         ngx_post_event(rev, &ngx_posted_events);
  2594.     }
  2595. }


  2596. static void
  2597. ngx_http_keepalive_handler(ngx_event_t *rev)
  2598. {
  2599.     size_t                  size;
  2600.     ssize_t                 n;
  2601.     ngx_buf_t              *b;
  2602.     ngx_connection_t       *c;
  2603.     ngx_http_connection_t  *hc;

  2604.     c = rev->data;
  2605.     hc = c->data;

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

  2607.     if (!ngx_terminate
  2608.          && !ngx_exiting
  2609.          && rev->timedout
  2610.          && hc->keepalive_timeout > 0)
  2611.     {
  2612.         c->idle = 1;
  2613.         ngx_reusable_connection(c, 1);

  2614.         ngx_add_timer(rev, hc->keepalive_timeout);

  2615.         hc->keepalive_timeout = 0;
  2616.         rev->timedout = 0;
  2617.         return;
  2618.     }

  2619.     if (rev->timedout || c->close) {
  2620.         ngx_http_close_connection(c);
  2621.         return;
  2622.     }

  2623. #if (NGX_HAVE_KQUEUE)

  2624.     if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
  2625.         if (rev->pending_eof) {
  2626.             c->log->handler = NULL;
  2627.             ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno,
  2628.                           "kevent() reported that client %V closed "
  2629.                           "keepalive connection", &c->addr_text);
  2630. #if (NGX_HTTP_SSL)
  2631.             if (c->ssl) {
  2632.                 c->ssl->no_send_shutdown = 1;
  2633.             }
  2634. #endif
  2635.             ngx_http_close_connection(c);
  2636.             return;
  2637.         }
  2638.     }

  2639. #endif

  2640.     b = c->buffer;
  2641.     size = b->end - b->start;

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

  2643.         /*
  2644.          * The c->buffer's memory was freed by ngx_http_set_keepalive().
  2645.          * However, the c->buffer->start and c->buffer->end were not changed
  2646.          * to keep the buffer size.
  2647.          */

  2648.         b->pos = ngx_palloc(c->pool, size);
  2649.         if (b->pos == NULL) {
  2650.             ngx_http_close_connection(c);
  2651.             return;
  2652.         }

  2653.         b->start = b->pos;
  2654.         b->last = b->pos;
  2655.         b->end = b->pos + size;
  2656.     }

  2657.     /*
  2658.      * MSIE closes a keepalive connection with RST flag
  2659.      * so we ignore ECONNRESET here.
  2660.      */

  2661.     c->log_error = NGX_ERROR_IGNORE_ECONNRESET;
  2662.     ngx_set_socket_errno(0);

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

  2665.     if (n == NGX_AGAIN) {
  2666.         if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  2667.             ngx_http_close_connection(c);
  2668.             return;
  2669.         }

  2670.         /*
  2671.          * Like ngx_http_set_keepalive() we are trying to not hold
  2672.          * c->buffer's memory for a keepalive connection.
  2673.          */

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

  2675.             /*
  2676.              * the special note that c->buffer's memory was freed
  2677.              */

  2678.             b->pos = NULL;
  2679.         }

  2680.         return;
  2681.     }

  2682.     if (n == NGX_ERROR) {
  2683.         ngx_http_close_connection(c);
  2684.         return;
  2685.     }

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

  2687.     if (n == 0) {
  2688.         ngx_log_error(NGX_LOG_INFO, c->log, ngx_socket_errno,
  2689.                       "client %V closed keepalive connection", &c->addr_text);
  2690.         ngx_http_close_connection(c);
  2691.         return;
  2692.     }

  2693.     b->last += n;

  2694.     c->log->handler = ngx_http_log_error;
  2695.     c->log->action = "reading client request line";

  2696.     c->idle = 0;
  2697.     ngx_reusable_connection(c, 0);

  2698.     c->data = ngx_http_create_request(c);
  2699.     if (c->data == NULL) {
  2700.         ngx_http_close_connection(c);
  2701.         return;
  2702.     }

  2703.     c->sent = 0;
  2704.     c->destroyed = 0;

  2705.     ngx_del_timer(rev);

  2706.     rev->handler = ngx_http_process_request_line;
  2707.     ngx_http_process_request_line(rev);
  2708. }


  2709. static void
  2710. ngx_http_set_lingering_close(ngx_connection_t *c)
  2711. {
  2712.     ngx_event_t               *rev, *wev;
  2713.     ngx_http_request_t        *r;
  2714.     ngx_http_core_loc_conf_t  *clcf;

  2715.     r = c->data;

  2716.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  2717.     if (r->lingering_time == 0) {
  2718.         r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000);
  2719.     }

  2720. #if (NGX_HTTP_SSL)
  2721.     if (c->ssl) {
  2722.         ngx_int_t  rc;

  2723.         c->ssl->shutdown_without_free = 1;

  2724.         rc = ngx_ssl_shutdown(c);

  2725.         if (rc == NGX_ERROR) {
  2726.             ngx_http_close_request(r, 0);
  2727.             return;
  2728.         }

  2729.         if (rc == NGX_AGAIN) {
  2730.             c->ssl->handler = ngx_http_set_lingering_close;
  2731.             return;
  2732.         }
  2733.     }
  2734. #endif

  2735.     rev = c->read;
  2736.     rev->handler = ngx_http_lingering_close_handler;

  2737.     if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  2738.         ngx_http_close_request(r, 0);
  2739.         return;
  2740.     }

  2741.     wev = c->write;
  2742.     wev->handler = ngx_http_empty_handler;

  2743.     if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
  2744.         if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) != NGX_OK) {
  2745.             ngx_http_close_request(r, 0);
  2746.             return;
  2747.         }
  2748.     }

  2749.     if (ngx_shutdown_socket(c->fd, NGX_WRITE_SHUTDOWN) == -1) {
  2750.         ngx_connection_error(c, ngx_socket_errno,
  2751.                              ngx_shutdown_socket_n " failed");
  2752.         ngx_http_close_request(r, 0);
  2753.         return;
  2754.     }

  2755.     c->close = 0;
  2756.     ngx_reusable_connection(c, 1);

  2757.     ngx_add_timer(rev, clcf->lingering_timeout);

  2758.     if (rev->ready) {
  2759.         ngx_http_lingering_close_handler(rev);
  2760.     }
  2761. }


  2762. static void
  2763. ngx_http_lingering_close_handler(ngx_event_t *rev)
  2764. {
  2765.     ssize_t                    n;
  2766.     ngx_msec_t                 timer;
  2767.     ngx_connection_t          *c;
  2768.     ngx_http_request_t        *r;
  2769.     ngx_http_core_loc_conf_t  *clcf;
  2770.     u_char                     buffer[NGX_HTTP_LINGERING_BUFFER_SIZE];

  2771.     c = rev->data;
  2772.     r = c->data;

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

  2775.     if (rev->timedout || c->close) {
  2776.         ngx_http_close_request(r, 0);
  2777.         return;
  2778.     }

  2779.     timer = (ngx_msec_t) r->lingering_time - (ngx_msec_t) ngx_time();
  2780.     if ((ngx_msec_int_t) timer <= 0) {
  2781.         ngx_http_close_request(r, 0);
  2782.         return;
  2783.     }

  2784.     do {
  2785.         n = c->recv(c, buffer, NGX_HTTP_LINGERING_BUFFER_SIZE);

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

  2787.         if (n == NGX_AGAIN) {
  2788.             break;
  2789.         }

  2790.         if (n == NGX_ERROR || n == 0) {
  2791.             ngx_http_close_request(r, 0);
  2792.             return;
  2793.         }

  2794.     } while (rev->ready);

  2795.     if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  2796.         ngx_http_close_request(r, 0);
  2797.         return;
  2798.     }

  2799.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  2800.     timer *= 1000;

  2801.     if (timer > clcf->lingering_timeout) {
  2802.         timer = clcf->lingering_timeout;
  2803.     }

  2804.     ngx_add_timer(rev, timer);
  2805. }


  2806. void
  2807. ngx_http_empty_handler(ngx_event_t *wev)
  2808. {
  2809.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, "http empty handler");

  2810.     return;
  2811. }


  2812. void
  2813. ngx_http_request_empty_handler(ngx_http_request_t *r)
  2814. {
  2815.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  2816.                    "http request empty handler");

  2817.     return;
  2818. }


  2819. ngx_int_t
  2820. ngx_http_send_special(ngx_http_request_t *r, ngx_uint_t flags)
  2821. {
  2822.     ngx_buf_t    *b;
  2823.     ngx_chain_t   out;

  2824.     b = ngx_calloc_buf(r->pool);
  2825.     if (b == NULL) {
  2826.         return NGX_ERROR;
  2827.     }

  2828.     if (flags & NGX_HTTP_LAST) {

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

  2831.         } else {
  2832.             b->sync = 1;
  2833.             b->last_in_chain = 1;
  2834.         }
  2835.     }

  2836.     if (flags & NGX_HTTP_FLUSH) {
  2837.         b->flush = 1;
  2838.     }

  2839.     out.buf = b;
  2840.     out.next = NULL;

  2841.     return ngx_http_output_filter(r, &out);
  2842. }


  2843. static ngx_int_t
  2844. ngx_http_post_action(ngx_http_request_t *r)
  2845. {
  2846.     ngx_http_core_loc_conf_t  *clcf;

  2847.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  2848.     if (clcf->post_action.data == NULL) {
  2849.         return NGX_DECLINED;
  2850.     }

  2851.     if (r->post_action && r->uri_changes == 0) {
  2852.         return NGX_DECLINED;
  2853.     }

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

  2856.     r->main->count--;

  2857.     r->http_version = NGX_HTTP_VERSION_9;
  2858.     r->header_only = 1;
  2859.     r->post_action = 1;

  2860.     r->read_event_handler = ngx_http_block_reading;

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

  2863.     } else {
  2864.         ngx_http_named_location(r, &clcf->post_action);
  2865.     }

  2866.     return NGX_OK;
  2867. }


  2868. void
  2869. ngx_http_close_request(ngx_http_request_t *r, ngx_int_t rc)
  2870. {
  2871.     ngx_connection_t  *c;

  2872.     r = r->main;
  2873.     c = r->connection;

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

  2876.     if (r->count == 0) {
  2877.         ngx_log_error(NGX_LOG_ALERT, c->log, 0, "http request count is zero");
  2878.     }

  2879.     r->count--;

  2880.     if (r->count || r->blocked) {
  2881.         return;
  2882.     }

  2883. #if (NGX_HTTP_V2)
  2884.     if (r->stream) {
  2885.         ngx_http_v2_close_stream(r->stream, rc);
  2886.         return;
  2887.     }
  2888. #endif

  2889.     ngx_http_free_request(r, rc);
  2890.     ngx_http_close_connection(c);
  2891. }


  2892. void
  2893. ngx_http_free_request(ngx_http_request_t *r, ngx_int_t rc)
  2894. {
  2895.     ngx_log_t                 *log;
  2896.     ngx_pool_t                *pool;
  2897.     struct linger              linger;
  2898.     ngx_http_cleanup_t        *cln;
  2899.     ngx_http_log_ctx_t        *ctx;
  2900.     ngx_http_core_loc_conf_t  *clcf;

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

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

  2903.     if (r->pool == NULL) {
  2904.         ngx_log_error(NGX_LOG_ALERT, log, 0, "http request already closed");
  2905.         return;
  2906.     }

  2907.     cln = r->cleanup;
  2908.     r->cleanup = NULL;

  2909.     while (cln) {
  2910.         if (cln->handler) {
  2911.             cln->handler(cln->data);
  2912.         }

  2913.         cln = cln->next;
  2914.     }

  2915. #if (NGX_STAT_STUB)

  2916.     if (r->stat_reading) {
  2917.         (void) ngx_atomic_fetch_add(ngx_stat_reading, -1);
  2918.     }

  2919.     if (r->stat_writing) {
  2920.         (void) ngx_atomic_fetch_add(ngx_stat_writing, -1);
  2921.     }

  2922. #endif

  2923.     if (rc > 0 && (r->headers_out.status == 0 || r->connection->sent == 0)) {
  2924.         r->headers_out.status = rc;
  2925.     }

  2926.     if (!r->logged) {
  2927.         log->action = "logging request";

  2928.         ngx_http_log_request(r);
  2929.     }

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

  2931.     if (r->connection->timedout
  2932. #if (NGX_HTTP_V3)
  2933.         && r->connection->quic == NULL
  2934. #endif
  2935.        )
  2936.     {
  2937.         clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  2938.         if (clcf->reset_timedout_connection) {
  2939.             linger.l_onoff = 1;
  2940.             linger.l_linger = 0;

  2941.             if (setsockopt(r->connection->fd, SOL_SOCKET, SO_LINGER,
  2942.                            (const void *) &linger, sizeof(struct linger)) == -1)
  2943.             {
  2944.                 ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno,
  2945.                               "setsockopt(SO_LINGER) failed");
  2946.             }
  2947.         }
  2948.     }

  2949.     /* the various request strings were allocated from r->pool */
  2950.     ctx = log->data;
  2951.     ctx->request = NULL;

  2952.     r->request_line.len = 0;

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

  2954.     /*
  2955.      * Setting r->pool to NULL will increase probability to catch double close
  2956.      * of request since the request object is allocated from its own pool.
  2957.      */

  2958.     pool = r->pool;
  2959.     r->pool = NULL;

  2960.     ngx_destroy_pool(pool);
  2961. }


  2962. static void
  2963. ngx_http_log_request(ngx_http_request_t *r)
  2964. {
  2965.     ngx_uint_t                  i, n;
  2966.     ngx_http_handler_pt        *log_handler;
  2967.     ngx_http_core_main_conf_t  *cmcf;

  2968.     cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

  2969.     log_handler = cmcf->phases[NGX_HTTP_LOG_PHASE].handlers.elts;
  2970.     n = cmcf->phases[NGX_HTTP_LOG_PHASE].handlers.nelts;

  2971.     for (i = 0; i < n; i++) {
  2972.         log_handler[i](r);
  2973.     }
  2974. }


  2975. void
  2976. ngx_http_close_connection(ngx_connection_t *c)
  2977. {
  2978.     ngx_pool_t  *pool;

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

  2981. #if (NGX_HTTP_SSL)

  2982.     if (c->ssl) {
  2983.         if (ngx_ssl_shutdown(c) == NGX_AGAIN) {
  2984.             c->ssl->handler = ngx_http_close_connection;
  2985.             return;
  2986.         }
  2987.     }

  2988. #endif

  2989. #if (NGX_HTTP_V3)
  2990.     if (c->quic) {
  2991.         ngx_http_v3_reset_stream(c);
  2992.     }
  2993. #endif

  2994. #if (NGX_STAT_STUB)
  2995.     (void) ngx_atomic_fetch_add(ngx_stat_active, -1);
  2996. #endif

  2997.     c->destroyed = 1;

  2998.     pool = c->pool;

  2999.     ngx_close_connection(c);

  3000.     ngx_destroy_pool(pool);
  3001. }


  3002. static u_char *
  3003. ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len)
  3004. {
  3005.     u_char              *p;
  3006.     ngx_http_request_t  *r;
  3007.     ngx_http_log_ctx_t  *ctx;

  3008.     if (log->action) {
  3009.         p = ngx_snprintf(buf, len, " while %s", log->action);
  3010.         len -= p - buf;
  3011.         buf = p;
  3012.     }

  3013.     ctx = log->data;

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

  3016.     r = ctx->request;

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

  3019.     } else {
  3020.         p = ngx_snprintf(p, len, ", server: %V",
  3021.                          &ctx->connection->listening->addr_text);
  3022.     }

  3023.     return p;
  3024. }


  3025. static u_char *
  3026. ngx_http_log_error_handler(ngx_http_request_t *r, ngx_http_request_t *sr,
  3027.     u_char *buf, size_t len)
  3028. {
  3029.     char                      *uri_separator;
  3030.     u_char                    *p;
  3031.     ngx_http_upstream_t       *u;
  3032.     ngx_http_core_srv_conf_t  *cscf;

  3033.     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);

  3034.     p = ngx_snprintf(buf, len, ", server: %V", &cscf->server_name);
  3035.     len -= p - buf;
  3036.     buf = p;

  3037.     if (r->request_line.data == NULL && r->request_start) {
  3038.         for (p = r->request_start; p < r->header_in->last; p++) {
  3039.             if (*p == CR || *p == LF) {
  3040.                 break;
  3041.             }
  3042.         }

  3043.         r->request_line.len = p - r->request_start;
  3044.         r->request_line.data = r->request_start;
  3045.     }

  3046.     if (r->request_line.len) {
  3047.         p = ngx_snprintf(buf, len, ", request: \"%V\"", &r->request_line);
  3048.         len -= p - buf;
  3049.         buf = p;
  3050.     }

  3051.     if (r != sr) {
  3052.         p = ngx_snprintf(buf, len, ", subrequest: \"%V\"", &sr->uri);
  3053.         len -= p - buf;
  3054.         buf = p;
  3055.     }

  3056.     u = sr->upstream;

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

  3058.         uri_separator = "";

  3059. #if (NGX_HAVE_UNIX_DOMAIN)
  3060.         if (u->peer.sockaddr && u->peer.sockaddr->sa_family == AF_UNIX) {
  3061.             uri_separator = ":";
  3062.         }
  3063. #endif

  3064.         p = ngx_snprintf(buf, len, ", upstream: \"%V%V%s%V\"",
  3065.                          &u->schema, u->peer.name,
  3066.                          uri_separator, &u->uri);
  3067.         len -= p - buf;
  3068.         buf = p;
  3069.     }

  3070.     if (r->headers_in.host) {
  3071.         p = ngx_snprintf(buf, len, ", host: \"%V\"",
  3072.                          &r->headers_in.host->value);
  3073.         len -= p - buf;
  3074.         buf = p;
  3075.     }

  3076.     if (r->headers_in.referer) {
  3077.         p = ngx_snprintf(buf, len, ", referrer: \"%V\"",
  3078.                          &r->headers_in.referer->value);
  3079.         buf = p;
  3080.     }

  3081.     return buf;
  3082. }