src/http/ngx_http_request.c - nginx-1.31.7 nginx/ @ 939334eff

Global variables defined

Data types defined

Functions defined

Source code


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


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


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

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

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

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

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

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

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


  52. ‌static char *ngx_http_client_errors[] = {

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

  177.     c->data = hc;

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

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

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

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

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

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

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

  194.             addr6 = port->addrs;

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

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

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

  202.             break;
  203. #endif

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

  206.             addr = port->addrs;

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

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

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

  214.             break;
  215.         }

  216.     } else {

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

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

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

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

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

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

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

  244.     c->log_error = NGX_ERROR_INFO;

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

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

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

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

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

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

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

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

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

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


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

  295.     c = rev->data;

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

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

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

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

  308.     size = cscf->client_header_buffer_size;

  309.     b = c->buffer;

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

  316.         c->buffer = b;

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

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

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

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

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

  329.     if (n == NGX_AGAIN) {

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

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

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

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

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

  347.         return;
  348.     }

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

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

  359.     b->last += n;

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

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

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

  367.         b->pos = p;

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

  376. #if (NGX_HTTP_V2)

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

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

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

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

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

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

  390. #endif

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

  392.     ngx_reusable_connection(c, 0);

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

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


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

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

  411.     c->requests++;

  412.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

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

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

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

  422.     return r;
  423. }


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

  433.     hc = c->data;

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

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

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

  444.     r->pool = pool;

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

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

  451.     r->read_event_handler = ngx_http_block_reading;

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

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

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

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

  472.     cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

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

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

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

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

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

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

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

  497.     r->http_state = NGX_HTTP_READING_REQUEST_STATE;

  498.     r->log_handler = ngx_http_log_error_handler;

  499.     return r;
  500. }


  501. #if (NGX_HTTP_SSL)

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

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

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

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

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

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

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

  530.     err = ngx_socket_errno;

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

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

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

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

  544.             return;
  545.         }

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

  548.         return;
  549.     }

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

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

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

  557.         size = p - buf;

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

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

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

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

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

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

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

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

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

  588.             ngx_reusable_connection(c, 0);

  589.             rc = ngx_ssl_handshake(c);

  590.             if (rc == NGX_AGAIN) {

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

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

  599.             ngx_http_ssl_handshake_handler(c);

  600.             return;
  601.         }

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

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

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

  606.         return;
  607.     }

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


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

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

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

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

  630.         hc = c->data;

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

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

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

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

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

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

  644.         ngx_reusable_connection(c, 1);

  645.         ngx_http_wait_request_handler(c->read);

  646.         return;
  647.     }

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

  651.     ngx_http_close_connection(c);
  652. }


  653. #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME

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

  665.     c = ngx_ssl_get_connection(ssl_conn);

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

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

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

  677.     hc = c->data;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  719.     *hc->ssl_servername = host;

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

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

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

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

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

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

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

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

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

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

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

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

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

  753. done:

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

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

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

  762. error:

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

  766. #endif


  767. #ifdef SSL_R_CERT_CB_ERROR

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

  777.     c = ngx_ssl_get_connection(ssl_conn);

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

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

  785.     r->logged = 1;

  786.     sscf = arg;

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

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

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

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

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

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

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

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

  813. failed:

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

  819. #endif

  820. #endif


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

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

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

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

  840.     rc = NGX_AGAIN;

  841.     for ( ;; ) {

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

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

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

  849.         if (rc == NGX_OK) {

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

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

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

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

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

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

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

  868.             if (r->host_end) {

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

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

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

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

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

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

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

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

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


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

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

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

  908.             break;
  909.         }

  910.         if (rc != NGX_AGAIN) {

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

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

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

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

  919.             break;
  920.         }

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

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

  923.             rv = ngx_http_alloc_large_header_buffer(r, 1);

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

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

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

  938.     ngx_http_run_posted_requests(c);
  939. }


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

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

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

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

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

  958.         cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);

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

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

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

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

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

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

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

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

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

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

  989.     while (p < last) {

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

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

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

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

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

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

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

  1013.         break;
  1014.     }

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

  1019.     }
  1020. #endif

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

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

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

  1027.     return NGX_OK;
  1028. }


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

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

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

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

  1052.     cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

  1053.     rc = NGX_AGAIN;

  1054.     for ( ;; ) {

  1055.         if (rc == NGX_AGAIN) {

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

  1057.                 rv = ngx_http_alloc_large_header_buffer(r, 0);

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

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

  1064.                     r->lingering_close = 1;

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

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

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

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

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

  1084.             n = ngx_http_read_request_header(r);

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

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

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

  1093.         if (rc == NGX_OK) {

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  1142.             continue;
  1143.         }

  1144.         if (rc == NGX_HTTP_PARSE_HEADER_DONE) {

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

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

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

  1149.             r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE;

  1150.             rc = ngx_http_process_request_header(r);

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

  1154.             ngx_http_process_request(r);

  1155.             break;
  1156.         }

  1157.         if (rc == NGX_AGAIN) {

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

  1159.             continue;
  1160.         }

  1161.         /* rc == NGX_HTTP_PARSE_INVALID_HEADER */

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

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

  1169.     ngx_http_run_posted_requests(c);
  1170. }


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

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

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

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

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

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

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

  1199.         return NGX_AGAIN;
  1200.     }

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

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

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

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

  1212.     return n;
  1213. }


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

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

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

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

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

  1229.         return NGX_OK;
  1230.     }

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

  1232.     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);

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

  1239.     hc = r->http_connection;

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

  1243.         b = cl->buf;

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

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

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

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

  1257.         cl->buf = b;

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

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

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

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

  1273.         r->header_in = b;

  1274.         return NGX_OK;
  1275.     }

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

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

  1283.     new = b->start;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  1334.     r->header_in = b;

  1335.     return NGX_OK;
  1336. }


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

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

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

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

  1346.     return NGX_OK;
  1347. }


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

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

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

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

  1363.     ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);

  1364.     return NGX_ERROR;
  1365. }


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

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

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

  1384.     host = h->value;

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

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

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

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

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

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

  1404.     return NGX_OK;
  1405. }


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

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

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

  1418.     return NGX_OK;
  1419. }


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

  1430.     return NGX_OK;
  1431. }


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

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

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

  1441.     user_agent = h->value.data;

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

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

  1444.         r->headers_in.msie = 1;

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

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

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

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

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

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

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

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

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

  1483.     return NGX_OK;
  1484. }


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

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

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

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

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

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

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

  1532.             r->headers_in.chunked = 1;

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

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

  1548.     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);

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

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

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

  1569.     return NGX_OK;
  1570. }


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

  1575.     c = r->connection;

  1576. #if (NGX_HTTP_SSL)

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

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

  1588.         sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);

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

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

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

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

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

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

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

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

  1612.                 X509_free(cert);
  1613.             }

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

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

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

  1624. #endif

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

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

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

  1637.     if (ngx_http_read_early_body(r) != NGX_OK) {
  1638.         return;
  1639.     }

  1640.     ngx_http_handler(r);
  1641. }


  1642. static ngx_int_t
  1643. ‌ngx_http_read_early_body(ngx_http_request_t *r)
  1644. {
  1645.     ngx_int_t                  rc;
  1646.     ngx_http_core_loc_conf_t  *clcf;
  1647.     ngx_http_core_srv_conf_t  *cscf;

  1648.     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);

  1649.     rc = ngx_http_test_predicates(r, cscf->client_body_early_read);

  1650.     if (rc == NGX_ERROR) {
  1651.         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1652.         return NGX_DONE;
  1653.     }

  1654.     if (rc == NGX_OK) {
  1655.         return NGX_OK;
  1656.     }

  1657.     /* rc == NGX_DECLINED */

  1658.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  1659.                    "http client request body early read");

  1660.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  1661.     if (r->headers_in.content_length_n != -1
  1662.         && !r->discard_body
  1663.         && clcf->client_max_body_size
  1664.         && clcf->client_max_body_size < r->headers_in.content_length_n)
  1665.     {
  1666.         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  1667.                       "client intended to send too large body: %O bytes",
  1668.                       r->headers_in.content_length_n);

  1669.         r->expect_tested = 1;
  1670.         (void) ngx_http_discard_request_body(r);
  1671.         ngx_http_finalize_request(r, NGX_HTTP_REQUEST_ENTITY_TOO_LARGE);
  1672.         return NGX_DONE;
  1673.     }

  1674.     rc = ngx_http_read_client_request_body(r, ngx_http_handler);

  1675.     if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
  1676.         ngx_http_finalize_request(r, rc);
  1677.         return NGX_DONE;
  1678.     }

  1679.     ngx_http_finalize_request(r, NGX_DONE);

  1680.     return NGX_DONE;
  1681. }


  1682. ngx_int_t
  1683. ‌ngx_http_validate_host(ngx_str_t *host, in_port_t *portp, ngx_pool_t *pool,
  1684.     ngx_uint_t alloc)
  1685. {
  1686.     u_char     *h, ch;
  1687.     size_t      i, dot_pos, host_len;
  1688.     ngx_int_t   port;

  1689. ‌    enum {
  1690.         sw_host_start = 0,
  1691.         sw_host,
  1692.         sw_host_ip_literal,
  1693.         sw_host_end,
  1694.         sw_port,
  1695.     } state;

  1696.     dot_pos = host->len;
  1697.     host_len = host->len;
  1698.     port = 0;

  1699.     h = host->data;

  1700.     state = sw_host_start;

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

  1703.         switch (state) {

  1704.         case sw_host_start:

  1705.             if (ch == '[') {
  1706.                 state = sw_host_ip_literal;
  1707.                 break;
  1708.             }

  1709.             state = sw_host;

  1710.             /* fall through */

  1711.         case sw_host:

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

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

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

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

  1759.         case sw_host_ip_literal:

  1760.             if (ch >= 'A' && ch <= 'Z') {
  1761.                 alloc = 1;
  1762.                 break;
  1763.             }

  1764.             if (ch >= 'a' && ch <= 'z') {
  1765.                 break;
  1766.             }

  1767.             if (ch >= '0' && ch <= '9') {
  1768.                 break;
  1769.             }

  1770.             switch (ch) {
  1771.             case ':':
  1772.                 break;
  1773.             case ']':
  1774.                 host_len = i + 1;
  1775.                 state = sw_host_end;
  1776.                 break;
  1777.             case '-':
  1778.                 break;
  1779.             case '.':
  1780.                 if (dot_pos == i - 1) {
  1781.                     return NGX_DECLINED;
  1782.                 }
  1783.                 dot_pos = i;
  1784.                 break;
  1785.             case '_':
  1786.             case '~':
  1787.                 /* unreserved */
  1788.                 break;
  1789.             case '!':
  1790.             case '$':
  1791.             case '&':
  1792.             case '\'':
  1793.             case '(':
  1794.             case ')':
  1795.             case '*':
  1796.             case '+':
  1797.             case ',':
  1798.             case ';':
  1799.             case '=':
  1800.                 /* sub-delims */
  1801.                 break;
  1802.             default:
  1803.                 return NGX_DECLINED;
  1804.             }
  1805.             break;

  1806.         case sw_host_end:

  1807.             if (ch == ':') {
  1808.                 state = sw_port;
  1809.                 break;
  1810.             }
  1811.             return NGX_DECLINED;

  1812.         case sw_port:

  1813.             if (ch >= '0' && ch <= '9') {
  1814.                 if (port >= 6553 && (port > 6553 || (ch - '0') > 5)) {
  1815.                     return NGX_DECLINED;
  1816.                 }

  1817.                 port = port * 10 + (ch - '0');
  1818.                 break;
  1819.             }
  1820.             return NGX_DECLINED;
  1821.         }
  1822.     }

  1823.     if (state == sw_host_ip_literal) {
  1824.         return NGX_DECLINED;
  1825.     }

  1826.     if (dot_pos == host_len - 1) {
  1827.         host_len--;
  1828.     }

  1829.     if (host_len == 0) {
  1830.         return NGX_DECLINED;
  1831.     }

  1832.     if (alloc) {
  1833.         host->data = ngx_pnalloc(pool, host_len);
  1834.         if (host->data == NULL) {
  1835.             return NGX_ERROR;
  1836.         }

  1837.         ngx_strlow(host->data, h, host_len);
  1838.     }

  1839.     host->len = host_len;

  1840.     if (portp) {
  1841.         *portp = port;
  1842.     }

  1843.     return NGX_OK;
  1844. }


  1845. ngx_int_t
  1846. ‌ngx_http_set_virtual_server(ngx_http_request_t *r, ngx_str_t *host)
  1847. {
  1848.     ngx_int_t                  rc;
  1849.     ngx_http_connection_t     *hc;
  1850.     ngx_http_core_loc_conf_t  *clcf;
  1851.     ngx_http_core_srv_conf_t  *cscf;

  1852. #if (NGX_SUPPRESS_WARN)
  1853.     cscf = NULL;
  1854. #endif

  1855.     hc = r->http_connection;

  1856. #if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)

  1857.     if (hc->ssl_servername) {
  1858.         if (hc->ssl_servername->len == host->len
  1859.             && ngx_strncmp(hc->ssl_servername->data,
  1860.                            host->data, host->len) == 0)
  1861.         {
  1862. #if (NGX_PCRE)
  1863.             if (hc->ssl_servername_regex
  1864.                 && ngx_http_regex_exec(r, hc->ssl_servername_regex,
  1865.                                           hc->ssl_servername) != NGX_OK)
  1866.             {
  1867.                 ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1868.                 return NGX_ERROR;
  1869.             }
  1870. #endif
  1871.             return NGX_OK;
  1872.         }
  1873.     }

  1874. #endif

  1875.     rc = ngx_http_find_virtual_server(r->connection,
  1876.                                       hc->addr_conf->virtual_names,
  1877.                                       host, r, &cscf);

  1878.     if (rc == NGX_ERROR) {
  1879.         ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1880.         return NGX_ERROR;
  1881.     }

  1882. #if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)

  1883.     if (hc->ssl_servername) {
  1884.         ngx_http_ssl_srv_conf_t  *sscf;

  1885.         if (rc == NGX_DECLINED) {
  1886.             cscf = hc->addr_conf->default_server;
  1887.             rc = NGX_OK;
  1888.         }

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

  1890.         if (sscf->verify) {
  1891.             ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1892.                           "client attempted to request the server name "
  1893.                           "different from the one that was negotiated");
  1894.             ngx_http_finalize_request(r, NGX_HTTP_MISDIRECTED_REQUEST);
  1895.             return NGX_ERROR;
  1896.         }
  1897.     }

  1898. #endif

  1899.     if (rc == NGX_DECLINED) {
  1900.         return NGX_OK;
  1901.     }

  1902.     r->srv_conf = cscf->ctx->srv_conf;
  1903.     r->loc_conf = cscf->ctx->loc_conf;

  1904.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

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

  1906.     return NGX_OK;
  1907. }


  1908. static ngx_int_t
  1909. ‌ngx_http_find_virtual_server(ngx_connection_t *c,
  1910.     ngx_http_virtual_names_t *virtual_names, ngx_str_t *host,
  1911.     ngx_http_request_t *r, ngx_http_core_srv_conf_t **cscfp)
  1912. {
  1913.     ngx_http_core_srv_conf_t  *cscf;

  1914.     if (virtual_names == NULL) {
  1915.         return NGX_DECLINED;
  1916.     }

  1917.     cscf = ngx_hash_find_combined(&virtual_names->names,
  1918.                                   ngx_hash_key(host->data, host->len),
  1919.                                   host->data, host->len);

  1920.     if (cscf) {
  1921.         *cscfp = cscf;
  1922.         return NGX_OK;
  1923.     }

  1924. #if (NGX_PCRE)

  1925.     if (host->len && virtual_names->nregex) {
  1926.         ngx_int_t                n;
  1927.         ngx_uint_t               i;
  1928.         ngx_http_server_name_t  *sn;

  1929.         sn = virtual_names->regex;

  1930. #if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)

  1931.         if (r == NULL) {
  1932.             ngx_http_connection_t  *hc;

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

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

  1935.                 if (n == NGX_REGEX_NO_MATCHED) {
  1936.                     continue;
  1937.                 }

  1938.                 if (n >= 0) {
  1939.                     hc = c->data;
  1940.                     hc->ssl_servername_regex = sn[i].regex;

  1941.                     *cscfp = sn[i].server;
  1942.                     return NGX_OK;
  1943.                 }

  1944.                 ngx_log_error(NGX_LOG_ALERT, c->log, 0,
  1945.                               ngx_regex_exec_n " failed: %i "
  1946.                               "on \"%V\" using \"%V\"",
  1947.                               n, host, &sn[i].regex->name);

  1948.                 return NGX_ERROR;
  1949.             }

  1950.             return NGX_DECLINED;
  1951.         }

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

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

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

  1955.             if (n == NGX_DECLINED) {
  1956.                 continue;
  1957.             }

  1958.             if (n == NGX_OK) {
  1959.                 *cscfp = sn[i].server;
  1960.                 return NGX_OK;
  1961.             }

  1962.             return NGX_ERROR;
  1963.         }
  1964.     }

  1965. #endif /* NGX_PCRE */

  1966.     return NGX_DECLINED;
  1967. }


  1968. static void
  1969. ‌ngx_http_request_handler(ngx_event_t *ev)
  1970. {
  1971.     ngx_connection_t    *c;
  1972.     ngx_http_request_t  *r;

  1973.     c = ev->data;
  1974.     r = c->data;

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

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

  1978.     if (c->close) {
  1979.         r->main->count++;
  1980.         ngx_http_terminate_request(r, 0);
  1981.         ngx_http_run_posted_requests(c);
  1982.         return;
  1983.     }

  1984.     if (ev->delayed && ev->timedout) {
  1985.         ev->delayed = 0;
  1986.         ev->timedout = 0;
  1987.     }

  1988.     if (ev->write) {
  1989.         r->write_event_handler(r);

  1990.     } else {
  1991.         r->read_event_handler(r);
  1992.     }

  1993.     ngx_http_run_posted_requests(c);
  1994. }


  1995. void
  1996. ‌ngx_http_run_posted_requests(ngx_connection_t *c)
  1997. {
  1998.     ngx_http_request_t         *r;
  1999.     ngx_http_posted_request_t  *pr;

  2000.     for ( ;; ) {

  2001.         if (c->destroyed) {
  2002.             return;
  2003.         }

  2004.         r = c->data;
  2005.         pr = r->main->posted_requests;

  2006.         if (pr == NULL) {
  2007.             return;
  2008.         }

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

  2010.         r = pr->request;

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

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

  2014.         r->write_event_handler(r);
  2015.     }
  2016. }


  2017. ngx_int_t
  2018. ‌ngx_http_post_request(ngx_http_request_t *r, ngx_http_posted_request_t *pr)
  2019. {
  2020.     ngx_http_posted_request_t  **p;

  2021.     for (p = &r->main->posted_requests; *p; p = &(*p)->next) {
  2022.         if ((*p)->request == r) {
  2023.             ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  2024.                            "http request already posted");
  2025.             return NGX_OK;
  2026.         }
  2027.     }

  2028.     if (pr == NULL) {
  2029.         pr = ngx_palloc(r->pool, sizeof(ngx_http_posted_request_t));
  2030.         if (pr == NULL) {
  2031.             return NGX_ERROR;
  2032.         }
  2033.     }

  2034.     pr->request = r;
  2035.     pr->next = NULL;

  2036.     *p = pr;

  2037.     return NGX_OK;
  2038. }


  2039. void
  2040. ‌ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
  2041. {
  2042.     ngx_connection_t          *c;
  2043.     ngx_http_request_t        *pr;
  2044.     ngx_http_core_loc_conf_t  *clcf;

  2045.     c = r->connection;

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

  2049.     if (rc == NGX_DONE) {
  2050.         ngx_http_finalize_connection(r);
  2051.         return;
  2052.     }

  2053.     if (rc == NGX_OK && r->filter_finalize) {
  2054.         c->error = 1;
  2055.     }

  2056.     if (rc == NGX_DECLINED) {
  2057.         r->content_handler = NULL;
  2058.         r->write_event_handler = ngx_http_core_run_phases;
  2059.         ngx_http_core_run_phases(r);
  2060.         return;
  2061.     }

  2062.     if (r != r->main && r->post_subrequest) {
  2063.         rc = r->post_subrequest->handler(r, r->post_subrequest->data, rc);
  2064.     }

  2065.     if (rc == NGX_ERROR
  2066.         || rc == NGX_HTTP_REQUEST_TIME_OUT
  2067.         || rc == NGX_HTTP_CLIENT_CLOSED_REQUEST
  2068.         || c->error)
  2069.     {
  2070.         if (ngx_http_post_action(r) == NGX_OK) {
  2071.             return;
  2072.         }

  2073.         ngx_http_terminate_request(r, rc);
  2074.         return;
  2075.     }

  2076.     if (rc >= NGX_HTTP_SPECIAL_RESPONSE
  2077.         || rc == NGX_HTTP_CREATED
  2078.         || rc == NGX_HTTP_NO_CONTENT)
  2079.     {
  2080.         if (rc == NGX_HTTP_CLOSE) {
  2081.             c->timedout = 1;
  2082.             ngx_http_terminate_request(r, rc);
  2083.             return;
  2084.         }

  2085.         if (r == r->main) {
  2086.             if (c->read->timer_set) {
  2087.                 ngx_del_timer(c->read);
  2088.             }

  2089.             if (c->write->timer_set) {
  2090.                 ngx_del_timer(c->write);
  2091.             }
  2092.         }

  2093.         c->read->handler = ngx_http_request_handler;
  2094.         c->write->handler = ngx_http_request_handler;

  2095.         ngx_http_finalize_request(r, ngx_http_special_response_handler(r, rc));
  2096.         return;
  2097.     }

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

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

  2100.             if (ngx_http_set_write_handler(r) != NGX_OK) {
  2101.                 ngx_http_terminate_request(r, 0);
  2102.             }

  2103.             return;
  2104.         }

  2105.         pr = r->parent;

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

  2107.             if (!r->logged) {

  2108.                 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  2109.                 if (clcf->log_subrequest) {
  2110.                     ngx_http_log_request(r);
  2111.                 }

  2112.                 r->logged = 1;

  2113.             } else {
  2114.                 ngx_log_error(NGX_LOG_ALERT, c->log, 0,
  2115.                               "subrequest: \"%V?%V\" logged again",
  2116.                               &r->uri, &r->args);
  2117.             }

  2118.             r->done = 1;

  2119.             if (r->background) {
  2120.                 ngx_http_finalize_connection(r);
  2121.                 return;
  2122.             }

  2123.             r->main->count--;

  2124.             r->write_event_handler = ngx_http_request_empty_handler;

  2125.             if (pr->postponed && pr->postponed->request == r) {
  2126.                 pr->postponed = pr->postponed->next;
  2127.             }

  2128.             c->data = pr;

  2129.         } else {

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

  2133.             r->write_event_handler = ngx_http_request_finalizer;

  2134.             if (r->waited) {
  2135.                 r->done = 1;
  2136.             }
  2137.         }

  2138.         if (ngx_http_post_request(pr, NULL) != NGX_OK) {
  2139.             r->main->count++;
  2140.             ngx_http_terminate_request(r, 0);
  2141.             return;
  2142.         }

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

  2146.         return;
  2147.     }

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

  2149.         if (ngx_http_set_write_handler(r) != NGX_OK) {
  2150.             ngx_http_terminate_request(r, 0);
  2151.         }

  2152.         return;
  2153.     }

  2154.     if (r != c->data) {
  2155.         ngx_log_error(NGX_LOG_ALERT, c->log, 0,
  2156.                       "http finalize non-active request: \"%V?%V\"",
  2157.                       &r->uri, &r->args);
  2158.         return;
  2159.     }

  2160.     r->done = 1;

  2161.     r->read_event_handler = ngx_http_block_reading;
  2162.     r->write_event_handler = ngx_http_request_empty_handler;

  2163.     if (!r->post_action) {
  2164.         r->request_complete = 1;
  2165.     }

  2166.     if (ngx_http_post_action(r) == NGX_OK) {
  2167.         return;
  2168.     }

  2169.     if (c->read->timer_set) {
  2170.         ngx_del_timer(c->read);
  2171.     }

  2172.     if (c->write->timer_set) {
  2173.         c->write->delayed = 0;
  2174.         ngx_del_timer(c->write);
  2175.     }

  2176.     ngx_http_finalize_connection(r);
  2177. }


  2178. static void
  2179. ‌ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc)
  2180. {
  2181.     ngx_http_cleanup_t    *cln;
  2182.     ngx_http_request_t    *mr;
  2183.     ngx_http_ephemeral_t  *e;

  2184.     mr = r->main;

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

  2187.     mr->terminated = 1;

  2188.     if (rc > 0 && (mr->headers_out.status == 0 || mr->connection->sent == 0)) {
  2189.         mr->headers_out.status = rc;
  2190.     }

  2191.     cln = mr->cleanup;
  2192.     mr->cleanup = NULL;

  2193.     while (cln) {
  2194.         if (cln->handler) {
  2195.             cln->handler(cln->data);
  2196.         }

  2197.         cln = cln->next;
  2198.     }

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

  2202.     if (mr->write_event_handler) {

  2203.         if (mr->blocked) {
  2204.             r = r->connection->data;

  2205.             r->connection->error = 1;
  2206.             r->write_event_handler = ngx_http_request_finalizer;

  2207.             return;
  2208.         }

  2209.         e = ngx_http_ephemeral(mr);
  2210.         mr->posted_requests = NULL;
  2211.         mr->write_event_handler = ngx_http_terminate_handler;
  2212.         (void) ngx_http_post_request(mr, &e->terminal_posted_request);
  2213.         return;
  2214.     }

  2215.     ngx_http_close_request(mr, rc);
  2216. }


  2217. static void
  2218. ‌ngx_http_terminate_handler(ngx_http_request_t *r)
  2219. {
  2220.     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  2221.                    "http terminate handler count:%d", r->count);

  2222.     r->count = 1;

  2223.     ngx_http_close_request(r, 0);
  2224. }


  2225. static void
  2226. ‌ngx_http_finalize_connection(ngx_http_request_t *r)
  2227. {
  2228.     ngx_http_core_loc_conf_t  *clcf;

  2229. #if (NGX_HTTP_V2)
  2230.     if (r->stream) {
  2231.         ngx_http_close_request(r, 0);
  2232.         return;
  2233.     }
  2234. #endif

  2235. #if (NGX_HTTP_V3)
  2236.     if (r->connection->quic) {
  2237.         ngx_http_close_request(r, 0);
  2238.         return;
  2239.     }
  2240. #endif

  2241.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

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

  2243.         if (r->discard_body) {
  2244.             r->read_event_handler = ngx_http_discarded_request_body_handler;
  2245.             ngx_add_timer(r->connection->read, clcf->lingering_timeout);

  2246.             if (r->lingering_time == 0) {
  2247.                 r->lingering_time = ngx_time()
  2248.                                       + (time_t) (clcf->lingering_time / 1000);
  2249.             }
  2250.         }

  2251.         ngx_http_close_request(r, 0);
  2252.         return;
  2253.     }

  2254.     r = r->main;

  2255.     if (r->connection->read->eof) {
  2256.         ngx_http_close_request(r, 0);
  2257.         return;
  2258.     }

  2259.     if (r->reading_body) {
  2260.         r->keepalive = 0;
  2261.         r->lingering_close = 1;
  2262.     }

  2263.     if (r->keepalive
  2264.         && clcf->keepalive_min_timeout > 0)
  2265.     {
  2266.         ngx_http_set_keepalive(r);
  2267.         return;
  2268.     }

  2269.     if (!ngx_terminate
  2270.          && !ngx_exiting
  2271.          && r->keepalive
  2272.          && clcf->keepalive_timeout > 0)
  2273.     {
  2274.         ngx_http_set_keepalive(r);
  2275.         return;
  2276.     }

  2277.     if (clcf->lingering_close == NGX_HTTP_LINGERING_ALWAYS
  2278.         || (clcf->lingering_close == NGX_HTTP_LINGERING_ON
  2279.             && (r->lingering_close
  2280.                 || r->header_in->pos < r->header_in->last
  2281.                 || r->connection->read->ready
  2282.                 || r->connection->pipeline)))
  2283.     {
  2284.         ngx_http_set_lingering_close(r->connection);
  2285.         return;
  2286.     }

  2287.     ngx_http_close_request(r, 0);
  2288. }


  2289. static ngx_int_t
  2290. ‌ngx_http_set_write_handler(ngx_http_request_t *r)
  2291. {
  2292.     ngx_event_t               *wev;
  2293.     ngx_http_core_loc_conf_t  *clcf;

  2294.     r->http_state = NGX_HTTP_WRITING_REQUEST_STATE;

  2295.     r->read_event_handler = r->discard_body ?
  2296.                                 ngx_http_discarded_request_body_handler:
  2297.                                 ngx_http_test_reading;
  2298.     r->write_event_handler = ngx_http_writer;

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

  2300.     if (wev->ready && wev->delayed) {
  2301.         return NGX_OK;
  2302.     }

  2303.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
  2304.     if (!wev->delayed) {
  2305.         ngx_add_timer(wev, clcf->send_timeout);
  2306.     }

  2307.     if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
  2308.         ngx_http_close_request(r, 0);
  2309.         return NGX_ERROR;
  2310.     }

  2311.     return NGX_OK;
  2312. }


  2313. static void
  2314. ‌ngx_http_writer(ngx_http_request_t *r)
  2315. {
  2316.     ngx_int_t                  rc;
  2317.     ngx_event_t               *wev;
  2318.     ngx_connection_t          *c;
  2319.     ngx_http_core_loc_conf_t  *clcf;

  2320.     c = r->connection;
  2321.     wev = c->write;

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

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

  2325.     if (wev->timedout) {
  2326.         ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
  2327.                       "client timed out");
  2328.         c->timedout = 1;

  2329.         ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT);
  2330.         return;
  2331.     }

  2332.     if (wev->delayed || r->aio) {
  2333.         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0,
  2334.                        "http writer delayed");

  2335.         if (!wev->delayed) {
  2336.             ngx_add_timer(wev, clcf->send_timeout);
  2337.         }

  2338.         if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
  2339.             ngx_http_close_request(r, 0);
  2340.         }

  2341.         return;
  2342.     }

  2343.     rc = ngx_http_output_filter(r, NULL);

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

  2347.     if (rc == NGX_ERROR) {
  2348.         ngx_http_finalize_request(r, rc);
  2349.         return;
  2350.     }

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

  2352.         if (!wev->delayed) {
  2353.             ngx_add_timer(wev, clcf->send_timeout);
  2354.         }

  2355.         if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
  2356.             ngx_http_close_request(r, 0);
  2357.         }

  2358.         return;
  2359.     }

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

  2362.     r->write_event_handler = ngx_http_request_empty_handler;

  2363.     ngx_http_finalize_request(r, rc);
  2364. }


  2365. static void
  2366. ‌ngx_http_request_finalizer(ngx_http_request_t *r)
  2367. {
  2368.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  2369.                    "http finalizer done: \"%V?%V\"", &r->uri, &r->args);

  2370.     ngx_http_finalize_request(r, 0);
  2371. }


  2372. void
  2373. ‌ngx_http_block_reading(ngx_http_request_t *r)
  2374. {
  2375.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  2376.                    "http reading blocked");

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

  2378.     if ((ngx_event_flags & NGX_USE_LEVEL_EVENT)
  2379.         && r->connection->read->active)
  2380.     {
  2381.         if (ngx_del_event(r->connection->read, NGX_READ_EVENT, 0) != NGX_OK) {
  2382.             ngx_http_close_request(r, 0);
  2383.         }
  2384.     }
  2385. }


  2386. void
  2387. ‌ngx_http_test_reading(ngx_http_request_t *r)
  2388. {
  2389.     int                n;
  2390.     char               buf[1];
  2391.     ngx_err_t          err;
  2392.     ngx_event_t       *rev;
  2393.     ngx_connection_t  *c;

  2394.     c = r->connection;
  2395.     rev = c->read;

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

  2397. #if (NGX_HTTP_V2)

  2398.     if (r->stream) {
  2399.         if (c->error) {
  2400.             err = 0;
  2401.             goto closed;
  2402.         }

  2403.         return;
  2404.     }

  2405. #endif

  2406. #if (NGX_HTTP_V3)

  2407.     if (c->quic) {
  2408.         if (rev->error) {
  2409.             c->error = 1;
  2410.             err = 0;
  2411.             goto closed;
  2412.         }

  2413.         return;
  2414.     }

  2415. #endif

  2416. #if (NGX_HAVE_KQUEUE)

  2417.     if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {

  2418.         if (!rev->pending_eof) {
  2419.             return;
  2420.         }

  2421.         rev->eof = 1;
  2422.         c->error = 1;
  2423.         err = rev->kq_errno;

  2424.         goto closed;
  2425.     }

  2426. #endif

  2427. #if (NGX_HAVE_EPOLLRDHUP)

  2428.     if ((ngx_event_flags & NGX_USE_EPOLL_EVENT) && ngx_use_epoll_rdhup) {
  2429.         socklen_t  len;

  2430.         if (!rev->pending_eof) {
  2431.             return;
  2432.         }

  2433.         rev->eof = 1;
  2434.         c->error = 1;

  2435.         err = 0;
  2436.         len = sizeof(ngx_err_t);

  2437.         /*
  2438.          * BSDs and Linux return 0 and set a pending error in err
  2439.          * Solaris returns -1 and sets errno
  2440.          */

  2441.         if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len)
  2442.             == -1)
  2443.         {
  2444.             err = ngx_socket_errno;
  2445.         }

  2446.         goto closed;
  2447.     }

  2448. #endif

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

  2450.     if (n == 0) {
  2451.         rev->eof = 1;
  2452.         c->error = 1;
  2453.         err = 0;

  2454.         goto closed;

  2455.     } else if (n == -1) {
  2456.         err = ngx_socket_errno;

  2457.         if (err != NGX_EAGAIN) {
  2458.             rev->eof = 1;
  2459.             c->error = 1;

  2460.             goto closed;
  2461.         }
  2462.     }

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

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

  2465.         if (ngx_del_event(rev, NGX_READ_EVENT, 0) != NGX_OK) {
  2466.             ngx_http_close_request(r, 0);
  2467.         }
  2468.     }

  2469.     return;

  2470. closed:

  2471.     if (err) {
  2472.         rev->error = 1;
  2473.     }

  2474. #if (NGX_HTTP_SSL)
  2475.     if (c->ssl) {
  2476.         c->ssl->no_send_shutdown = 1;
  2477.     }
  2478. #endif

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

  2481.     ngx_http_finalize_request(r, NGX_HTTP_CLIENT_CLOSED_REQUEST);
  2482. }


  2483. static void
  2484. ‌ngx_http_set_keepalive(ngx_http_request_t *r)
  2485. {
  2486.     int                        tcp_nodelay;
  2487.     ngx_buf_t                 *b, *f;
  2488.     ngx_chain_t               *cl, *ln;
  2489.     ngx_event_t               *rev, *wev;
  2490.     ngx_connection_t          *c;
  2491.     ngx_http_connection_t     *hc;
  2492.     ngx_http_core_loc_conf_t  *clcf;

  2493.     c = r->connection;
  2494.     rev = c->read;

  2495.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

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

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

  2498.     hc = r->http_connection;
  2499.     b = r->header_in;

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

  2501.         /* the pipelined request */

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

  2503.             /*
  2504.              * If the large header buffers were allocated while the previous
  2505.              * request processing then we do not use c->buffer for
  2506.              * the pipelined request (see ngx_http_create_request()).
  2507.              *
  2508.              * Now we would move the large header buffers to the free list.
  2509.              */

  2510.             for (cl = hc->busy; cl; /* void */) {
  2511.                 ln = cl;
  2512.                 cl = cl->next;

  2513.                 if (ln->buf == b) {
  2514.                     ngx_free_chain(c->pool, ln);
  2515.                     continue;
  2516.                 }

  2517.                 f = ln->buf;
  2518.                 f->pos = f->start;
  2519.                 f->last = f->start;

  2520.                 ln->next = hc->free;
  2521.                 hc->free = ln;
  2522.             }

  2523.             cl = ngx_alloc_chain_link(c->pool);
  2524.             if (cl == NULL) {
  2525.                 ngx_http_close_request(r, 0);
  2526.                 return;
  2527.             }

  2528.             cl->buf = b;
  2529.             cl->next = NULL;

  2530.             hc->busy = cl;
  2531.             hc->nbusy = 1;
  2532.         }
  2533.     }

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

  2536.     ngx_http_free_request(r, 0);

  2537.     c->data = hc;

  2538.     if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  2539.         ngx_http_close_connection(c);
  2540.         return;
  2541.     }

  2542.     wev = c->write;
  2543.     wev->handler = ngx_http_empty_handler;

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

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

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

  2547.         r = ngx_http_create_request(c);
  2548.         if (r == NULL) {
  2549.             ngx_http_close_connection(c);
  2550.             return;
  2551.         }

  2552.         r->pipeline = 1;

  2553.         c->data = r;

  2554.         c->sent = 0;
  2555.         c->destroyed = 0;
  2556.         c->pipeline = 1;

  2557.         if (rev->timer_set) {
  2558.             ngx_del_timer(rev);
  2559.         }

  2560.         rev->handler = ngx_http_process_request_line;
  2561.         ngx_post_event(rev, &ngx_posted_events);
  2562.         return;
  2563.     }

  2564.     /*
  2565.      * To keep a memory footprint as small as possible for an idle keepalive
  2566.      * connection we try to free c->buffer's memory if it was allocated outside
  2567.      * the c->pool.  The large header buffers are always allocated outside the
  2568.      * c->pool and are freed too.
  2569.      */

  2570.     b = c->buffer;

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

  2572.         /*
  2573.          * the special note for ngx_http_keepalive_handler() that
  2574.          * c->buffer's memory was freed
  2575.          */

  2576.         b->pos = NULL;

  2577.     } else {
  2578.         b->pos = b->start;
  2579.         b->last = b->start;
  2580.     }

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

  2583.     if (hc->free) {
  2584.         for (cl = hc->free; cl; /* void */) {
  2585.             ln = cl;
  2586.             cl = cl->next;
  2587.             ngx_pfree(c->pool, ln->buf->start);
  2588.             ngx_free_chain(c->pool, ln);
  2589.         }

  2590.         hc->free = NULL;
  2591.     }

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

  2594.     if (hc->busy) {
  2595.         for (cl = hc->busy; cl; /* void */) {
  2596.             ln = cl;
  2597.             cl = cl->next;
  2598.             ngx_pfree(c->pool, ln->buf->start);
  2599.             ngx_free_chain(c->pool, ln);
  2600.         }

  2601.         hc->busy = NULL;
  2602.         hc->nbusy = 0;
  2603.     }

  2604. #if (NGX_HTTP_SSL)
  2605.     if (c->ssl) {
  2606.         ngx_ssl_free_buffer(c);
  2607.     }
  2608. #endif

  2609.     rev->handler = ngx_http_keepalive_handler;

  2610.     if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
  2611.         if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) != NGX_OK) {
  2612.             ngx_http_close_connection(c);
  2613.             return;
  2614.         }
  2615.     }

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

  2617.     if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
  2618.         if (ngx_tcp_push(c->fd) == -1) {
  2619.             ngx_connection_error(c, ngx_socket_errno, ngx_tcp_push_n " failed");
  2620.             ngx_http_close_connection(c);
  2621.             return;
  2622.         }

  2623.         c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
  2624.         tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0;

  2625.     } else {
  2626.         tcp_nodelay = 1;
  2627.     }

  2628.     if (tcp_nodelay && clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) {
  2629.         ngx_http_close_connection(c);
  2630.         return;
  2631.     }

  2632. #if 0
  2633.     /* if ngx_http_request_t was freed then we need some other place */
  2634.     r->http_state = NGX_HTTP_KEEPALIVE_STATE;
  2635. #endif

  2636.     if (clcf->keepalive_min_timeout == 0) {
  2637.         c->idle = 1;
  2638.         ngx_reusable_connection(c, 1);
  2639.     }

  2640.     if (clcf->keepalive_min_timeout > 0
  2641.         && clcf->keepalive_timeout > clcf->keepalive_min_timeout)
  2642.     {
  2643.         hc->keepalive_timeout = clcf->keepalive_timeout
  2644.                                 - clcf->keepalive_min_timeout;

  2645.     } else {
  2646.         hc->keepalive_timeout = 0;
  2647.     }

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

  2649.     if (rev->ready) {
  2650.         ngx_post_event(rev, &ngx_posted_events);
  2651.     }
  2652. }


  2653. static void
  2654. ‌ngx_http_keepalive_handler(ngx_event_t *rev)
  2655. {
  2656.     size_t                  size;
  2657.     ssize_t                 n;
  2658.     ngx_buf_t              *b;
  2659.     ngx_connection_t       *c;
  2660.     ngx_http_connection_t  *hc;

  2661.     c = rev->data;
  2662.     hc = c->data;

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

  2664.     if (!ngx_terminate
  2665.          && !ngx_exiting
  2666.          && rev->timedout
  2667.          && hc->keepalive_timeout > 0)
  2668.     {
  2669.         c->idle = 1;
  2670.         ngx_reusable_connection(c, 1);

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

  2672.         hc->keepalive_timeout = 0;
  2673.         rev->timedout = 0;
  2674.         return;
  2675.     }

  2676.     if (rev->timedout || c->close) {
  2677.         ngx_http_close_connection(c);
  2678.         return;
  2679.     }

  2680. #if (NGX_HAVE_KQUEUE)

  2681.     if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
  2682.         if (rev->pending_eof) {
  2683.             c->log->handler = NULL;
  2684.             ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno,
  2685.                           "kevent() reported that client %V closed "
  2686.                           "keepalive connection", &c->addr_text);
  2687. #if (NGX_HTTP_SSL)
  2688.             if (c->ssl) {
  2689.                 c->ssl->no_send_shutdown = 1;
  2690.             }
  2691. #endif
  2692.             ngx_http_close_connection(c);
  2693.             return;
  2694.         }
  2695.     }

  2696. #endif

  2697.     b = c->buffer;
  2698.     size = b->end - b->start;

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

  2700.         /*
  2701.          * The c->buffer's memory was freed by ngx_http_set_keepalive().
  2702.          * However, the c->buffer->start and c->buffer->end were not changed
  2703.          * to keep the buffer size.
  2704.          */

  2705.         b->pos = ngx_palloc(c->pool, size);
  2706.         if (b->pos == NULL) {
  2707.             ngx_http_close_connection(c);
  2708.             return;
  2709.         }

  2710.         b->start = b->pos;
  2711.         b->last = b->pos;
  2712.         b->end = b->pos + size;
  2713.     }

  2714.     /*
  2715.      * MSIE closes a keepalive connection with RST flag
  2716.      * so we ignore ECONNRESET here.
  2717.      */

  2718.     c->log_error = NGX_ERROR_IGNORE_ECONNRESET;
  2719.     ngx_set_socket_errno(0);

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

  2722.     if (n == NGX_AGAIN) {
  2723.         if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  2724.             ngx_http_close_connection(c);
  2725.             return;
  2726.         }

  2727.         /*
  2728.          * Like ngx_http_set_keepalive() we are trying to not hold
  2729.          * c->buffer's memory for a keepalive connection.
  2730.          */

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

  2732.             /*
  2733.              * the special note that c->buffer's memory was freed
  2734.              */

  2735.             b->pos = NULL;
  2736.         }

  2737.         return;
  2738.     }

  2739.     if (n == NGX_ERROR) {
  2740.         ngx_http_close_connection(c);
  2741.         return;
  2742.     }

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

  2744.     if (n == 0) {
  2745.         ngx_log_error(NGX_LOG_INFO, c->log, ngx_socket_errno,
  2746.                       "client %V closed keepalive connection", &c->addr_text);
  2747.         ngx_http_close_connection(c);
  2748.         return;
  2749.     }

  2750.     b->last += n;

  2751.     c->log->handler = ngx_http_log_error;
  2752.     c->log->action = "reading client request line";

  2753.     c->idle = 0;
  2754.     ngx_reusable_connection(c, 0);

  2755.     c->data = ngx_http_create_request(c);
  2756.     if (c->data == NULL) {
  2757.         ngx_http_close_connection(c);
  2758.         return;
  2759.     }

  2760.     c->sent = 0;
  2761.     c->destroyed = 0;

  2762.     ngx_del_timer(rev);

  2763.     rev->handler = ngx_http_process_request_line;
  2764.     ngx_http_process_request_line(rev);
  2765. }


  2766. static void
  2767. ‌ngx_http_set_lingering_close(ngx_connection_t *c)
  2768. {
  2769.     ngx_event_t               *rev, *wev;
  2770.     ngx_http_request_t        *r;
  2771.     ngx_http_core_loc_conf_t  *clcf;

  2772.     r = c->data;

  2773.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  2774.     if (r->lingering_time == 0) {
  2775.         r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000);
  2776.     }

  2777. #if (NGX_HTTP_SSL)
  2778.     if (c->ssl) {
  2779.         ngx_int_t  rc;

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

  2781.         rc = ngx_ssl_shutdown(c);

  2782.         if (rc == NGX_ERROR) {
  2783.             ngx_http_close_request(r, 0);
  2784.             return;
  2785.         }

  2786.         if (rc == NGX_AGAIN) {
  2787.             c->ssl->handler = ngx_http_set_lingering_close;
  2788.             return;
  2789.         }
  2790.     }
  2791. #endif

  2792.     rev = c->read;
  2793.     rev->handler = ngx_http_lingering_close_handler;

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

  2798.     wev = c->write;
  2799.     wev->handler = ngx_http_empty_handler;

  2800.     if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
  2801.         if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) != NGX_OK) {
  2802.             ngx_http_close_request(r, 0);
  2803.             return;
  2804.         }
  2805.     }

  2806.     if (ngx_shutdown_socket(c->fd, NGX_WRITE_SHUTDOWN) == -1) {
  2807.         ngx_connection_error(c, ngx_socket_errno,
  2808.                              ngx_shutdown_socket_n " failed");
  2809.         ngx_http_close_request(r, 0);
  2810.         return;
  2811.     }

  2812.     c->close = 0;
  2813.     ngx_reusable_connection(c, 1);

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

  2815.     if (rev->ready) {
  2816.         ngx_http_lingering_close_handler(rev);
  2817.     }
  2818. }


  2819. static void
  2820. ‌ngx_http_lingering_close_handler(ngx_event_t *rev)
  2821. {
  2822.     ssize_t                    n;
  2823.     ngx_msec_t                 timer;
  2824.     ngx_connection_t          *c;
  2825.     ngx_http_request_t        *r;
  2826.     ngx_http_core_loc_conf_t  *clcf;
  2827.     u_char                     buffer[NGX_HTTP_LINGERING_BUFFER_SIZE];

  2828.     c = rev->data;
  2829.     r = c->data;

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

  2832.     if (rev->timedout || c->close) {
  2833.         ngx_http_close_request(r, 0);
  2834.         return;
  2835.     }

  2836.     timer = (ngx_msec_t) r->lingering_time - (ngx_msec_t) ngx_time();
  2837.     if ((ngx_msec_int_t) timer <= 0) {
  2838.         ngx_http_close_request(r, 0);
  2839.         return;
  2840.     }

  2841.     do {
  2842.         n = c->recv(c, buffer, NGX_HTTP_LINGERING_BUFFER_SIZE);

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

  2844.         if (n == NGX_AGAIN) {
  2845.             break;
  2846.         }

  2847.         if (n == NGX_ERROR || n == 0) {
  2848.             ngx_http_close_request(r, 0);
  2849.             return;
  2850.         }

  2851.     } while (rev->ready);

  2852.     if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  2853.         ngx_http_close_request(r, 0);
  2854.         return;
  2855.     }

  2856.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  2857.     timer *= 1000;

  2858.     if (timer > clcf->lingering_timeout) {
  2859.         timer = clcf->lingering_timeout;
  2860.     }

  2861.     ngx_add_timer(rev, timer);
  2862. }


  2863. void
  2864. ‌ngx_http_empty_handler(ngx_event_t *wev)
  2865. {
  2866.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, "http empty handler");

  2867.     return;
  2868. }


  2869. void
  2870. ‌ngx_http_request_empty_handler(ngx_http_request_t *r)
  2871. {
  2872.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  2873.                    "http request empty handler");

  2874.     return;
  2875. }


  2876. ngx_int_t
  2877. ‌ngx_http_send_special(ngx_http_request_t *r, ngx_uint_t flags)
  2878. {
  2879.     ngx_buf_t    *b;
  2880.     ngx_chain_t   out;

  2881.     b = ngx_calloc_buf(r->pool);
  2882.     if (b == NULL) {
  2883.         return NGX_ERROR;
  2884.     }

  2885.     if (flags & NGX_HTTP_LAST) {

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

  2888.         } else {
  2889.             b->sync = 1;
  2890.             b->last_in_chain = 1;
  2891.         }
  2892.     }

  2893.     if (flags & NGX_HTTP_FLUSH) {
  2894.         b->flush = 1;
  2895.     }

  2896.     out.buf = b;
  2897.     out.next = NULL;

  2898.     return ngx_http_output_filter(r, &out);
  2899. }


  2900. static ngx_int_t
  2901. ‌ngx_http_post_action(ngx_http_request_t *r)
  2902. {
  2903.     ngx_http_core_loc_conf_t  *clcf;

  2904.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  2905.     if (clcf->post_action.data == NULL) {
  2906.         return NGX_DECLINED;
  2907.     }

  2908.     if (r->post_action && r->uri_changes == 0) {
  2909.         return NGX_DECLINED;
  2910.     }

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

  2913.     r->main->count--;

  2914.     r->http_version = NGX_HTTP_VERSION_9;
  2915.     r->header_only = 1;
  2916.     r->post_action = 1;

  2917.     r->read_event_handler = ngx_http_block_reading;

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

  2920.     } else {
  2921.         ngx_http_named_location(r, &clcf->post_action);
  2922.     }

  2923.     return NGX_OK;
  2924. }


  2925. void
  2926. ‌ngx_http_close_request(ngx_http_request_t *r, ngx_int_t rc)
  2927. {
  2928.     ngx_connection_t  *c;

  2929.     r = r->main;
  2930.     c = r->connection;

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

  2933.     if (r->count == 0) {
  2934.         ngx_log_error(NGX_LOG_ALERT, c->log, 0, "http request count is zero");
  2935.     }

  2936.     r->count--;

  2937.     if (r->count || r->blocked) {
  2938.         return;
  2939.     }

  2940. #if (NGX_HTTP_V2)
  2941.     if (r->stream) {
  2942.         ngx_http_v2_close_stream(r->stream, rc);
  2943.         return;
  2944.     }
  2945. #endif

  2946.     ngx_http_free_request(r, rc);
  2947.     ngx_http_close_connection(c);
  2948. }


  2949. void
  2950. ‌ngx_http_free_request(ngx_http_request_t *r, ngx_int_t rc)
  2951. {
  2952.     ngx_log_t                 *log;
  2953.     ngx_pool_t                *pool;
  2954.     struct linger              linger;
  2955.     ngx_http_cleanup_t        *cln;
  2956.     ngx_http_log_ctx_t        *ctx;
  2957.     ngx_http_core_loc_conf_t  *clcf;

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

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

  2960.     if (r->pool == NULL) {
  2961.         ngx_log_error(NGX_LOG_ALERT, log, 0, "http request already closed");
  2962.         return;
  2963.     }

  2964.     cln = r->cleanup;
  2965.     r->cleanup = NULL;

  2966.     while (cln) {
  2967.         if (cln->handler) {
  2968.             cln->handler(cln->data);
  2969.         }

  2970.         cln = cln->next;
  2971.     }

  2972. #if (NGX_STAT_STUB)

  2973.     if (r->stat_reading) {
  2974.         (void) ngx_atomic_fetch_add(ngx_stat_reading, -1);
  2975.     }

  2976.     if (r->stat_writing) {
  2977.         (void) ngx_atomic_fetch_add(ngx_stat_writing, -1);
  2978.     }

  2979. #endif

  2980.     if (rc > 0 && (r->headers_out.status == 0 || r->connection->sent == 0)) {
  2981.         r->headers_out.status = rc;
  2982.     }

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

  2985.         ngx_http_log_request(r);
  2986.     }

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

  2988.     if (r->connection->timedout
  2989. #if (NGX_HTTP_V3)
  2990.         && r->connection->quic == NULL
  2991. #endif
  2992.        )
  2993.     {
  2994.         clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  2995.         if (clcf->reset_timedout_connection) {
  2996.             linger.l_onoff = 1;
  2997.             linger.l_linger = 0;

  2998.             if (setsockopt(r->connection->fd, SOL_SOCKET, SO_LINGER,
  2999.                            (const void *) &linger, sizeof(struct linger)) == -1)
  3000.             {
  3001.                 ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno,
  3002.                               "setsockopt(SO_LINGER) failed");
  3003.             }
  3004.         }
  3005.     }

  3006.     /* the various request strings were allocated from r->pool */
  3007.     ctx = log->data;
  3008.     ctx->request = NULL;

  3009.     r->request_line.len = 0;

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

  3011.     /*
  3012.      * Setting r->pool to NULL will increase probability to catch double close
  3013.      * of request since the request object is allocated from its own pool.
  3014.      */

  3015.     pool = r->pool;
  3016.     r->pool = NULL;

  3017.     ngx_destroy_pool(pool);
  3018. }


  3019. static void
  3020. ‌ngx_http_log_request(ngx_http_request_t *r)
  3021. {
  3022.     ngx_uint_t                  i, n;
  3023.     ngx_http_handler_pt        *log_handler;
  3024.     ngx_http_core_main_conf_t  *cmcf;

  3025.     cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

  3026.     log_handler = cmcf->phases[NGX_HTTP_LOG_PHASE].handlers.elts;
  3027.     n = cmcf->phases[NGX_HTTP_LOG_PHASE].handlers.nelts;

  3028.     for (i = 0; i < n; i++) {
  3029.         log_handler[i](r);
  3030.     }
  3031. }


  3032. void
  3033. ‌ngx_http_close_connection(ngx_connection_t *c)
  3034. {
  3035.     ngx_pool_t  *pool;

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

  3038. #if (NGX_HTTP_SSL)

  3039.     if (c->ssl) {
  3040.         if (ngx_ssl_shutdown(c) == NGX_AGAIN) {
  3041.             c->ssl->handler = ngx_http_close_connection;
  3042.             return;
  3043.         }
  3044.     }

  3045. #endif

  3046. #if (NGX_HTTP_V3)
  3047.     if (c->quic) {
  3048.         ngx_http_v3_reset_stream(c);
  3049.     }
  3050. #endif

  3051. #if (NGX_STAT_STUB)
  3052.     (void) ngx_atomic_fetch_add(ngx_stat_active, -1);
  3053. #endif

  3054.     c->destroyed = 1;

  3055.     pool = c->pool;

  3056.     ngx_close_connection(c);

  3057.     ngx_destroy_pool(pool);
  3058. }


  3059. static u_char *
  3060. ‌ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len)
  3061. {
  3062.     u_char              *p;
  3063.     ngx_http_request_t  *r;
  3064.     ngx_http_log_ctx_t  *ctx;

  3065.     if (log->action) {
  3066.         p = ngx_snprintf(buf, len, " while %s", log->action);
  3067.         len -= p - buf;
  3068.         buf = p;
  3069.     }

  3070.     ctx = log->data;

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

  3073.     r = ctx->request;

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

  3076.     } else {
  3077.         p = ngx_snprintf(p, len, ", server: %V",
  3078.                          &ctx->connection->listening->addr_text);
  3079.     }

  3080.     return p;
  3081. }


  3082. static u_char *
  3083. ‌ngx_http_log_error_handler(ngx_http_request_t *r, ngx_http_request_t *sr,
  3084.     u_char *buf, size_t len)
  3085. {
  3086.     char                      *uri_separator;
  3087.     u_char                    *p;
  3088.     ngx_http_upstream_t       *u;
  3089.     ngx_http_core_srv_conf_t  *cscf;

  3090.     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);

  3091.     p = ngx_snprintf(buf, len, ", server: %V", &cscf->server_name);
  3092.     len -= p - buf;
  3093.     buf = p;

  3094.     if (r->request_line.data == NULL && r->request_start) {
  3095.         for (p = r->request_start; p < r->header_in->last; p++) {
  3096.             if (*p == CR || *p == LF) {
  3097.                 break;
  3098.             }
  3099.         }

  3100.         r->request_line.len = p - r->request_start;
  3101.         r->request_line.data = r->request_start;
  3102.     }

  3103.     if (r->request_line.len) {
  3104.         p = ngx_snprintf(buf, len, ", request: \"%V\"", &r->request_line);
  3105.         len -= p - buf;
  3106.         buf = p;
  3107.     }

  3108.     if (r != sr) {
  3109.         p = ngx_snprintf(buf, len, ", subrequest: \"%V\"", &sr->uri);
  3110.         len -= p - buf;
  3111.         buf = p;
  3112.     }

  3113.     u = sr->upstream;

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

  3115.         uri_separator = "";

  3116. #if (NGX_HAVE_UNIX_DOMAIN)
  3117.         if (u->peer.sockaddr && u->peer.sockaddr->sa_family == AF_UNIX) {
  3118.             uri_separator = ":";
  3119.         }
  3120. #endif

  3121.         p = ngx_snprintf(buf, len, ", upstream: \"%V%V%s%V\"",
  3122.                          &u->schema, u->peer.name,
  3123.                          uri_separator, &u->uri);
  3124.         len -= p - buf;
  3125.         buf = p;
  3126.     }

  3127.     if (r->headers_in.host) {
  3128.         p = ngx_snprintf(buf, len, ", host: \"%V\"",
  3129.                          &r->headers_in.host->value);
  3130.         len -= p - buf;
  3131.         buf = p;
  3132.     }

  3133.     if (r->headers_in.referer) {
  3134.         p = ngx_snprintf(buf, len, ", referrer: \"%V\"",
  3135.                          &r->headers_in.referer->value);
  3136.         buf = p;
  3137.     }

  3138.     return buf;
  3139. }