src/http/ngx_http_request.c - nginx-1.31.4 nginx/ @ 8d9666701

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.         if (r->http_version != NGX_HTTP_VERSION_11 || !cscf->allow_connect) {
  1550.             ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1551.                           "client sent CONNECT method");
  1552.             ngx_http_finalize_request(r, NGX_HTTP_NOT_ALLOWED);
  1553.             return NGX_ERROR;
  1554.         }

  1555.         if (r->headers_in.content_length_n > 0 || r->headers_in.chunked) {
  1556.             ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1557.                           "client sent CONNECT request with body");
  1558.             ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  1559.             return NGX_ERROR;
  1560.         }
  1561.     }

  1562.     if (r->method == NGX_HTTP_TRACE) {
  1563.         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1564.                       "client sent TRACE method");
  1565.         ngx_http_finalize_request(r, NGX_HTTP_NOT_ALLOWED);
  1566.         return NGX_ERROR;
  1567.     }

  1568.     return NGX_OK;
  1569. }


  1570. void
  1571. ngx_http_process_request(ngx_http_request_t *r)
  1572. {
  1573.     ngx_connection_t  *c;

  1574.     c = r->connection;

  1575. #if (NGX_HTTP_SSL)

  1576.     if (r->http_connection->ssl) {
  1577.         long                      rc;
  1578.         X509                     *cert;
  1579.         const char               *s;
  1580.         ngx_http_ssl_srv_conf_t  *sscf;

  1581.         if (c->ssl == NULL) {
  1582.             ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1583.                           "client sent plain HTTP request to HTTPS port");
  1584.             ngx_http_finalize_request(r, NGX_HTTP_TO_HTTPS);
  1585.             return;
  1586.         }

  1587.         sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);

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

  1590.             if (rc != X509_V_OK
  1591.                 && (sscf->verify != 3 || !ngx_ssl_verify_error_optional(rc)))
  1592.             {
  1593.                 ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1594.                               "client SSL certificate verify error: (%l:%s)",
  1595.                               rc, X509_verify_cert_error_string(rc));

  1596.                 ngx_ssl_remove_cached_session(c->ssl->session_ctx,
  1597.                                        (SSL_get0_session(c->ssl->connection)));

  1598.                 ngx_http_finalize_request(r, NGX_HTTPS_CERT_ERROR);
  1599.                 return;
  1600.             }

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

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

  1606.                     ngx_ssl_remove_cached_session(c->ssl->session_ctx,
  1607.                                        (SSL_get0_session(c->ssl->connection)));

  1608.                     ngx_http_finalize_request(r, NGX_HTTPS_NO_CERT);
  1609.                     return;
  1610.                 }

  1611.                 X509_free(cert);
  1612.             }

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

  1616.                 ngx_ssl_remove_cached_session(c->ssl->session_ctx,
  1617.                                        (SSL_get0_session(c->ssl->connection)));

  1618.                 ngx_http_finalize_request(r, NGX_HTTPS_CERT_ERROR);
  1619.                 return;
  1620.             }
  1621.         }
  1622.     }

  1623. #endif

  1624.     if (c->read->timer_set) {
  1625.         ngx_del_timer(c->read);
  1626.     }

  1627. #if (NGX_STAT_STUB)
  1628.     (void) ngx_atomic_fetch_add(ngx_stat_reading, -1);
  1629.     r->stat_reading = 0;
  1630.     (void) ngx_atomic_fetch_add(ngx_stat_writing, 1);
  1631.     r->stat_writing = 1;
  1632. #endif

  1633.     c->read->handler = ngx_http_request_handler;
  1634.     c->write->handler = ngx_http_request_handler;
  1635.     r->read_event_handler = ngx_http_block_reading;

  1636.     ngx_http_handler(r);
  1637. }


  1638. ngx_int_t
  1639. ngx_http_validate_host(ngx_str_t *host, in_port_t *portp, ngx_pool_t *pool,
  1640.     ngx_uint_t alloc)
  1641. {
  1642.     u_char     *h, ch;
  1643.     size_t      i, dot_pos, host_len;
  1644.     ngx_int_t   port;

  1645.     enum {
  1646.         sw_host_start = 0,
  1647.         sw_host,
  1648.         sw_host_ip_literal,
  1649.         sw_host_end,
  1650.         sw_port,
  1651.     } state;

  1652.     dot_pos = host->len;
  1653.     host_len = host->len;
  1654.     port = 0;

  1655.     h = host->data;

  1656.     state = sw_host_start;

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

  1659.         switch (state) {

  1660.         case sw_host_start:

  1661.             if (ch == '[') {
  1662.                 state = sw_host_ip_literal;
  1663.                 break;
  1664.             }

  1665.             state = sw_host;

  1666.             /* fall through */

  1667.         case sw_host:

  1668.             if (ch >= 'A' && ch <= 'Z') {
  1669.                 alloc = 1;
  1670.                 break;
  1671.             }

  1672.             if (ch >= 'a' && ch <= 'z') {
  1673.                 break;
  1674.             }

  1675.             if (ch >= '0' && ch <= '9') {
  1676.                 break;
  1677.             }

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

  1715.         case sw_host_ip_literal:

  1716.             if (ch >= 'A' && ch <= 'Z') {
  1717.                 alloc = 1;
  1718.                 break;
  1719.             }

  1720.             if (ch >= 'a' && ch <= 'z') {
  1721.                 break;
  1722.             }

  1723.             if (ch >= '0' && ch <= '9') {
  1724.                 break;
  1725.             }

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

  1762.         case sw_host_end:

  1763.             if (ch == ':') {
  1764.                 state = sw_port;
  1765.                 break;
  1766.             }
  1767.             return NGX_DECLINED;

  1768.         case sw_port:

  1769.             if (ch >= '0' && ch <= '9') {
  1770.                 if (port >= 6553 && (port > 6553 || (ch - '0') > 5)) {
  1771.                     return NGX_DECLINED;
  1772.                 }

  1773.                 port = port * 10 + (ch - '0');
  1774.                 break;
  1775.             }
  1776.             return NGX_DECLINED;
  1777.         }
  1778.     }

  1779.     if (state == sw_host_ip_literal) {
  1780.         return NGX_DECLINED;
  1781.     }

  1782.     if (dot_pos == host_len - 1) {
  1783.         host_len--;
  1784.     }

  1785.     if (host_len == 0) {
  1786.         return NGX_DECLINED;
  1787.     }

  1788.     if (alloc) {
  1789.         host->data = ngx_pnalloc(pool, host_len);
  1790.         if (host->data == NULL) {
  1791.             return NGX_ERROR;
  1792.         }

  1793.         ngx_strlow(host->data, h, host_len);
  1794.     }

  1795.     host->len = host_len;

  1796.     if (portp) {
  1797.         *portp = port;
  1798.     }

  1799.     return NGX_OK;
  1800. }


  1801. ngx_int_t
  1802. ngx_http_set_virtual_server(ngx_http_request_t *r, ngx_str_t *host)
  1803. {
  1804.     ngx_int_t                  rc;
  1805.     ngx_http_connection_t     *hc;
  1806.     ngx_http_core_loc_conf_t  *clcf;
  1807.     ngx_http_core_srv_conf_t  *cscf;

  1808. #if (NGX_SUPPRESS_WARN)
  1809.     cscf = NULL;
  1810. #endif

  1811.     hc = r->http_connection;

  1812. #if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)

  1813.     if (hc->ssl_servername) {
  1814.         if (hc->ssl_servername->len == host->len
  1815.             && ngx_strncmp(hc->ssl_servername->data,
  1816.                            host->data, host->len) == 0)
  1817.         {
  1818. #if (NGX_PCRE)
  1819.             if (hc->ssl_servername_regex
  1820.                 && ngx_http_regex_exec(r, hc->ssl_servername_regex,
  1821.                                           hc->ssl_servername) != NGX_OK)
  1822.             {
  1823.                 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1824.                 return NGX_ERROR;
  1825.             }
  1826. #endif
  1827.             return NGX_OK;
  1828.         }
  1829.     }

  1830. #endif

  1831.     rc = ngx_http_find_virtual_server(r->connection,
  1832.                                       hc->addr_conf->virtual_names,
  1833.                                       host, r, &cscf);

  1834.     if (rc == NGX_ERROR) {
  1835.         ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1836.         return NGX_ERROR;
  1837.     }

  1838. #if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)

  1839.     if (hc->ssl_servername) {
  1840.         ngx_http_ssl_srv_conf_t  *sscf;

  1841.         if (rc == NGX_DECLINED) {
  1842.             cscf = hc->addr_conf->default_server;
  1843.             rc = NGX_OK;
  1844.         }

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

  1846.         if (sscf->verify) {
  1847.             ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1848.                           "client attempted to request the server name "
  1849.                           "different from the one that was negotiated");
  1850.             ngx_http_finalize_request(r, NGX_HTTP_MISDIRECTED_REQUEST);
  1851.             return NGX_ERROR;
  1852.         }
  1853.     }

  1854. #endif

  1855.     if (rc == NGX_DECLINED) {
  1856.         return NGX_OK;
  1857.     }

  1858.     r->srv_conf = cscf->ctx->srv_conf;
  1859.     r->loc_conf = cscf->ctx->loc_conf;

  1860.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

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

  1862.     return NGX_OK;
  1863. }


  1864. static ngx_int_t
  1865. ngx_http_find_virtual_server(ngx_connection_t *c,
  1866.     ngx_http_virtual_names_t *virtual_names, ngx_str_t *host,
  1867.     ngx_http_request_t *r, ngx_http_core_srv_conf_t **cscfp)
  1868. {
  1869.     ngx_http_core_srv_conf_t  *cscf;

  1870.     if (virtual_names == NULL) {
  1871.         return NGX_DECLINED;
  1872.     }

  1873.     cscf = ngx_hash_find_combined(&virtual_names->names,
  1874.                                   ngx_hash_key(host->data, host->len),
  1875.                                   host->data, host->len);

  1876.     if (cscf) {
  1877.         *cscfp = cscf;
  1878.         return NGX_OK;
  1879.     }

  1880. #if (NGX_PCRE)

  1881.     if (host->len && virtual_names->nregex) {
  1882.         ngx_int_t                n;
  1883.         ngx_uint_t               i;
  1884.         ngx_http_server_name_t  *sn;

  1885.         sn = virtual_names->regex;

  1886. #if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)

  1887.         if (r == NULL) {
  1888.             ngx_http_connection_t  *hc;

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

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

  1891.                 if (n == NGX_REGEX_NO_MATCHED) {
  1892.                     continue;
  1893.                 }

  1894.                 if (n >= 0) {
  1895.                     hc = c->data;
  1896.                     hc->ssl_servername_regex = sn[i].regex;

  1897.                     *cscfp = sn[i].server;
  1898.                     return NGX_OK;
  1899.                 }

  1900.                 ngx_log_error(NGX_LOG_ALERT, c->log, 0,
  1901.                               ngx_regex_exec_n " failed: %i "
  1902.                               "on \"%V\" using \"%V\"",
  1903.                               n, host, &sn[i].regex->name);

  1904.                 return NGX_ERROR;
  1905.             }

  1906.             return NGX_DECLINED;
  1907.         }

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

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

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

  1911.             if (n == NGX_DECLINED) {
  1912.                 continue;
  1913.             }

  1914.             if (n == NGX_OK) {
  1915.                 *cscfp = sn[i].server;
  1916.                 return NGX_OK;
  1917.             }

  1918.             return NGX_ERROR;
  1919.         }
  1920.     }

  1921. #endif /* NGX_PCRE */

  1922.     return NGX_DECLINED;
  1923. }


  1924. static void
  1925. ngx_http_request_handler(ngx_event_t *ev)
  1926. {
  1927.     ngx_connection_t    *c;
  1928.     ngx_http_request_t  *r;

  1929.     c = ev->data;
  1930.     r = c->data;

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

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

  1934.     if (c->close) {
  1935.         r->main->count++;
  1936.         ngx_http_terminate_request(r, 0);
  1937.         ngx_http_run_posted_requests(c);
  1938.         return;
  1939.     }

  1940.     if (ev->delayed && ev->timedout) {
  1941.         ev->delayed = 0;
  1942.         ev->timedout = 0;
  1943.     }

  1944.     if (ev->write) {
  1945.         r->write_event_handler(r);

  1946.     } else {
  1947.         r->read_event_handler(r);
  1948.     }

  1949.     ngx_http_run_posted_requests(c);
  1950. }


  1951. void
  1952. ngx_http_run_posted_requests(ngx_connection_t *c)
  1953. {
  1954.     ngx_http_request_t         *r;
  1955.     ngx_http_posted_request_t  *pr;

  1956.     for ( ;; ) {

  1957.         if (c->destroyed) {
  1958.             return;
  1959.         }

  1960.         r = c->data;
  1961.         pr = r->main->posted_requests;

  1962.         if (pr == NULL) {
  1963.             return;
  1964.         }

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

  1966.         r = pr->request;

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

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

  1970.         r->write_event_handler(r);
  1971.     }
  1972. }


  1973. ngx_int_t
  1974. ngx_http_post_request(ngx_http_request_t *r, ngx_http_posted_request_t *pr)
  1975. {
  1976.     ngx_http_posted_request_t  **p;

  1977.     for (p = &r->main->posted_requests; *p; p = &(*p)->next) {
  1978.         if ((*p)->request == r) {
  1979.             ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  1980.                            "http request already posted");
  1981.             return NGX_OK;
  1982.         }
  1983.     }

  1984.     if (pr == NULL) {
  1985.         pr = ngx_palloc(r->pool, sizeof(ngx_http_posted_request_t));
  1986.         if (pr == NULL) {
  1987.             return NGX_ERROR;
  1988.         }
  1989.     }

  1990.     pr->request = r;
  1991.     pr->next = NULL;

  1992.     *p = pr;

  1993.     return NGX_OK;
  1994. }


  1995. void
  1996. ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
  1997. {
  1998.     ngx_connection_t          *c;
  1999.     ngx_http_request_t        *pr;
  2000.     ngx_http_core_loc_conf_t  *clcf;

  2001.     c = r->connection;

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

  2005.     if (rc == NGX_DONE) {
  2006.         ngx_http_finalize_connection(r);
  2007.         return;
  2008.     }

  2009.     if (rc == NGX_OK && r->filter_finalize) {
  2010.         c->error = 1;
  2011.     }

  2012.     if (rc == NGX_DECLINED) {
  2013.         r->content_handler = NULL;
  2014.         r->write_event_handler = ngx_http_core_run_phases;
  2015.         ngx_http_core_run_phases(r);
  2016.         return;
  2017.     }

  2018.     if (r != r->main && r->post_subrequest) {
  2019.         rc = r->post_subrequest->handler(r, r->post_subrequest->data, rc);
  2020.     }

  2021.     if (rc == NGX_ERROR
  2022.         || rc == NGX_HTTP_REQUEST_TIME_OUT
  2023.         || rc == NGX_HTTP_CLIENT_CLOSED_REQUEST
  2024.         || c->error)
  2025.     {
  2026.         if (ngx_http_post_action(r) == NGX_OK) {
  2027.             return;
  2028.         }

  2029.         ngx_http_terminate_request(r, rc);
  2030.         return;
  2031.     }

  2032.     if (rc >= NGX_HTTP_SPECIAL_RESPONSE
  2033.         || rc == NGX_HTTP_CREATED
  2034.         || rc == NGX_HTTP_NO_CONTENT)
  2035.     {
  2036.         if (rc == NGX_HTTP_CLOSE) {
  2037.             c->timedout = 1;
  2038.             ngx_http_terminate_request(r, rc);
  2039.             return;
  2040.         }

  2041.         if (r == r->main) {
  2042.             if (c->read->timer_set) {
  2043.                 ngx_del_timer(c->read);
  2044.             }

  2045.             if (c->write->timer_set) {
  2046.                 ngx_del_timer(c->write);
  2047.             }
  2048.         }

  2049.         c->read->handler = ngx_http_request_handler;
  2050.         c->write->handler = ngx_http_request_handler;

  2051.         ngx_http_finalize_request(r, ngx_http_special_response_handler(r, rc));
  2052.         return;
  2053.     }

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

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

  2056.             if (ngx_http_set_write_handler(r) != NGX_OK) {
  2057.                 ngx_http_terminate_request(r, 0);
  2058.             }

  2059.             return;
  2060.         }

  2061.         pr = r->parent;

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

  2063.             if (!r->logged) {

  2064.                 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  2065.                 if (clcf->log_subrequest) {
  2066.                     ngx_http_log_request(r);
  2067.                 }

  2068.                 r->logged = 1;

  2069.             } else {
  2070.                 ngx_log_error(NGX_LOG_ALERT, c->log, 0,
  2071.                               "subrequest: \"%V?%V\" logged again",
  2072.                               &r->uri, &r->args);
  2073.             }

  2074.             r->done = 1;

  2075.             if (r->background) {
  2076.                 ngx_http_finalize_connection(r);
  2077.                 return;
  2078.             }

  2079.             r->main->count--;

  2080.             r->write_event_handler = ngx_http_request_empty_handler;

  2081.             if (pr->postponed && pr->postponed->request == r) {
  2082.                 pr->postponed = pr->postponed->next;
  2083.             }

  2084.             c->data = pr;

  2085.         } else {

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

  2089.             r->write_event_handler = ngx_http_request_finalizer;

  2090.             if (r->waited) {
  2091.                 r->done = 1;
  2092.             }
  2093.         }

  2094.         if (ngx_http_post_request(pr, NULL) != NGX_OK) {
  2095.             r->main->count++;
  2096.             ngx_http_terminate_request(r, 0);
  2097.             return;
  2098.         }

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

  2102.         return;
  2103.     }

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

  2105.         if (ngx_http_set_write_handler(r) != NGX_OK) {
  2106.             ngx_http_terminate_request(r, 0);
  2107.         }

  2108.         return;
  2109.     }

  2110.     if (r != c->data) {
  2111.         ngx_log_error(NGX_LOG_ALERT, c->log, 0,
  2112.                       "http finalize non-active request: \"%V?%V\"",
  2113.                       &r->uri, &r->args);
  2114.         return;
  2115.     }

  2116.     r->done = 1;

  2117.     r->read_event_handler = ngx_http_block_reading;
  2118.     r->write_event_handler = ngx_http_request_empty_handler;

  2119.     if (!r->post_action) {
  2120.         r->request_complete = 1;
  2121.     }

  2122.     if (ngx_http_post_action(r) == NGX_OK) {
  2123.         return;
  2124.     }

  2125.     if (c->read->timer_set) {
  2126.         ngx_del_timer(c->read);
  2127.     }

  2128.     if (c->write->timer_set) {
  2129.         c->write->delayed = 0;
  2130.         ngx_del_timer(c->write);
  2131.     }

  2132.     ngx_http_finalize_connection(r);
  2133. }


  2134. static void
  2135. ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc)
  2136. {
  2137.     ngx_http_cleanup_t    *cln;
  2138.     ngx_http_request_t    *mr;
  2139.     ngx_http_ephemeral_t  *e;

  2140.     mr = r->main;

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

  2143.     mr->terminated = 1;

  2144.     if (rc > 0 && (mr->headers_out.status == 0 || mr->connection->sent == 0)) {
  2145.         mr->headers_out.status = rc;
  2146.     }

  2147.     cln = mr->cleanup;
  2148.     mr->cleanup = NULL;

  2149.     while (cln) {
  2150.         if (cln->handler) {
  2151.             cln->handler(cln->data);
  2152.         }

  2153.         cln = cln->next;
  2154.     }

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

  2158.     if (mr->write_event_handler) {

  2159.         if (mr->blocked) {
  2160.             r = r->connection->data;

  2161.             r->connection->error = 1;
  2162.             r->write_event_handler = ngx_http_request_finalizer;

  2163.             return;
  2164.         }

  2165.         e = ngx_http_ephemeral(mr);
  2166.         mr->posted_requests = NULL;
  2167.         mr->write_event_handler = ngx_http_terminate_handler;
  2168.         (void) ngx_http_post_request(mr, &e->terminal_posted_request);
  2169.         return;
  2170.     }

  2171.     ngx_http_close_request(mr, rc);
  2172. }


  2173. static void
  2174. ngx_http_terminate_handler(ngx_http_request_t *r)
  2175. {
  2176.     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  2177.                    "http terminate handler count:%d", r->count);

  2178.     r->count = 1;

  2179.     ngx_http_close_request(r, 0);
  2180. }


  2181. static void
  2182. ngx_http_finalize_connection(ngx_http_request_t *r)
  2183. {
  2184.     ngx_http_core_loc_conf_t  *clcf;

  2185. #if (NGX_HTTP_V2)
  2186.     if (r->stream) {
  2187.         ngx_http_close_request(r, 0);
  2188.         return;
  2189.     }
  2190. #endif

  2191. #if (NGX_HTTP_V3)
  2192.     if (r->connection->quic) {
  2193.         ngx_http_close_request(r, 0);
  2194.         return;
  2195.     }
  2196. #endif

  2197.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

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

  2199.         if (r->discard_body) {
  2200.             r->read_event_handler = ngx_http_discarded_request_body_handler;
  2201.             ngx_add_timer(r->connection->read, clcf->lingering_timeout);

  2202.             if (r->lingering_time == 0) {
  2203.                 r->lingering_time = ngx_time()
  2204.                                       + (time_t) (clcf->lingering_time / 1000);
  2205.             }
  2206.         }

  2207.         ngx_http_close_request(r, 0);
  2208.         return;
  2209.     }

  2210.     r = r->main;

  2211.     if (r->connection->read->eof) {
  2212.         ngx_http_close_request(r, 0);
  2213.         return;
  2214.     }

  2215.     if (r->reading_body) {
  2216.         r->keepalive = 0;
  2217.         r->lingering_close = 1;
  2218.     }

  2219.     if (r->keepalive
  2220.         && clcf->keepalive_min_timeout > 0)
  2221.     {
  2222.         ngx_http_set_keepalive(r);
  2223.         return;
  2224.     }

  2225.     if (!ngx_terminate
  2226.          && !ngx_exiting
  2227.          && r->keepalive
  2228.          && clcf->keepalive_timeout > 0)
  2229.     {
  2230.         ngx_http_set_keepalive(r);
  2231.         return;
  2232.     }

  2233.     if (clcf->lingering_close == NGX_HTTP_LINGERING_ALWAYS
  2234.         || (clcf->lingering_close == NGX_HTTP_LINGERING_ON
  2235.             && (r->lingering_close
  2236.                 || r->header_in->pos < r->header_in->last
  2237.                 || r->connection->read->ready
  2238.                 || r->connection->pipeline)))
  2239.     {
  2240.         ngx_http_set_lingering_close(r->connection);
  2241.         return;
  2242.     }

  2243.     ngx_http_close_request(r, 0);
  2244. }


  2245. static ngx_int_t
  2246. ngx_http_set_write_handler(ngx_http_request_t *r)
  2247. {
  2248.     ngx_event_t               *wev;
  2249.     ngx_http_core_loc_conf_t  *clcf;

  2250.     r->http_state = NGX_HTTP_WRITING_REQUEST_STATE;

  2251.     r->read_event_handler = r->discard_body ?
  2252.                                 ngx_http_discarded_request_body_handler:
  2253.                                 ngx_http_test_reading;
  2254.     r->write_event_handler = ngx_http_writer;

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

  2256.     if (wev->ready && wev->delayed) {
  2257.         return NGX_OK;
  2258.     }

  2259.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
  2260.     if (!wev->delayed) {
  2261.         ngx_add_timer(wev, clcf->send_timeout);
  2262.     }

  2263.     if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
  2264.         ngx_http_close_request(r, 0);
  2265.         return NGX_ERROR;
  2266.     }

  2267.     return NGX_OK;
  2268. }


  2269. static void
  2270. ngx_http_writer(ngx_http_request_t *r)
  2271. {
  2272.     ngx_int_t                  rc;
  2273.     ngx_event_t               *wev;
  2274.     ngx_connection_t          *c;
  2275.     ngx_http_core_loc_conf_t  *clcf;

  2276.     c = r->connection;
  2277.     wev = c->write;

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

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

  2281.     if (wev->timedout) {
  2282.         ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
  2283.                       "client timed out");
  2284.         c->timedout = 1;

  2285.         ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT);
  2286.         return;
  2287.     }

  2288.     if (wev->delayed || r->aio) {
  2289.         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0,
  2290.                        "http writer delayed");

  2291.         if (!wev->delayed) {
  2292.             ngx_add_timer(wev, clcf->send_timeout);
  2293.         }

  2294.         if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
  2295.             ngx_http_close_request(r, 0);
  2296.         }

  2297.         return;
  2298.     }

  2299.     rc = ngx_http_output_filter(r, NULL);

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

  2303.     if (rc == NGX_ERROR) {
  2304.         ngx_http_finalize_request(r, rc);
  2305.         return;
  2306.     }

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

  2308.         if (!wev->delayed) {
  2309.             ngx_add_timer(wev, clcf->send_timeout);
  2310.         }

  2311.         if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
  2312.             ngx_http_close_request(r, 0);
  2313.         }

  2314.         return;
  2315.     }

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

  2318.     r->write_event_handler = ngx_http_request_empty_handler;

  2319.     ngx_http_finalize_request(r, rc);
  2320. }


  2321. static void
  2322. ngx_http_request_finalizer(ngx_http_request_t *r)
  2323. {
  2324.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  2325.                    "http finalizer done: \"%V?%V\"", &r->uri, &r->args);

  2326.     ngx_http_finalize_request(r, 0);
  2327. }


  2328. void
  2329. ngx_http_block_reading(ngx_http_request_t *r)
  2330. {
  2331.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  2332.                    "http reading blocked");

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

  2334.     if ((ngx_event_flags & NGX_USE_LEVEL_EVENT)
  2335.         && r->connection->read->active)
  2336.     {
  2337.         if (ngx_del_event(r->connection->read, NGX_READ_EVENT, 0) != NGX_OK) {
  2338.             ngx_http_close_request(r, 0);
  2339.         }
  2340.     }
  2341. }


  2342. void
  2343. ngx_http_test_reading(ngx_http_request_t *r)
  2344. {
  2345.     int                n;
  2346.     char               buf[1];
  2347.     ngx_err_t          err;
  2348.     ngx_event_t       *rev;
  2349.     ngx_connection_t  *c;

  2350.     c = r->connection;
  2351.     rev = c->read;

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

  2353. #if (NGX_HTTP_V2)

  2354.     if (r->stream) {
  2355.         if (c->error) {
  2356.             err = 0;
  2357.             goto closed;
  2358.         }

  2359.         return;
  2360.     }

  2361. #endif

  2362. #if (NGX_HTTP_V3)

  2363.     if (c->quic) {
  2364.         if (rev->error) {
  2365.             c->error = 1;
  2366.             err = 0;
  2367.             goto closed;
  2368.         }

  2369.         return;
  2370.     }

  2371. #endif

  2372. #if (NGX_HAVE_KQUEUE)

  2373.     if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {

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

  2377.         rev->eof = 1;
  2378.         c->error = 1;
  2379.         err = rev->kq_errno;

  2380.         goto closed;
  2381.     }

  2382. #endif

  2383. #if (NGX_HAVE_EPOLLRDHUP)

  2384.     if ((ngx_event_flags & NGX_USE_EPOLL_EVENT) && ngx_use_epoll_rdhup) {
  2385.         socklen_t  len;

  2386.         if (!rev->pending_eof) {
  2387.             return;
  2388.         }

  2389.         rev->eof = 1;
  2390.         c->error = 1;

  2391.         err = 0;
  2392.         len = sizeof(ngx_err_t);

  2393.         /*
  2394.          * BSDs and Linux return 0 and set a pending error in err
  2395.          * Solaris returns -1 and sets errno
  2396.          */

  2397.         if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len)
  2398.             == -1)
  2399.         {
  2400.             err = ngx_socket_errno;
  2401.         }

  2402.         goto closed;
  2403.     }

  2404. #endif

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

  2406.     if (n == 0) {
  2407.         rev->eof = 1;
  2408.         c->error = 1;
  2409.         err = 0;

  2410.         goto closed;

  2411.     } else if (n == -1) {
  2412.         err = ngx_socket_errno;

  2413.         if (err != NGX_EAGAIN) {
  2414.             rev->eof = 1;
  2415.             c->error = 1;

  2416.             goto closed;
  2417.         }
  2418.     }

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

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

  2421.         if (ngx_del_event(rev, NGX_READ_EVENT, 0) != NGX_OK) {
  2422.             ngx_http_close_request(r, 0);
  2423.         }
  2424.     }

  2425.     return;

  2426. closed:

  2427.     if (err) {
  2428.         rev->error = 1;
  2429.     }

  2430. #if (NGX_HTTP_SSL)
  2431.     if (c->ssl) {
  2432.         c->ssl->no_send_shutdown = 1;
  2433.     }
  2434. #endif

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

  2437.     ngx_http_finalize_request(r, NGX_HTTP_CLIENT_CLOSED_REQUEST);
  2438. }


  2439. static void
  2440. ngx_http_set_keepalive(ngx_http_request_t *r)
  2441. {
  2442.     int                        tcp_nodelay;
  2443.     ngx_buf_t                 *b, *f;
  2444.     ngx_chain_t               *cl, *ln;
  2445.     ngx_event_t               *rev, *wev;
  2446.     ngx_connection_t          *c;
  2447.     ngx_http_connection_t     *hc;
  2448.     ngx_http_core_loc_conf_t  *clcf;

  2449.     c = r->connection;
  2450.     rev = c->read;

  2451.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

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

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

  2454.     hc = r->http_connection;
  2455.     b = r->header_in;

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

  2457.         /* the pipelined request */

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

  2459.             /*
  2460.              * If the large header buffers were allocated while the previous
  2461.              * request processing then we do not use c->buffer for
  2462.              * the pipelined request (see ngx_http_create_request()).
  2463.              *
  2464.              * Now we would move the large header buffers to the free list.
  2465.              */

  2466.             for (cl = hc->busy; cl; /* void */) {
  2467.                 ln = cl;
  2468.                 cl = cl->next;

  2469.                 if (ln->buf == b) {
  2470.                     ngx_free_chain(c->pool, ln);
  2471.                     continue;
  2472.                 }

  2473.                 f = ln->buf;
  2474.                 f->pos = f->start;
  2475.                 f->last = f->start;

  2476.                 ln->next = hc->free;
  2477.                 hc->free = ln;
  2478.             }

  2479.             cl = ngx_alloc_chain_link(c->pool);
  2480.             if (cl == NULL) {
  2481.                 ngx_http_close_request(r, 0);
  2482.                 return;
  2483.             }

  2484.             cl->buf = b;
  2485.             cl->next = NULL;

  2486.             hc->busy = cl;
  2487.             hc->nbusy = 1;
  2488.         }
  2489.     }

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

  2492.     ngx_http_free_request(r, 0);

  2493.     c->data = hc;

  2494.     if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  2495.         ngx_http_close_connection(c);
  2496.         return;
  2497.     }

  2498.     wev = c->write;
  2499.     wev->handler = ngx_http_empty_handler;

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

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

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

  2503.         r = ngx_http_create_request(c);
  2504.         if (r == NULL) {
  2505.             ngx_http_close_connection(c);
  2506.             return;
  2507.         }

  2508.         r->pipeline = 1;

  2509.         c->data = r;

  2510.         c->sent = 0;
  2511.         c->destroyed = 0;
  2512.         c->pipeline = 1;

  2513.         if (rev->timer_set) {
  2514.             ngx_del_timer(rev);
  2515.         }

  2516.         rev->handler = ngx_http_process_request_line;
  2517.         ngx_post_event(rev, &ngx_posted_events);
  2518.         return;
  2519.     }

  2520.     /*
  2521.      * To keep a memory footprint as small as possible for an idle keepalive
  2522.      * connection we try to free c->buffer's memory if it was allocated outside
  2523.      * the c->pool.  The large header buffers are always allocated outside the
  2524.      * c->pool and are freed too.
  2525.      */

  2526.     b = c->buffer;

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

  2528.         /*
  2529.          * the special note for ngx_http_keepalive_handler() that
  2530.          * c->buffer's memory was freed
  2531.          */

  2532.         b->pos = NULL;

  2533.     } else {
  2534.         b->pos = b->start;
  2535.         b->last = b->start;
  2536.     }

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

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

  2546.         hc->free = NULL;
  2547.     }

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

  2550.     if (hc->busy) {
  2551.         for (cl = hc->busy; cl; /* void */) {
  2552.             ln = cl;
  2553.             cl = cl->next;
  2554.             ngx_pfree(c->pool, ln->buf->start);
  2555.             ngx_free_chain(c->pool, ln);
  2556.         }

  2557.         hc->busy = NULL;
  2558.         hc->nbusy = 0;
  2559.     }

  2560. #if (NGX_HTTP_SSL)
  2561.     if (c->ssl) {
  2562.         ngx_ssl_free_buffer(c);
  2563.     }
  2564. #endif

  2565.     rev->handler = ngx_http_keepalive_handler;

  2566.     if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
  2567.         if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) != NGX_OK) {
  2568.             ngx_http_close_connection(c);
  2569.             return;
  2570.         }
  2571.     }

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

  2573.     if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
  2574.         if (ngx_tcp_push(c->fd) == -1) {
  2575.             ngx_connection_error(c, ngx_socket_errno, ngx_tcp_push_n " failed");
  2576.             ngx_http_close_connection(c);
  2577.             return;
  2578.         }

  2579.         c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
  2580.         tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0;

  2581.     } else {
  2582.         tcp_nodelay = 1;
  2583.     }

  2584.     if (tcp_nodelay && clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) {
  2585.         ngx_http_close_connection(c);
  2586.         return;
  2587.     }

  2588. #if 0
  2589.     /* if ngx_http_request_t was freed then we need some other place */
  2590.     r->http_state = NGX_HTTP_KEEPALIVE_STATE;
  2591. #endif

  2592.     if (clcf->keepalive_min_timeout == 0) {
  2593.         c->idle = 1;
  2594.         ngx_reusable_connection(c, 1);
  2595.     }

  2596.     if (clcf->keepalive_min_timeout > 0
  2597.         && clcf->keepalive_timeout > clcf->keepalive_min_timeout)
  2598.     {
  2599.         hc->keepalive_timeout = clcf->keepalive_timeout
  2600.                                 - clcf->keepalive_min_timeout;

  2601.     } else {
  2602.         hc->keepalive_timeout = 0;
  2603.     }

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

  2605.     if (rev->ready) {
  2606.         ngx_post_event(rev, &ngx_posted_events);
  2607.     }
  2608. }


  2609. static void
  2610. ngx_http_keepalive_handler(ngx_event_t *rev)
  2611. {
  2612.     size_t                  size;
  2613.     ssize_t                 n;
  2614.     ngx_buf_t              *b;
  2615.     ngx_connection_t       *c;
  2616.     ngx_http_connection_t  *hc;

  2617.     c = rev->data;
  2618.     hc = c->data;

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

  2620.     if (!ngx_terminate
  2621.          && !ngx_exiting
  2622.          && rev->timedout
  2623.          && hc->keepalive_timeout > 0)
  2624.     {
  2625.         c->idle = 1;
  2626.         ngx_reusable_connection(c, 1);

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

  2628.         hc->keepalive_timeout = 0;
  2629.         rev->timedout = 0;
  2630.         return;
  2631.     }

  2632.     if (rev->timedout || c->close) {
  2633.         ngx_http_close_connection(c);
  2634.         return;
  2635.     }

  2636. #if (NGX_HAVE_KQUEUE)

  2637.     if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
  2638.         if (rev->pending_eof) {
  2639.             c->log->handler = NULL;
  2640.             ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno,
  2641.                           "kevent() reported that client %V closed "
  2642.                           "keepalive connection", &c->addr_text);
  2643. #if (NGX_HTTP_SSL)
  2644.             if (c->ssl) {
  2645.                 c->ssl->no_send_shutdown = 1;
  2646.             }
  2647. #endif
  2648.             ngx_http_close_connection(c);
  2649.             return;
  2650.         }
  2651.     }

  2652. #endif

  2653.     b = c->buffer;
  2654.     size = b->end - b->start;

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

  2656.         /*
  2657.          * The c->buffer's memory was freed by ngx_http_set_keepalive().
  2658.          * However, the c->buffer->start and c->buffer->end were not changed
  2659.          * to keep the buffer size.
  2660.          */

  2661.         b->pos = ngx_palloc(c->pool, size);
  2662.         if (b->pos == NULL) {
  2663.             ngx_http_close_connection(c);
  2664.             return;
  2665.         }

  2666.         b->start = b->pos;
  2667.         b->last = b->pos;
  2668.         b->end = b->pos + size;
  2669.     }

  2670.     /*
  2671.      * MSIE closes a keepalive connection with RST flag
  2672.      * so we ignore ECONNRESET here.
  2673.      */

  2674.     c->log_error = NGX_ERROR_IGNORE_ECONNRESET;
  2675.     ngx_set_socket_errno(0);

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

  2678.     if (n == NGX_AGAIN) {
  2679.         if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  2680.             ngx_http_close_connection(c);
  2681.             return;
  2682.         }

  2683.         /*
  2684.          * Like ngx_http_set_keepalive() we are trying to not hold
  2685.          * c->buffer's memory for a keepalive connection.
  2686.          */

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

  2688.             /*
  2689.              * the special note that c->buffer's memory was freed
  2690.              */

  2691.             b->pos = NULL;
  2692.         }

  2693.         return;
  2694.     }

  2695.     if (n == NGX_ERROR) {
  2696.         ngx_http_close_connection(c);
  2697.         return;
  2698.     }

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

  2700.     if (n == 0) {
  2701.         ngx_log_error(NGX_LOG_INFO, c->log, ngx_socket_errno,
  2702.                       "client %V closed keepalive connection", &c->addr_text);
  2703.         ngx_http_close_connection(c);
  2704.         return;
  2705.     }

  2706.     b->last += n;

  2707.     c->log->handler = ngx_http_log_error;
  2708.     c->log->action = "reading client request line";

  2709.     c->idle = 0;
  2710.     ngx_reusable_connection(c, 0);

  2711.     c->data = ngx_http_create_request(c);
  2712.     if (c->data == NULL) {
  2713.         ngx_http_close_connection(c);
  2714.         return;
  2715.     }

  2716.     c->sent = 0;
  2717.     c->destroyed = 0;

  2718.     ngx_del_timer(rev);

  2719.     rev->handler = ngx_http_process_request_line;
  2720.     ngx_http_process_request_line(rev);
  2721. }


  2722. static void
  2723. ngx_http_set_lingering_close(ngx_connection_t *c)
  2724. {
  2725.     ngx_event_t               *rev, *wev;
  2726.     ngx_http_request_t        *r;
  2727.     ngx_http_core_loc_conf_t  *clcf;

  2728.     r = c->data;

  2729.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  2730.     if (r->lingering_time == 0) {
  2731.         r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000);
  2732.     }

  2733. #if (NGX_HTTP_SSL)
  2734.     if (c->ssl) {
  2735.         ngx_int_t  rc;

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

  2737.         rc = ngx_ssl_shutdown(c);

  2738.         if (rc == NGX_ERROR) {
  2739.             ngx_http_close_request(r, 0);
  2740.             return;
  2741.         }

  2742.         if (rc == NGX_AGAIN) {
  2743.             c->ssl->handler = ngx_http_set_lingering_close;
  2744.             return;
  2745.         }
  2746.     }
  2747. #endif

  2748.     rev = c->read;
  2749.     rev->handler = ngx_http_lingering_close_handler;

  2750.     if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  2751.         ngx_http_close_request(r, 0);
  2752.         return;
  2753.     }

  2754.     wev = c->write;
  2755.     wev->handler = ngx_http_empty_handler;

  2756.     if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
  2757.         if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) != NGX_OK) {
  2758.             ngx_http_close_request(r, 0);
  2759.             return;
  2760.         }
  2761.     }

  2762.     if (ngx_shutdown_socket(c->fd, NGX_WRITE_SHUTDOWN) == -1) {
  2763.         ngx_connection_error(c, ngx_socket_errno,
  2764.                              ngx_shutdown_socket_n " failed");
  2765.         ngx_http_close_request(r, 0);
  2766.         return;
  2767.     }

  2768.     c->close = 0;
  2769.     ngx_reusable_connection(c, 1);

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

  2771.     if (rev->ready) {
  2772.         ngx_http_lingering_close_handler(rev);
  2773.     }
  2774. }


  2775. static void
  2776. ngx_http_lingering_close_handler(ngx_event_t *rev)
  2777. {
  2778.     ssize_t                    n;
  2779.     ngx_msec_t                 timer;
  2780.     ngx_connection_t          *c;
  2781.     ngx_http_request_t        *r;
  2782.     ngx_http_core_loc_conf_t  *clcf;
  2783.     u_char                     buffer[NGX_HTTP_LINGERING_BUFFER_SIZE];

  2784.     c = rev->data;
  2785.     r = c->data;

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

  2788.     if (rev->timedout || c->close) {
  2789.         ngx_http_close_request(r, 0);
  2790.         return;
  2791.     }

  2792.     timer = (ngx_msec_t) r->lingering_time - (ngx_msec_t) ngx_time();
  2793.     if ((ngx_msec_int_t) timer <= 0) {
  2794.         ngx_http_close_request(r, 0);
  2795.         return;
  2796.     }

  2797.     do {
  2798.         n = c->recv(c, buffer, NGX_HTTP_LINGERING_BUFFER_SIZE);

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

  2800.         if (n == NGX_AGAIN) {
  2801.             break;
  2802.         }

  2803.         if (n == NGX_ERROR || n == 0) {
  2804.             ngx_http_close_request(r, 0);
  2805.             return;
  2806.         }

  2807.     } while (rev->ready);

  2808.     if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  2809.         ngx_http_close_request(r, 0);
  2810.         return;
  2811.     }

  2812.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  2813.     timer *= 1000;

  2814.     if (timer > clcf->lingering_timeout) {
  2815.         timer = clcf->lingering_timeout;
  2816.     }

  2817.     ngx_add_timer(rev, timer);
  2818. }


  2819. void
  2820. ngx_http_empty_handler(ngx_event_t *wev)
  2821. {
  2822.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, "http empty handler");

  2823.     return;
  2824. }


  2825. void
  2826. ngx_http_request_empty_handler(ngx_http_request_t *r)
  2827. {
  2828.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  2829.                    "http request empty handler");

  2830.     return;
  2831. }


  2832. ngx_int_t
  2833. ngx_http_send_special(ngx_http_request_t *r, ngx_uint_t flags)
  2834. {
  2835.     ngx_buf_t    *b;
  2836.     ngx_chain_t   out;

  2837.     b = ngx_calloc_buf(r->pool);
  2838.     if (b == NULL) {
  2839.         return NGX_ERROR;
  2840.     }

  2841.     if (flags & NGX_HTTP_LAST) {

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

  2844.         } else {
  2845.             b->sync = 1;
  2846.             b->last_in_chain = 1;
  2847.         }
  2848.     }

  2849.     if (flags & NGX_HTTP_FLUSH) {
  2850.         b->flush = 1;
  2851.     }

  2852.     out.buf = b;
  2853.     out.next = NULL;

  2854.     return ngx_http_output_filter(r, &out);
  2855. }


  2856. static ngx_int_t
  2857. ngx_http_post_action(ngx_http_request_t *r)
  2858. {
  2859.     ngx_http_core_loc_conf_t  *clcf;

  2860.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  2861.     if (clcf->post_action.data == NULL) {
  2862.         return NGX_DECLINED;
  2863.     }

  2864.     if (r->post_action && r->uri_changes == 0) {
  2865.         return NGX_DECLINED;
  2866.     }

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

  2869.     r->main->count--;

  2870.     r->http_version = NGX_HTTP_VERSION_9;
  2871.     r->header_only = 1;
  2872.     r->post_action = 1;

  2873.     r->read_event_handler = ngx_http_block_reading;

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

  2876.     } else {
  2877.         ngx_http_named_location(r, &clcf->post_action);
  2878.     }

  2879.     return NGX_OK;
  2880. }


  2881. void
  2882. ngx_http_close_request(ngx_http_request_t *r, ngx_int_t rc)
  2883. {
  2884.     ngx_connection_t  *c;

  2885.     r = r->main;
  2886.     c = r->connection;

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

  2889.     if (r->count == 0) {
  2890.         ngx_log_error(NGX_LOG_ALERT, c->log, 0, "http request count is zero");
  2891.     }

  2892.     r->count--;

  2893.     if (r->count || r->blocked) {
  2894.         return;
  2895.     }

  2896. #if (NGX_HTTP_V2)
  2897.     if (r->stream) {
  2898.         ngx_http_v2_close_stream(r->stream, rc);
  2899.         return;
  2900.     }
  2901. #endif

  2902.     ngx_http_free_request(r, rc);
  2903.     ngx_http_close_connection(c);
  2904. }


  2905. void
  2906. ngx_http_free_request(ngx_http_request_t *r, ngx_int_t rc)
  2907. {
  2908.     ngx_log_t                 *log;
  2909.     ngx_pool_t                *pool;
  2910.     struct linger              linger;
  2911.     ngx_http_cleanup_t        *cln;
  2912.     ngx_http_log_ctx_t        *ctx;
  2913.     ngx_http_core_loc_conf_t  *clcf;

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

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

  2916.     if (r->pool == NULL) {
  2917.         ngx_log_error(NGX_LOG_ALERT, log, 0, "http request already closed");
  2918.         return;
  2919.     }

  2920.     cln = r->cleanup;
  2921.     r->cleanup = NULL;

  2922.     while (cln) {
  2923.         if (cln->handler) {
  2924.             cln->handler(cln->data);
  2925.         }

  2926.         cln = cln->next;
  2927.     }

  2928. #if (NGX_STAT_STUB)

  2929.     if (r->stat_reading) {
  2930.         (void) ngx_atomic_fetch_add(ngx_stat_reading, -1);
  2931.     }

  2932.     if (r->stat_writing) {
  2933.         (void) ngx_atomic_fetch_add(ngx_stat_writing, -1);
  2934.     }

  2935. #endif

  2936.     if (rc > 0 && (r->headers_out.status == 0 || r->connection->sent == 0)) {
  2937.         r->headers_out.status = rc;
  2938.     }

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

  2941.         ngx_http_log_request(r);
  2942.     }

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

  2944.     if (r->connection->timedout
  2945. #if (NGX_HTTP_V3)
  2946.         && r->connection->quic == NULL
  2947. #endif
  2948.        )
  2949.     {
  2950.         clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  2951.         if (clcf->reset_timedout_connection) {
  2952.             linger.l_onoff = 1;
  2953.             linger.l_linger = 0;

  2954.             if (setsockopt(r->connection->fd, SOL_SOCKET, SO_LINGER,
  2955.                            (const void *) &linger, sizeof(struct linger)) == -1)
  2956.             {
  2957.                 ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno,
  2958.                               "setsockopt(SO_LINGER) failed");
  2959.             }
  2960.         }
  2961.     }

  2962.     /* the various request strings were allocated from r->pool */
  2963.     ctx = log->data;
  2964.     ctx->request = NULL;

  2965.     r->request_line.len = 0;

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

  2967.     /*
  2968.      * Setting r->pool to NULL will increase probability to catch double close
  2969.      * of request since the request object is allocated from its own pool.
  2970.      */

  2971.     pool = r->pool;
  2972.     r->pool = NULL;

  2973.     ngx_destroy_pool(pool);
  2974. }


  2975. static void
  2976. ngx_http_log_request(ngx_http_request_t *r)
  2977. {
  2978.     ngx_uint_t                  i, n;
  2979.     ngx_http_handler_pt        *log_handler;
  2980.     ngx_http_core_main_conf_t  *cmcf;

  2981.     cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

  2982.     log_handler = cmcf->phases[NGX_HTTP_LOG_PHASE].handlers.elts;
  2983.     n = cmcf->phases[NGX_HTTP_LOG_PHASE].handlers.nelts;

  2984.     for (i = 0; i < n; i++) {
  2985.         log_handler[i](r);
  2986.     }
  2987. }


  2988. void
  2989. ngx_http_close_connection(ngx_connection_t *c)
  2990. {
  2991.     ngx_pool_t  *pool;

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

  2994. #if (NGX_HTTP_SSL)

  2995.     if (c->ssl) {
  2996.         if (ngx_ssl_shutdown(c) == NGX_AGAIN) {
  2997.             c->ssl->handler = ngx_http_close_connection;
  2998.             return;
  2999.         }
  3000.     }

  3001. #endif

  3002. #if (NGX_HTTP_V3)
  3003.     if (c->quic) {
  3004.         ngx_http_v3_reset_stream(c);
  3005.     }
  3006. #endif

  3007. #if (NGX_STAT_STUB)
  3008.     (void) ngx_atomic_fetch_add(ngx_stat_active, -1);
  3009. #endif

  3010.     c->destroyed = 1;

  3011.     pool = c->pool;

  3012.     ngx_close_connection(c);

  3013.     ngx_destroy_pool(pool);
  3014. }


  3015. static u_char *
  3016. ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len)
  3017. {
  3018.     u_char              *p;
  3019.     ngx_http_request_t  *r;
  3020.     ngx_http_log_ctx_t  *ctx;

  3021.     if (log->action) {
  3022.         p = ngx_snprintf(buf, len, " while %s", log->action);
  3023.         len -= p - buf;
  3024.         buf = p;
  3025.     }

  3026.     ctx = log->data;

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

  3029.     r = ctx->request;

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

  3032.     } else {
  3033.         p = ngx_snprintf(p, len, ", server: %V",
  3034.                          &ctx->connection->listening->addr_text);
  3035.     }

  3036.     return p;
  3037. }


  3038. static u_char *
  3039. ngx_http_log_error_handler(ngx_http_request_t *r, ngx_http_request_t *sr,
  3040.     u_char *buf, size_t len)
  3041. {
  3042.     char                      *uri_separator;
  3043.     u_char                    *p;
  3044.     ngx_http_upstream_t       *u;
  3045.     ngx_http_core_srv_conf_t  *cscf;

  3046.     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);

  3047.     p = ngx_snprintf(buf, len, ", server: %V", &cscf->server_name);
  3048.     len -= p - buf;
  3049.     buf = p;

  3050.     if (r->request_line.data == NULL && r->request_start) {
  3051.         for (p = r->request_start; p < r->header_in->last; p++) {
  3052.             if (*p == CR || *p == LF) {
  3053.                 break;
  3054.             }
  3055.         }

  3056.         r->request_line.len = p - r->request_start;
  3057.         r->request_line.data = r->request_start;
  3058.     }

  3059.     if (r->request_line.len) {
  3060.         p = ngx_snprintf(buf, len, ", request: \"%V\"", &r->request_line);
  3061.         len -= p - buf;
  3062.         buf = p;
  3063.     }

  3064.     if (r != sr) {
  3065.         p = ngx_snprintf(buf, len, ", subrequest: \"%V\"", &sr->uri);
  3066.         len -= p - buf;
  3067.         buf = p;
  3068.     }

  3069.     u = sr->upstream;

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

  3071.         uri_separator = "";

  3072. #if (NGX_HAVE_UNIX_DOMAIN)
  3073.         if (u->peer.sockaddr && u->peer.sockaddr->sa_family == AF_UNIX) {
  3074.             uri_separator = ":";
  3075.         }
  3076. #endif

  3077.         p = ngx_snprintf(buf, len, ", upstream: \"%V%V%s%V\"",
  3078.                          &u->schema, u->peer.name,
  3079.                          uri_separator, &u->uri);
  3080.         len -= p - buf;
  3081.         buf = p;
  3082.     }

  3083.     if (r->headers_in.host) {
  3084.         p = ngx_snprintf(buf, len, ", host: \"%V\"",
  3085.                          &r->headers_in.host->value);
  3086.         len -= p - buf;
  3087.         buf = p;
  3088.     }

  3089.     if (r->headers_in.referer) {
  3090.         p = ngx_snprintf(buf, len, ", referrer: \"%V\"",
  3091.                          &r->headers_in.referer->value);
  3092.         buf = p;
  3093.     }

  3094.     return buf;
  3095. }