src/http/ngx_http_request.c - nginx source code

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_user_agent(ngx_http_request_t *r,
  24.     ngx_table_elt_t *h, ngx_uint_t offset);

  25. static ngx_int_t ngx_http_find_virtual_server(ngx_connection_t *c,
  26.     ngx_http_virtual_names_t *virtual_names, ngx_str_t *host,
  27.     ngx_http_request_t *r, ngx_http_core_srv_conf_t **cscfp);

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

  35. static void ngx_http_set_keepalive(ngx_http_request_t *r);
  36. static void ngx_http_keepalive_handler(ngx_event_t *ev);
  37. static void ngx_http_set_lingering_close(ngx_connection_t *c);
  38. static void ngx_http_lingering_close_handler(ngx_event_t *ev);
  39. static ngx_int_t ngx_http_post_action(ngx_http_request_t *r);
  40. static void ngx_http_log_request(ngx_http_request_t *r);

  41. static u_char *ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len);
  42. static u_char *ngx_http_log_error_handler(ngx_http_request_t *r,
  43.     ngx_http_request_t *sr, u_char *buf, size_t len);

  44. #if (NGX_HTTP_SSL)
  45. static void ngx_http_ssl_handshake(ngx_event_t *rev);
  46. static void ngx_http_ssl_handshake_handler(ngx_connection_t *c);
  47. #endif


  48. static char *ngx_http_client_errors[] = {

  49.     /* NGX_HTTP_PARSE_INVALID_METHOD */
  50.     "client sent invalid method",

  51.     /* NGX_HTTP_PARSE_INVALID_REQUEST */
  52.     "client sent invalid request",

  53.     /* NGX_HTTP_PARSE_INVALID_VERSION */
  54.     "client sent invalid version",

  55.     /* NGX_HTTP_PARSE_INVALID_09_METHOD */
  56.     "client sent invalid method in HTTP/0.9 request"
  57. };


  58. ngx_http_header_t  ngx_http_headers_in[] = {
  59.     { ngx_string("Host"), offsetof(ngx_http_headers_in_t, host),
  60.                  ngx_http_process_host },

  61.     { ngx_string("Connection"), offsetof(ngx_http_headers_in_t, connection),
  62.                  ngx_http_process_connection },

  63.     { ngx_string("If-Modified-Since"),
  64.                  offsetof(ngx_http_headers_in_t, if_modified_since),
  65.                  ngx_http_process_unique_header_line },

  66.     { ngx_string("If-Unmodified-Since"),
  67.                  offsetof(ngx_http_headers_in_t, if_unmodified_since),
  68.                  ngx_http_process_unique_header_line },

  69.     { ngx_string("If-Match"),
  70.                  offsetof(ngx_http_headers_in_t, if_match),
  71.                  ngx_http_process_unique_header_line },

  72.     { ngx_string("If-None-Match"),
  73.                  offsetof(ngx_http_headers_in_t, if_none_match),
  74.                  ngx_http_process_unique_header_line },

  75.     { ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent),
  76.                  ngx_http_process_user_agent },

  77.     { ngx_string("Referer"), offsetof(ngx_http_headers_in_t, referer),
  78.                  ngx_http_process_header_line },

  79.     { ngx_string("Content-Length"),
  80.                  offsetof(ngx_http_headers_in_t, content_length),
  81.                  ngx_http_process_unique_header_line },

  82.     { ngx_string("Content-Range"),
  83.                  offsetof(ngx_http_headers_in_t, content_range),
  84.                  ngx_http_process_unique_header_line },

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

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

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

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

  96.     { ngx_string("TE"),
  97.                  offsetof(ngx_http_headers_in_t, te),
  98.                  ngx_http_process_header_line },

  99.     { ngx_string("Expect"),
  100.                  offsetof(ngx_http_headers_in_t, expect),
  101.                  ngx_http_process_unique_header_line },

  102.     { ngx_string("Upgrade"),
  103.                  offsetof(ngx_http_headers_in_t, upgrade),
  104.                  ngx_http_process_header_line },

  105. #if (NGX_HTTP_GZIP || NGX_HTTP_HEADERS)
  106.     { ngx_string("Accept-Encoding"),
  107.                  offsetof(ngx_http_headers_in_t, accept_encoding),
  108.                  ngx_http_process_header_line },

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

  112.     { ngx_string("Authorization"),
  113.                  offsetof(ngx_http_headers_in_t, authorization),
  114.                  ngx_http_process_unique_header_line },

  115.     { ngx_string("Keep-Alive"), offsetof(ngx_http_headers_in_t, keep_alive),
  116.                  ngx_http_process_header_line },

  117. #if (NGX_HTTP_X_FORWARDED_FOR)
  118.     { ngx_string("X-Forwarded-For"),
  119.                  offsetof(ngx_http_headers_in_t, x_forwarded_for),
  120.                  ngx_http_process_header_line },
  121. #endif

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

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

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

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

  137.     { ngx_string("Destination"), offsetof(ngx_http_headers_in_t, destination),
  138.                  ngx_http_process_header_line },

  139.     { ngx_string("Overwrite"), offsetof(ngx_http_headers_in_t, overwrite),
  140.                  ngx_http_process_header_line },

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

  144.     { ngx_string("Cookie"), offsetof(ngx_http_headers_in_t, cookie),
  145.                  ngx_http_process_header_line },

  146.     { ngx_null_string, 0, NULL }
  147. };


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

  163.     hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t));
  164.     if (hc == NULL) {
  165.         ngx_http_close_connection(c);
  166.         return;
  167.     }

  168.     c->data = hc;

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

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

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

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

  177.         if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) {
  178.             ngx_http_close_connection(c);
  179.             return;
  180.         }

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

  182. #if (NGX_HAVE_INET6)
  183.         case AF_INET6:
  184.             sin6 = (struct sockaddr_in6 *) c->local_sockaddr;

  185.             addr6 = port->addrs;

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

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

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

  193.             break;
  194. #endif

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

  197.             addr = port->addrs;

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

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

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

  205.             break;
  206.         }

  207.     } else {

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

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

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

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

  223.     ctx = ngx_palloc(c->pool, sizeof(ngx_http_log_ctx_t));
  224.     if (ctx == NULL) {
  225.         ngx_http_close_connection(c);
  226.         return;
  227.     }

  228.     ctx->connection = c;
  229.     ctx->request = NULL;
  230.     ctx->current_request = NULL;

  231.     c->log->connection = c->number;
  232.     c->log->handler = ngx_http_log_error;
  233.     c->log->data = ctx;
  234.     c->log->action = "waiting for request";

  235.     c->log_error = NGX_ERROR_INFO;

  236.     rev = c->read;
  237.     rev->handler = ngx_http_wait_request_handler;
  238.     c->write->handler = ngx_http_empty_handler;

  239. #if (NGX_HTTP_V3)
  240.     if (hc->addr_conf->quic) {
  241.         ngx_http_v3_init_stream(c);
  242.         return;
  243.     }
  244. #endif

  245. #if (NGX_HTTP_SSL)
  246.     if (hc->addr_conf->ssl) {
  247.         hc->ssl = 1;
  248.         c->log->action = "SSL handshaking";
  249.         rev->handler = ngx_http_ssl_handshake;
  250.     }
  251. #endif

  252.     if (hc->addr_conf->proxy_protocol) {
  253.         hc->proxy_protocol = 1;
  254.         c->log->action = "reading PROXY protocol";
  255.     }

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

  258.         if (ngx_use_accept_mutex) {
  259.             ngx_post_event(rev, &ngx_posted_events);
  260.             return;
  261.         }

  262.         rev->handler(rev);
  263.         return;
  264.     }

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

  266.     ngx_add_timer(rev, cscf->client_header_timeout);
  267.     ngx_reusable_connection(c, 1);

  268.     if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  269.         ngx_http_close_connection(c);
  270.         return;
  271.     }
  272. }


  273. static void
  274. ngx_http_wait_request_handler(ngx_event_t *rev)
  275. {
  276.     u_char                    *p;
  277.     size_t                     size;
  278.     ssize_t                    n;
  279.     ngx_buf_t                 *b;
  280.     ngx_connection_t          *c;
  281.     ngx_http_connection_t     *hc;
  282. #if (NGX_HTTP_V2)
  283.     ngx_http_v2_srv_conf_t    *h2scf;
  284. #endif
  285.     ngx_http_core_srv_conf_t  *cscf;

  286.     c = rev->data;

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

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

  293.     if (c->close) {
  294.         ngx_http_close_connection(c);
  295.         return;
  296.     }

  297.     hc = c->data;
  298.     cscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_core_module);

  299.     size = cscf->client_header_buffer_size;

  300.     b = c->buffer;

  301.     if (b == NULL) {
  302.         b = ngx_create_temp_buf(c->pool, size);
  303.         if (b == NULL) {
  304.             ngx_http_close_connection(c);
  305.             return;
  306.         }

  307.         c->buffer = b;

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

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

  314.         b->pos = b->start;
  315.         b->last = b->start;
  316.         b->end = b->last + size;
  317.     }

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

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

  320.     if (n == NGX_AGAIN) {

  321.         if (!rev->timer_set) {
  322.             ngx_add_timer(rev, cscf->client_header_timeout);
  323.             ngx_reusable_connection(c, 1);
  324.         }

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

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

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

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

  338.         return;
  339.     }

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

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

  350.     b->last += n;

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

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

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

  358.         b->pos = p;

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

  367. #if (NGX_HTTP_V2)

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

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

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

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

  373.             if (size == sizeof(NGX_HTTP_V2_PREFACE) - 1) {
  374.                 ngx_http_v2_init(rev);
  375.                 return;
  376.             }

  377.             ngx_post_event(rev, &ngx_posted_events);
  378.             return;
  379.         }
  380.     }

  381. #endif

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

  383.     ngx_reusable_connection(c, 0);

  384.     c->data = ngx_http_create_request(c);
  385.     if (c->data == NULL) {
  386.         ngx_http_close_connection(c);
  387.         return;
  388.     }

  389.     rev->handler = ngx_http_process_request_line;
  390.     ngx_http_process_request_line(rev);
  391. }


  392. ngx_http_request_t *
  393. ngx_http_create_request(ngx_connection_t *c)
  394. {
  395.     ngx_http_request_t        *r;
  396.     ngx_http_log_ctx_t        *ctx;
  397.     ngx_http_core_loc_conf_t  *clcf;

  398.     r = ngx_http_alloc_request(c);
  399.     if (r == NULL) {
  400.         return NULL;
  401.     }

  402.     c->requests++;

  403.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

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

  405.     ctx = c->log->data;
  406.     ctx->request = r;
  407.     ctx->current_request = r;

  408. #if (NGX_STAT_STUB)
  409.     (void) ngx_atomic_fetch_add(ngx_stat_reading, 1);
  410.     r->stat_reading = 1;
  411.     (void) ngx_atomic_fetch_add(ngx_stat_requests, 1);
  412. #endif

  413.     return r;
  414. }


  415. static ngx_http_request_t *
  416. ngx_http_alloc_request(ngx_connection_t *c)
  417. {
  418.     ngx_pool_t                 *pool;
  419.     ngx_time_t                 *tp;
  420.     ngx_http_request_t         *r;
  421.     ngx_http_connection_t      *hc;
  422.     ngx_http_core_srv_conf_t   *cscf;
  423.     ngx_http_core_main_conf_t  *cmcf;

  424.     hc = c->data;

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

  426.     pool = ngx_create_pool(cscf->request_pool_size, c->log);
  427.     if (pool == NULL) {
  428.         return NULL;
  429.     }

  430.     r = ngx_pcalloc(pool, sizeof(ngx_http_request_t));
  431.     if (r == NULL) {
  432.         ngx_destroy_pool(pool);
  433.         return NULL;
  434.     }

  435.     r->pool = pool;

  436.     r->http_connection = hc;
  437.     r->signature = NGX_HTTP_MODULE;
  438.     r->connection = c;

  439.     r->main_conf = hc->conf_ctx->main_conf;
  440.     r->srv_conf = hc->conf_ctx->srv_conf;
  441.     r->loc_conf = hc->conf_ctx->loc_conf;

  442.     r->read_event_handler = ngx_http_block_reading;

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

  444.     if (ngx_list_init(&r->headers_out.headers, r->pool, 20,
  445.                       sizeof(ngx_table_elt_t))
  446.         != NGX_OK)
  447.     {
  448.         ngx_destroy_pool(r->pool);
  449.         return NULL;
  450.     }

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

  458.     r->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
  459.     if (r->ctx == NULL) {
  460.         ngx_destroy_pool(r->pool);
  461.         return NULL;
  462.     }

  463.     cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

  464.     r->variables = ngx_pcalloc(r->pool, cmcf->variables.nelts
  465.                                         * sizeof(ngx_http_variable_value_t));
  466.     if (r->variables == NULL) {
  467.         ngx_destroy_pool(r->pool);
  468.         return NULL;
  469.     }

  470. #if (NGX_HTTP_SSL)
  471.     if (c->ssl && !c->ssl->sendfile) {
  472.         r->main_filter_need_in_memory = 1;
  473.     }
  474. #endif

  475.     r->main = r;
  476.     r->count = 1;

  477.     tp = ngx_timeofday();
  478.     r->start_sec = tp->sec;
  479.     r->start_msec = tp->msec;

  480.     r->method = NGX_HTTP_UNKNOWN;
  481.     r->http_version = NGX_HTTP_VERSION_10;

  482.     r->headers_in.content_length_n = -1;
  483.     r->headers_in.keep_alive_n = -1;
  484.     r->headers_out.content_length_n = -1;
  485.     r->headers_out.last_modified_time = -1;

  486.     r->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1;
  487.     r->subrequests = NGX_HTTP_MAX_SUBREQUESTS + 1;

  488.     r->http_state = NGX_HTTP_READING_REQUEST_STATE;

  489.     r->log_handler = ngx_http_log_error_handler;

  490.     return r;
  491. }


  492. #if (NGX_HTTP_SSL)

  493. static void
  494. ngx_http_ssl_handshake(ngx_event_t *rev)
  495. {
  496.     u_char                    *p, buf[NGX_PROXY_PROTOCOL_MAX_HEADER + 1];
  497.     size_t                     size;
  498.     ssize_t                    n;
  499.     ngx_err_t                  err;
  500.     ngx_int_t                  rc;
  501.     ngx_connection_t          *c;
  502.     ngx_http_connection_t     *hc;
  503.     ngx_http_ssl_srv_conf_t   *sscf;
  504.     ngx_http_core_loc_conf_t  *clcf;
  505.     ngx_http_core_srv_conf_t  *cscf;

  506.     c = rev->data;
  507.     hc = c->data;

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

  510.     if (rev->timedout) {
  511.         ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
  512.         ngx_http_close_connection(c);
  513.         return;
  514.     }

  515.     if (c->close) {
  516.         ngx_http_close_connection(c);
  517.         return;
  518.     }

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

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

  521.     err = ngx_socket_errno;

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

  523.     if (n == -1) {
  524.         if (err == NGX_EAGAIN) {
  525.             rev->ready = 0;

  526.             if (!rev->timer_set) {
  527.                 cscf = ngx_http_get_module_srv_conf(hc->conf_ctx,
  528.                                                     ngx_http_core_module);
  529.                 ngx_add_timer(rev, cscf->client_header_timeout);
  530.                 ngx_reusable_connection(c, 1);
  531.             }

  532.             if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  533.                 ngx_http_close_connection(c);
  534.             }

  535.             return;
  536.         }

  537.         ngx_connection_error(c, err, "recv() failed");
  538.         ngx_http_close_connection(c);

  539.         return;
  540.     }

  541.     if (hc->proxy_protocol) {
  542.         hc->proxy_protocol = 0;

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

  544.         if (p == NULL) {
  545.             ngx_http_close_connection(c);
  546.             return;
  547.         }

  548.         size = p - buf;

  549.         if (c->recv(c, buf, size) != (ssize_t) size) {
  550.             ngx_http_close_connection(c);
  551.             return;
  552.         }

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

  554.         if (n == (ssize_t) size) {
  555.             ngx_post_event(rev, &ngx_posted_events);
  556.             return;
  557.         }

  558.         n = 1;
  559.         buf[0] = *p;
  560.     }

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

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

  567.             if (clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) {
  568.                 ngx_http_close_connection(c);
  569.                 return;
  570.             }

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

  573.             if (ngx_ssl_create_connection(&sscf->ssl, c, NGX_SSL_BUFFER)
  574.                 != NGX_OK)
  575.             {
  576.                 ngx_http_close_connection(c);
  577.                 return;
  578.             }

  579.             ngx_reusable_connection(c, 0);

  580.             rc = ngx_ssl_handshake(c);

  581.             if (rc == NGX_AGAIN) {

  582.                 if (!rev->timer_set) {
  583.                     cscf = ngx_http_get_module_srv_conf(hc->conf_ctx,
  584.                                                         ngx_http_core_module);
  585.                     ngx_add_timer(rev, cscf->client_header_timeout);
  586.                 }

  587.                 c->ssl->handler = ngx_http_ssl_handshake_handler;
  588.                 return;
  589.             }

  590.             ngx_http_ssl_handshake_handler(c);

  591.             return;
  592.         }

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

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

  595.         rev->handler = ngx_http_wait_request_handler;
  596.         ngx_http_wait_request_handler(rev);

  597.         return;
  598.     }

  599.     ngx_log_error(NGX_LOG_INFO, c->log, 0, "client closed connection");
  600.     ngx_http_close_connection(c);
  601. }


  602. static void
  603. ngx_http_ssl_handshake_handler(ngx_connection_t *c)
  604. {
  605.     if (c->ssl->handshaked) {

  606.         /*
  607.          * The majority of browsers do not send the "close notify" alert.
  608.          * Among them are MSIE, old Mozilla, Netscape 4, Konqueror,
  609.          * and Links.  And what is more, MSIE ignores the server's alert.
  610.          *
  611.          * Opera and recent Mozilla send the alert.
  612.          */

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

  614. #if (NGX_HTTP_V2                                                              \
  615.      && defined TLSEXT_TYPE_application_layer_protocol_negotiation)
  616.         {
  617.         unsigned int             len;
  618.         const unsigned char     *data;
  619.         ngx_http_connection_t   *hc;
  620.         ngx_http_v2_srv_conf_t  *h2scf;

  621.         hc = c->data;

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

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

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

  625.             if (len == 2 && data[0] == 'h' && data[1] == '2') {
  626.                 ngx_http_v2_init(c->read);
  627.                 return;
  628.             }
  629.         }
  630.         }
  631. #endif

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

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

  635.         ngx_reusable_connection(c, 1);

  636.         ngx_http_wait_request_handler(c->read);

  637.         return;
  638.     }

  639.     if (c->read->timedout) {
  640.         ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
  641.     }

  642.     ngx_http_close_connection(c);
  643. }


  644. #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME

  645. int
  646. ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
  647. {
  648.     ngx_int_t                  rc;
  649.     ngx_str_t                  host;
  650.     const char                *servername;
  651.     ngx_connection_t          *c;
  652.     ngx_http_connection_t     *hc;
  653.     ngx_http_ssl_srv_conf_t   *sscf;
  654.     ngx_http_core_loc_conf_t  *clcf;
  655.     ngx_http_core_srv_conf_t  *cscf;

  656.     c = ngx_ssl_get_connection(ssl_conn);

  657.     if (c->ssl->handshaked) {
  658.         *ad = SSL_AD_NO_RENEGOTIATION;
  659.         return SSL_TLSEXT_ERR_ALERT_FATAL;
  660.     }

  661.     hc = c->data;

  662.     servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name);

  663.     if (servername == NULL) {
  664.         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
  665.                        "SSL server name: null");
  666.         goto done;
  667.     }

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

  670.     host.len = ngx_strlen(servername);

  671.     if (host.len == 0) {
  672.         goto done;
  673.     }

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

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

  676.     if (rc == NGX_ERROR) {
  677.         goto error;
  678.     }

  679.     if (rc == NGX_DECLINED) {
  680.         goto done;
  681.     }

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

  684.     if (rc == NGX_ERROR) {
  685.         goto error;
  686.     }

  687.     if (rc == NGX_DECLINED) {
  688.         goto done;
  689.     }

  690.     hc->ssl_servername = ngx_palloc(c->pool, sizeof(ngx_str_t));
  691.     if (hc->ssl_servername == NULL) {
  692.         goto error;
  693.     }

  694.     *hc->ssl_servername = host;

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

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

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

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

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

  700.     if (sscf->ssl.ctx) {
  701.         if (SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx) == NULL) {
  702.             goto error;
  703.         }

  704.         /*
  705.          * SSL_set_SSL_CTX() only changes certs as of 1.0.0d
  706.          * adjust other things we care about
  707.          */

  708.         SSL_set_verify(ssl_conn, SSL_CTX_get_verify_mode(sscf->ssl.ctx),
  709.                        SSL_CTX_get_verify_callback(sscf->ssl.ctx));

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

  711. #if OPENSSL_VERSION_NUMBER >= 0x009080dfL
  712.         /* only in 0.9.8m+ */
  713.         SSL_clear_options(ssl_conn, SSL_get_options(ssl_conn) &
  714.                                     ~SSL_CTX_get_options(sscf->ssl.ctx));
  715. #endif

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

  717. #ifdef SSL_OP_NO_RENEGOTIATION
  718.         SSL_set_options(ssl_conn, SSL_OP_NO_RENEGOTIATION);
  719. #endif

  720. #ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT
  721. #if (NGX_HTTP_V3)
  722.         if (c->listening->quic) {
  723.             SSL_clear_options(ssl_conn, SSL_OP_ENABLE_MIDDLEBOX_COMPAT);
  724.         }
  725. #endif
  726. #endif
  727.     }

  728. done:

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

  730.     if (sscf->reject_handshake) {
  731.         c->ssl->handshake_rejected = 1;
  732.         *ad = SSL_AD_UNRECOGNIZED_NAME;
  733.         return SSL_TLSEXT_ERR_ALERT_FATAL;
  734.     }

  735.     return SSL_TLSEXT_ERR_OK;

  736. error:

  737.     *ad = SSL_AD_INTERNAL_ERROR;
  738.     return SSL_TLSEXT_ERR_ALERT_FATAL;
  739. }

  740. #endif


  741. #ifdef SSL_R_CERT_CB_ERROR

  742. int
  743. ngx_http_ssl_certificate(ngx_ssl_conn_t *ssl_conn, void *arg)
  744. {
  745.     ngx_str_t                  cert, key;
  746.     ngx_uint_t                 i, nelts;
  747.     ngx_connection_t          *c;
  748.     ngx_http_request_t        *r;
  749.     ngx_http_ssl_srv_conf_t   *sscf;
  750.     ngx_http_complex_value_t  *certs, *keys;

  751.     c = ngx_ssl_get_connection(ssl_conn);

  752.     if (c->ssl->handshaked) {
  753.         return 0;
  754.     }

  755.     r = ngx_http_alloc_request(c);
  756.     if (r == NULL) {
  757.         return 0;
  758.     }

  759.     r->logged = 1;

  760.     sscf = arg;

  761.     nelts = sscf->certificate_values->nelts;
  762.     certs = sscf->certificate_values->elts;
  763.     keys = sscf->certificate_key_values->elts;

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

  765.         if (ngx_http_complex_value(r, &certs[i], &cert) != NGX_OK) {
  766.             goto failed;
  767.         }

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

  770.         if (ngx_http_complex_value(r, &keys[i], &key) != NGX_OK) {
  771.             goto failed;
  772.         }

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

  775.         if (ngx_ssl_connection_certificate(c, r->pool, &cert, &key,
  776.                                            sscf->passwords)
  777.             != NGX_OK)
  778.         {
  779.             goto failed;
  780.         }
  781.     }

  782.     ngx_http_free_request(r, 0);
  783.     c->log->action = "SSL handshaking";
  784.     c->destroyed = 0;
  785.     return 1;

  786. failed:

  787.     ngx_http_free_request(r, 0);
  788.     c->log->action = "SSL handshaking";
  789.     c->destroyed = 0;
  790.     return 0;
  791. }

  792. #endif

  793. #endif


  794. static void
  795. ngx_http_process_request_line(ngx_event_t *rev)
  796. {
  797.     ssize_t              n;
  798.     ngx_int_t            rc, rv;
  799.     ngx_str_t            host;
  800.     ngx_connection_t    *c;
  801.     ngx_http_request_t  *r;

  802.     c = rev->data;
  803.     r = c->data;

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

  806.     if (rev->timedout) {
  807.         ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
  808.         c->timedout = 1;
  809.         ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT);
  810.         return;
  811.     }

  812.     rc = NGX_AGAIN;

  813.     for ( ;; ) {

  814.         if (rc == NGX_AGAIN) {
  815.             n = ngx_http_read_request_header(r);

  816.             if (n == NGX_AGAIN || n == NGX_ERROR) {
  817.                 break;
  818.             }
  819.         }

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

  821.         if (rc == NGX_OK) {

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

  823.             r->request_line.len = r->request_end - r->request_start;
  824.             r->request_line.data = r->request_start;
  825.             r->request_length = r->header_in->pos - r->request_start;

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

  828.             r->method_name.len = r->method_end - r->request_start + 1;
  829.             r->method_name.data = r->request_line.data;

  830.             if (r->http_protocol.data) {
  831.                 r->http_protocol.len = r->request_end - r->http_protocol.data;
  832.             }

  833.             if (ngx_http_process_request_uri(r) != NGX_OK) {
  834.                 break;
  835.             }

  836.             if (r->schema_end) {
  837.                 r->schema.len = r->schema_end - r->schema_start;
  838.                 r->schema.data = r->schema_start;
  839.             }

  840.             if (r->host_end) {

  841.                 host.len = r->host_end - r->host_start;
  842.                 host.data = r->host_start;

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

  844.                 if (rc == NGX_DECLINED) {
  845.                     ngx_log_error(NGX_LOG_INFO, c->log, 0,
  846.                                   "client sent invalid host in request line");
  847.                     ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  848.                     break;
  849.                 }

  850.                 if (rc == NGX_ERROR) {
  851.                     ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  852.                     break;
  853.                 }

  854.                 if (ngx_http_set_virtual_server(r, &host) == NGX_ERROR) {
  855.                     break;
  856.                 }

  857.                 r->headers_in.server = host;
  858.             }

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

  860.                 if (r->headers_in.server.len == 0
  861.                     && ngx_http_set_virtual_server(r, &r->headers_in.server)
  862.                        == NGX_ERROR)
  863.                 {
  864.                     break;
  865.                 }

  866.                 ngx_http_process_request(r);
  867.                 break;
  868.             }


  869.             if (ngx_list_init(&r->headers_in.headers, r->pool, 20,
  870.                               sizeof(ngx_table_elt_t))
  871.                 != NGX_OK)
  872.             {
  873.                 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  874.                 break;
  875.             }

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

  877.             rev->handler = ngx_http_process_request_headers;
  878.             ngx_http_process_request_headers(rev);

  879.             break;
  880.         }

  881.         if (rc != NGX_AGAIN) {

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

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

  885.             if (rc == NGX_HTTP_PARSE_INVALID_VERSION) {
  886.                 ngx_http_finalize_request(r, NGX_HTTP_VERSION_NOT_SUPPORTED);

  887.             } else {
  888.                 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  889.             }

  890.             break;
  891.         }

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

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

  894.             rv = ngx_http_alloc_large_header_buffer(r, 1);

  895.             if (rv == NGX_ERROR) {
  896.                 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  897.                 break;
  898.             }

  899.             if (rv == NGX_DECLINED) {
  900.                 r->request_line.len = r->header_in->end - r->request_start;
  901.                 r->request_line.data = r->request_start;

  902.                 ngx_log_error(NGX_LOG_INFO, c->log, 0,
  903.                               "client sent too long URI");
  904.                 ngx_http_finalize_request(r, NGX_HTTP_REQUEST_URI_TOO_LARGE);
  905.                 break;
  906.             }
  907.         }
  908.     }

  909.     ngx_http_run_posted_requests(c);
  910. }


  911. ngx_int_t
  912. ngx_http_process_request_uri(ngx_http_request_t *r)
  913. {
  914.     ngx_http_core_srv_conf_t  *cscf;

  915.     if (r->args_start) {
  916.         r->uri.len = r->args_start - 1 - r->uri_start;
  917.     } else {
  918.         r->uri.len = r->uri_end - r->uri_start;
  919.     }

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

  921.         if (r->empty_path_in_uri) {
  922.             r->uri.len++;
  923.         }

  924.         r->uri.data = ngx_pnalloc(r->pool, r->uri.len);
  925.         if (r->uri.data == NULL) {
  926.             ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  927.             return NGX_ERROR;
  928.         }

  929.         cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);

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

  932.             ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  933.                           "client sent invalid request");
  934.             ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  935.             return NGX_ERROR;
  936.         }

  937.     } else {
  938.         r->uri.data = r->uri_start;
  939.     }

  940.     r->unparsed_uri.len = r->uri_end - r->uri_start;
  941.     r->unparsed_uri.data = r->uri_start;

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

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

  949.         r->exten.data = r->uri_ext;
  950.     }

  951.     if (r->args_start && r->uri_end > r->args_start) {
  952.         r->args.len = r->uri_end - r->args_start;
  953.         r->args.data = r->args_start;
  954.     }

  955. #if (NGX_WIN32)
  956.     {
  957.     u_char  *p, *last;

  958.     p = r->uri.data;
  959.     last = r->uri.data + r->uri.len;

  960.     while (p < last) {

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

  962.             /*
  963.              * this check covers "::$data", "::$index_allocation" and
  964.              * ":$i30:$index_allocation"
  965.              */

  966.             if (p < last && *p == '$') {
  967.                 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  968.                               "client sent unsafe win32 URI");
  969.                 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  970.                 return NGX_ERROR;
  971.             }
  972.         }
  973.     }

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

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

  976.         if (*p == ' ') {
  977.             p--;
  978.             continue;
  979.         }

  980.         if (*p == '.') {
  981.             p--;
  982.             continue;
  983.         }

  984.         break;
  985.     }

  986.     if (p != r->uri.data + r->uri.len - 1) {
  987.         r->uri.len = p + 1 - r->uri.data;
  988.         ngx_http_set_exten(r);
  989.     }

  990.     }
  991. #endif

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

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

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

  998.     return NGX_OK;
  999. }


  1000. static void
  1001. ngx_http_process_request_headers(ngx_event_t *rev)
  1002. {
  1003.     u_char                     *p;
  1004.     size_t                      len;
  1005.     ssize_t                     n;
  1006.     ngx_int_t                   rc, rv;
  1007.     ngx_table_elt_t            *h;
  1008.     ngx_connection_t           *c;
  1009.     ngx_http_header_t          *hh;
  1010.     ngx_http_request_t         *r;
  1011.     ngx_http_core_srv_conf_t   *cscf;
  1012.     ngx_http_core_main_conf_t  *cmcf;

  1013.     c = rev->data;
  1014.     r = c->data;

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

  1017.     if (rev->timedout) {
  1018.         ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
  1019.         c->timedout = 1;
  1020.         ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT);
  1021.         return;
  1022.     }

  1023.     cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

  1024.     rc = NGX_AGAIN;

  1025.     for ( ;; ) {

  1026.         if (rc == NGX_AGAIN) {

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

  1028.                 rv = ngx_http_alloc_large_header_buffer(r, 0);

  1029.                 if (rv == NGX_ERROR) {
  1030.                     ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1031.                     break;
  1032.                 }

  1033.                 if (rv == NGX_DECLINED) {
  1034.                     p = r->header_name_start;

  1035.                     r->lingering_close = 1;

  1036.                     if (p == NULL) {
  1037.                         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1038.                                       "client sent too large request");
  1039.                         ngx_http_finalize_request(r,
  1040.                                             NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
  1041.                         break;
  1042.                     }

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

  1044.                     if (len > NGX_MAX_ERROR_STR - 300) {
  1045.                         len = NGX_MAX_ERROR_STR - 300;
  1046.                     }

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

  1050.                     ngx_http_finalize_request(r,
  1051.                                             NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
  1052.                     break;
  1053.                 }
  1054.             }

  1055.             n = ngx_http_read_request_header(r);

  1056.             if (n == NGX_AGAIN || n == NGX_ERROR) {
  1057.                 break;
  1058.             }
  1059.         }

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

  1062.         rc = ngx_http_parse_header_line(r, r->header_in,
  1063.                                         cscf->underscores_in_headers);

  1064.         if (rc == NGX_OK) {

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

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

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

  1068.                 ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1069.                               "client sent invalid header line: \"%*s\"",
  1070.                               r->header_end - r->header_name_start,
  1071.                               r->header_name_start);
  1072.                 continue;
  1073.             }

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

  1075.             h = ngx_list_push(&r->headers_in.headers);
  1076.             if (h == NULL) {
  1077.                 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1078.                 break;
  1079.             }

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

  1081.             h->key.len = r->header_name_end - r->header_name_start;
  1082.             h->key.data = r->header_name_start;
  1083.             h->key.data[h->key.len] = '\0';

  1084.             h->value.len = r->header_end - r->header_start;
  1085.             h->value.data = r->header_start;
  1086.             h->value.data[h->value.len] = '\0';

  1087.             h->lowcase_key = ngx_pnalloc(r->pool, h->key.len);
  1088.             if (h->lowcase_key == NULL) {
  1089.                 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1090.                 break;
  1091.             }

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

  1094.             } else {
  1095.                 ngx_strlow(h->lowcase_key, h->key.data, h->key.len);
  1096.             }

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

  1099.             if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
  1100.                 break;
  1101.             }

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

  1105.             continue;
  1106.         }

  1107.         if (rc == NGX_HTTP_PARSE_HEADER_DONE) {

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

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

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

  1112.             r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE;

  1113.             rc = ngx_http_process_request_header(r);

  1114.             if (rc != NGX_OK) {
  1115.                 break;
  1116.             }

  1117.             ngx_http_process_request(r);

  1118.             break;
  1119.         }

  1120.         if (rc == NGX_AGAIN) {

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

  1122.             continue;
  1123.         }

  1124.         /* rc == NGX_HTTP_PARSE_INVALID_HEADER */

  1125.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1126.                       "client sent invalid header line: \"%*s\\x%02xd...\"",
  1127.                       r->header_end - r->header_name_start,
  1128.                       r->header_name_start, *r->header_end);

  1129.         ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  1130.         break;
  1131.     }

  1132.     ngx_http_run_posted_requests(c);
  1133. }


  1134. static ssize_t
  1135. ngx_http_read_request_header(ngx_http_request_t *r)
  1136. {
  1137.     ssize_t                    n;
  1138.     ngx_event_t               *rev;
  1139.     ngx_connection_t          *c;
  1140.     ngx_http_core_srv_conf_t  *cscf;

  1141.     c = r->connection;
  1142.     rev = c->read;

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

  1144.     if (n > 0) {
  1145.         return n;
  1146.     }

  1147.     if (rev->ready) {
  1148.         n = c->recv(c, r->header_in->last,
  1149.                     r->header_in->end - r->header_in->last);
  1150.     } else {
  1151.         n = NGX_AGAIN;
  1152.     }

  1153.     if (n == NGX_AGAIN) {
  1154.         if (!rev->timer_set) {
  1155.             cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
  1156.             ngx_add_timer(rev, cscf->client_header_timeout);
  1157.         }

  1158.         if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  1159.             ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1160.             return NGX_ERROR;
  1161.         }

  1162.         return NGX_AGAIN;
  1163.     }

  1164.     if (n == 0) {
  1165.         ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1166.                       "client prematurely closed connection");
  1167.     }

  1168.     if (n == 0 || n == NGX_ERROR) {
  1169.         c->error = 1;
  1170.         c->log->action = "reading client request headers";

  1171.         ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  1172.         return NGX_ERROR;
  1173.     }

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

  1175.     return n;
  1176. }


  1177. static ngx_int_t
  1178. ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
  1179.     ngx_uint_t request_line)
  1180. {
  1181.     u_char                    *old, *new;
  1182.     ngx_buf_t                 *b;
  1183.     ngx_chain_t               *cl;
  1184.     ngx_http_connection_t     *hc;
  1185.     ngx_http_core_srv_conf_t  *cscf;

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

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

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

  1190.         r->header_in->pos = r->header_in->start;
  1191.         r->header_in->last = r->header_in->start;

  1192.         return NGX_OK;
  1193.     }

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

  1195.     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);

  1196.     if (r->state != 0
  1197.         && (size_t) (r->header_in->pos - old)
  1198.                                      >= cscf->large_client_header_buffers.size)
  1199.     {
  1200.         return NGX_DECLINED;
  1201.     }

  1202.     hc = r->http_connection;

  1203.     if (hc->free) {
  1204.         cl = hc->free;
  1205.         hc->free = cl->next;

  1206.         b = cl->buf;

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

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

  1211.         b = ngx_create_temp_buf(r->connection->pool,
  1212.                                 cscf->large_client_header_buffers.size);
  1213.         if (b == NULL) {
  1214.             return NGX_ERROR;
  1215.         }

  1216.         cl = ngx_alloc_chain_link(r->connection->pool);
  1217.         if (cl == NULL) {
  1218.             return NGX_ERROR;
  1219.         }

  1220.         cl->buf = b;

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

  1224.     } else {
  1225.         return NGX_DECLINED;
  1226.     }

  1227.     cl->next = hc->busy;
  1228.     hc->busy = cl;
  1229.     hc->nbusy++;

  1230.     if (r->state == 0) {
  1231.         /*
  1232.          * r->state == 0 means that a header line was parsed successfully
  1233.          * and we do not need to copy incomplete header line and
  1234.          * to relocate the parser header pointers
  1235.          */

  1236.         r->header_in = b;

  1237.         return NGX_OK;
  1238.     }

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

  1241.     if (r->header_in->pos - old > b->end - b->start) {
  1242.         ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
  1243.                       "too large header to copy");
  1244.         return NGX_ERROR;
  1245.     }

  1246.     new = b->start;

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

  1248.     b->pos = new + (r->header_in->pos - old);
  1249.     b->last = new + (r->header_in->pos - old);

  1250.     if (request_line) {
  1251.         r->request_start = new;

  1252.         if (r->request_end) {
  1253.             r->request_end = new + (r->request_end - old);
  1254.         }

  1255.         if (r->method_end) {
  1256.             r->method_end = new + (r->method_end - old);
  1257.         }

  1258.         if (r->uri_start) {
  1259.             r->uri_start = new + (r->uri_start - old);
  1260.         }

  1261.         if (r->uri_end) {
  1262.             r->uri_end = new + (r->uri_end - old);
  1263.         }

  1264.         if (r->schema_start) {
  1265.             r->schema_start = new + (r->schema_start - old);
  1266.             if (r->schema_end) {
  1267.                 r->schema_end = new + (r->schema_end - old);
  1268.             }
  1269.         }

  1270.         if (r->host_start) {
  1271.             r->host_start = new + (r->host_start - old);
  1272.             if (r->host_end) {
  1273.                 r->host_end = new + (r->host_end - old);
  1274.             }
  1275.         }

  1276.         if (r->uri_ext) {
  1277.             r->uri_ext = new + (r->uri_ext - old);
  1278.         }

  1279.         if (r->args_start) {
  1280.             r->args_start = new + (r->args_start - old);
  1281.         }

  1282.         if (r->http_protocol.data) {
  1283.             r->http_protocol.data = new + (r->http_protocol.data - old);
  1284.         }

  1285.     } else {
  1286.         r->header_name_start = new;

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

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

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

  1297.     r->header_in = b;

  1298.     return NGX_OK;
  1299. }


  1300. static ngx_int_t
  1301. ngx_http_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
  1302.     ngx_uint_t offset)
  1303. {
  1304.     ngx_table_elt_t  **ph;

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

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

  1307.     *ph = h;
  1308.     h->next = NULL;

  1309.     return NGX_OK;
  1310. }


  1311. static ngx_int_t
  1312. ngx_http_process_unique_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
  1313.     ngx_uint_t offset)
  1314. {
  1315.     ngx_table_elt_t  **ph;

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

  1317.     if (*ph == NULL) {
  1318.         *ph = h;
  1319.         h->next = NULL;
  1320.         return NGX_OK;
  1321.     }

  1322.     ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1323.                   "client sent duplicate header line: \"%V: %V\", "
  1324.                   "previous value: \"%V: %V\"",
  1325.                   &h->key, &h->value, &(*ph)->key, &(*ph)->value);

  1326.     ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);

  1327.     return NGX_ERROR;
  1328. }


  1329. static ngx_int_t
  1330. ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h,
  1331.     ngx_uint_t offset)
  1332. {
  1333.     ngx_int_t  rc;
  1334.     ngx_str_t  host;

  1335.     if (r->headers_in.host) {
  1336.         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1337.                       "client sent duplicate host header: \"%V: %V\", "
  1338.                       "previous value: \"%V: %V\"",
  1339.                       &h->key, &h->value, &r->headers_in.host->key,
  1340.                       &r->headers_in.host->value);
  1341.         ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  1342.         return NGX_ERROR;
  1343.     }

  1344.     r->headers_in.host = h;
  1345.     h->next = NULL;

  1346.     host = h->value;

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

  1348.     if (rc == NGX_DECLINED) {
  1349.         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1350.                       "client sent invalid host header");
  1351.         ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  1352.         return NGX_ERROR;
  1353.     }

  1354.     if (rc == NGX_ERROR) {
  1355.         ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1356.         return NGX_ERROR;
  1357.     }

  1358.     if (r->headers_in.server.len) {
  1359.         return NGX_OK;
  1360.     }

  1361.     if (ngx_http_set_virtual_server(r, &host) == NGX_ERROR) {
  1362.         return NGX_ERROR;
  1363.     }

  1364.     r->headers_in.server = host;

  1365.     return NGX_OK;
  1366. }


  1367. static ngx_int_t
  1368. ngx_http_process_connection(ngx_http_request_t *r, ngx_table_elt_t *h,
  1369.     ngx_uint_t offset)
  1370. {
  1371.     if (ngx_http_process_header_line(r, h, offset) != NGX_OK) {
  1372.         return NGX_ERROR;
  1373.     }

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

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

  1379.     return NGX_OK;
  1380. }


  1381. static ngx_int_t
  1382. ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h,
  1383.     ngx_uint_t offset)
  1384. {
  1385.     u_char  *user_agent, *msie;

  1386.     if (ngx_http_process_header_line(r, h, offset) != NGX_OK) {
  1387.         return NGX_ERROR;
  1388.     }

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

  1390.     user_agent = h->value.data;

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

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

  1393.         r->headers_in.msie = 1;

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

  1395.             switch (msie[5]) {
  1396.             case '4':
  1397.             case '5':
  1398.                 r->headers_in.msie6 = 1;
  1399.                 break;
  1400.             case '6':
  1401.                 if (ngx_strstrn(msie + 8, "SV1", 3 - 1) == NULL) {
  1402.                     r->headers_in.msie6 = 1;
  1403.                 }
  1404.                 break;
  1405.             }
  1406.         }

  1407. #if 0
  1408.         /* MSIE ignores the SSL "close notify" alert */
  1409.         if (c->ssl) {
  1410.             c->ssl->no_send_shutdown = 1;
  1411.         }
  1412. #endif
  1413.     }

  1414.     if (ngx_strstrn(user_agent, "Opera", 5 - 1)) {
  1415.         r->headers_in.opera = 1;
  1416.         r->headers_in.msie = 0;
  1417.         r->headers_in.msie6 = 0;
  1418.     }

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

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

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

  1424.         } else if (ngx_strstrn(user_agent, "Safari/", 7 - 1)
  1425.                    && ngx_strstrn(user_agent, "Mac OS X", 8 - 1))
  1426.         {
  1427.             r->headers_in.safari = 1;

  1428.         } else if (ngx_strstrn(user_agent, "Konqueror", 9 - 1)) {
  1429.             r->headers_in.konqueror = 1;
  1430.         }
  1431.     }

  1432.     return NGX_OK;
  1433. }


  1434. ngx_int_t
  1435. ngx_http_process_request_header(ngx_http_request_t *r)
  1436. {
  1437.     if (r->headers_in.server.len == 0
  1438.         && ngx_http_set_virtual_server(r, &r->headers_in.server)
  1439.            == NGX_ERROR)
  1440.     {
  1441.         return NGX_ERROR;
  1442.     }

  1443.     if (r->headers_in.host == NULL && r->http_version > NGX_HTTP_VERSION_10) {
  1444.         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1445.                    "client sent HTTP/1.1 request without \"Host\" header");
  1446.         ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  1447.         return NGX_ERROR;
  1448.     }

  1449.     if (r->headers_in.content_length) {
  1450.         r->headers_in.content_length_n =
  1451.                             ngx_atoof(r->headers_in.content_length->value.data,
  1452.                                       r->headers_in.content_length->value.len);

  1453.         if (r->headers_in.content_length_n == NGX_ERROR) {
  1454.             ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1455.                           "client sent invalid \"Content-Length\" header");
  1456.             ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  1457.             return NGX_ERROR;
  1458.         }
  1459.     }

  1460.     if (r->headers_in.transfer_encoding) {
  1461.         if (r->http_version < NGX_HTTP_VERSION_11) {
  1462.             ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1463.                           "client sent HTTP/1.0 request with "
  1464.                           "\"Transfer-Encoding\" header");
  1465.             ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  1466.             return NGX_ERROR;
  1467.         }

  1468.         if (r->headers_in.transfer_encoding->value.len == 7
  1469.             && ngx_strncasecmp(r->headers_in.transfer_encoding->value.data,
  1470.                                (u_char *) "chunked", 7) == 0)
  1471.         {
  1472.             if (r->headers_in.content_length) {
  1473.                 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1474.                               "client sent \"Content-Length\" and "
  1475.                               "\"Transfer-Encoding\" headers "
  1476.                               "at the same time");
  1477.                 ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  1478.                 return NGX_ERROR;
  1479.             }

  1480.             r->headers_in.chunked = 1;

  1481.         } else {
  1482.             ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1483.                           "client sent unknown \"Transfer-Encoding\": \"%V\"",
  1484.                           &r->headers_in.transfer_encoding->value);
  1485.             ngx_http_finalize_request(r, NGX_HTTP_NOT_IMPLEMENTED);
  1486.             return NGX_ERROR;
  1487.         }
  1488.     }

  1489.     if (r->headers_in.connection_type == NGX_HTTP_CONNECTION_KEEP_ALIVE) {
  1490.         if (r->headers_in.keep_alive) {
  1491.             r->headers_in.keep_alive_n =
  1492.                             ngx_atotm(r->headers_in.keep_alive->value.data,
  1493.                                       r->headers_in.keep_alive->value.len);
  1494.         }
  1495.     }

  1496.     if (r->method == NGX_HTTP_CONNECT) {
  1497.         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1498.                       "client sent CONNECT method");
  1499.         ngx_http_finalize_request(r, NGX_HTTP_NOT_ALLOWED);
  1500.         return NGX_ERROR;
  1501.     }

  1502.     if (r->method == NGX_HTTP_TRACE) {
  1503.         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1504.                       "client sent TRACE method");
  1505.         ngx_http_finalize_request(r, NGX_HTTP_NOT_ALLOWED);
  1506.         return NGX_ERROR;
  1507.     }

  1508.     return NGX_OK;
  1509. }


  1510. void
  1511. ngx_http_process_request(ngx_http_request_t *r)
  1512. {
  1513.     ngx_connection_t  *c;

  1514.     c = r->connection;

  1515. #if (NGX_HTTP_SSL)

  1516.     if (r->http_connection->ssl) {
  1517.         long                      rc;
  1518.         X509                     *cert;
  1519.         const char               *s;
  1520.         ngx_http_ssl_srv_conf_t  *sscf;

  1521.         if (c->ssl == NULL) {
  1522.             ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1523.                           "client sent plain HTTP request to HTTPS port");
  1524.             ngx_http_finalize_request(r, NGX_HTTP_TO_HTTPS);
  1525.             return;
  1526.         }

  1527.         sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);

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

  1530.             if (rc != X509_V_OK
  1531.                 && (sscf->verify != 3 || !ngx_ssl_verify_error_optional(rc)))
  1532.             {
  1533.                 ngx_log_error(NGX_LOG_INFO, c->log, 0,
  1534.                               "client SSL certificate verify error: (%l:%s)",
  1535.                               rc, X509_verify_cert_error_string(rc));

  1536.                 ngx_ssl_remove_cached_session(c->ssl->session_ctx,
  1537.                                        (SSL_get0_session(c->ssl->connection)));

  1538.                 ngx_http_finalize_request(r, NGX_HTTPS_CERT_ERROR);
  1539.                 return;
  1540.             }

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

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

  1546.                     ngx_ssl_remove_cached_session(c->ssl->session_ctx,
  1547.                                        (SSL_get0_session(c->ssl->connection)));

  1548.                     ngx_http_finalize_request(r, NGX_HTTPS_NO_CERT);
  1549.                     return;
  1550.                 }

  1551.                 X509_free(cert);
  1552.             }

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

  1556.                 ngx_ssl_remove_cached_session(c->ssl->session_ctx,
  1557.                                        (SSL_get0_session(c->ssl->connection)));

  1558.                 ngx_http_finalize_request(r, NGX_HTTPS_CERT_ERROR);
  1559.                 return;
  1560.             }
  1561.         }
  1562.     }

  1563. #endif

  1564.     if (c->read->timer_set) {
  1565.         ngx_del_timer(c->read);
  1566.     }

  1567. #if (NGX_STAT_STUB)
  1568.     (void) ngx_atomic_fetch_add(ngx_stat_reading, -1);
  1569.     r->stat_reading = 0;
  1570.     (void) ngx_atomic_fetch_add(ngx_stat_writing, 1);
  1571.     r->stat_writing = 1;
  1572. #endif

  1573.     c->read->handler = ngx_http_request_handler;
  1574.     c->write->handler = ngx_http_request_handler;
  1575.     r->read_event_handler = ngx_http_block_reading;

  1576.     ngx_http_handler(r);
  1577. }


  1578. ngx_int_t
  1579. ngx_http_validate_host(ngx_str_t *host, ngx_pool_t *pool, ngx_uint_t alloc)
  1580. {
  1581.     u_char  *h, ch;
  1582.     size_t   i, dot_pos, host_len;

  1583.     enum {
  1584.         sw_usual = 0,
  1585.         sw_literal,
  1586.         sw_rest
  1587.     } state;

  1588.     dot_pos = host->len;
  1589.     host_len = host->len;

  1590.     h = host->data;

  1591.     state = sw_usual;

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

  1594.         switch (ch) {

  1595.         case '.':
  1596.             if (dot_pos == i - 1) {
  1597.                 return NGX_DECLINED;
  1598.             }
  1599.             dot_pos = i;
  1600.             break;

  1601.         case ':':
  1602.             if (state == sw_usual) {
  1603.                 host_len = i;
  1604.                 state = sw_rest;
  1605.             }
  1606.             break;

  1607.         case '[':
  1608.             if (i == 0) {
  1609.                 state = sw_literal;
  1610.             }
  1611.             break;

  1612.         case ']':
  1613.             if (state == sw_literal) {
  1614.                 host_len = i + 1;
  1615.                 state = sw_rest;
  1616.             }
  1617.             break;

  1618.         default:

  1619.             if (ngx_path_separator(ch)) {
  1620.                 return NGX_DECLINED;
  1621.             }

  1622.             if (ch <= 0x20 || ch == 0x7f) {
  1623.                 return NGX_DECLINED;
  1624.             }

  1625.             if (ch >= 'A' && ch <= 'Z') {
  1626.                 alloc = 1;
  1627.             }

  1628.             break;
  1629.         }
  1630.     }

  1631.     if (dot_pos == host_len - 1) {
  1632.         host_len--;
  1633.     }

  1634.     if (host_len == 0) {
  1635.         return NGX_DECLINED;
  1636.     }

  1637.     if (alloc) {
  1638.         host->data = ngx_pnalloc(pool, host_len);
  1639.         if (host->data == NULL) {
  1640.             return NGX_ERROR;
  1641.         }

  1642.         ngx_strlow(host->data, h, host_len);
  1643.     }

  1644.     host->len = host_len;

  1645.     return NGX_OK;
  1646. }


  1647. ngx_int_t
  1648. ngx_http_set_virtual_server(ngx_http_request_t *r, ngx_str_t *host)
  1649. {
  1650.     ngx_int_t                  rc;
  1651.     ngx_http_connection_t     *hc;
  1652.     ngx_http_core_loc_conf_t  *clcf;
  1653.     ngx_http_core_srv_conf_t  *cscf;

  1654. #if (NGX_SUPPRESS_WARN)
  1655.     cscf = NULL;
  1656. #endif

  1657.     hc = r->http_connection;

  1658. #if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)

  1659.     if (hc->ssl_servername) {
  1660.         if (hc->ssl_servername->len == host->len
  1661.             && ngx_strncmp(hc->ssl_servername->data,
  1662.                            host->data, host->len) == 0)
  1663.         {
  1664. #if (NGX_PCRE)
  1665.             if (hc->ssl_servername_regex
  1666.                 && ngx_http_regex_exec(r, hc->ssl_servername_regex,
  1667.                                           hc->ssl_servername) != NGX_OK)
  1668.             {
  1669.                 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1670.                 return NGX_ERROR;
  1671.             }
  1672. #endif
  1673.             return NGX_OK;
  1674.         }
  1675.     }

  1676. #endif

  1677.     rc = ngx_http_find_virtual_server(r->connection,
  1678.                                       hc->addr_conf->virtual_names,
  1679.                                       host, r, &cscf);

  1680.     if (rc == NGX_ERROR) {
  1681.         ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1682.         return NGX_ERROR;
  1683.     }

  1684. #if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)

  1685.     if (hc->ssl_servername) {
  1686.         ngx_http_ssl_srv_conf_t  *sscf;

  1687.         if (rc == NGX_DECLINED) {
  1688.             cscf = hc->addr_conf->default_server;
  1689.             rc = NGX_OK;
  1690.         }

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

  1692.         if (sscf->verify) {
  1693.             ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1694.                           "client attempted to request the server name "
  1695.                           "different from the one that was negotiated");
  1696.             ngx_http_finalize_request(r, NGX_HTTP_MISDIRECTED_REQUEST);
  1697.             return NGX_ERROR;
  1698.         }
  1699.     }

  1700. #endif

  1701.     if (rc == NGX_DECLINED) {
  1702.         return NGX_OK;
  1703.     }

  1704.     r->srv_conf = cscf->ctx->srv_conf;
  1705.     r->loc_conf = cscf->ctx->loc_conf;

  1706.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

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

  1708.     return NGX_OK;
  1709. }


  1710. static ngx_int_t
  1711. ngx_http_find_virtual_server(ngx_connection_t *c,
  1712.     ngx_http_virtual_names_t *virtual_names, ngx_str_t *host,
  1713.     ngx_http_request_t *r, ngx_http_core_srv_conf_t **cscfp)
  1714. {
  1715.     ngx_http_core_srv_conf_t  *cscf;

  1716.     if (virtual_names == NULL) {
  1717.         return NGX_DECLINED;
  1718.     }

  1719.     cscf = ngx_hash_find_combined(&virtual_names->names,
  1720.                                   ngx_hash_key(host->data, host->len),
  1721.                                   host->data, host->len);

  1722.     if (cscf) {
  1723.         *cscfp = cscf;
  1724.         return NGX_OK;
  1725.     }

  1726. #if (NGX_PCRE)

  1727.     if (host->len && virtual_names->nregex) {
  1728.         ngx_int_t                n;
  1729.         ngx_uint_t               i;
  1730.         ngx_http_server_name_t  *sn;

  1731.         sn = virtual_names->regex;

  1732. #if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)

  1733.         if (r == NULL) {
  1734.             ngx_http_connection_t  *hc;

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

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

  1737.                 if (n == NGX_REGEX_NO_MATCHED) {
  1738.                     continue;
  1739.                 }

  1740.                 if (n >= 0) {
  1741.                     hc = c->data;
  1742.                     hc->ssl_servername_regex = sn[i].regex;

  1743.                     *cscfp = sn[i].server;
  1744.                     return NGX_OK;
  1745.                 }

  1746.                 ngx_log_error(NGX_LOG_ALERT, c->log, 0,
  1747.                               ngx_regex_exec_n " failed: %i "
  1748.                               "on \"%V\" using \"%V\"",
  1749.                               n, host, &sn[i].regex->name);

  1750.                 return NGX_ERROR;
  1751.             }

  1752.             return NGX_DECLINED;
  1753.         }

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

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

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

  1757.             if (n == NGX_DECLINED) {
  1758.                 continue;
  1759.             }

  1760.             if (n == NGX_OK) {
  1761.                 *cscfp = sn[i].server;
  1762.                 return NGX_OK;
  1763.             }

  1764.             return NGX_ERROR;
  1765.         }
  1766.     }

  1767. #endif /* NGX_PCRE */

  1768.     return NGX_DECLINED;
  1769. }


  1770. static void
  1771. ngx_http_request_handler(ngx_event_t *ev)
  1772. {
  1773.     ngx_connection_t    *c;
  1774.     ngx_http_request_t  *r;

  1775.     c = ev->data;
  1776.     r = c->data;

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

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

  1780.     if (c->close) {
  1781.         r->main->count++;
  1782.         ngx_http_terminate_request(r, 0);
  1783.         ngx_http_run_posted_requests(c);
  1784.         return;
  1785.     }

  1786.     if (ev->delayed && ev->timedout) {
  1787.         ev->delayed = 0;
  1788.         ev->timedout = 0;
  1789.     }

  1790.     if (ev->write) {
  1791.         r->write_event_handler(r);

  1792.     } else {
  1793.         r->read_event_handler(r);
  1794.     }

  1795.     ngx_http_run_posted_requests(c);
  1796. }


  1797. void
  1798. ngx_http_run_posted_requests(ngx_connection_t *c)
  1799. {
  1800.     ngx_http_request_t         *r;
  1801.     ngx_http_posted_request_t  *pr;

  1802.     for ( ;; ) {

  1803.         if (c->destroyed) {
  1804.             return;
  1805.         }

  1806.         r = c->data;
  1807.         pr = r->main->posted_requests;

  1808.         if (pr == NULL) {
  1809.             return;
  1810.         }

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

  1812.         r = pr->request;

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

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

  1816.         r->write_event_handler(r);
  1817.     }
  1818. }


  1819. ngx_int_t
  1820. ngx_http_post_request(ngx_http_request_t *r, ngx_http_posted_request_t *pr)
  1821. {
  1822.     ngx_http_posted_request_t  **p;

  1823.     if (pr == NULL) {
  1824.         pr = ngx_palloc(r->pool, sizeof(ngx_http_posted_request_t));
  1825.         if (pr == NULL) {
  1826.             return NGX_ERROR;
  1827.         }
  1828.     }

  1829.     pr->request = r;
  1830.     pr->next = NULL;

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

  1832.     *p = pr;

  1833.     return NGX_OK;
  1834. }


  1835. void
  1836. ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
  1837. {
  1838.     ngx_connection_t          *c;
  1839.     ngx_http_request_t        *pr;
  1840.     ngx_http_core_loc_conf_t  *clcf;

  1841.     c = r->connection;

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

  1845.     if (rc == NGX_DONE) {
  1846.         ngx_http_finalize_connection(r);
  1847.         return;
  1848.     }

  1849.     if (rc == NGX_OK && r->filter_finalize) {
  1850.         c->error = 1;
  1851.     }

  1852.     if (rc == NGX_DECLINED) {
  1853.         r->content_handler = NULL;
  1854.         r->write_event_handler = ngx_http_core_run_phases;
  1855.         ngx_http_core_run_phases(r);
  1856.         return;
  1857.     }

  1858.     if (r != r->main && r->post_subrequest) {
  1859.         rc = r->post_subrequest->handler(r, r->post_subrequest->data, rc);
  1860.     }

  1861.     if (rc == NGX_ERROR
  1862.         || rc == NGX_HTTP_REQUEST_TIME_OUT
  1863.         || rc == NGX_HTTP_CLIENT_CLOSED_REQUEST
  1864.         || c->error)
  1865.     {
  1866.         if (ngx_http_post_action(r) == NGX_OK) {
  1867.             return;
  1868.         }

  1869.         ngx_http_terminate_request(r, rc);
  1870.         return;
  1871.     }

  1872.     if (rc >= NGX_HTTP_SPECIAL_RESPONSE
  1873.         || rc == NGX_HTTP_CREATED
  1874.         || rc == NGX_HTTP_NO_CONTENT)
  1875.     {
  1876.         if (rc == NGX_HTTP_CLOSE) {
  1877.             c->timedout = 1;
  1878.             ngx_http_terminate_request(r, rc);
  1879.             return;
  1880.         }

  1881.         if (r == r->main) {
  1882.             if (c->read->timer_set) {
  1883.                 ngx_del_timer(c->read);
  1884.             }

  1885.             if (c->write->timer_set) {
  1886.                 ngx_del_timer(c->write);
  1887.             }
  1888.         }

  1889.         c->read->handler = ngx_http_request_handler;
  1890.         c->write->handler = ngx_http_request_handler;

  1891.         ngx_http_finalize_request(r, ngx_http_special_response_handler(r, rc));
  1892.         return;
  1893.     }

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

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

  1896.             if (ngx_http_set_write_handler(r) != NGX_OK) {
  1897.                 ngx_http_terminate_request(r, 0);
  1898.             }

  1899.             return;
  1900.         }

  1901.         pr = r->parent;

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

  1903.             if (!r->logged) {

  1904.                 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  1905.                 if (clcf->log_subrequest) {
  1906.                     ngx_http_log_request(r);
  1907.                 }

  1908.                 r->logged = 1;

  1909.             } else {
  1910.                 ngx_log_error(NGX_LOG_ALERT, c->log, 0,
  1911.                               "subrequest: \"%V?%V\" logged again",
  1912.                               &r->uri, &r->args);
  1913.             }

  1914.             r->done = 1;

  1915.             if (r->background) {
  1916.                 ngx_http_finalize_connection(r);
  1917.                 return;
  1918.             }

  1919.             r->main->count--;

  1920.             if (pr->postponed && pr->postponed->request == r) {
  1921.                 pr->postponed = pr->postponed->next;
  1922.             }

  1923.             c->data = pr;

  1924.         } else {

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

  1928.             r->write_event_handler = ngx_http_request_finalizer;

  1929.             if (r->waited) {
  1930.                 r->done = 1;
  1931.             }
  1932.         }

  1933.         if (ngx_http_post_request(pr, NULL) != NGX_OK) {
  1934.             r->main->count++;
  1935.             ngx_http_terminate_request(r, 0);
  1936.             return;
  1937.         }

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

  1941.         return;
  1942.     }

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

  1944.         if (ngx_http_set_write_handler(r) != NGX_OK) {
  1945.             ngx_http_terminate_request(r, 0);
  1946.         }

  1947.         return;
  1948.     }

  1949.     if (r != c->data) {
  1950.         ngx_log_error(NGX_LOG_ALERT, c->log, 0,
  1951.                       "http finalize non-active request: \"%V?%V\"",
  1952.                       &r->uri, &r->args);
  1953.         return;
  1954.     }

  1955.     r->done = 1;

  1956.     r->read_event_handler = ngx_http_block_reading;
  1957.     r->write_event_handler = ngx_http_request_empty_handler;

  1958.     if (!r->post_action) {
  1959.         r->request_complete = 1;
  1960.     }

  1961.     if (ngx_http_post_action(r) == NGX_OK) {
  1962.         return;
  1963.     }

  1964.     if (c->read->timer_set) {
  1965.         ngx_del_timer(c->read);
  1966.     }

  1967.     if (c->write->timer_set) {
  1968.         c->write->delayed = 0;
  1969.         ngx_del_timer(c->write);
  1970.     }

  1971.     ngx_http_finalize_connection(r);
  1972. }


  1973. static void
  1974. ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc)
  1975. {
  1976.     ngx_http_cleanup_t    *cln;
  1977.     ngx_http_request_t    *mr;
  1978.     ngx_http_ephemeral_t  *e;

  1979.     mr = r->main;

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

  1982.     mr->terminated = 1;

  1983.     if (rc > 0 && (mr->headers_out.status == 0 || mr->connection->sent == 0)) {
  1984.         mr->headers_out.status = rc;
  1985.     }

  1986.     cln = mr->cleanup;
  1987.     mr->cleanup = NULL;

  1988.     while (cln) {
  1989.         if (cln->handler) {
  1990.             cln->handler(cln->data);
  1991.         }

  1992.         cln = cln->next;
  1993.     }

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

  1997.     if (mr->write_event_handler) {

  1998.         if (mr->blocked) {
  1999.             r = r->connection->data;

  2000.             r->connection->error = 1;
  2001.             r->write_event_handler = ngx_http_request_finalizer;

  2002.             return;
  2003.         }

  2004.         e = ngx_http_ephemeral(mr);
  2005.         mr->posted_requests = NULL;
  2006.         mr->write_event_handler = ngx_http_terminate_handler;
  2007.         (void) ngx_http_post_request(mr, &e->terminal_posted_request);
  2008.         return;
  2009.     }

  2010.     ngx_http_close_request(mr, rc);
  2011. }


  2012. static void
  2013. ngx_http_terminate_handler(ngx_http_request_t *r)
  2014. {
  2015.     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  2016.                    "http terminate handler count:%d", r->count);

  2017.     r->count = 1;

  2018.     ngx_http_close_request(r, 0);
  2019. }


  2020. static void
  2021. ngx_http_finalize_connection(ngx_http_request_t *r)
  2022. {
  2023.     ngx_http_core_loc_conf_t  *clcf;

  2024. #if (NGX_HTTP_V2)
  2025.     if (r->stream) {
  2026.         ngx_http_close_request(r, 0);
  2027.         return;
  2028.     }
  2029. #endif

  2030. #if (NGX_HTTP_V3)
  2031.     if (r->connection->quic) {
  2032.         ngx_http_close_request(r, 0);
  2033.         return;
  2034.     }
  2035. #endif

  2036.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

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

  2038.         if (r->discard_body) {
  2039.             r->read_event_handler = ngx_http_discarded_request_body_handler;
  2040.             ngx_add_timer(r->connection->read, clcf->lingering_timeout);

  2041.             if (r->lingering_time == 0) {
  2042.                 r->lingering_time = ngx_time()
  2043.                                       + (time_t) (clcf->lingering_time / 1000);
  2044.             }
  2045.         }

  2046.         ngx_http_close_request(r, 0);
  2047.         return;
  2048.     }

  2049.     r = r->main;

  2050.     if (r->connection->read->eof) {
  2051.         ngx_http_close_request(r, 0);
  2052.         return;
  2053.     }

  2054.     if (r->reading_body) {
  2055.         r->keepalive = 0;
  2056.         r->lingering_close = 1;
  2057.     }

  2058.     if (!ngx_terminate
  2059.          && !ngx_exiting
  2060.          && r->keepalive
  2061.          && clcf->keepalive_timeout > 0)
  2062.     {
  2063.         ngx_http_set_keepalive(r);
  2064.         return;
  2065.     }

  2066.     if (clcf->lingering_close == NGX_HTTP_LINGERING_ALWAYS
  2067.         || (clcf->lingering_close == NGX_HTTP_LINGERING_ON
  2068.             && (r->lingering_close
  2069.                 || r->header_in->pos < r->header_in->last
  2070.                 || r->connection->read->ready
  2071.                 || r->connection->pipeline)))
  2072.     {
  2073.         ngx_http_set_lingering_close(r->connection);
  2074.         return;
  2075.     }

  2076.     ngx_http_close_request(r, 0);
  2077. }


  2078. static ngx_int_t
  2079. ngx_http_set_write_handler(ngx_http_request_t *r)
  2080. {
  2081.     ngx_event_t               *wev;
  2082.     ngx_http_core_loc_conf_t  *clcf;

  2083.     r->http_state = NGX_HTTP_WRITING_REQUEST_STATE;

  2084.     r->read_event_handler = r->discard_body ?
  2085.                                 ngx_http_discarded_request_body_handler:
  2086.                                 ngx_http_test_reading;
  2087.     r->write_event_handler = ngx_http_writer;

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

  2089.     if (wev->ready && wev->delayed) {
  2090.         return NGX_OK;
  2091.     }

  2092.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
  2093.     if (!wev->delayed) {
  2094.         ngx_add_timer(wev, clcf->send_timeout);
  2095.     }

  2096.     if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
  2097.         ngx_http_close_request(r, 0);
  2098.         return NGX_ERROR;
  2099.     }

  2100.     return NGX_OK;
  2101. }


  2102. static void
  2103. ngx_http_writer(ngx_http_request_t *r)
  2104. {
  2105.     ngx_int_t                  rc;
  2106.     ngx_event_t               *wev;
  2107.     ngx_connection_t          *c;
  2108.     ngx_http_core_loc_conf_t  *clcf;

  2109.     c = r->connection;
  2110.     wev = c->write;

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

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

  2114.     if (wev->timedout) {
  2115.         ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
  2116.                       "client timed out");
  2117.         c->timedout = 1;

  2118.         ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT);
  2119.         return;
  2120.     }

  2121.     if (wev->delayed || r->aio) {
  2122.         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0,
  2123.                        "http writer delayed");

  2124.         if (!wev->delayed) {
  2125.             ngx_add_timer(wev, clcf->send_timeout);
  2126.         }

  2127.         if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
  2128.             ngx_http_close_request(r, 0);
  2129.         }

  2130.         return;
  2131.     }

  2132.     rc = ngx_http_output_filter(r, NULL);

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

  2136.     if (rc == NGX_ERROR) {
  2137.         ngx_http_finalize_request(r, rc);
  2138.         return;
  2139.     }

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

  2141.         if (!wev->delayed) {
  2142.             ngx_add_timer(wev, clcf->send_timeout);
  2143.         }

  2144.         if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
  2145.             ngx_http_close_request(r, 0);
  2146.         }

  2147.         return;
  2148.     }

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

  2151.     r->write_event_handler = ngx_http_request_empty_handler;

  2152.     ngx_http_finalize_request(r, rc);
  2153. }


  2154. static void
  2155. ngx_http_request_finalizer(ngx_http_request_t *r)
  2156. {
  2157.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  2158.                    "http finalizer done: \"%V?%V\"", &r->uri, &r->args);

  2159.     ngx_http_finalize_request(r, 0);
  2160. }


  2161. void
  2162. ngx_http_block_reading(ngx_http_request_t *r)
  2163. {
  2164.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  2165.                    "http reading blocked");

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

  2167.     if ((ngx_event_flags & NGX_USE_LEVEL_EVENT)
  2168.         && r->connection->read->active)
  2169.     {
  2170.         if (ngx_del_event(r->connection->read, NGX_READ_EVENT, 0) != NGX_OK) {
  2171.             ngx_http_close_request(r, 0);
  2172.         }
  2173.     }
  2174. }


  2175. void
  2176. ngx_http_test_reading(ngx_http_request_t *r)
  2177. {
  2178.     int                n;
  2179.     char               buf[1];
  2180.     ngx_err_t          err;
  2181.     ngx_event_t       *rev;
  2182.     ngx_connection_t  *c;

  2183.     c = r->connection;
  2184.     rev = c->read;

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

  2186. #if (NGX_HTTP_V2)

  2187.     if (r->stream) {
  2188.         if (c->error) {
  2189.             err = 0;
  2190.             goto closed;
  2191.         }

  2192.         return;
  2193.     }

  2194. #endif

  2195. #if (NGX_HTTP_V3)

  2196.     if (c->quic) {
  2197.         if (rev->error) {
  2198.             c->error = 1;
  2199.             err = 0;
  2200.             goto closed;
  2201.         }

  2202.         return;
  2203.     }

  2204. #endif

  2205. #if (NGX_HAVE_KQUEUE)

  2206.     if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {

  2207.         if (!rev->pending_eof) {
  2208.             return;
  2209.         }

  2210.         rev->eof = 1;
  2211.         c->error = 1;
  2212.         err = rev->kq_errno;

  2213.         goto closed;
  2214.     }

  2215. #endif

  2216. #if (NGX_HAVE_EPOLLRDHUP)

  2217.     if ((ngx_event_flags & NGX_USE_EPOLL_EVENT) && ngx_use_epoll_rdhup) {
  2218.         socklen_t  len;

  2219.         if (!rev->pending_eof) {
  2220.             return;
  2221.         }

  2222.         rev->eof = 1;
  2223.         c->error = 1;

  2224.         err = 0;
  2225.         len = sizeof(ngx_err_t);

  2226.         /*
  2227.          * BSDs and Linux return 0 and set a pending error in err
  2228.          * Solaris returns -1 and sets errno
  2229.          */

  2230.         if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len)
  2231.             == -1)
  2232.         {
  2233.             err = ngx_socket_errno;
  2234.         }

  2235.         goto closed;
  2236.     }

  2237. #endif

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

  2239.     if (n == 0) {
  2240.         rev->eof = 1;
  2241.         c->error = 1;
  2242.         err = 0;

  2243.         goto closed;

  2244.     } else if (n == -1) {
  2245.         err = ngx_socket_errno;

  2246.         if (err != NGX_EAGAIN) {
  2247.             rev->eof = 1;
  2248.             c->error = 1;

  2249.             goto closed;
  2250.         }
  2251.     }

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

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

  2254.         if (ngx_del_event(rev, NGX_READ_EVENT, 0) != NGX_OK) {
  2255.             ngx_http_close_request(r, 0);
  2256.         }
  2257.     }

  2258.     return;

  2259. closed:

  2260.     if (err) {
  2261.         rev->error = 1;
  2262.     }

  2263. #if (NGX_HTTP_SSL)
  2264.     if (c->ssl) {
  2265.         c->ssl->no_send_shutdown = 1;
  2266.     }
  2267. #endif

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

  2270.     ngx_http_finalize_request(r, NGX_HTTP_CLIENT_CLOSED_REQUEST);
  2271. }


  2272. static void
  2273. ngx_http_set_keepalive(ngx_http_request_t *r)
  2274. {
  2275.     int                        tcp_nodelay;
  2276.     ngx_buf_t                 *b, *f;
  2277.     ngx_chain_t               *cl, *ln;
  2278.     ngx_event_t               *rev, *wev;
  2279.     ngx_connection_t          *c;
  2280.     ngx_http_connection_t     *hc;
  2281.     ngx_http_core_loc_conf_t  *clcf;

  2282.     c = r->connection;
  2283.     rev = c->read;

  2284.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

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

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

  2287.     hc = r->http_connection;
  2288.     b = r->header_in;

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

  2290.         /* the pipelined request */

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

  2292.             /*
  2293.              * If the large header buffers were allocated while the previous
  2294.              * request processing then we do not use c->buffer for
  2295.              * the pipelined request (see ngx_http_create_request()).
  2296.              *
  2297.              * Now we would move the large header buffers to the free list.
  2298.              */

  2299.             for (cl = hc->busy; cl; /* void */) {
  2300.                 ln = cl;
  2301.                 cl = cl->next;

  2302.                 if (ln->buf == b) {
  2303.                     ngx_free_chain(c->pool, ln);
  2304.                     continue;
  2305.                 }

  2306.                 f = ln->buf;
  2307.                 f->pos = f->start;
  2308.                 f->last = f->start;

  2309.                 ln->next = hc->free;
  2310.                 hc->free = ln;
  2311.             }

  2312.             cl = ngx_alloc_chain_link(c->pool);
  2313.             if (cl == NULL) {
  2314.                 ngx_http_close_request(r, 0);
  2315.                 return;
  2316.             }

  2317.             cl->buf = b;
  2318.             cl->next = NULL;

  2319.             hc->busy = cl;
  2320.             hc->nbusy = 1;
  2321.         }
  2322.     }

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

  2325.     ngx_http_free_request(r, 0);

  2326.     c->data = hc;

  2327.     if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  2328.         ngx_http_close_connection(c);
  2329.         return;
  2330.     }

  2331.     wev = c->write;
  2332.     wev->handler = ngx_http_empty_handler;

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

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

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

  2336.         r = ngx_http_create_request(c);
  2337.         if (r == NULL) {
  2338.             ngx_http_close_connection(c);
  2339.             return;
  2340.         }

  2341.         r->pipeline = 1;

  2342.         c->data = r;

  2343.         c->sent = 0;
  2344.         c->destroyed = 0;
  2345.         c->pipeline = 1;

  2346.         if (rev->timer_set) {
  2347.             ngx_del_timer(rev);
  2348.         }

  2349.         rev->handler = ngx_http_process_request_line;
  2350.         ngx_post_event(rev, &ngx_posted_events);
  2351.         return;
  2352.     }

  2353.     /*
  2354.      * To keep a memory footprint as small as possible for an idle keepalive
  2355.      * connection we try to free c->buffer's memory if it was allocated outside
  2356.      * the c->pool.  The large header buffers are always allocated outside the
  2357.      * c->pool and are freed too.
  2358.      */

  2359.     b = c->buffer;

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

  2361.         /*
  2362.          * the special note for ngx_http_keepalive_handler() that
  2363.          * c->buffer's memory was freed
  2364.          */

  2365.         b->pos = NULL;

  2366.     } else {
  2367.         b->pos = b->start;
  2368.         b->last = b->start;
  2369.     }

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

  2372.     if (hc->free) {
  2373.         for (cl = hc->free; cl; /* void */) {
  2374.             ln = cl;
  2375.             cl = cl->next;
  2376.             ngx_pfree(c->pool, ln->buf->start);
  2377.             ngx_free_chain(c->pool, ln);
  2378.         }

  2379.         hc->free = NULL;
  2380.     }

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

  2383.     if (hc->busy) {
  2384.         for (cl = hc->busy; cl; /* void */) {
  2385.             ln = cl;
  2386.             cl = cl->next;
  2387.             ngx_pfree(c->pool, ln->buf->start);
  2388.             ngx_free_chain(c->pool, ln);
  2389.         }

  2390.         hc->busy = NULL;
  2391.         hc->nbusy = 0;
  2392.     }

  2393. #if (NGX_HTTP_SSL)
  2394.     if (c->ssl) {
  2395.         ngx_ssl_free_buffer(c);
  2396.     }
  2397. #endif

  2398.     rev->handler = ngx_http_keepalive_handler;

  2399.     if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
  2400.         if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) != NGX_OK) {
  2401.             ngx_http_close_connection(c);
  2402.             return;
  2403.         }
  2404.     }

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

  2406.     if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
  2407.         if (ngx_tcp_push(c->fd) == -1) {
  2408.             ngx_connection_error(c, ngx_socket_errno, ngx_tcp_push_n " failed");
  2409.             ngx_http_close_connection(c);
  2410.             return;
  2411.         }

  2412.         c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
  2413.         tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0;

  2414.     } else {
  2415.         tcp_nodelay = 1;
  2416.     }

  2417.     if (tcp_nodelay && clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) {
  2418.         ngx_http_close_connection(c);
  2419.         return;
  2420.     }

  2421. #if 0
  2422.     /* if ngx_http_request_t was freed then we need some other place */
  2423.     r->http_state = NGX_HTTP_KEEPALIVE_STATE;
  2424. #endif

  2425.     c->idle = 1;
  2426.     ngx_reusable_connection(c, 1);

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

  2428.     if (rev->ready) {
  2429.         ngx_post_event(rev, &ngx_posted_events);
  2430.     }
  2431. }


  2432. static void
  2433. ngx_http_keepalive_handler(ngx_event_t *rev)
  2434. {
  2435.     size_t             size;
  2436.     ssize_t            n;
  2437.     ngx_buf_t         *b;
  2438.     ngx_connection_t  *c;

  2439.     c = rev->data;

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

  2441.     if (rev->timedout || c->close) {
  2442.         ngx_http_close_connection(c);
  2443.         return;
  2444.     }

  2445. #if (NGX_HAVE_KQUEUE)

  2446.     if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
  2447.         if (rev->pending_eof) {
  2448.             c->log->handler = NULL;
  2449.             ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno,
  2450.                           "kevent() reported that client %V closed "
  2451.                           "keepalive connection", &c->addr_text);
  2452. #if (NGX_HTTP_SSL)
  2453.             if (c->ssl) {
  2454.                 c->ssl->no_send_shutdown = 1;
  2455.             }
  2456. #endif
  2457.             ngx_http_close_connection(c);
  2458.             return;
  2459.         }
  2460.     }

  2461. #endif

  2462.     b = c->buffer;
  2463.     size = b->end - b->start;

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

  2465.         /*
  2466.          * The c->buffer's memory was freed by ngx_http_set_keepalive().
  2467.          * However, the c->buffer->start and c->buffer->end were not changed
  2468.          * to keep the buffer size.
  2469.          */

  2470.         b->pos = ngx_palloc(c->pool, size);
  2471.         if (b->pos == NULL) {
  2472.             ngx_http_close_connection(c);
  2473.             return;
  2474.         }

  2475.         b->start = b->pos;
  2476.         b->last = b->pos;
  2477.         b->end = b->pos + size;
  2478.     }

  2479.     /*
  2480.      * MSIE closes a keepalive connection with RST flag
  2481.      * so we ignore ECONNRESET here.
  2482.      */

  2483.     c->log_error = NGX_ERROR_IGNORE_ECONNRESET;
  2484.     ngx_set_socket_errno(0);

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

  2487.     if (n == NGX_AGAIN) {
  2488.         if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  2489.             ngx_http_close_connection(c);
  2490.             return;
  2491.         }

  2492.         /*
  2493.          * Like ngx_http_set_keepalive() we are trying to not hold
  2494.          * c->buffer's memory for a keepalive connection.
  2495.          */

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

  2497.             /*
  2498.              * the special note that c->buffer's memory was freed
  2499.              */

  2500.             b->pos = NULL;
  2501.         }

  2502.         return;
  2503.     }

  2504.     if (n == NGX_ERROR) {
  2505.         ngx_http_close_connection(c);
  2506.         return;
  2507.     }

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

  2509.     if (n == 0) {
  2510.         ngx_log_error(NGX_LOG_INFO, c->log, ngx_socket_errno,
  2511.                       "client %V closed keepalive connection", &c->addr_text);
  2512.         ngx_http_close_connection(c);
  2513.         return;
  2514.     }

  2515.     b->last += n;

  2516.     c->log->handler = ngx_http_log_error;
  2517.     c->log->action = "reading client request line";

  2518.     c->idle = 0;
  2519.     ngx_reusable_connection(c, 0);

  2520.     c->data = ngx_http_create_request(c);
  2521.     if (c->data == NULL) {
  2522.         ngx_http_close_connection(c);
  2523.         return;
  2524.     }

  2525.     c->sent = 0;
  2526.     c->destroyed = 0;

  2527.     ngx_del_timer(rev);

  2528.     rev->handler = ngx_http_process_request_line;
  2529.     ngx_http_process_request_line(rev);
  2530. }


  2531. static void
  2532. ngx_http_set_lingering_close(ngx_connection_t *c)
  2533. {
  2534.     ngx_event_t               *rev, *wev;
  2535.     ngx_http_request_t        *r;
  2536.     ngx_http_core_loc_conf_t  *clcf;

  2537.     r = c->data;

  2538.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  2539.     if (r->lingering_time == 0) {
  2540.         r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000);
  2541.     }

  2542. #if (NGX_HTTP_SSL)
  2543.     if (c->ssl) {
  2544.         ngx_int_t  rc;

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

  2546.         rc = ngx_ssl_shutdown(c);

  2547.         if (rc == NGX_ERROR) {
  2548.             ngx_http_close_request(r, 0);
  2549.             return;
  2550.         }

  2551.         if (rc == NGX_AGAIN) {
  2552.             c->ssl->handler = ngx_http_set_lingering_close;
  2553.             return;
  2554.         }
  2555.     }
  2556. #endif

  2557.     rev = c->read;
  2558.     rev->handler = ngx_http_lingering_close_handler;

  2559.     if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  2560.         ngx_http_close_request(r, 0);
  2561.         return;
  2562.     }

  2563.     wev = c->write;
  2564.     wev->handler = ngx_http_empty_handler;

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

  2571.     if (ngx_shutdown_socket(c->fd, NGX_WRITE_SHUTDOWN) == -1) {
  2572.         ngx_connection_error(c, ngx_socket_errno,
  2573.                              ngx_shutdown_socket_n " failed");
  2574.         ngx_http_close_request(r, 0);
  2575.         return;
  2576.     }

  2577.     c->close = 0;
  2578.     ngx_reusable_connection(c, 1);

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

  2580.     if (rev->ready) {
  2581.         ngx_http_lingering_close_handler(rev);
  2582.     }
  2583. }


  2584. static void
  2585. ngx_http_lingering_close_handler(ngx_event_t *rev)
  2586. {
  2587.     ssize_t                    n;
  2588.     ngx_msec_t                 timer;
  2589.     ngx_connection_t          *c;
  2590.     ngx_http_request_t        *r;
  2591.     ngx_http_core_loc_conf_t  *clcf;
  2592.     u_char                     buffer[NGX_HTTP_LINGERING_BUFFER_SIZE];

  2593.     c = rev->data;
  2594.     r = c->data;

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

  2597.     if (rev->timedout || c->close) {
  2598.         ngx_http_close_request(r, 0);
  2599.         return;
  2600.     }

  2601.     timer = (ngx_msec_t) r->lingering_time - (ngx_msec_t) ngx_time();
  2602.     if ((ngx_msec_int_t) timer <= 0) {
  2603.         ngx_http_close_request(r, 0);
  2604.         return;
  2605.     }

  2606.     do {
  2607.         n = c->recv(c, buffer, NGX_HTTP_LINGERING_BUFFER_SIZE);

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

  2609.         if (n == NGX_AGAIN) {
  2610.             break;
  2611.         }

  2612.         if (n == NGX_ERROR || n == 0) {
  2613.             ngx_http_close_request(r, 0);
  2614.             return;
  2615.         }

  2616.     } while (rev->ready);

  2617.     if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  2618.         ngx_http_close_request(r, 0);
  2619.         return;
  2620.     }

  2621.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  2622.     timer *= 1000;

  2623.     if (timer > clcf->lingering_timeout) {
  2624.         timer = clcf->lingering_timeout;
  2625.     }

  2626.     ngx_add_timer(rev, timer);
  2627. }


  2628. void
  2629. ngx_http_empty_handler(ngx_event_t *wev)
  2630. {
  2631.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, "http empty handler");

  2632.     return;
  2633. }


  2634. void
  2635. ngx_http_request_empty_handler(ngx_http_request_t *r)
  2636. {
  2637.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  2638.                    "http request empty handler");

  2639.     return;
  2640. }


  2641. ngx_int_t
  2642. ngx_http_send_special(ngx_http_request_t *r, ngx_uint_t flags)
  2643. {
  2644.     ngx_buf_t    *b;
  2645.     ngx_chain_t   out;

  2646.     b = ngx_calloc_buf(r->pool);
  2647.     if (b == NULL) {
  2648.         return NGX_ERROR;
  2649.     }

  2650.     if (flags & NGX_HTTP_LAST) {

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

  2653.         } else {
  2654.             b->sync = 1;
  2655.             b->last_in_chain = 1;
  2656.         }
  2657.     }

  2658.     if (flags & NGX_HTTP_FLUSH) {
  2659.         b->flush = 1;
  2660.     }

  2661.     out.buf = b;
  2662.     out.next = NULL;

  2663.     return ngx_http_output_filter(r, &out);
  2664. }


  2665. static ngx_int_t
  2666. ngx_http_post_action(ngx_http_request_t *r)
  2667. {
  2668.     ngx_http_core_loc_conf_t  *clcf;

  2669.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  2670.     if (clcf->post_action.data == NULL) {
  2671.         return NGX_DECLINED;
  2672.     }

  2673.     if (r->post_action && r->uri_changes == 0) {
  2674.         return NGX_DECLINED;
  2675.     }

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

  2678.     r->main->count--;

  2679.     r->http_version = NGX_HTTP_VERSION_9;
  2680.     r->header_only = 1;
  2681.     r->post_action = 1;

  2682.     r->read_event_handler = ngx_http_block_reading;

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

  2685.     } else {
  2686.         ngx_http_named_location(r, &clcf->post_action);
  2687.     }

  2688.     return NGX_OK;
  2689. }


  2690. void
  2691. ngx_http_close_request(ngx_http_request_t *r, ngx_int_t rc)
  2692. {
  2693.     ngx_connection_t  *c;

  2694.     r = r->main;
  2695.     c = r->connection;

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

  2698.     if (r->count == 0) {
  2699.         ngx_log_error(NGX_LOG_ALERT, c->log, 0, "http request count is zero");
  2700.     }

  2701.     r->count--;

  2702.     if (r->count || r->blocked) {
  2703.         return;
  2704.     }

  2705. #if (NGX_HTTP_V2)
  2706.     if (r->stream) {
  2707.         ngx_http_v2_close_stream(r->stream, rc);
  2708.         return;
  2709.     }
  2710. #endif

  2711.     ngx_http_free_request(r, rc);
  2712.     ngx_http_close_connection(c);
  2713. }


  2714. void
  2715. ngx_http_free_request(ngx_http_request_t *r, ngx_int_t rc)
  2716. {
  2717.     ngx_log_t                 *log;
  2718.     ngx_pool_t                *pool;
  2719.     struct linger              linger;
  2720.     ngx_http_cleanup_t        *cln;
  2721.     ngx_http_log_ctx_t        *ctx;
  2722.     ngx_http_core_loc_conf_t  *clcf;

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

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

  2725.     if (r->pool == NULL) {
  2726.         ngx_log_error(NGX_LOG_ALERT, log, 0, "http request already closed");
  2727.         return;
  2728.     }

  2729.     cln = r->cleanup;
  2730.     r->cleanup = NULL;

  2731.     while (cln) {
  2732.         if (cln->handler) {
  2733.             cln->handler(cln->data);
  2734.         }

  2735.         cln = cln->next;
  2736.     }

  2737. #if (NGX_STAT_STUB)

  2738.     if (r->stat_reading) {
  2739.         (void) ngx_atomic_fetch_add(ngx_stat_reading, -1);
  2740.     }

  2741.     if (r->stat_writing) {
  2742.         (void) ngx_atomic_fetch_add(ngx_stat_writing, -1);
  2743.     }

  2744. #endif

  2745.     if (rc > 0 && (r->headers_out.status == 0 || r->connection->sent == 0)) {
  2746.         r->headers_out.status = rc;
  2747.     }

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

  2750.         ngx_http_log_request(r);
  2751.     }

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

  2753.     if (r->connection->timedout
  2754. #if (NGX_HTTP_V3)
  2755.         && r->connection->quic == NULL
  2756. #endif
  2757.        )
  2758.     {
  2759.         clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  2760.         if (clcf->reset_timedout_connection) {
  2761.             linger.l_onoff = 1;
  2762.             linger.l_linger = 0;

  2763.             if (setsockopt(r->connection->fd, SOL_SOCKET, SO_LINGER,
  2764.                            (const void *) &linger, sizeof(struct linger)) == -1)
  2765.             {
  2766.                 ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno,
  2767.                               "setsockopt(SO_LINGER) failed");
  2768.             }
  2769.         }
  2770.     }

  2771.     /* the various request strings were allocated from r->pool */
  2772.     ctx = log->data;
  2773.     ctx->request = NULL;

  2774.     r->request_line.len = 0;

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

  2776.     /*
  2777.      * Setting r->pool to NULL will increase probability to catch double close
  2778.      * of request since the request object is allocated from its own pool.
  2779.      */

  2780.     pool = r->pool;
  2781.     r->pool = NULL;

  2782.     ngx_destroy_pool(pool);
  2783. }


  2784. static void
  2785. ngx_http_log_request(ngx_http_request_t *r)
  2786. {
  2787.     ngx_uint_t                  i, n;
  2788.     ngx_http_handler_pt        *log_handler;
  2789.     ngx_http_core_main_conf_t  *cmcf;

  2790.     cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

  2791.     log_handler = cmcf->phases[NGX_HTTP_LOG_PHASE].handlers.elts;
  2792.     n = cmcf->phases[NGX_HTTP_LOG_PHASE].handlers.nelts;

  2793.     for (i = 0; i < n; i++) {
  2794.         log_handler[i](r);
  2795.     }
  2796. }


  2797. void
  2798. ngx_http_close_connection(ngx_connection_t *c)
  2799. {
  2800.     ngx_pool_t  *pool;

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

  2803. #if (NGX_HTTP_SSL)

  2804.     if (c->ssl) {
  2805.         if (ngx_ssl_shutdown(c) == NGX_AGAIN) {
  2806.             c->ssl->handler = ngx_http_close_connection;
  2807.             return;
  2808.         }
  2809.     }

  2810. #endif

  2811. #if (NGX_HTTP_V3)
  2812.     if (c->quic) {
  2813.         ngx_http_v3_reset_stream(c);
  2814.     }
  2815. #endif

  2816. #if (NGX_STAT_STUB)
  2817.     (void) ngx_atomic_fetch_add(ngx_stat_active, -1);
  2818. #endif

  2819.     c->destroyed = 1;

  2820.     pool = c->pool;

  2821.     ngx_close_connection(c);

  2822.     ngx_destroy_pool(pool);
  2823. }


  2824. static u_char *
  2825. ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len)
  2826. {
  2827.     u_char              *p;
  2828.     ngx_http_request_t  *r;
  2829.     ngx_http_log_ctx_t  *ctx;

  2830.     if (log->action) {
  2831.         p = ngx_snprintf(buf, len, " while %s", log->action);
  2832.         len -= p - buf;
  2833.         buf = p;
  2834.     }

  2835.     ctx = log->data;

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

  2838.     r = ctx->request;

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

  2841.     } else {
  2842.         p = ngx_snprintf(p, len, ", server: %V",
  2843.                          &ctx->connection->listening->addr_text);
  2844.     }

  2845.     return p;
  2846. }


  2847. static u_char *
  2848. ngx_http_log_error_handler(ngx_http_request_t *r, ngx_http_request_t *sr,
  2849.     u_char *buf, size_t len)
  2850. {
  2851.     char                      *uri_separator;
  2852.     u_char                    *p;
  2853.     ngx_http_upstream_t       *u;
  2854.     ngx_http_core_srv_conf_t  *cscf;

  2855.     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);

  2856.     p = ngx_snprintf(buf, len, ", server: %V", &cscf->server_name);
  2857.     len -= p - buf;
  2858.     buf = p;

  2859.     if (r->request_line.data == NULL && r->request_start) {
  2860.         for (p = r->request_start; p < r->header_in->last; p++) {
  2861.             if (*p == CR || *p == LF) {
  2862.                 break;
  2863.             }
  2864.         }

  2865.         r->request_line.len = p - r->request_start;
  2866.         r->request_line.data = r->request_start;
  2867.     }

  2868.     if (r->request_line.len) {
  2869.         p = ngx_snprintf(buf, len, ", request: \"%V\"", &r->request_line);
  2870.         len -= p - buf;
  2871.         buf = p;
  2872.     }

  2873.     if (r != sr) {
  2874.         p = ngx_snprintf(buf, len, ", subrequest: \"%V\"", &sr->uri);
  2875.         len -= p - buf;
  2876.         buf = p;
  2877.     }

  2878.     u = sr->upstream;

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

  2880.         uri_separator = "";

  2881. #if (NGX_HAVE_UNIX_DOMAIN)
  2882.         if (u->peer.sockaddr && u->peer.sockaddr->sa_family == AF_UNIX) {
  2883.             uri_separator = ":";
  2884.         }
  2885. #endif

  2886.         p = ngx_snprintf(buf, len, ", upstream: \"%V%V%s%V\"",
  2887.                          &u->schema, u->peer.name,
  2888.                          uri_separator, &u->uri);
  2889.         len -= p - buf;
  2890.         buf = p;
  2891.     }

  2892.     if (r->headers_in.host) {
  2893.         p = ngx_snprintf(buf, len, ", host: \"%V\"",
  2894.                          &r->headers_in.host->value);
  2895.         len -= p - buf;
  2896.         buf = p;
  2897.     }

  2898.     if (r->headers_in.referer) {
  2899.         p = ngx_snprintf(buf, len, ", referrer: \"%V\"",
  2900.                          &r->headers_in.referer->value);
  2901.         buf = p;
  2902.     }

  2903.     return buf;
  2904. }