src/http/v2/ngx_http_v2.c - nginx source code

Global variables defined

Data types defined

Functions defined

Macros defined

Source code


  1. /*
  2. * Copyright (C) Nginx, Inc.
  3. * Copyright (C) Valentin V. Bartenev
  4. */


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


  9. /* errors */
  10. #define NGX_HTTP_V2_NO_ERROR                     0x0
  11. #define NGX_HTTP_V2_PROTOCOL_ERROR               0x1
  12. #define NGX_HTTP_V2_INTERNAL_ERROR               0x2
  13. #define NGX_HTTP_V2_FLOW_CTRL_ERROR              0x3
  14. #define NGX_HTTP_V2_SETTINGS_TIMEOUT             0x4
  15. #define NGX_HTTP_V2_STREAM_CLOSED                0x5
  16. #define NGX_HTTP_V2_SIZE_ERROR                   0x6
  17. #define NGX_HTTP_V2_REFUSED_STREAM               0x7
  18. #define NGX_HTTP_V2_CANCEL                       0x8
  19. #define NGX_HTTP_V2_COMP_ERROR                   0x9
  20. #define NGX_HTTP_V2_CONNECT_ERROR                0xa
  21. #define NGX_HTTP_V2_ENHANCE_YOUR_CALM            0xb
  22. #define NGX_HTTP_V2_INADEQUATE_SECURITY          0xc
  23. #define NGX_HTTP_V2_HTTP_1_1_REQUIRED            0xd

  24. /* frame sizes */
  25. #define NGX_HTTP_V2_SETTINGS_ACK_SIZE            0
  26. #define NGX_HTTP_V2_RST_STREAM_SIZE              4
  27. #define NGX_HTTP_V2_PRIORITY_SIZE                5
  28. #define NGX_HTTP_V2_PING_SIZE                    8
  29. #define NGX_HTTP_V2_GOAWAY_SIZE                  8
  30. #define NGX_HTTP_V2_WINDOW_UPDATE_SIZE           4

  31. #define NGX_HTTP_V2_SETTINGS_PARAM_SIZE          6

  32. /* settings fields */
  33. #define NGX_HTTP_V2_HEADER_TABLE_SIZE_SETTING    0x1
  34. #define NGX_HTTP_V2_ENABLE_PUSH_SETTING          0x2
  35. #define NGX_HTTP_V2_MAX_STREAMS_SETTING          0x3
  36. #define NGX_HTTP_V2_INIT_WINDOW_SIZE_SETTING     0x4
  37. #define NGX_HTTP_V2_MAX_FRAME_SIZE_SETTING       0x5

  38. #define NGX_HTTP_V2_FRAME_BUFFER_SIZE            24

  39. #define NGX_HTTP_V2_ROOT                         (void *) -1


  40. static void ngx_http_v2_read_handler(ngx_event_t *rev);
  41. static void ngx_http_v2_write_handler(ngx_event_t *wev);
  42. static void ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c);
  43. static void ngx_http_v2_lingering_close(ngx_connection_t *c);
  44. static void ngx_http_v2_lingering_close_handler(ngx_event_t *rev);

  45. static u_char *ngx_http_v2_state_preface(ngx_http_v2_connection_t *h2c,
  46.     u_char *pos, u_char *end);
  47. static u_char *ngx_http_v2_state_preface_end(ngx_http_v2_connection_t *h2c,
  48.     u_char *pos, u_char *end);
  49. static u_char *ngx_http_v2_state_head(ngx_http_v2_connection_t *h2c,
  50.     u_char *pos, u_char *end);
  51. static u_char *ngx_http_v2_state_data(ngx_http_v2_connection_t *h2c,
  52.     u_char *pos, u_char *end);
  53. static u_char *ngx_http_v2_state_read_data(ngx_http_v2_connection_t *h2c,
  54.     u_char *pos, u_char *end);
  55. static u_char *ngx_http_v2_state_headers(ngx_http_v2_connection_t *h2c,
  56.     u_char *pos, u_char *end);
  57. static u_char *ngx_http_v2_state_header_block(ngx_http_v2_connection_t *h2c,
  58.     u_char *pos, u_char *end);
  59. static u_char *ngx_http_v2_state_field_len(ngx_http_v2_connection_t *h2c,
  60.     u_char *pos, u_char *end);
  61. static u_char *ngx_http_v2_state_field_huff(ngx_http_v2_connection_t *h2c,
  62.     u_char *pos, u_char *end);
  63. static u_char *ngx_http_v2_state_field_raw(ngx_http_v2_connection_t *h2c,
  64.     u_char *pos, u_char *end);
  65. static u_char *ngx_http_v2_state_field_skip(ngx_http_v2_connection_t *h2c,
  66.     u_char *pos, u_char *end);
  67. static u_char *ngx_http_v2_state_process_header(ngx_http_v2_connection_t *h2c,
  68.     u_char *pos, u_char *end);
  69. static u_char *ngx_http_v2_state_header_complete(ngx_http_v2_connection_t *h2c,
  70.     u_char *pos, u_char *end);
  71. static u_char *ngx_http_v2_handle_continuation(ngx_http_v2_connection_t *h2c,
  72.     u_char *pos, u_char *end, ngx_http_v2_handler_pt handler);
  73. static u_char *ngx_http_v2_state_priority(ngx_http_v2_connection_t *h2c,
  74.     u_char *pos, u_char *end);
  75. static u_char *ngx_http_v2_state_rst_stream(ngx_http_v2_connection_t *h2c,
  76.     u_char *pos, u_char *end);
  77. static u_char *ngx_http_v2_state_settings(ngx_http_v2_connection_t *h2c,
  78.     u_char *pos, u_char *end);
  79. static u_char *ngx_http_v2_state_settings_params(ngx_http_v2_connection_t *h2c,
  80.     u_char *pos, u_char *end);
  81. static u_char *ngx_http_v2_state_push_promise(ngx_http_v2_connection_t *h2c,
  82.     u_char *pos, u_char *end);
  83. static u_char *ngx_http_v2_state_ping(ngx_http_v2_connection_t *h2c,
  84.     u_char *pos, u_char *end);
  85. static u_char *ngx_http_v2_state_goaway(ngx_http_v2_connection_t *h2c,
  86.     u_char *pos, u_char *end);
  87. static u_char *ngx_http_v2_state_window_update(ngx_http_v2_connection_t *h2c,
  88.     u_char *pos, u_char *end);
  89. static u_char *ngx_http_v2_state_continuation(ngx_http_v2_connection_t *h2c,
  90.     u_char *pos, u_char *end);
  91. static u_char *ngx_http_v2_state_complete(ngx_http_v2_connection_t *h2c,
  92.     u_char *pos, u_char *end);
  93. static u_char *ngx_http_v2_state_skip_padded(ngx_http_v2_connection_t *h2c,
  94.     u_char *pos, u_char *end);
  95. static u_char *ngx_http_v2_state_skip(ngx_http_v2_connection_t *h2c,
  96.     u_char *pos, u_char *end);
  97. static u_char *ngx_http_v2_state_save(ngx_http_v2_connection_t *h2c,
  98.     u_char *pos, u_char *end, ngx_http_v2_handler_pt handler);
  99. static u_char *ngx_http_v2_state_headers_save(ngx_http_v2_connection_t *h2c,
  100.     u_char *pos, u_char *end, ngx_http_v2_handler_pt handler);
  101. static u_char *ngx_http_v2_connection_error(ngx_http_v2_connection_t *h2c,
  102.     ngx_uint_t err);

  103. static ngx_int_t ngx_http_v2_parse_int(ngx_http_v2_connection_t *h2c,
  104.     u_char **pos, u_char *end, ngx_uint_t prefix);

  105. static ngx_http_v2_stream_t *ngx_http_v2_create_stream(
  106.     ngx_http_v2_connection_t *h2c);
  107. static ngx_http_v2_node_t *ngx_http_v2_get_node_by_id(
  108.     ngx_http_v2_connection_t *h2c, ngx_uint_t sid, ngx_uint_t alloc);
  109. static ngx_http_v2_node_t *ngx_http_v2_get_closed_node(
  110.     ngx_http_v2_connection_t *h2c);
  111. #define ngx_http_v2_index_size(h2scf)  (h2scf->streams_index_mask + 1)
  112. #define ngx_http_v2_index(h2scf, sid)  ((sid >> 1) & h2scf->streams_index_mask)

  113. static ngx_int_t ngx_http_v2_send_settings(ngx_http_v2_connection_t *h2c);
  114. static ngx_int_t ngx_http_v2_settings_frame_handler(
  115.     ngx_http_v2_connection_t *h2c, ngx_http_v2_out_frame_t *frame);
  116. static ngx_int_t ngx_http_v2_send_window_update(ngx_http_v2_connection_t *h2c,
  117.     ngx_uint_t sid, size_t window);
  118. static ngx_int_t ngx_http_v2_send_rst_stream(ngx_http_v2_connection_t *h2c,
  119.     ngx_uint_t sid, ngx_uint_t status);
  120. static ngx_int_t ngx_http_v2_send_goaway(ngx_http_v2_connection_t *h2c,
  121.     ngx_uint_t status);

  122. static ngx_http_v2_out_frame_t *ngx_http_v2_get_frame(
  123.     ngx_http_v2_connection_t *h2c, size_t length, ngx_uint_t type,
  124.     u_char flags, ngx_uint_t sid);
  125. static ngx_int_t ngx_http_v2_frame_handler(ngx_http_v2_connection_t *h2c,
  126.     ngx_http_v2_out_frame_t *frame);

  127. static ngx_int_t ngx_http_v2_validate_header(ngx_http_request_t *r,
  128.     ngx_http_v2_header_t *header);
  129. static ngx_int_t ngx_http_v2_pseudo_header(ngx_http_request_t *r,
  130.     ngx_http_v2_header_t *header);
  131. static ngx_int_t ngx_http_v2_parse_path(ngx_http_request_t *r,
  132.     ngx_str_t *value);
  133. static ngx_int_t ngx_http_v2_parse_method(ngx_http_request_t *r,
  134.     ngx_str_t *value);
  135. static ngx_int_t ngx_http_v2_parse_scheme(ngx_http_request_t *r,
  136.     ngx_str_t *value);
  137. static ngx_int_t ngx_http_v2_parse_authority(ngx_http_request_t *r,
  138.     ngx_str_t *value);
  139. static ngx_int_t ngx_http_v2_construct_request_line(ngx_http_request_t *r);
  140. static ngx_int_t ngx_http_v2_cookie(ngx_http_request_t *r,
  141.     ngx_http_v2_header_t *header);
  142. static ngx_int_t ngx_http_v2_construct_cookie_header(ngx_http_request_t *r);
  143. static void ngx_http_v2_run_request(ngx_http_request_t *r);
  144. static ngx_int_t ngx_http_v2_process_request_body(ngx_http_request_t *r,
  145.     u_char *pos, size_t size, ngx_uint_t last, ngx_uint_t flush);
  146. static ngx_int_t ngx_http_v2_filter_request_body(ngx_http_request_t *r);
  147. static void ngx_http_v2_read_client_request_body_handler(ngx_http_request_t *r);

  148. static ngx_int_t ngx_http_v2_terminate_stream(ngx_http_v2_connection_t *h2c,
  149.     ngx_http_v2_stream_t *stream, ngx_uint_t status);
  150. static void ngx_http_v2_close_stream_handler(ngx_event_t *ev);
  151. static void ngx_http_v2_retry_close_stream_handler(ngx_event_t *ev);
  152. static void ngx_http_v2_handle_connection_handler(ngx_event_t *rev);
  153. static void ngx_http_v2_idle_handler(ngx_event_t *rev);
  154. static void ngx_http_v2_finalize_connection(ngx_http_v2_connection_t *h2c,
  155.     ngx_uint_t status);

  156. static ngx_int_t ngx_http_v2_adjust_windows(ngx_http_v2_connection_t *h2c,
  157.     ssize_t delta);
  158. static void ngx_http_v2_set_dependency(ngx_http_v2_connection_t *h2c,
  159.     ngx_http_v2_node_t *node, ngx_uint_t depend, ngx_uint_t exclusive);
  160. static void ngx_http_v2_node_children_update(ngx_http_v2_node_t *node);

  161. static void ngx_http_v2_pool_cleanup(void *data);


  162. static ngx_http_v2_handler_pt ngx_http_v2_frame_states[] = {
  163.     ngx_http_v2_state_data,               /* NGX_HTTP_V2_DATA_FRAME */
  164.     ngx_http_v2_state_headers,            /* NGX_HTTP_V2_HEADERS_FRAME */
  165.     ngx_http_v2_state_priority,           /* NGX_HTTP_V2_PRIORITY_FRAME */
  166.     ngx_http_v2_state_rst_stream,         /* NGX_HTTP_V2_RST_STREAM_FRAME */
  167.     ngx_http_v2_state_settings,           /* NGX_HTTP_V2_SETTINGS_FRAME */
  168.     ngx_http_v2_state_push_promise,       /* NGX_HTTP_V2_PUSH_PROMISE_FRAME */
  169.     ngx_http_v2_state_ping,               /* NGX_HTTP_V2_PING_FRAME */
  170.     ngx_http_v2_state_goaway,             /* NGX_HTTP_V2_GOAWAY_FRAME */
  171.     ngx_http_v2_state_window_update,      /* NGX_HTTP_V2_WINDOW_UPDATE_FRAME */
  172.     ngx_http_v2_state_continuation        /* NGX_HTTP_V2_CONTINUATION_FRAME */
  173. };

  174. #define NGX_HTTP_V2_FRAME_STATES                                              \
  175.     (sizeof(ngx_http_v2_frame_states) / sizeof(ngx_http_v2_handler_pt))


  176. void
  177. ngx_http_v2_init(ngx_event_t *rev)
  178. {
  179.     u_char                    *p, *end;
  180.     ngx_connection_t          *c;
  181.     ngx_pool_cleanup_t        *cln;
  182.     ngx_http_connection_t     *hc;
  183.     ngx_http_v2_srv_conf_t    *h2scf;
  184.     ngx_http_v2_main_conf_t   *h2mcf;
  185.     ngx_http_v2_connection_t  *h2c;
  186.     ngx_http_core_srv_conf_t  *cscf;

  187.     c = rev->data;
  188.     hc = c->data;

  189.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "init http2 connection");

  190.     c->log->action = "processing HTTP/2 connection";

  191.     h2mcf = ngx_http_get_module_main_conf(hc->conf_ctx, ngx_http_v2_module);

  192.     if (h2mcf->recv_buffer == NULL) {
  193.         h2mcf->recv_buffer = ngx_palloc(ngx_cycle->pool,
  194.                                         h2mcf->recv_buffer_size);
  195.         if (h2mcf->recv_buffer == NULL) {
  196.             ngx_http_close_connection(c);
  197.             return;
  198.         }
  199.     }

  200.     h2c = ngx_pcalloc(c->pool, sizeof(ngx_http_v2_connection_t));
  201.     if (h2c == NULL) {
  202.         ngx_http_close_connection(c);
  203.         return;
  204.     }

  205.     h2c->connection = c;
  206.     h2c->http_connection = hc;

  207.     h2c->send_window = NGX_HTTP_V2_DEFAULT_WINDOW;
  208.     h2c->recv_window = NGX_HTTP_V2_MAX_WINDOW;

  209.     h2c->init_window = NGX_HTTP_V2_DEFAULT_WINDOW;

  210.     h2c->frame_size = NGX_HTTP_V2_DEFAULT_FRAME_SIZE;

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

  212.     h2c->priority_limit = ngx_max(h2scf->concurrent_streams, 100);

  213.     h2c->pool = ngx_create_pool(h2scf->pool_size, h2c->connection->log);
  214.     if (h2c->pool == NULL) {
  215.         ngx_http_close_connection(c);
  216.         return;
  217.     }

  218.     cln = ngx_pool_cleanup_add(c->pool, 0);
  219.     if (cln == NULL) {
  220.         ngx_http_close_connection(c);
  221.         return;
  222.     }

  223.     cln->handler = ngx_http_v2_pool_cleanup;
  224.     cln->data = h2c;

  225.     h2c->streams_index = ngx_pcalloc(c->pool, ngx_http_v2_index_size(h2scf)
  226.                                               * sizeof(ngx_http_v2_node_t *));
  227.     if (h2c->streams_index == NULL) {
  228.         ngx_http_close_connection(c);
  229.         return;
  230.     }

  231.     if (ngx_http_v2_send_settings(h2c) == NGX_ERROR) {
  232.         ngx_http_close_connection(c);
  233.         return;
  234.     }

  235.     if (ngx_http_v2_send_window_update(h2c, 0, NGX_HTTP_V2_MAX_WINDOW
  236.                                                - NGX_HTTP_V2_DEFAULT_WINDOW)
  237.         == NGX_ERROR)
  238.     {
  239.         ngx_http_close_connection(c);
  240.         return;
  241.     }

  242.     h2c->state.handler = ngx_http_v2_state_preface;

  243.     ngx_queue_init(&h2c->waiting);
  244.     ngx_queue_init(&h2c->dependencies);
  245.     ngx_queue_init(&h2c->closed);

  246.     c->data = h2c;

  247.     if (ngx_exiting) {
  248.         ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_NO_ERROR);
  249.         return;
  250.     }

  251.     rev->handler = ngx_http_v2_read_handler;
  252.     c->write->handler = ngx_http_v2_write_handler;

  253.     if (!rev->timer_set) {
  254.         cscf = ngx_http_get_module_srv_conf(hc->conf_ctx,
  255.                                             ngx_http_core_module);
  256.         ngx_add_timer(rev, cscf->client_header_timeout);
  257.     }

  258.     c->idle = 1;
  259.     ngx_reusable_connection(c, 0);

  260.     if (c->buffer) {
  261.         p = c->buffer->pos;
  262.         end = c->buffer->last;

  263.         do {
  264.             p = h2c->state.handler(h2c, p, end);

  265.             if (p == NULL) {
  266.                 return;
  267.             }

  268.         } while (p != end);

  269.         h2c->total_bytes += p - c->buffer->pos;
  270.         c->buffer->pos = p;
  271.     }

  272.     ngx_http_v2_read_handler(rev);
  273. }


  274. static void
  275. ngx_http_v2_read_handler(ngx_event_t *rev)
  276. {
  277.     u_char                    *p, *end;
  278.     size_t                     available;
  279.     ssize_t                    n;
  280.     ngx_connection_t          *c;
  281.     ngx_http_v2_main_conf_t   *h2mcf;
  282.     ngx_http_v2_connection_t  *h2c;

  283.     c = rev->data;
  284.     h2c = c->data;

  285.     if (rev->timedout) {
  286.         ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
  287.         ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
  288.         return;
  289.     }

  290.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http2 read handler");

  291.     h2c->blocked = 1;
  292.     h2c->new_streams = 0;

  293.     if (c->close) {
  294.         c->close = 0;

  295.         if (c->error) {
  296.             ngx_http_v2_finalize_connection(h2c, 0);
  297.             return;
  298.         }

  299.         if (!h2c->processing) {
  300.             ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_NO_ERROR);
  301.             return;
  302.         }

  303.         if (!h2c->goaway) {
  304.             h2c->goaway = 1;

  305.             if (ngx_http_v2_send_goaway(h2c, NGX_HTTP_V2_NO_ERROR)
  306.                 == NGX_ERROR)
  307.             {
  308.                 ngx_http_v2_finalize_connection(h2c, 0);
  309.                 return;
  310.             }

  311.             if (ngx_http_v2_send_output_queue(h2c) == NGX_ERROR) {
  312.                 ngx_http_v2_finalize_connection(h2c, 0);
  313.                 return;
  314.             }
  315.         }

  316.         h2c->blocked = 0;

  317.         return;
  318.     }

  319.     h2mcf = ngx_http_get_module_main_conf(h2c->http_connection->conf_ctx,
  320.                                           ngx_http_v2_module);

  321.     available = h2mcf->recv_buffer_size - NGX_HTTP_V2_STATE_BUFFER_SIZE;

  322.     do {
  323.         p = h2mcf->recv_buffer;
  324.         end = ngx_cpymem(p, h2c->state.buffer, h2c->state.buffer_used);

  325.         n = c->recv(c, end, available);

  326.         if (n == NGX_AGAIN) {
  327.             break;
  328.         }

  329.         if (n == 0 && (h2c->state.incomplete || h2c->processing)) {
  330.             ngx_log_error(NGX_LOG_INFO, c->log, 0,
  331.                           "client prematurely closed connection");
  332.         }

  333.         if (n == 0 || n == NGX_ERROR) {
  334.             c->error = 1;
  335.             ngx_http_v2_finalize_connection(h2c, 0);
  336.             return;
  337.         }

  338.         end += n;

  339.         h2c->state.buffer_used = 0;
  340.         h2c->state.incomplete = 0;

  341.         do {
  342.             p = h2c->state.handler(h2c, p, end);

  343.             if (p == NULL) {
  344.                 return;
  345.             }

  346.         } while (p != end);

  347.         h2c->total_bytes += n;

  348.         if (h2c->total_bytes / 8 > h2c->payload_bytes + 1048576) {
  349.             ngx_log_error(NGX_LOG_INFO, c->log, 0, "http2 flood detected");
  350.             ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_NO_ERROR);
  351.             return;
  352.         }

  353.     } while (rev->ready);

  354.     if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  355.         ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
  356.         return;
  357.     }

  358.     if (h2c->last_out && ngx_http_v2_send_output_queue(h2c) == NGX_ERROR) {
  359.         ngx_http_v2_finalize_connection(h2c, 0);
  360.         return;
  361.     }

  362.     h2c->blocked = 0;

  363.     ngx_http_v2_handle_connection(h2c);
  364. }


  365. static void
  366. ngx_http_v2_write_handler(ngx_event_t *wev)
  367. {
  368.     ngx_int_t                  rc;
  369.     ngx_connection_t          *c;
  370.     ngx_http_v2_connection_t  *h2c;

  371.     c = wev->data;
  372.     h2c = c->data;

  373.     if (wev->timedout) {
  374.         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
  375.                        "http2 write event timed out");
  376.         c->error = 1;
  377.         c->timedout = 1;
  378.         ngx_http_v2_finalize_connection(h2c, 0);
  379.         return;
  380.     }

  381.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http2 write handler");

  382.     if (h2c->last_out == NULL && !c->buffered) {

  383.         if (wev->timer_set) {
  384.             ngx_del_timer(wev);
  385.         }

  386.         ngx_http_v2_handle_connection(h2c);
  387.         return;
  388.     }

  389.     h2c->blocked = 1;

  390.     rc = ngx_http_v2_send_output_queue(h2c);

  391.     if (rc == NGX_ERROR) {
  392.         ngx_http_v2_finalize_connection(h2c, 0);
  393.         return;
  394.     }

  395.     h2c->blocked = 0;

  396.     if (rc == NGX_AGAIN) {
  397.         return;
  398.     }

  399.     ngx_http_v2_handle_connection(h2c);
  400. }


  401. ngx_int_t
  402. ngx_http_v2_send_output_queue(ngx_http_v2_connection_t *h2c)
  403. {
  404.     int                        tcp_nodelay;
  405.     ngx_chain_t               *cl;
  406.     ngx_event_t               *wev;
  407.     ngx_connection_t          *c;
  408.     ngx_http_v2_out_frame_t   *out, *frame, *fn;
  409.     ngx_http_core_loc_conf_t  *clcf;

  410.     c = h2c->connection;
  411.     wev = c->write;

  412.     if (c->error) {
  413.         goto error;
  414.     }

  415.     if (!wev->ready) {
  416.         return NGX_AGAIN;
  417.     }

  418.     cl = NULL;
  419.     out = NULL;

  420.     for (frame = h2c->last_out; frame; frame = fn) {
  421.         frame->last->next = cl;
  422.         cl = frame->first;

  423.         fn = frame->next;
  424.         frame->next = out;
  425.         out = frame;

  426.         ngx_log_debug4(NGX_LOG_DEBUG_HTTP, c->log, 0,
  427.                        "http2 frame out: %p sid:%ui bl:%d len:%uz",
  428.                        out, out->stream ? out->stream->node->id : 0,
  429.                        out->blocked, out->length);
  430.     }

  431.     cl = c->send_chain(c, cl, 0);

  432.     if (cl == NGX_CHAIN_ERROR) {
  433.         goto error;
  434.     }

  435.     clcf = ngx_http_get_module_loc_conf(h2c->http_connection->conf_ctx,
  436.                                         ngx_http_core_module);

  437.     if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
  438.         goto error;
  439.     }

  440.     if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
  441.         if (ngx_tcp_push(c->fd) == -1) {
  442.             ngx_connection_error(c, ngx_socket_errno, ngx_tcp_push_n " failed");
  443.             goto error;
  444.         }

  445.         c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
  446.         tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0;

  447.     } else {
  448.         tcp_nodelay = 1;
  449.     }

  450.     if (tcp_nodelay && clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) {
  451.         goto error;
  452.     }

  453.     for ( /* void */ ; out; out = fn) {
  454.         fn = out->next;

  455.         if (out->handler(h2c, out) != NGX_OK) {
  456.             out->blocked = 1;
  457.             break;
  458.         }

  459.         ngx_log_debug4(NGX_LOG_DEBUG_HTTP, c->log, 0,
  460.                        "http2 frame sent: %p sid:%ui bl:%d len:%uz",
  461.                        out, out->stream ? out->stream->node->id : 0,
  462.                        out->blocked, out->length);
  463.     }

  464.     frame = NULL;

  465.     for ( /* void */ ; out; out = fn) {
  466.         fn = out->next;
  467.         out->next = frame;
  468.         frame = out;
  469.     }

  470.     h2c->last_out = frame;

  471.     if (!wev->ready) {
  472.         ngx_add_timer(wev, clcf->send_timeout);
  473.         return NGX_AGAIN;
  474.     }

  475.     if (wev->timer_set) {
  476.         ngx_del_timer(wev);
  477.     }

  478.     return NGX_OK;

  479. error:

  480.     c->error = 1;

  481.     if (!h2c->blocked) {
  482.         ngx_post_event(wev, &ngx_posted_events);
  483.     }

  484.     return NGX_ERROR;
  485. }


  486. static void
  487. ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c)
  488. {
  489.     ngx_int_t                  rc;
  490.     ngx_connection_t          *c;
  491.     ngx_http_core_loc_conf_t  *clcf;

  492.     if (h2c->last_out || h2c->processing) {
  493.         return;
  494.     }

  495.     c = h2c->connection;

  496.     if (c->error) {
  497.         ngx_http_close_connection(c);
  498.         return;
  499.     }

  500.     if (c->buffered) {
  501.         h2c->blocked = 1;

  502.         rc = ngx_http_v2_send_output_queue(h2c);

  503.         h2c->blocked = 0;

  504.         if (rc == NGX_ERROR) {
  505.             ngx_http_close_connection(c);
  506.             return;
  507.         }

  508.         if (rc == NGX_AGAIN) {
  509.             return;
  510.         }

  511.         /* rc == NGX_OK */
  512.     }

  513.     if (h2c->goaway) {
  514.         ngx_http_v2_lingering_close(c);
  515.         return;
  516.     }

  517.     clcf = ngx_http_get_module_loc_conf(h2c->http_connection->conf_ctx,
  518.                                         ngx_http_core_module);

  519.     if (!c->read->timer_set) {
  520.         ngx_add_timer(c->read, clcf->keepalive_timeout);
  521.     }

  522.     ngx_reusable_connection(c, 1);

  523.     if (h2c->state.incomplete) {
  524.         return;
  525.     }

  526.     ngx_destroy_pool(h2c->pool);

  527.     h2c->pool = NULL;
  528.     h2c->free_frames = NULL;
  529.     h2c->frames = 0;
  530.     h2c->free_fake_connections = NULL;

  531. #if (NGX_HTTP_SSL)
  532.     if (c->ssl) {
  533.         ngx_ssl_free_buffer(c);
  534.     }
  535. #endif

  536.     c->destroyed = 1;

  537.     c->write->handler = ngx_http_empty_handler;
  538.     c->read->handler = ngx_http_v2_idle_handler;

  539.     if (c->write->timer_set) {
  540.         ngx_del_timer(c->write);
  541.     }
  542. }


  543. static void
  544. ngx_http_v2_lingering_close(ngx_connection_t *c)
  545. {
  546.     ngx_event_t               *rev, *wev;
  547.     ngx_http_v2_connection_t  *h2c;
  548.     ngx_http_core_loc_conf_t  *clcf;

  549.     h2c = c->data;

  550.     clcf = ngx_http_get_module_loc_conf(h2c->http_connection->conf_ctx,
  551.                                         ngx_http_core_module);

  552.     if (clcf->lingering_close == NGX_HTTP_LINGERING_OFF) {
  553.         ngx_http_close_connection(c);
  554.         return;
  555.     }

  556.     if (h2c->lingering_time == 0) {
  557.         h2c->lingering_time = ngx_time()
  558.                               + (time_t) (clcf->lingering_time / 1000);
  559.     }

  560. #if (NGX_HTTP_SSL)
  561.     if (c->ssl) {
  562.         ngx_int_t  rc;

  563.         rc = ngx_ssl_shutdown(c);

  564.         if (rc == NGX_ERROR) {
  565.             ngx_http_close_connection(c);
  566.             return;
  567.         }

  568.         if (rc == NGX_AGAIN) {
  569.             c->ssl->handler = ngx_http_v2_lingering_close;
  570.             return;
  571.         }
  572.     }
  573. #endif

  574.     rev = c->read;
  575.     rev->handler = ngx_http_v2_lingering_close_handler;

  576.     if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  577.         ngx_http_close_connection(c);
  578.         return;
  579.     }

  580.     wev = c->write;
  581.     wev->handler = ngx_http_empty_handler;

  582.     if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
  583.         if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) != NGX_OK) {
  584.             ngx_http_close_connection(c);
  585.             return;
  586.         }
  587.     }

  588.     if (ngx_shutdown_socket(c->fd, NGX_WRITE_SHUTDOWN) == -1) {
  589.         ngx_connection_error(c, ngx_socket_errno,
  590.                              ngx_shutdown_socket_n " failed");
  591.         ngx_http_close_connection(c);
  592.         return;
  593.     }

  594.     c->close = 0;
  595.     ngx_reusable_connection(c, 1);

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

  597.     if (rev->ready) {
  598.         ngx_http_v2_lingering_close_handler(rev);
  599.     }
  600. }


  601. static void
  602. ngx_http_v2_lingering_close_handler(ngx_event_t *rev)
  603. {
  604.     ssize_t                    n;
  605.     ngx_msec_t                 timer;
  606.     ngx_connection_t          *c;
  607.     ngx_http_core_loc_conf_t  *clcf;
  608.     ngx_http_v2_connection_t  *h2c;
  609.     u_char                     buffer[NGX_HTTP_LINGERING_BUFFER_SIZE];

  610.     c = rev->data;
  611.     h2c = c->data;

  612.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
  613.                    "http2 lingering close handler");

  614.     if (rev->timedout || c->close) {
  615.         ngx_http_close_connection(c);
  616.         return;
  617.     }

  618.     timer = (ngx_msec_t) h2c->lingering_time - (ngx_msec_t) ngx_time();
  619.     if ((ngx_msec_int_t) timer <= 0) {
  620.         ngx_http_close_connection(c);
  621.         return;
  622.     }

  623.     do {
  624.         n = c->recv(c, buffer, NGX_HTTP_LINGERING_BUFFER_SIZE);

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

  626.         if (n == NGX_AGAIN) {
  627.             break;
  628.         }

  629.         if (n == NGX_ERROR || n == 0) {
  630.             ngx_http_close_connection(c);
  631.             return;
  632.         }

  633.     } while (rev->ready);

  634.     if (ngx_handle_read_event(rev, 0) != NGX_OK) {
  635.         ngx_http_close_connection(c);
  636.         return;
  637.     }

  638.     clcf = ngx_http_get_module_loc_conf(h2c->http_connection->conf_ctx,
  639.                                         ngx_http_core_module);
  640.     timer *= 1000;

  641.     if (timer > clcf->lingering_timeout) {
  642.         timer = clcf->lingering_timeout;
  643.     }

  644.     ngx_add_timer(rev, timer);
  645. }


  646. static u_char *
  647. ngx_http_v2_state_preface(ngx_http_v2_connection_t *h2c, u_char *pos,
  648.     u_char *end)
  649. {
  650.     static const u_char preface[] = NGX_HTTP_V2_PREFACE_START;

  651.     if ((size_t) (end - pos) < sizeof(preface) - 1) {
  652.         return ngx_http_v2_state_save(h2c, pos, end, ngx_http_v2_state_preface);
  653.     }

  654.     if (ngx_memcmp(pos, preface, sizeof(preface) - 1) != 0) {
  655.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  656.                       "invalid connection preface");

  657.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
  658.     }

  659.     return ngx_http_v2_state_preface_end(h2c, pos + sizeof(preface) - 1, end);
  660. }


  661. static u_char *
  662. ngx_http_v2_state_preface_end(ngx_http_v2_connection_t *h2c, u_char *pos,
  663.     u_char *end)
  664. {
  665.     static const u_char preface[] = NGX_HTTP_V2_PREFACE_END;

  666.     if ((size_t) (end - pos) < sizeof(preface) - 1) {
  667.         return ngx_http_v2_state_save(h2c, pos, end,
  668.                                       ngx_http_v2_state_preface_end);
  669.     }

  670.     if (ngx_memcmp(pos, preface, sizeof(preface) - 1) != 0) {
  671.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  672.                       "invalid connection preface");

  673.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
  674.     }

  675.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  676.                    "http2 preface verified");

  677.     return ngx_http_v2_state_head(h2c, pos + sizeof(preface) - 1, end);
  678. }


  679. static u_char *
  680. ngx_http_v2_state_head(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end)
  681. {
  682.     uint32_t    head;
  683.     ngx_uint_t  type;

  684.     if (end - pos < NGX_HTTP_V2_FRAME_HEADER_SIZE) {
  685.         return ngx_http_v2_state_save(h2c, pos, end, ngx_http_v2_state_head);
  686.     }

  687.     head = ngx_http_v2_parse_uint32(pos);

  688.     h2c->state.length = ngx_http_v2_parse_length(head);
  689.     h2c->state.flags = pos[4];

  690.     h2c->state.sid = ngx_http_v2_parse_sid(&pos[5]);

  691.     pos += NGX_HTTP_V2_FRAME_HEADER_SIZE;

  692.     type = ngx_http_v2_parse_type(head);

  693.     ngx_log_debug4(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  694.                    "http2 frame type:%ui f:%Xd l:%uz sid:%ui",
  695.                    type, h2c->state.flags, h2c->state.length, h2c->state.sid);

  696.     if (type >= NGX_HTTP_V2_FRAME_STATES) {
  697.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  698.                       "client sent frame with unknown type %ui", type);
  699.         return ngx_http_v2_state_skip(h2c, pos, end);
  700.     }

  701.     return ngx_http_v2_frame_states[type](h2c, pos, end);
  702. }


  703. static u_char *
  704. ngx_http_v2_state_data(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end)
  705. {
  706.     size_t                 size;
  707.     ngx_http_v2_node_t    *node;
  708.     ngx_http_v2_stream_t  *stream;

  709.     size = h2c->state.length;

  710.     if (h2c->state.flags & NGX_HTTP_V2_PADDED_FLAG) {

  711.         if (h2c->state.length == 0) {
  712.             ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  713.                           "client sent padded DATA frame "
  714.                           "with incorrect length: 0");

  715.             return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
  716.         }

  717.         if (end - pos == 0) {
  718.             return ngx_http_v2_state_save(h2c, pos, end,
  719.                                           ngx_http_v2_state_data);
  720.         }

  721.         h2c->state.padding = *pos++;

  722.         if (h2c->state.padding >= size) {
  723.             ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  724.                           "client sent padded DATA frame "
  725.                           "with incorrect length: %uz, padding: %uz",
  726.                           size, h2c->state.padding);

  727.             return ngx_http_v2_connection_error(h2c,
  728.                                                 NGX_HTTP_V2_PROTOCOL_ERROR);
  729.         }

  730.         h2c->state.length -= 1 + h2c->state.padding;
  731.     }

  732.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  733.                    "http2 DATA frame");

  734.     if (h2c->state.sid == 0) {
  735.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  736.                       "client sent DATA frame with incorrect identifier");

  737.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
  738.     }

  739.     if (size > h2c->recv_window) {
  740.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  741.                       "client violated connection flow control: "
  742.                       "received DATA frame length %uz, available window %uz",
  743.                       size, h2c->recv_window);

  744.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_FLOW_CTRL_ERROR);
  745.     }

  746.     h2c->recv_window -= size;

  747.     if (h2c->recv_window < NGX_HTTP_V2_MAX_WINDOW / 4) {

  748.         if (ngx_http_v2_send_window_update(h2c, 0, NGX_HTTP_V2_MAX_WINDOW
  749.                                                    - h2c->recv_window)
  750.             == NGX_ERROR)
  751.         {
  752.             return ngx_http_v2_connection_error(h2c,
  753.                                                 NGX_HTTP_V2_INTERNAL_ERROR);
  754.         }

  755.         h2c->recv_window = NGX_HTTP_V2_MAX_WINDOW;
  756.     }

  757.     node = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 0);

  758.     if (node == NULL || node->stream == NULL) {
  759.         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  760.                        "unknown http2 stream");

  761.         return ngx_http_v2_state_skip_padded(h2c, pos, end);
  762.     }

  763.     stream = node->stream;

  764.     if (size > stream->recv_window) {
  765.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  766.                       "client violated flow control for stream %ui: "
  767.                       "received DATA frame length %uz, available window %uz",
  768.                       node->id, size, stream->recv_window);

  769.         if (ngx_http_v2_terminate_stream(h2c, stream,
  770.                                          NGX_HTTP_V2_FLOW_CTRL_ERROR)
  771.             == NGX_ERROR)
  772.         {
  773.             return ngx_http_v2_connection_error(h2c,
  774.                                                 NGX_HTTP_V2_INTERNAL_ERROR);
  775.         }

  776.         return ngx_http_v2_state_skip_padded(h2c, pos, end);
  777.     }

  778.     stream->recv_window -= size;

  779.     if (stream->no_flow_control
  780.         && stream->recv_window < NGX_HTTP_V2_MAX_WINDOW / 4)
  781.     {
  782.         if (ngx_http_v2_send_window_update(h2c, node->id,
  783.                                            NGX_HTTP_V2_MAX_WINDOW
  784.                                            - stream->recv_window)
  785.             == NGX_ERROR)
  786.         {
  787.             return ngx_http_v2_connection_error(h2c,
  788.                                                 NGX_HTTP_V2_INTERNAL_ERROR);
  789.         }

  790.         stream->recv_window = NGX_HTTP_V2_MAX_WINDOW;
  791.     }

  792.     if (stream->in_closed) {
  793.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  794.                       "client sent DATA frame for half-closed stream %ui",
  795.                       node->id);

  796.         if (ngx_http_v2_terminate_stream(h2c, stream,
  797.                                          NGX_HTTP_V2_STREAM_CLOSED)
  798.             == NGX_ERROR)
  799.         {
  800.             return ngx_http_v2_connection_error(h2c,
  801.                                                 NGX_HTTP_V2_INTERNAL_ERROR);
  802.         }

  803.         return ngx_http_v2_state_skip_padded(h2c, pos, end);
  804.     }

  805.     h2c->state.stream = stream;

  806.     return ngx_http_v2_state_read_data(h2c, pos, end);
  807. }


  808. static u_char *
  809. ngx_http_v2_state_read_data(ngx_http_v2_connection_t *h2c, u_char *pos,
  810.     u_char *end)
  811. {
  812.     size_t                   size;
  813.     ngx_buf_t               *buf;
  814.     ngx_int_t                rc;
  815.     ngx_connection_t        *fc;
  816.     ngx_http_request_t      *r;
  817.     ngx_http_v2_stream_t    *stream;
  818.     ngx_http_v2_srv_conf_t  *h2scf;

  819.     stream = h2c->state.stream;

  820.     if (stream == NULL) {
  821.         return ngx_http_v2_state_skip_padded(h2c, pos, end);
  822.     }

  823.     if (stream->skip_data) {
  824.         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  825.                        "skipping http2 DATA frame");

  826.         return ngx_http_v2_state_skip_padded(h2c, pos, end);
  827.     }

  828.     r = stream->request;
  829.     fc = r->connection;

  830.     if (r->reading_body && !r->request_body_no_buffering) {
  831.         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  832.                        "skipping http2 DATA frame");

  833.         return ngx_http_v2_state_skip_padded(h2c, pos, end);
  834.     }

  835.     if (r->headers_in.content_length_n < 0 && !r->headers_in.chunked) {
  836.         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  837.                        "skipping http2 DATA frame");

  838.         return ngx_http_v2_state_skip_padded(h2c, pos, end);
  839.     }

  840.     size = end - pos;

  841.     if (size >= h2c->state.length) {
  842.         size = h2c->state.length;
  843.         stream->in_closed = h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG;
  844.     }

  845.     h2c->payload_bytes += size;

  846.     if (r->request_body) {
  847.         rc = ngx_http_v2_process_request_body(r, pos, size,
  848.                                               stream->in_closed, 0);

  849.         if (rc != NGX_OK && rc != NGX_AGAIN) {
  850.             stream->skip_data = 1;
  851.             ngx_http_finalize_request(r, rc);
  852.         }

  853.         ngx_http_run_posted_requests(fc);

  854.     } else if (size) {
  855.         buf = stream->preread;

  856.         if (buf == NULL) {
  857.             h2scf = ngx_http_get_module_srv_conf(r, ngx_http_v2_module);

  858.             buf = ngx_create_temp_buf(r->pool, h2scf->preread_size);
  859.             if (buf == NULL) {
  860.                 return ngx_http_v2_connection_error(h2c,
  861.                                                     NGX_HTTP_V2_INTERNAL_ERROR);
  862.             }

  863.             stream->preread = buf;
  864.         }

  865.         if (size > (size_t) (buf->end - buf->last)) {
  866.             ngx_log_error(NGX_LOG_ALERT, h2c->connection->log, 0,
  867.                           "http2 preread buffer overflow");
  868.             return ngx_http_v2_connection_error(h2c,
  869.                                                 NGX_HTTP_V2_INTERNAL_ERROR);
  870.         }

  871.         buf->last = ngx_cpymem(buf->last, pos, size);
  872.     }

  873.     pos += size;
  874.     h2c->state.length -= size;

  875.     if (h2c->state.length) {
  876.         return ngx_http_v2_state_save(h2c, pos, end,
  877.                                       ngx_http_v2_state_read_data);
  878.     }

  879.     if (h2c->state.padding) {
  880.         return ngx_http_v2_state_skip_padded(h2c, pos, end);
  881.     }

  882.     return ngx_http_v2_state_complete(h2c, pos, end);
  883. }


  884. static u_char *
  885. ngx_http_v2_state_headers(ngx_http_v2_connection_t *h2c, u_char *pos,
  886.     u_char *end)
  887. {
  888.     size_t                     size;
  889.     ngx_uint_t                 padded, priority, depend, dependency, excl,
  890.                                weight;
  891.     ngx_uint_t                 status;
  892.     ngx_http_v2_node_t        *node;
  893.     ngx_http_v2_stream_t      *stream;
  894.     ngx_http_v2_srv_conf_t    *h2scf;
  895.     ngx_http_core_srv_conf_t  *cscf;
  896.     ngx_http_core_loc_conf_t  *clcf;

  897.     padded = h2c->state.flags & NGX_HTTP_V2_PADDED_FLAG;
  898.     priority = h2c->state.flags & NGX_HTTP_V2_PRIORITY_FLAG;

  899.     size = 0;

  900.     if (padded) {
  901.         size++;
  902.     }

  903.     if (priority) {
  904.         size += sizeof(uint32_t) + 1;
  905.     }

  906.     if (h2c->state.length < size) {
  907.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  908.                       "client sent HEADERS frame with incorrect length %uz",
  909.                       h2c->state.length);

  910.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
  911.     }

  912.     if (h2c->state.length == size) {
  913.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  914.                       "client sent HEADERS frame with empty header block");

  915.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
  916.     }

  917.     if (h2c->goaway) {
  918.         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  919.                        "skipping http2 HEADERS frame");
  920.         return ngx_http_v2_state_skip(h2c, pos, end);
  921.     }

  922.     if ((size_t) (end - pos) < size) {
  923.         return ngx_http_v2_state_save(h2c, pos, end,
  924.                                       ngx_http_v2_state_headers);
  925.     }

  926.     h2c->state.length -= size;

  927.     if (padded) {
  928.         h2c->state.padding = *pos++;

  929.         if (h2c->state.padding > h2c->state.length) {
  930.             ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  931.                           "client sent padded HEADERS frame "
  932.                           "with incorrect length: %uz, padding: %uz",
  933.                           h2c->state.length, h2c->state.padding);

  934.             return ngx_http_v2_connection_error(h2c,
  935.                                                 NGX_HTTP_V2_PROTOCOL_ERROR);
  936.         }

  937.         h2c->state.length -= h2c->state.padding;
  938.     }

  939.     depend = 0;
  940.     excl = 0;
  941.     weight = NGX_HTTP_V2_DEFAULT_WEIGHT;

  942.     if (priority) {
  943.         dependency = ngx_http_v2_parse_uint32(pos);

  944.         depend = dependency & 0x7fffffff;
  945.         excl = dependency >> 31;
  946.         weight = pos[4] + 1;

  947.         pos += sizeof(uint32_t) + 1;
  948.     }

  949.     ngx_log_debug4(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  950.                    "http2 HEADERS frame sid:%ui "
  951.                    "depends on %ui excl:%ui weight:%ui",
  952.                    h2c->state.sid, depend, excl, weight);

  953.     if (h2c->state.sid % 2 == 0 || h2c->state.sid <= h2c->last_sid) {
  954.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  955.                       "client sent HEADERS frame with incorrect identifier "
  956.                       "%ui, the last was %ui", h2c->state.sid, h2c->last_sid);

  957.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
  958.     }

  959.     if (depend == h2c->state.sid) {
  960.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  961.                       "client sent HEADERS frame for stream %ui "
  962.                       "with incorrect dependency", h2c->state.sid);

  963.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
  964.     }

  965.     h2c->last_sid = h2c->state.sid;

  966.     h2c->state.pool = ngx_create_pool(1024, h2c->connection->log);
  967.     if (h2c->state.pool == NULL) {
  968.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
  969.     }

  970.     cscf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
  971.                                         ngx_http_core_module);

  972.     h2c->state.header_limit = cscf->large_client_header_buffers.size
  973.                               * cscf->large_client_header_buffers.num;

  974.     h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
  975.                                          ngx_http_v2_module);

  976.     if (h2c->processing >= h2scf->concurrent_streams) {
  977.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  978.                       "concurrent streams exceeded %ui", h2c->processing);

  979.         status = NGX_HTTP_V2_REFUSED_STREAM;
  980.         goto rst_stream;
  981.     }

  982.     if (h2c->new_streams++ >= 2 * h2scf->concurrent_streams) {
  983.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  984.                       "client sent too many streams at once");

  985.         status = NGX_HTTP_V2_REFUSED_STREAM;
  986.         goto rst_stream;
  987.     }

  988.     if (!h2c->settings_ack
  989.         && !(h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG)
  990.         && h2scf->preread_size < NGX_HTTP_V2_DEFAULT_WINDOW)
  991.     {
  992.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  993.                       "client sent stream with data "
  994.                       "before settings were acknowledged");

  995.         status = NGX_HTTP_V2_REFUSED_STREAM;
  996.         goto rst_stream;
  997.     }

  998.     node = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 1);

  999.     if (node == NULL) {
  1000.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
  1001.     }

  1002.     if (node->parent) {
  1003.         ngx_queue_remove(&node->reuse);
  1004.         h2c->closed_nodes--;
  1005.     }

  1006.     stream = ngx_http_v2_create_stream(h2c);
  1007.     if (stream == NULL) {
  1008.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
  1009.     }

  1010.     h2c->state.stream = stream;

  1011.     stream->pool = h2c->state.pool;
  1012.     h2c->state.keep_pool = 1;

  1013.     stream->request->request_length = h2c->state.length;

  1014.     stream->in_closed = h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG;
  1015.     stream->node = node;

  1016.     node->stream = stream;

  1017.     if (priority || node->parent == NULL) {
  1018.         node->weight = weight;
  1019.         ngx_http_v2_set_dependency(h2c, node, depend, excl);
  1020.     }

  1021.     clcf = ngx_http_get_module_loc_conf(h2c->http_connection->conf_ctx,
  1022.                                         ngx_http_core_module);

  1023.     if (clcf->keepalive_timeout == 0
  1024.         || h2c->connection->requests >= clcf->keepalive_requests
  1025.         || ngx_current_msec - h2c->connection->start_time
  1026.            > clcf->keepalive_time)
  1027.     {
  1028.         h2c->goaway = 1;

  1029.         if (ngx_http_v2_send_goaway(h2c, NGX_HTTP_V2_NO_ERROR) == NGX_ERROR) {
  1030.             return ngx_http_v2_connection_error(h2c,
  1031.                                                 NGX_HTTP_V2_INTERNAL_ERROR);
  1032.         }
  1033.     }

  1034.     return ngx_http_v2_state_header_block(h2c, pos, end);

  1035. rst_stream:

  1036.     if (h2c->refused_streams++ > ngx_max(h2scf->concurrent_streams, 100)) {
  1037.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1038.                       "client sent too many refused streams");
  1039.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_NO_ERROR);
  1040.     }

  1041.     if (ngx_http_v2_send_rst_stream(h2c, h2c->state.sid, status) != NGX_OK) {
  1042.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
  1043.     }

  1044.     return ngx_http_v2_state_header_block(h2c, pos, end);
  1045. }


  1046. static u_char *
  1047. ngx_http_v2_state_header_block(ngx_http_v2_connection_t *h2c, u_char *pos,
  1048.     u_char *end)
  1049. {
  1050.     u_char      ch;
  1051.     ngx_int_t   value;
  1052.     ngx_uint_t  indexed, size_update, prefix;

  1053.     if (end - pos < 1) {
  1054.         return ngx_http_v2_state_headers_save(h2c, pos, end,
  1055.                                               ngx_http_v2_state_header_block);
  1056.     }

  1057.     if (!(h2c->state.flags & NGX_HTTP_V2_END_HEADERS_FLAG)
  1058.         && h2c->state.length < NGX_HTTP_V2_INT_OCTETS)
  1059.     {
  1060.         return ngx_http_v2_handle_continuation(h2c, pos, end,
  1061.                                                ngx_http_v2_state_header_block);
  1062.     }

  1063.     size_update = 0;
  1064.     indexed = 0;

  1065.     ch = *pos;

  1066.     if (ch >= (1 << 7)) {
  1067.         /* indexed header field */
  1068.         indexed = 1;
  1069.         prefix = ngx_http_v2_prefix(7);

  1070.     } else if (ch >= (1 << 6)) {
  1071.         /* literal header field with incremental indexing */
  1072.         h2c->state.index = 1;
  1073.         prefix = ngx_http_v2_prefix(6);

  1074.     } else if (ch >= (1 << 5)) {
  1075.         /* dynamic table size update */
  1076.         size_update = 1;
  1077.         prefix = ngx_http_v2_prefix(5);

  1078.     } else if (ch >= (1 << 4)) {
  1079.         /* literal header field never indexed */
  1080.         prefix = ngx_http_v2_prefix(4);

  1081.     } else {
  1082.         /* literal header field without indexing */
  1083.         prefix = ngx_http_v2_prefix(4);
  1084.     }

  1085.     value = ngx_http_v2_parse_int(h2c, &pos, end, prefix);

  1086.     if (value < 0) {
  1087.         if (value == NGX_AGAIN) {
  1088.             return ngx_http_v2_state_headers_save(h2c, pos, end,
  1089.                                                ngx_http_v2_state_header_block);
  1090.         }

  1091.         if (value == NGX_DECLINED) {
  1092.             ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1093.                           "client sent header block with too long %s value",
  1094.                           size_update ? "size update" : "header index");

  1095.             return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_COMP_ERROR);
  1096.         }

  1097.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1098.                       "client sent header block with incorrect length");

  1099.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
  1100.     }

  1101.     if (indexed) {
  1102.         if (ngx_http_v2_get_indexed_header(h2c, value, 0) != NGX_OK) {
  1103.             return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_COMP_ERROR);
  1104.         }

  1105.         return ngx_http_v2_state_process_header(h2c, pos, end);
  1106.     }

  1107.     if (size_update) {
  1108.         if (ngx_http_v2_table_size(h2c, value) != NGX_OK) {
  1109.             return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_COMP_ERROR);
  1110.         }

  1111.         return ngx_http_v2_state_header_complete(h2c, pos, end);
  1112.     }

  1113.     if (value == 0) {
  1114.         h2c->state.parse_name = 1;

  1115.     } else if (ngx_http_v2_get_indexed_header(h2c, value, 1) != NGX_OK) {
  1116.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_COMP_ERROR);
  1117.     }

  1118.     h2c->state.parse_value = 1;

  1119.     return ngx_http_v2_state_field_len(h2c, pos, end);
  1120. }


  1121. static u_char *
  1122. ngx_http_v2_state_field_len(ngx_http_v2_connection_t *h2c, u_char *pos,
  1123.     u_char *end)
  1124. {
  1125.     size_t                     alloc;
  1126.     ngx_int_t                  len;
  1127.     ngx_uint_t                 huff;
  1128.     ngx_http_core_srv_conf_t  *cscf;

  1129.     if (!(h2c->state.flags & NGX_HTTP_V2_END_HEADERS_FLAG)
  1130.         && h2c->state.length < NGX_HTTP_V2_INT_OCTETS)
  1131.     {
  1132.         return ngx_http_v2_handle_continuation(h2c, pos, end,
  1133.                                                ngx_http_v2_state_field_len);
  1134.     }

  1135.     if (h2c->state.length < 1) {
  1136.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1137.                       "client sent header block with incorrect length");

  1138.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
  1139.     }

  1140.     if (end - pos < 1) {
  1141.         return ngx_http_v2_state_headers_save(h2c, pos, end,
  1142.                                               ngx_http_v2_state_field_len);
  1143.     }

  1144.     huff = *pos >> 7;
  1145.     len = ngx_http_v2_parse_int(h2c, &pos, end, ngx_http_v2_prefix(7));

  1146.     if (len < 0) {
  1147.         if (len == NGX_AGAIN) {
  1148.             return ngx_http_v2_state_headers_save(h2c, pos, end,
  1149.                                                   ngx_http_v2_state_field_len);
  1150.         }

  1151.         if (len == NGX_DECLINED) {
  1152.             ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1153.                         "client sent header field with too long length value");

  1154.             return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_COMP_ERROR);
  1155.         }

  1156.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1157.                       "client sent header block with incorrect length");

  1158.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
  1159.     }

  1160.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  1161.                    "http2 %s string, len:%i",
  1162.                    huff ? "encoded" : "raw", len);

  1163.     cscf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
  1164.                                         ngx_http_core_module);

  1165.     if ((size_t) len > cscf->large_client_header_buffers.size) {
  1166.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1167.                       "client sent too large header field");

  1168.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_ENHANCE_YOUR_CALM);
  1169.     }

  1170.     h2c->state.field_rest = len;

  1171.     if (h2c->state.stream == NULL && !h2c->state.index) {
  1172.         return ngx_http_v2_state_field_skip(h2c, pos, end);
  1173.     }

  1174.     alloc = (huff ? len * 8 / 5 : len) + 1;

  1175.     h2c->state.field_start = ngx_pnalloc(h2c->state.pool, alloc);
  1176.     if (h2c->state.field_start == NULL) {
  1177.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
  1178.     }

  1179.     h2c->state.field_end = h2c->state.field_start;

  1180.     if (huff) {
  1181.         return ngx_http_v2_state_field_huff(h2c, pos, end);
  1182.     }

  1183.     return ngx_http_v2_state_field_raw(h2c, pos, end);
  1184. }


  1185. static u_char *
  1186. ngx_http_v2_state_field_huff(ngx_http_v2_connection_t *h2c, u_char *pos,
  1187.     u_char *end)
  1188. {
  1189.     size_t  size;

  1190.     size = end - pos;

  1191.     if (size > h2c->state.field_rest) {
  1192.         size = h2c->state.field_rest;
  1193.     }

  1194.     if (size > h2c->state.length) {
  1195.         size = h2c->state.length;
  1196.     }

  1197.     h2c->state.length -= size;
  1198.     h2c->state.field_rest -= size;

  1199.     if (ngx_http_huff_decode(&h2c->state.field_state, pos, size,
  1200.                              &h2c->state.field_end,
  1201.                              h2c->state.field_rest == 0,
  1202.                              h2c->connection->log)
  1203.         != NGX_OK)
  1204.     {
  1205.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1206.                       "client sent invalid encoded header field");

  1207.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_COMP_ERROR);
  1208.     }

  1209.     pos += size;

  1210.     if (h2c->state.field_rest == 0) {
  1211.         *h2c->state.field_end = '\0';
  1212.         return ngx_http_v2_state_process_header(h2c, pos, end);
  1213.     }

  1214.     if (h2c->state.length) {
  1215.         return ngx_http_v2_state_headers_save(h2c, pos, end,
  1216.                                               ngx_http_v2_state_field_huff);
  1217.     }

  1218.     if (h2c->state.flags & NGX_HTTP_V2_END_HEADERS_FLAG) {
  1219.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1220.                       "client sent header field with incorrect length");

  1221.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
  1222.     }

  1223.     return ngx_http_v2_handle_continuation(h2c, pos, end,
  1224.                                            ngx_http_v2_state_field_huff);
  1225. }


  1226. static u_char *
  1227. ngx_http_v2_state_field_raw(ngx_http_v2_connection_t *h2c, u_char *pos,
  1228.     u_char *end)
  1229. {
  1230.     size_t  size;

  1231.     size = end - pos;

  1232.     if (size > h2c->state.field_rest) {
  1233.         size = h2c->state.field_rest;
  1234.     }

  1235.     if (size > h2c->state.length) {
  1236.         size = h2c->state.length;
  1237.     }

  1238.     h2c->state.length -= size;
  1239.     h2c->state.field_rest -= size;

  1240.     h2c->state.field_end = ngx_cpymem(h2c->state.field_end, pos, size);

  1241.     pos += size;

  1242.     if (h2c->state.field_rest == 0) {
  1243.         *h2c->state.field_end = '\0';
  1244.         return ngx_http_v2_state_process_header(h2c, pos, end);
  1245.     }

  1246.     if (h2c->state.length) {
  1247.         return ngx_http_v2_state_headers_save(h2c, pos, end,
  1248.                                               ngx_http_v2_state_field_raw);
  1249.     }

  1250.     if (h2c->state.flags & NGX_HTTP_V2_END_HEADERS_FLAG) {
  1251.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1252.                       "client sent header field with incorrect length");

  1253.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
  1254.     }

  1255.     return ngx_http_v2_handle_continuation(h2c, pos, end,
  1256.                                            ngx_http_v2_state_field_raw);
  1257. }


  1258. static u_char *
  1259. ngx_http_v2_state_field_skip(ngx_http_v2_connection_t *h2c, u_char *pos,
  1260.     u_char *end)
  1261. {
  1262.     size_t  size;

  1263.     size = end - pos;

  1264.     if (size > h2c->state.field_rest) {
  1265.         size = h2c->state.field_rest;
  1266.     }

  1267.     if (size > h2c->state.length) {
  1268.         size = h2c->state.length;
  1269.     }

  1270.     h2c->state.length -= size;
  1271.     h2c->state.field_rest -= size;

  1272.     pos += size;

  1273.     if (h2c->state.field_rest == 0) {
  1274.         return ngx_http_v2_state_process_header(h2c, pos, end);
  1275.     }

  1276.     if (h2c->state.length) {
  1277.         return ngx_http_v2_state_save(h2c, pos, end,
  1278.                                       ngx_http_v2_state_field_skip);
  1279.     }

  1280.     if (h2c->state.flags & NGX_HTTP_V2_END_HEADERS_FLAG) {
  1281.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1282.                       "client sent header field with incorrect length");

  1283.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
  1284.     }

  1285.     return ngx_http_v2_handle_continuation(h2c, pos, end,
  1286.                                            ngx_http_v2_state_field_skip);
  1287. }


  1288. static u_char *
  1289. ngx_http_v2_state_process_header(ngx_http_v2_connection_t *h2c, u_char *pos,
  1290.     u_char *end)
  1291. {
  1292.     size_t                      len;
  1293.     ngx_int_t                   rc;
  1294.     ngx_table_elt_t            *h;
  1295.     ngx_connection_t           *fc;
  1296.     ngx_http_header_t          *hh;
  1297.     ngx_http_request_t         *r;
  1298.     ngx_http_v2_header_t       *header;
  1299.     ngx_http_core_srv_conf_t   *cscf;
  1300.     ngx_http_core_main_conf_t  *cmcf;

  1301.     static ngx_str_t cookie = ngx_string("cookie");

  1302.     header = &h2c->state.header;

  1303.     if (h2c->state.parse_name) {
  1304.         h2c->state.parse_name = 0;

  1305.         header->name.len = h2c->state.field_end - h2c->state.field_start;
  1306.         header->name.data = h2c->state.field_start;

  1307.         if (header->name.len == 0) {
  1308.             ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1309.                           "client sent zero header name length");

  1310.             return ngx_http_v2_connection_error(h2c,
  1311.                                                 NGX_HTTP_V2_PROTOCOL_ERROR);
  1312.         }

  1313.         return ngx_http_v2_state_field_len(h2c, pos, end);
  1314.     }

  1315.     if (h2c->state.parse_value) {
  1316.         h2c->state.parse_value = 0;

  1317.         header->value.len = h2c->state.field_end - h2c->state.field_start;
  1318.         header->value.data = h2c->state.field_start;
  1319.     }

  1320.     len = header->name.len + header->value.len;

  1321.     if (len > h2c->state.header_limit) {
  1322.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1323.                       "client sent too large header");

  1324.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_ENHANCE_YOUR_CALM);
  1325.     }

  1326.     h2c->state.header_limit -= len;

  1327.     if (h2c->state.index) {
  1328.         if (ngx_http_v2_add_header(h2c, header) != NGX_OK) {
  1329.             return ngx_http_v2_connection_error(h2c,
  1330.                                                 NGX_HTTP_V2_INTERNAL_ERROR);
  1331.         }

  1332.         h2c->state.index = 0;
  1333.     }

  1334.     if (h2c->state.stream == NULL) {
  1335.         return ngx_http_v2_state_header_complete(h2c, pos, end);
  1336.     }

  1337.     r = h2c->state.stream->request;
  1338.     fc = r->connection;

  1339.     /* TODO Optimization: validate headers while parsing. */
  1340.     if (ngx_http_v2_validate_header(r, header) != NGX_OK) {
  1341.         ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  1342.         goto error;
  1343.     }

  1344.     if (header->name.data[0] == ':') {
  1345.         rc = ngx_http_v2_pseudo_header(r, header);

  1346.         if (rc == NGX_OK) {
  1347.             ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  1348.                            "http2 header: \":%V: %V\"",
  1349.                            &header->name, &header->value);

  1350.             return ngx_http_v2_state_header_complete(h2c, pos, end);
  1351.         }

  1352.         if (rc == NGX_ABORT) {
  1353.             goto error;
  1354.         }

  1355.         if (rc == NGX_DECLINED) {
  1356.             ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  1357.             goto error;
  1358.         }

  1359.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
  1360.     }

  1361.     if (r->invalid_header) {
  1362.         cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);

  1363.         if (cscf->ignore_invalid_headers) {
  1364.             ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  1365.                           "client sent invalid header: \"%V\"", &header->name);

  1366.             return ngx_http_v2_state_header_complete(h2c, pos, end);
  1367.         }
  1368.     }

  1369.     if (header->name.len == cookie.len
  1370.         && ngx_memcmp(header->name.data, cookie.data, cookie.len) == 0)
  1371.     {
  1372.         if (ngx_http_v2_cookie(r, header) != NGX_OK) {
  1373.             return ngx_http_v2_connection_error(h2c,
  1374.                                                 NGX_HTTP_V2_INTERNAL_ERROR);
  1375.         }

  1376.     } else {
  1377.         h = ngx_list_push(&r->headers_in.headers);
  1378.         if (h == NULL) {
  1379.             return ngx_http_v2_connection_error(h2c,
  1380.                                                 NGX_HTTP_V2_INTERNAL_ERROR);
  1381.         }

  1382.         h->key.len = header->name.len;
  1383.         h->key.data = header->name.data;

  1384.         /*
  1385.          * TODO Optimization: precalculate hash
  1386.          * and handler for indexed headers.
  1387.          */
  1388.         h->hash = ngx_hash_key(h->key.data, h->key.len);

  1389.         h->value.len = header->value.len;
  1390.         h->value.data = header->value.data;

  1391.         h->lowcase_key = h->key.data;

  1392.         cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

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

  1395.         if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
  1396.             goto error;
  1397.         }
  1398.     }

  1399.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  1400.                    "http2 header: \"%V: %V\"",
  1401.                    &header->name, &header->value);

  1402.     return ngx_http_v2_state_header_complete(h2c, pos, end);

  1403. error:

  1404.     h2c->state.stream = NULL;

  1405.     ngx_http_run_posted_requests(fc);

  1406.     return ngx_http_v2_state_header_complete(h2c, pos, end);
  1407. }


  1408. static u_char *
  1409. ngx_http_v2_state_header_complete(ngx_http_v2_connection_t *h2c, u_char *pos,
  1410.     u_char *end)
  1411. {
  1412.     ngx_http_v2_stream_t  *stream;

  1413.     if (h2c->state.length) {
  1414.         if (end - pos > 0) {
  1415.             h2c->state.handler = ngx_http_v2_state_header_block;
  1416.             return pos;
  1417.         }

  1418.         return ngx_http_v2_state_headers_save(h2c, pos, end,
  1419.                                               ngx_http_v2_state_header_block);
  1420.     }

  1421.     if (!(h2c->state.flags & NGX_HTTP_V2_END_HEADERS_FLAG)) {
  1422.         return ngx_http_v2_handle_continuation(h2c, pos, end,
  1423.                                              ngx_http_v2_state_header_complete);
  1424.     }

  1425.     stream = h2c->state.stream;

  1426.     if (stream) {
  1427.         ngx_http_v2_run_request(stream->request);
  1428.     }

  1429.     if (!h2c->state.keep_pool) {
  1430.         ngx_destroy_pool(h2c->state.pool);
  1431.     }

  1432.     h2c->state.pool = NULL;
  1433.     h2c->state.keep_pool = 0;

  1434.     if (h2c->state.padding) {
  1435.         return ngx_http_v2_state_skip_padded(h2c, pos, end);
  1436.     }

  1437.     return ngx_http_v2_state_complete(h2c, pos, end);
  1438. }


  1439. static u_char *
  1440. ngx_http_v2_handle_continuation(ngx_http_v2_connection_t *h2c, u_char *pos,
  1441.     u_char *end, ngx_http_v2_handler_pt handler)
  1442. {
  1443.     u_char    *p;
  1444.     size_t     len, skip;
  1445.     uint32_t   head;

  1446.     len = h2c->state.length;

  1447.     if (h2c->state.padding && (size_t) (end - pos) > len) {
  1448.         skip = ngx_min(h2c->state.padding, (end - pos) - len);

  1449.         h2c->state.padding -= skip;

  1450.         p = pos;
  1451.         pos += skip;
  1452.         ngx_memmove(pos, p, len);
  1453.     }

  1454.     if ((size_t) (end - pos) < len + NGX_HTTP_V2_FRAME_HEADER_SIZE) {
  1455.         return ngx_http_v2_state_headers_save(h2c, pos, end, handler);
  1456.     }

  1457.     p = pos + len;

  1458.     head = ngx_http_v2_parse_uint32(p);

  1459.     if (ngx_http_v2_parse_type(head) != NGX_HTTP_V2_CONTINUATION_FRAME) {
  1460.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1461.              "client sent inappropriate frame while CONTINUATION was expected");

  1462.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
  1463.     }

  1464.     h2c->state.flags |= p[4];

  1465.     if (h2c->state.sid != ngx_http_v2_parse_sid(&p[5])) {
  1466.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1467.                     "client sent CONTINUATION frame with incorrect identifier");

  1468.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
  1469.     }

  1470.     p = pos;
  1471.     pos += NGX_HTTP_V2_FRAME_HEADER_SIZE;

  1472.     ngx_memcpy(pos, p, len);

  1473.     len = ngx_http_v2_parse_length(head);

  1474.     h2c->state.length += len;

  1475.     if (h2c->state.stream) {
  1476.         h2c->state.stream->request->request_length += len;
  1477.     }

  1478.     h2c->state.handler = handler;
  1479.     return pos;
  1480. }


  1481. static u_char *
  1482. ngx_http_v2_state_priority(ngx_http_v2_connection_t *h2c, u_char *pos,
  1483.     u_char *end)
  1484. {
  1485.     ngx_uint_t           depend, dependency, excl, weight;
  1486.     ngx_http_v2_node_t  *node;

  1487.     if (h2c->state.length != NGX_HTTP_V2_PRIORITY_SIZE) {
  1488.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1489.                       "client sent PRIORITY frame with incorrect length %uz",
  1490.                       h2c->state.length);

  1491.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
  1492.     }

  1493.     if (--h2c->priority_limit == 0) {
  1494.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1495.                       "client sent too many PRIORITY frames");

  1496.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_ENHANCE_YOUR_CALM);
  1497.     }

  1498.     if (end - pos < NGX_HTTP_V2_PRIORITY_SIZE) {
  1499.         return ngx_http_v2_state_save(h2c, pos, end,
  1500.                                       ngx_http_v2_state_priority);
  1501.     }

  1502.     dependency = ngx_http_v2_parse_uint32(pos);

  1503.     depend = dependency & 0x7fffffff;
  1504.     excl = dependency >> 31;
  1505.     weight = pos[4] + 1;

  1506.     pos += NGX_HTTP_V2_PRIORITY_SIZE;

  1507.     ngx_log_debug4(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  1508.                    "http2 PRIORITY frame sid:%ui "
  1509.                    "depends on %ui excl:%ui weight:%ui",
  1510.                    h2c->state.sid, depend, excl, weight);

  1511.     if (h2c->state.sid == 0) {
  1512.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1513.                       "client sent PRIORITY frame with incorrect identifier");

  1514.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
  1515.     }

  1516.     if (depend == h2c->state.sid) {
  1517.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1518.                       "client sent PRIORITY frame for stream %ui "
  1519.                       "with incorrect dependency", h2c->state.sid);

  1520.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
  1521.     }

  1522.     node = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 1);

  1523.     if (node == NULL) {
  1524.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
  1525.     }

  1526.     node->weight = weight;

  1527.     if (node->stream == NULL) {
  1528.         if (node->parent == NULL) {
  1529.             h2c->closed_nodes++;

  1530.         } else {
  1531.             ngx_queue_remove(&node->reuse);
  1532.         }

  1533.         ngx_queue_insert_tail(&h2c->closed, &node->reuse);
  1534.     }

  1535.     ngx_http_v2_set_dependency(h2c, node, depend, excl);

  1536.     return ngx_http_v2_state_complete(h2c, pos, end);
  1537. }


  1538. static u_char *
  1539. ngx_http_v2_state_rst_stream(ngx_http_v2_connection_t *h2c, u_char *pos,
  1540.     u_char *end)
  1541. {
  1542.     ngx_uint_t             status;
  1543.     ngx_event_t           *ev;
  1544.     ngx_connection_t      *fc;
  1545.     ngx_http_v2_node_t    *node;
  1546.     ngx_http_v2_stream_t  *stream;

  1547.     if (h2c->state.length != NGX_HTTP_V2_RST_STREAM_SIZE) {
  1548.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1549.                       "client sent RST_STREAM frame with incorrect length %uz",
  1550.                       h2c->state.length);

  1551.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
  1552.     }

  1553.     if (end - pos < NGX_HTTP_V2_RST_STREAM_SIZE) {
  1554.         return ngx_http_v2_state_save(h2c, pos, end,
  1555.                                       ngx_http_v2_state_rst_stream);
  1556.     }

  1557.     status = ngx_http_v2_parse_uint32(pos);

  1558.     pos += NGX_HTTP_V2_RST_STREAM_SIZE;

  1559.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  1560.                    "http2 RST_STREAM frame, sid:%ui status:%ui",
  1561.                    h2c->state.sid, status);

  1562.     if (h2c->state.sid == 0) {
  1563.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1564.                       "client sent RST_STREAM frame with incorrect identifier");

  1565.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
  1566.     }

  1567.     node = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 0);

  1568.     if (node == NULL || node->stream == NULL) {
  1569.         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  1570.                        "unknown http2 stream");

  1571.         return ngx_http_v2_state_complete(h2c, pos, end);
  1572.     }

  1573.     stream = node->stream;

  1574.     stream->in_closed = 1;
  1575.     stream->out_closed = 1;

  1576.     fc = stream->request->connection;
  1577.     fc->error = 1;

  1578.     switch (status) {

  1579.     case NGX_HTTP_V2_CANCEL:
  1580.         ngx_log_error(NGX_LOG_INFO, fc->log, 0,
  1581.                       "client canceled stream %ui", h2c->state.sid);
  1582.         break;

  1583.     case NGX_HTTP_V2_INTERNAL_ERROR:
  1584.         ngx_log_error(NGX_LOG_INFO, fc->log, 0,
  1585.                       "client terminated stream %ui due to internal error",
  1586.                       h2c->state.sid);
  1587.         break;

  1588.     default:
  1589.         ngx_log_error(NGX_LOG_INFO, fc->log, 0,
  1590.                       "client terminated stream %ui with status %ui",
  1591.                       h2c->state.sid, status);
  1592.         break;
  1593.     }

  1594.     ev = fc->read;
  1595.     ev->handler(ev);

  1596.     return ngx_http_v2_state_complete(h2c, pos, end);
  1597. }


  1598. static u_char *
  1599. ngx_http_v2_state_settings(ngx_http_v2_connection_t *h2c, u_char *pos,
  1600.     u_char *end)
  1601. {
  1602.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  1603.                    "http2 SETTINGS frame");

  1604.     if (h2c->state.sid) {
  1605.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1606.                       "client sent SETTINGS frame with incorrect identifier");

  1607.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
  1608.     }

  1609.     if (h2c->state.flags == NGX_HTTP_V2_ACK_FLAG) {

  1610.         if (h2c->state.length != 0) {
  1611.             ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1612.                           "client sent SETTINGS frame with the ACK flag "
  1613.                           "and nonzero length");

  1614.             return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
  1615.         }

  1616.         h2c->settings_ack = 1;

  1617.         return ngx_http_v2_state_complete(h2c, pos, end);
  1618.     }

  1619.     if (h2c->state.length % NGX_HTTP_V2_SETTINGS_PARAM_SIZE) {
  1620.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1621.                       "client sent SETTINGS frame with incorrect length %uz",
  1622.                       h2c->state.length);

  1623.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
  1624.     }

  1625.     return ngx_http_v2_state_settings_params(h2c, pos, end);
  1626. }


  1627. static u_char *
  1628. ngx_http_v2_state_settings_params(ngx_http_v2_connection_t *h2c, u_char *pos,
  1629.     u_char *end)
  1630. {
  1631.     ssize_t                   window_delta;
  1632.     ngx_uint_t                id, value;
  1633.     ngx_http_v2_out_frame_t  *frame;

  1634.     window_delta = 0;

  1635.     while (h2c->state.length) {
  1636.         if (end - pos < NGX_HTTP_V2_SETTINGS_PARAM_SIZE) {
  1637.             return ngx_http_v2_state_save(h2c, pos, end,
  1638.                                           ngx_http_v2_state_settings_params);
  1639.         }

  1640.         h2c->state.length -= NGX_HTTP_V2_SETTINGS_PARAM_SIZE;

  1641.         id = ngx_http_v2_parse_uint16(pos);
  1642.         value = ngx_http_v2_parse_uint32(&pos[2]);

  1643.         ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  1644.                        "http2 setting %ui:%ui", id, value);

  1645.         switch (id) {

  1646.         case NGX_HTTP_V2_INIT_WINDOW_SIZE_SETTING:

  1647.             if (value > NGX_HTTP_V2_MAX_WINDOW) {
  1648.                 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1649.                               "client sent SETTINGS frame with incorrect "
  1650.                               "INITIAL_WINDOW_SIZE value %ui", value);

  1651.                 return ngx_http_v2_connection_error(h2c,
  1652.                                                   NGX_HTTP_V2_FLOW_CTRL_ERROR);
  1653.             }

  1654.             window_delta = value - h2c->init_window;
  1655.             break;

  1656.         case NGX_HTTP_V2_MAX_FRAME_SIZE_SETTING:

  1657.             if (value > NGX_HTTP_V2_MAX_FRAME_SIZE
  1658.                 || value < NGX_HTTP_V2_DEFAULT_FRAME_SIZE)
  1659.             {
  1660.                 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1661.                               "client sent SETTINGS frame with incorrect "
  1662.                               "MAX_FRAME_SIZE value %ui", value);

  1663.                 return ngx_http_v2_connection_error(h2c,
  1664.                                                     NGX_HTTP_V2_PROTOCOL_ERROR);
  1665.             }

  1666.             h2c->frame_size = value;
  1667.             break;

  1668.         case NGX_HTTP_V2_ENABLE_PUSH_SETTING:

  1669.             if (value > 1) {
  1670.                 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1671.                               "client sent SETTINGS frame with incorrect "
  1672.                               "ENABLE_PUSH value %ui", value);

  1673.                 return ngx_http_v2_connection_error(h2c,
  1674.                                                     NGX_HTTP_V2_PROTOCOL_ERROR);
  1675.             }

  1676.             break;

  1677.         case NGX_HTTP_V2_HEADER_TABLE_SIZE_SETTING:

  1678.             h2c->table_update = 1;
  1679.             break;

  1680.         default:
  1681.             break;
  1682.         }

  1683.         pos += NGX_HTTP_V2_SETTINGS_PARAM_SIZE;
  1684.     }

  1685.     frame = ngx_http_v2_get_frame(h2c, NGX_HTTP_V2_SETTINGS_ACK_SIZE,
  1686.                                   NGX_HTTP_V2_SETTINGS_FRAME,
  1687.                                   NGX_HTTP_V2_ACK_FLAG, 0);
  1688.     if (frame == NULL) {
  1689.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
  1690.     }

  1691.     ngx_http_v2_queue_ordered_frame(h2c, frame);

  1692.     if (window_delta) {
  1693.         h2c->init_window += window_delta;

  1694.         if (ngx_http_v2_adjust_windows(h2c, window_delta) != NGX_OK) {
  1695.             return ngx_http_v2_connection_error(h2c,
  1696.                                                 NGX_HTTP_V2_INTERNAL_ERROR);
  1697.         }
  1698.     }

  1699.     return ngx_http_v2_state_complete(h2c, pos, end);
  1700. }


  1701. static u_char *
  1702. ngx_http_v2_state_push_promise(ngx_http_v2_connection_t *h2c, u_char *pos,
  1703.     u_char *end)
  1704. {
  1705.     ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1706.                   "client sent PUSH_PROMISE frame");

  1707.     return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
  1708. }


  1709. static u_char *
  1710. ngx_http_v2_state_ping(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end)
  1711. {
  1712.     ngx_buf_t                *buf;
  1713.     ngx_http_v2_out_frame_t  *frame;

  1714.     if (h2c->state.length != NGX_HTTP_V2_PING_SIZE) {
  1715.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1716.                       "client sent PING frame with incorrect length %uz",
  1717.                       h2c->state.length);

  1718.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
  1719.     }

  1720.     if (end - pos < NGX_HTTP_V2_PING_SIZE) {
  1721.         return ngx_http_v2_state_save(h2c, pos, end, ngx_http_v2_state_ping);
  1722.     }

  1723.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  1724.                    "http2 PING frame");

  1725.     if (h2c->state.sid) {
  1726.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1727.                       "client sent PING frame with incorrect identifier");

  1728.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
  1729.     }

  1730.     if (h2c->state.flags & NGX_HTTP_V2_ACK_FLAG) {
  1731.         return ngx_http_v2_state_skip(h2c, pos, end);
  1732.     }

  1733.     frame = ngx_http_v2_get_frame(h2c, NGX_HTTP_V2_PING_SIZE,
  1734.                                   NGX_HTTP_V2_PING_FRAME,
  1735.                                   NGX_HTTP_V2_ACK_FLAG, 0);
  1736.     if (frame == NULL) {
  1737.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
  1738.     }

  1739.     buf = frame->first->buf;

  1740.     buf->last = ngx_cpymem(buf->last, pos, NGX_HTTP_V2_PING_SIZE);

  1741.     ngx_http_v2_queue_blocked_frame(h2c, frame);

  1742.     return ngx_http_v2_state_complete(h2c, pos + NGX_HTTP_V2_PING_SIZE, end);
  1743. }


  1744. static u_char *
  1745. ngx_http_v2_state_goaway(ngx_http_v2_connection_t *h2c, u_char *pos,
  1746.     u_char *end)
  1747. {
  1748. #if (NGX_DEBUG)
  1749.     ngx_uint_t  last_sid, error;
  1750. #endif

  1751.     if (h2c->state.length < NGX_HTTP_V2_GOAWAY_SIZE) {
  1752.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1753.                       "client sent GOAWAY frame "
  1754.                       "with incorrect length %uz", h2c->state.length);

  1755.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
  1756.     }

  1757.     if (end - pos < NGX_HTTP_V2_GOAWAY_SIZE) {
  1758.         return ngx_http_v2_state_save(h2c, pos, end, ngx_http_v2_state_goaway);
  1759.     }

  1760.     if (h2c->state.sid) {
  1761.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1762.                       "client sent GOAWAY frame with incorrect identifier");

  1763.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
  1764.     }

  1765. #if (NGX_DEBUG)
  1766.     h2c->state.length -= NGX_HTTP_V2_GOAWAY_SIZE;

  1767.     last_sid = ngx_http_v2_parse_sid(pos);
  1768.     error = ngx_http_v2_parse_uint32(&pos[4]);

  1769.     pos += NGX_HTTP_V2_GOAWAY_SIZE;

  1770.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  1771.                    "http2 GOAWAY frame: last sid %ui, error %ui",
  1772.                    last_sid, error);
  1773. #endif

  1774.     return ngx_http_v2_state_skip(h2c, pos, end);
  1775. }


  1776. static u_char *
  1777. ngx_http_v2_state_window_update(ngx_http_v2_connection_t *h2c, u_char *pos,
  1778.     u_char *end)
  1779. {
  1780.     size_t                 window;
  1781.     ngx_event_t           *wev;
  1782.     ngx_queue_t           *q;
  1783.     ngx_http_v2_node_t    *node;
  1784.     ngx_http_v2_stream_t  *stream;

  1785.     if (h2c->state.length != NGX_HTTP_V2_WINDOW_UPDATE_SIZE) {
  1786.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1787.                       "client sent WINDOW_UPDATE frame "
  1788.                       "with incorrect length %uz", h2c->state.length);

  1789.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
  1790.     }

  1791.     if (end - pos < NGX_HTTP_V2_WINDOW_UPDATE_SIZE) {
  1792.         return ngx_http_v2_state_save(h2c, pos, end,
  1793.                                       ngx_http_v2_state_window_update);
  1794.     }

  1795.     window = ngx_http_v2_parse_window(pos);

  1796.     pos += NGX_HTTP_V2_WINDOW_UPDATE_SIZE;

  1797.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  1798.                    "http2 WINDOW_UPDATE frame sid:%ui window:%uz",
  1799.                    h2c->state.sid, window);

  1800.     if (window == 0) {
  1801.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1802.                       "client sent WINDOW_UPDATE frame "
  1803.                       "with incorrect window increment 0");

  1804.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
  1805.     }

  1806.     if (h2c->state.sid) {
  1807.         node = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 0);

  1808.         if (node == NULL || node->stream == NULL) {
  1809.             ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  1810.                            "unknown http2 stream");

  1811.             return ngx_http_v2_state_complete(h2c, pos, end);
  1812.         }

  1813.         stream = node->stream;

  1814.         if (window > (size_t) (NGX_HTTP_V2_MAX_WINDOW - stream->send_window)) {

  1815.             ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1816.                           "client violated flow control for stream %ui: "
  1817.                           "received WINDOW_UPDATE frame "
  1818.                           "with window increment %uz "
  1819.                           "not allowed for window %z",
  1820.                           h2c->state.sid, window, stream->send_window);

  1821.             if (ngx_http_v2_terminate_stream(h2c, stream,
  1822.                                              NGX_HTTP_V2_FLOW_CTRL_ERROR)
  1823.                 == NGX_ERROR)
  1824.             {
  1825.                 return ngx_http_v2_connection_error(h2c,
  1826.                                                     NGX_HTTP_V2_INTERNAL_ERROR);
  1827.             }

  1828.             return ngx_http_v2_state_complete(h2c, pos, end);
  1829.         }

  1830.         stream->send_window += window;

  1831.         if (stream->exhausted) {
  1832.             stream->exhausted = 0;

  1833.             wev = stream->request->connection->write;

  1834.             wev->active = 0;
  1835.             wev->ready = 1;

  1836.             if (!wev->delayed) {
  1837.                 wev->handler(wev);
  1838.             }
  1839.         }

  1840.         return ngx_http_v2_state_complete(h2c, pos, end);
  1841.     }

  1842.     if (window > NGX_HTTP_V2_MAX_WINDOW - h2c->send_window) {
  1843.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1844.                       "client violated connection flow control: "
  1845.                       "received WINDOW_UPDATE frame "
  1846.                       "with window increment %uz "
  1847.                       "not allowed for window %uz",
  1848.                       window, h2c->send_window);

  1849.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_FLOW_CTRL_ERROR);
  1850.     }

  1851.     h2c->send_window += window;

  1852.     while (!ngx_queue_empty(&h2c->waiting)) {
  1853.         q = ngx_queue_head(&h2c->waiting);

  1854.         ngx_queue_remove(q);

  1855.         stream = ngx_queue_data(q, ngx_http_v2_stream_t, queue);

  1856.         stream->waiting = 0;

  1857.         wev = stream->request->connection->write;

  1858.         wev->active = 0;
  1859.         wev->ready = 1;

  1860.         if (!wev->delayed) {
  1861.             wev->handler(wev);

  1862.             if (h2c->send_window == 0) {
  1863.                 break;
  1864.             }
  1865.         }
  1866.     }

  1867.     return ngx_http_v2_state_complete(h2c, pos, end);
  1868. }


  1869. static u_char *
  1870. ngx_http_v2_state_continuation(ngx_http_v2_connection_t *h2c, u_char *pos,
  1871.     u_char *end)
  1872. {
  1873.     ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  1874.                   "client sent unexpected CONTINUATION frame");

  1875.     return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
  1876. }


  1877. static u_char *
  1878. ngx_http_v2_state_complete(ngx_http_v2_connection_t *h2c, u_char *pos,
  1879.     u_char *end)
  1880. {
  1881.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  1882.                    "http2 frame complete pos:%p end:%p", pos, end);

  1883.     if (pos > end) {
  1884.         ngx_log_error(NGX_LOG_ALERT, h2c->connection->log, 0,
  1885.                       "receive buffer overrun");

  1886.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
  1887.     }

  1888.     h2c->state.stream = NULL;
  1889.     h2c->state.handler = ngx_http_v2_state_head;

  1890.     return pos;
  1891. }


  1892. static u_char *
  1893. ngx_http_v2_state_skip_padded(ngx_http_v2_connection_t *h2c, u_char *pos,
  1894.     u_char *end)
  1895. {
  1896.     h2c->state.length += h2c->state.padding;
  1897.     h2c->state.padding = 0;

  1898.     return ngx_http_v2_state_skip(h2c, pos, end);
  1899. }


  1900. static u_char *
  1901. ngx_http_v2_state_skip(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end)
  1902. {
  1903.     size_t  size;

  1904.     size = end - pos;

  1905.     if (size < h2c->state.length) {
  1906.         ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  1907.                        "http2 frame skip %uz of %uz", size, h2c->state.length);

  1908.         h2c->state.length -= size;
  1909.         return ngx_http_v2_state_save(h2c, end, end, ngx_http_v2_state_skip);
  1910.     }

  1911.     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  1912.                    "http2 frame skip %uz", h2c->state.length);

  1913.     return ngx_http_v2_state_complete(h2c, pos + h2c->state.length, end);
  1914. }


  1915. static u_char *
  1916. ngx_http_v2_state_save(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end,
  1917.     ngx_http_v2_handler_pt handler)
  1918. {
  1919.     size_t  size;

  1920.     ngx_log_debug3(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  1921.                    "http2 frame state save pos:%p end:%p handler:%p",
  1922.                    pos, end, handler);

  1923.     size = end - pos;

  1924.     if (size > NGX_HTTP_V2_STATE_BUFFER_SIZE) {
  1925.         ngx_log_error(NGX_LOG_ALERT, h2c->connection->log, 0,
  1926.                       "state buffer overflow: %uz bytes required", size);

  1927.         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
  1928.     }

  1929.     ngx_memcpy(h2c->state.buffer, pos, size);

  1930.     h2c->state.buffer_used = size;
  1931.     h2c->state.handler = handler;
  1932.     h2c->state.incomplete = 1;

  1933.     return end;
  1934. }


  1935. static u_char *
  1936. ngx_http_v2_state_headers_save(ngx_http_v2_connection_t *h2c, u_char *pos,
  1937.     u_char *end, ngx_http_v2_handler_pt handler)
  1938. {
  1939.     ngx_event_t               *rev;
  1940.     ngx_http_request_t        *r;
  1941.     ngx_http_core_srv_conf_t  *cscf;

  1942.     if (h2c->state.stream) {
  1943.         r = h2c->state.stream->request;
  1944.         rev = r->connection->read;

  1945.         if (!rev->timer_set) {
  1946.             cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
  1947.             ngx_add_timer(rev, cscf->client_header_timeout);
  1948.         }
  1949.     }

  1950.     return ngx_http_v2_state_save(h2c, pos, end, handler);
  1951. }


  1952. static u_char *
  1953. ngx_http_v2_connection_error(ngx_http_v2_connection_t *h2c,
  1954.     ngx_uint_t err)
  1955. {
  1956.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  1957.                    "http2 state connection error");

  1958.     ngx_http_v2_finalize_connection(h2c, err);

  1959.     return NULL;
  1960. }


  1961. static ngx_int_t
  1962. ngx_http_v2_parse_int(ngx_http_v2_connection_t *h2c, u_char **pos, u_char *end,
  1963.     ngx_uint_t prefix)
  1964. {
  1965.     u_char      *start, *p;
  1966.     ngx_uint_t   value, octet, shift;

  1967.     start = *pos;
  1968.     p = start;

  1969.     value = *p++ & prefix;

  1970.     if (value != prefix) {
  1971.         if (h2c->state.length == 0) {
  1972.             return NGX_ERROR;
  1973.         }

  1974.         h2c->state.length--;

  1975.         *pos = p;
  1976.         return value;
  1977.     }

  1978.     if (end - start > NGX_HTTP_V2_INT_OCTETS) {
  1979.         end = start + NGX_HTTP_V2_INT_OCTETS;
  1980.     }

  1981.     for (shift = 0; p != end; shift += 7) {
  1982.         octet = *p++;

  1983.         value += (octet & 0x7f) << shift;

  1984.         if (octet < 128) {
  1985.             if ((size_t) (p - start) > h2c->state.length) {
  1986.                 return NGX_ERROR;
  1987.             }

  1988.             h2c->state.length -= p - start;

  1989.             *pos = p;
  1990.             return value;
  1991.         }
  1992.     }

  1993.     if ((size_t) (end - start) >= h2c->state.length) {
  1994.         return NGX_ERROR;
  1995.     }

  1996.     if (end == start + NGX_HTTP_V2_INT_OCTETS) {
  1997.         return NGX_DECLINED;
  1998.     }

  1999.     return NGX_AGAIN;
  2000. }


  2001. static ngx_int_t
  2002. ngx_http_v2_send_settings(ngx_http_v2_connection_t *h2c)
  2003. {
  2004.     size_t                    len;
  2005.     ngx_buf_t                *buf;
  2006.     ngx_chain_t              *cl;
  2007.     ngx_http_v2_srv_conf_t   *h2scf;
  2008.     ngx_http_v2_out_frame_t  *frame;

  2009.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  2010.                    "http2 send SETTINGS frame");

  2011.     frame = ngx_palloc(h2c->pool, sizeof(ngx_http_v2_out_frame_t));
  2012.     if (frame == NULL) {
  2013.         return NGX_ERROR;
  2014.     }

  2015.     cl = ngx_alloc_chain_link(h2c->pool);
  2016.     if (cl == NULL) {
  2017.         return NGX_ERROR;
  2018.     }

  2019.     len = NGX_HTTP_V2_SETTINGS_PARAM_SIZE * 3;

  2020.     buf = ngx_create_temp_buf(h2c->pool, NGX_HTTP_V2_FRAME_HEADER_SIZE + len);
  2021.     if (buf == NULL) {
  2022.         return NGX_ERROR;
  2023.     }

  2024.     buf->last_buf = 1;

  2025.     cl->buf = buf;
  2026.     cl->next = NULL;

  2027.     frame->first = cl;
  2028.     frame->last = cl;
  2029.     frame->handler = ngx_http_v2_settings_frame_handler;
  2030.     frame->stream = NULL;
  2031. #if (NGX_DEBUG)
  2032.     frame->length = len;
  2033. #endif
  2034.     frame->blocked = 0;

  2035.     buf->last = ngx_http_v2_write_len_and_type(buf->last, len,
  2036.                                                NGX_HTTP_V2_SETTINGS_FRAME);

  2037.     *buf->last++ = NGX_HTTP_V2_NO_FLAG;

  2038.     buf->last = ngx_http_v2_write_sid(buf->last, 0);

  2039.     h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
  2040.                                          ngx_http_v2_module);

  2041.     buf->last = ngx_http_v2_write_uint16(buf->last,
  2042.                                          NGX_HTTP_V2_MAX_STREAMS_SETTING);
  2043.     buf->last = ngx_http_v2_write_uint32(buf->last,
  2044.                                          h2scf->concurrent_streams);

  2045.     buf->last = ngx_http_v2_write_uint16(buf->last,
  2046.                                          NGX_HTTP_V2_INIT_WINDOW_SIZE_SETTING);
  2047.     buf->last = ngx_http_v2_write_uint32(buf->last, h2scf->preread_size);

  2048.     buf->last = ngx_http_v2_write_uint16(buf->last,
  2049.                                          NGX_HTTP_V2_MAX_FRAME_SIZE_SETTING);
  2050.     buf->last = ngx_http_v2_write_uint32(buf->last,
  2051.                                          NGX_HTTP_V2_MAX_FRAME_SIZE);

  2052.     ngx_http_v2_queue_blocked_frame(h2c, frame);

  2053.     return NGX_OK;
  2054. }


  2055. static ngx_int_t
  2056. ngx_http_v2_settings_frame_handler(ngx_http_v2_connection_t *h2c,
  2057.     ngx_http_v2_out_frame_t *frame)
  2058. {
  2059.     ngx_buf_t  *buf;

  2060.     buf = frame->first->buf;

  2061.     if (buf->pos != buf->last) {
  2062.         return NGX_AGAIN;
  2063.     }

  2064.     ngx_free_chain(h2c->pool, frame->first);

  2065.     return NGX_OK;
  2066. }


  2067. static ngx_int_t
  2068. ngx_http_v2_send_window_update(ngx_http_v2_connection_t *h2c, ngx_uint_t sid,
  2069.     size_t window)
  2070. {
  2071.     ngx_buf_t                *buf;
  2072.     ngx_http_v2_out_frame_t  *frame;

  2073.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  2074.                    "http2 send WINDOW_UPDATE frame sid:%ui, window:%uz",
  2075.                    sid, window);

  2076.     frame = ngx_http_v2_get_frame(h2c, NGX_HTTP_V2_WINDOW_UPDATE_SIZE,
  2077.                                   NGX_HTTP_V2_WINDOW_UPDATE_FRAME,
  2078.                                   NGX_HTTP_V2_NO_FLAG, sid);
  2079.     if (frame == NULL) {
  2080.         return NGX_ERROR;
  2081.     }

  2082.     buf = frame->first->buf;

  2083.     buf->last = ngx_http_v2_write_uint32(buf->last, window);

  2084.     ngx_http_v2_queue_blocked_frame(h2c, frame);

  2085.     return NGX_OK;
  2086. }


  2087. static ngx_int_t
  2088. ngx_http_v2_send_rst_stream(ngx_http_v2_connection_t *h2c, ngx_uint_t sid,
  2089.     ngx_uint_t status)
  2090. {
  2091.     ngx_buf_t                *buf;
  2092.     ngx_http_v2_out_frame_t  *frame;

  2093.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  2094.                    "http2 send RST_STREAM frame sid:%ui, status:%ui",
  2095.                    sid, status);

  2096.     frame = ngx_http_v2_get_frame(h2c, NGX_HTTP_V2_RST_STREAM_SIZE,
  2097.                                   NGX_HTTP_V2_RST_STREAM_FRAME,
  2098.                                   NGX_HTTP_V2_NO_FLAG, sid);
  2099.     if (frame == NULL) {
  2100.         return NGX_ERROR;
  2101.     }

  2102.     buf = frame->first->buf;

  2103.     buf->last = ngx_http_v2_write_uint32(buf->last, status);

  2104.     ngx_http_v2_queue_blocked_frame(h2c, frame);

  2105.     return NGX_OK;
  2106. }


  2107. static ngx_int_t
  2108. ngx_http_v2_send_goaway(ngx_http_v2_connection_t *h2c, ngx_uint_t status)
  2109. {
  2110.     ngx_buf_t                *buf;
  2111.     ngx_http_v2_out_frame_t  *frame;

  2112.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  2113.                    "http2 send GOAWAY frame: last sid %ui, error %ui",
  2114.                    h2c->last_sid, status);

  2115.     frame = ngx_http_v2_get_frame(h2c, NGX_HTTP_V2_GOAWAY_SIZE,
  2116.                                   NGX_HTTP_V2_GOAWAY_FRAME,
  2117.                                   NGX_HTTP_V2_NO_FLAG, 0);
  2118.     if (frame == NULL) {
  2119.         return NGX_ERROR;
  2120.     }

  2121.     buf = frame->first->buf;

  2122.     buf->last = ngx_http_v2_write_sid(buf->last, h2c->last_sid);
  2123.     buf->last = ngx_http_v2_write_uint32(buf->last, status);

  2124.     ngx_http_v2_queue_blocked_frame(h2c, frame);

  2125.     return NGX_OK;
  2126. }


  2127. static ngx_http_v2_out_frame_t *
  2128. ngx_http_v2_get_frame(ngx_http_v2_connection_t *h2c, size_t length,
  2129.     ngx_uint_t type, u_char flags, ngx_uint_t sid)
  2130. {
  2131.     ngx_buf_t                *buf;
  2132.     ngx_pool_t               *pool;
  2133.     ngx_http_v2_out_frame_t  *frame;

  2134.     frame = h2c->free_frames;

  2135.     if (frame) {
  2136.         h2c->free_frames = frame->next;

  2137.         buf = frame->first->buf;
  2138.         buf->pos = buf->start;

  2139.         frame->blocked = 0;

  2140.     } else if (h2c->frames < 10000) {
  2141.         pool = h2c->pool ? h2c->pool : h2c->connection->pool;

  2142.         frame = ngx_pcalloc(pool, sizeof(ngx_http_v2_out_frame_t));
  2143.         if (frame == NULL) {
  2144.             return NULL;
  2145.         }

  2146.         frame->first = ngx_alloc_chain_link(pool);
  2147.         if (frame->first == NULL) {
  2148.             return NULL;
  2149.         }

  2150.         buf = ngx_create_temp_buf(pool, NGX_HTTP_V2_FRAME_BUFFER_SIZE);
  2151.         if (buf == NULL) {
  2152.             return NULL;
  2153.         }

  2154.         buf->last_buf = 1;

  2155.         frame->first->buf = buf;
  2156.         frame->last = frame->first;

  2157.         frame->handler = ngx_http_v2_frame_handler;

  2158.         h2c->frames++;

  2159.     } else {
  2160.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  2161.                       "http2 flood detected");

  2162.         h2c->connection->error = 1;
  2163.         return NULL;
  2164.     }

  2165. #if (NGX_DEBUG)
  2166.     if (length > NGX_HTTP_V2_FRAME_BUFFER_SIZE - NGX_HTTP_V2_FRAME_HEADER_SIZE)
  2167.     {
  2168.         ngx_log_error(NGX_LOG_ALERT, h2c->connection->log, 0,
  2169.                       "requested control frame is too large: %uz", length);
  2170.         return NULL;
  2171.     }
  2172. #endif

  2173.     frame->length = length;

  2174.     buf->last = ngx_http_v2_write_len_and_type(buf->pos, length, type);

  2175.     *buf->last++ = flags;

  2176.     buf->last = ngx_http_v2_write_sid(buf->last, sid);

  2177.     return frame;
  2178. }


  2179. static ngx_int_t
  2180. ngx_http_v2_frame_handler(ngx_http_v2_connection_t *h2c,
  2181.     ngx_http_v2_out_frame_t *frame)
  2182. {
  2183.     ngx_buf_t  *buf;

  2184.     buf = frame->first->buf;

  2185.     if (buf->pos != buf->last) {
  2186.         return NGX_AGAIN;
  2187.     }

  2188.     frame->next = h2c->free_frames;
  2189.     h2c->free_frames = frame;

  2190.     h2c->total_bytes += NGX_HTTP_V2_FRAME_HEADER_SIZE + frame->length;

  2191.     return NGX_OK;
  2192. }


  2193. static ngx_http_v2_stream_t *
  2194. ngx_http_v2_create_stream(ngx_http_v2_connection_t *h2c)
  2195. {
  2196.     ngx_log_t                 *log;
  2197.     ngx_event_t               *rev, *wev;
  2198.     ngx_connection_t          *fc;
  2199.     ngx_http_log_ctx_t        *ctx;
  2200.     ngx_http_request_t        *r;
  2201.     ngx_http_v2_stream_t      *stream;
  2202.     ngx_http_v2_srv_conf_t    *h2scf;
  2203.     ngx_http_core_srv_conf_t  *cscf;

  2204.     fc = h2c->free_fake_connections;

  2205.     if (fc) {
  2206.         h2c->free_fake_connections = fc->data;

  2207.         rev = fc->read;
  2208.         wev = fc->write;
  2209.         log = fc->log;
  2210.         ctx = log->data;

  2211.     } else {
  2212.         fc = ngx_palloc(h2c->pool, sizeof(ngx_connection_t));
  2213.         if (fc == NULL) {
  2214.             return NULL;
  2215.         }

  2216.         rev = ngx_palloc(h2c->pool, sizeof(ngx_event_t));
  2217.         if (rev == NULL) {
  2218.             return NULL;
  2219.         }

  2220.         wev = ngx_palloc(h2c->pool, sizeof(ngx_event_t));
  2221.         if (wev == NULL) {
  2222.             return NULL;
  2223.         }

  2224.         log = ngx_palloc(h2c->pool, sizeof(ngx_log_t));
  2225.         if (log == NULL) {
  2226.             return NULL;
  2227.         }

  2228.         ctx = ngx_palloc(h2c->pool, sizeof(ngx_http_log_ctx_t));
  2229.         if (ctx == NULL) {
  2230.             return NULL;
  2231.         }

  2232.         ctx->connection = fc;
  2233.         ctx->request = NULL;
  2234.         ctx->current_request = NULL;
  2235.     }

  2236.     ngx_memcpy(log, h2c->connection->log, sizeof(ngx_log_t));

  2237.     log->data = ctx;
  2238.     log->action = "reading client request headers";

  2239.     ngx_memzero(rev, sizeof(ngx_event_t));

  2240.     rev->data = fc;
  2241.     rev->ready = 1;
  2242.     rev->handler = ngx_http_v2_close_stream_handler;
  2243.     rev->log = log;

  2244.     ngx_memcpy(wev, rev, sizeof(ngx_event_t));

  2245.     wev->write = 1;

  2246.     ngx_memcpy(fc, h2c->connection, sizeof(ngx_connection_t));

  2247.     fc->data = h2c->http_connection;
  2248.     fc->read = rev;
  2249.     fc->write = wev;
  2250.     fc->sent = 0;
  2251.     fc->log = log;
  2252.     fc->buffered = 0;
  2253.     fc->sndlowat = 1;
  2254.     fc->tcp_nodelay = NGX_TCP_NODELAY_DISABLED;

  2255.     r = ngx_http_create_request(fc);
  2256.     if (r == NULL) {
  2257.         return NULL;
  2258.     }

  2259.     ngx_str_set(&r->http_protocol, "HTTP/2.0");

  2260.     r->http_version = NGX_HTTP_VERSION_20;
  2261.     r->valid_location = 1;

  2262.     fc->data = r;
  2263.     h2c->connection->requests++;

  2264.     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);

  2265.     r->header_in = ngx_create_temp_buf(r->pool,
  2266.                                        cscf->client_header_buffer_size);
  2267.     if (r->header_in == NULL) {
  2268.         ngx_http_free_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  2269.         return NULL;
  2270.     }

  2271.     if (ngx_list_init(&r->headers_in.headers, r->pool, 20,
  2272.                       sizeof(ngx_table_elt_t))
  2273.         != NGX_OK)
  2274.     {
  2275.         ngx_http_free_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  2276.         return NULL;
  2277.     }

  2278.     r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE;

  2279.     stream = ngx_pcalloc(r->pool, sizeof(ngx_http_v2_stream_t));
  2280.     if (stream == NULL) {
  2281.         ngx_http_free_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  2282.         return NULL;
  2283.     }

  2284.     r->stream = stream;

  2285.     stream->request = r;
  2286.     stream->connection = h2c;

  2287.     h2scf = ngx_http_get_module_srv_conf(r, ngx_http_v2_module);

  2288.     stream->send_window = h2c->init_window;
  2289.     stream->recv_window = h2scf->preread_size;

  2290.     h2c->processing++;

  2291.     h2c->priority_limit += h2scf->concurrent_streams;

  2292.     if (h2c->connection->read->timer_set) {
  2293.         ngx_del_timer(h2c->connection->read);
  2294.     }

  2295.     return stream;
  2296. }


  2297. static ngx_http_v2_node_t *
  2298. ngx_http_v2_get_node_by_id(ngx_http_v2_connection_t *h2c, ngx_uint_t sid,
  2299.     ngx_uint_t alloc)
  2300. {
  2301.     ngx_uint_t               index;
  2302.     ngx_http_v2_node_t      *node;
  2303.     ngx_http_v2_srv_conf_t  *h2scf;

  2304.     h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
  2305.                                          ngx_http_v2_module);

  2306.     index = ngx_http_v2_index(h2scf, sid);

  2307.     for (node = h2c->streams_index[index]; node; node = node->index) {

  2308.         if (node->id == sid) {
  2309.             return node;
  2310.         }
  2311.     }

  2312.     if (!alloc) {
  2313.         return NULL;
  2314.     }

  2315.     if (h2c->closed_nodes < 32) {
  2316.         node = ngx_pcalloc(h2c->connection->pool, sizeof(ngx_http_v2_node_t));
  2317.         if (node == NULL) {
  2318.             return NULL;
  2319.         }

  2320.     } else {
  2321.         node = ngx_http_v2_get_closed_node(h2c);
  2322.     }

  2323.     node->id = sid;

  2324.     ngx_queue_init(&node->children);

  2325.     node->index = h2c->streams_index[index];
  2326.     h2c->streams_index[index] = node;

  2327.     return node;
  2328. }


  2329. static ngx_http_v2_node_t *
  2330. ngx_http_v2_get_closed_node(ngx_http_v2_connection_t *h2c)
  2331. {
  2332.     ngx_uint_t               weight;
  2333.     ngx_queue_t             *q, *children;
  2334.     ngx_http_v2_node_t      *node, **next, *n, *parent, *child;
  2335.     ngx_http_v2_srv_conf_t  *h2scf;

  2336.     h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
  2337.                                          ngx_http_v2_module);

  2338.     h2c->closed_nodes--;

  2339.     q = ngx_queue_head(&h2c->closed);

  2340.     ngx_queue_remove(q);

  2341.     node = ngx_queue_data(q, ngx_http_v2_node_t, reuse);

  2342.     next = &h2c->streams_index[ngx_http_v2_index(h2scf, node->id)];

  2343.     for ( ;; ) {
  2344.         n = *next;

  2345.         if (n == node) {
  2346.             *next = n->index;
  2347.             break;
  2348.         }

  2349.         next = &n->index;
  2350.     }

  2351.     ngx_queue_remove(&node->queue);

  2352.     weight = 0;

  2353.     for (q = ngx_queue_head(&node->children);
  2354.          q != ngx_queue_sentinel(&node->children);
  2355.          q = ngx_queue_next(q))
  2356.     {
  2357.         child = ngx_queue_data(q, ngx_http_v2_node_t, queue);
  2358.         weight += child->weight;
  2359.     }

  2360.     parent = node->parent;

  2361.     for (q = ngx_queue_head(&node->children);
  2362.          q != ngx_queue_sentinel(&node->children);
  2363.          q = ngx_queue_next(q))
  2364.     {
  2365.         child = ngx_queue_data(q, ngx_http_v2_node_t, queue);
  2366.         child->parent = parent;
  2367.         child->weight = node->weight * child->weight / weight;

  2368.         if (child->weight == 0) {
  2369.             child->weight = 1;
  2370.         }
  2371.     }

  2372.     if (parent == NGX_HTTP_V2_ROOT) {
  2373.         node->rank = 0;
  2374.         node->rel_weight = 1.0;

  2375.         children = &h2c->dependencies;

  2376.     } else {
  2377.         node->rank = parent->rank;
  2378.         node->rel_weight = parent->rel_weight;

  2379.         children = &parent->children;
  2380.     }

  2381.     ngx_http_v2_node_children_update(node);
  2382.     ngx_queue_add(children, &node->children);

  2383.     ngx_memzero(node, sizeof(ngx_http_v2_node_t));

  2384.     return node;
  2385. }


  2386. static ngx_int_t
  2387. ngx_http_v2_validate_header(ngx_http_request_t *r, ngx_http_v2_header_t *header)
  2388. {
  2389.     u_char                     ch;
  2390.     ngx_uint_t                 i;
  2391.     ngx_http_core_srv_conf_t  *cscf;

  2392.     r->invalid_header = 0;

  2393.     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);

  2394.     for (i = (header->name.data[0] == ':'); i != header->name.len; i++) {
  2395.         ch = header->name.data[i];

  2396.         if ((ch >= 'a' && ch <= 'z')
  2397.             || (ch == '-')
  2398.             || (ch >= '0' && ch <= '9')
  2399.             || (ch == '_' && cscf->underscores_in_headers))
  2400.         {
  2401.             continue;
  2402.         }

  2403.         if (ch <= 0x20 || ch == 0x7f || ch == ':'
  2404.             || (ch >= 'A' && ch <= 'Z'))
  2405.         {
  2406.             ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  2407.                           "client sent invalid header name: \"%V\"",
  2408.                           &header->name);

  2409.             return NGX_ERROR;
  2410.         }

  2411.         r->invalid_header = 1;
  2412.     }

  2413.     for (i = 0; i != header->value.len; i++) {
  2414.         ch = header->value.data[i];

  2415.         if (ch == '\0' || ch == LF || ch == CR) {
  2416.             ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  2417.                           "client sent header \"%V\" with "
  2418.                           "invalid value: \"%V\"",
  2419.                           &header->name, &header->value);

  2420.             return NGX_ERROR;
  2421.         }
  2422.     }

  2423.     return NGX_OK;
  2424. }


  2425. static ngx_int_t
  2426. ngx_http_v2_pseudo_header(ngx_http_request_t *r, ngx_http_v2_header_t *header)
  2427. {
  2428.     header->name.len--;
  2429.     header->name.data++;

  2430.     switch (header->name.len) {
  2431.     case 4:
  2432.         if (ngx_memcmp(header->name.data, "path", sizeof("path") - 1)
  2433.             == 0)
  2434.         {
  2435.             return ngx_http_v2_parse_path(r, &header->value);
  2436.         }

  2437.         break;

  2438.     case 6:
  2439.         if (ngx_memcmp(header->name.data, "method", sizeof("method") - 1)
  2440.             == 0)
  2441.         {
  2442.             return ngx_http_v2_parse_method(r, &header->value);
  2443.         }

  2444.         if (ngx_memcmp(header->name.data, "scheme", sizeof("scheme") - 1)
  2445.             == 0)
  2446.         {
  2447.             return ngx_http_v2_parse_scheme(r, &header->value);
  2448.         }

  2449.         break;

  2450.     case 9:
  2451.         if (ngx_memcmp(header->name.data, "authority", sizeof("authority") - 1)
  2452.             == 0)
  2453.         {
  2454.             return ngx_http_v2_parse_authority(r, &header->value);
  2455.         }

  2456.         break;
  2457.     }

  2458.     ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  2459.                   "client sent unknown pseudo-header \":%V\"",
  2460.                   &header->name);

  2461.     return NGX_DECLINED;
  2462. }


  2463. static ngx_int_t
  2464. ngx_http_v2_parse_path(ngx_http_request_t *r, ngx_str_t *value)
  2465. {
  2466.     if (r->unparsed_uri.len) {
  2467.         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  2468.                       "client sent duplicate :path header");

  2469.         return NGX_DECLINED;
  2470.     }

  2471.     if (value->len == 0) {
  2472.         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  2473.                       "client sent empty :path header");

  2474.         return NGX_DECLINED;
  2475.     }

  2476.     r->uri_start = value->data;
  2477.     r->uri_end = value->data + value->len;

  2478.     if (ngx_http_parse_uri(r) != NGX_OK) {
  2479.         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  2480.                       "client sent invalid :path header: \"%V\"", value);

  2481.         return NGX_DECLINED;
  2482.     }

  2483.     if (ngx_http_process_request_uri(r) != NGX_OK) {
  2484.         /*
  2485.          * request has been finalized already
  2486.          * in ngx_http_process_request_uri()
  2487.          */
  2488.         return NGX_ABORT;
  2489.     }

  2490.     return NGX_OK;
  2491. }


  2492. static ngx_int_t
  2493. ngx_http_v2_parse_method(ngx_http_request_t *r, ngx_str_t *value)
  2494. {
  2495.     size_t         k, len;
  2496.     ngx_uint_t     n;
  2497.     const u_char  *p, *m;

  2498.     /*
  2499.      * This array takes less than 256 sequential bytes,
  2500.      * and if typical CPU cache line size is 64 bytes,
  2501.      * it is prefetched for 4 load operations.
  2502.      */
  2503.     static const struct {
  2504.         u_char            len;
  2505.         const u_char      method[11];
  2506.         uint32_t          value;
  2507.     } tests[] = {
  2508.         { 3, "GET",       NGX_HTTP_GET },
  2509.         { 4, "POST",      NGX_HTTP_POST },
  2510.         { 4, "HEAD",      NGX_HTTP_HEAD },
  2511.         { 7, "OPTIONS",   NGX_HTTP_OPTIONS },
  2512.         { 8, "PROPFIND"NGX_HTTP_PROPFIND },
  2513.         { 3, "PUT",       NGX_HTTP_PUT },
  2514.         { 5, "MKCOL",     NGX_HTTP_MKCOL },
  2515.         { 6, "DELETE",    NGX_HTTP_DELETE },
  2516.         { 4, "COPY",      NGX_HTTP_COPY },
  2517.         { 4, "MOVE",      NGX_HTTP_MOVE },
  2518.         { 9, "PROPPATCH", NGX_HTTP_PROPPATCH },
  2519.         { 4, "LOCK",      NGX_HTTP_LOCK },
  2520.         { 6, "UNLOCK",    NGX_HTTP_UNLOCK },
  2521.         { 5, "PATCH",     NGX_HTTP_PATCH },
  2522.         { 5, "TRACE",     NGX_HTTP_TRACE },
  2523.         { 7, "CONNECT",   NGX_HTTP_CONNECT }
  2524.     }, *test;

  2525.     if (r->method_name.len) {
  2526.         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  2527.                       "client sent duplicate :method header");

  2528.         return NGX_DECLINED;
  2529.     }

  2530.     if (value->len == 0) {
  2531.         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  2532.                       "client sent empty :method header");

  2533.         return NGX_DECLINED;
  2534.     }

  2535.     r->method_name.len = value->len;
  2536.     r->method_name.data = value->data;

  2537.     len = r->method_name.len;
  2538.     n = sizeof(tests) / sizeof(tests[0]);
  2539.     test = tests;

  2540.     do {
  2541.         if (len == test->len) {
  2542.             p = r->method_name.data;
  2543.             m = test->method;
  2544.             k = len;

  2545.             do {
  2546.                 if (*p++ != *m++) {
  2547.                     goto next;
  2548.                 }
  2549.             } while (--k);

  2550.             r->method = test->value;
  2551.             return NGX_OK;
  2552.         }

  2553.     next:
  2554.         test++;

  2555.     } while (--n);

  2556.     p = r->method_name.data;

  2557.     do {
  2558.         if ((*p < 'A' || *p > 'Z') && *p != '_' && *p != '-') {
  2559.             ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  2560.                           "client sent invalid method: \"%V\"",
  2561.                           &r->method_name);

  2562.             return NGX_DECLINED;
  2563.         }

  2564.         p++;

  2565.     } while (--len);

  2566.     return NGX_OK;
  2567. }


  2568. static ngx_int_t
  2569. ngx_http_v2_parse_scheme(ngx_http_request_t *r, ngx_str_t *value)
  2570. {
  2571.     u_char      c, ch;
  2572.     ngx_uint_t  i;

  2573.     if (r->schema.len) {
  2574.         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  2575.                       "client sent duplicate :scheme header");

  2576.         return NGX_DECLINED;
  2577.     }

  2578.     if (value->len == 0) {
  2579.         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  2580.                       "client sent empty :scheme header");

  2581.         return NGX_DECLINED;
  2582.     }

  2583.     for (i = 0; i < value->len; i++) {
  2584.         ch = value->data[i];

  2585.         c = (u_char) (ch | 0x20);
  2586.         if (c >= 'a' && c <= 'z') {
  2587.             continue;
  2588.         }

  2589.         if (((ch >= '0' && ch <= '9') || ch == '+' || ch == '-' || ch == '.')
  2590.             && i > 0)
  2591.         {
  2592.             continue;
  2593.         }

  2594.         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  2595.                       "client sent invalid :scheme header: \"%V\"", value);

  2596.         return NGX_DECLINED;
  2597.     }

  2598.     r->schema = *value;

  2599.     return NGX_OK;
  2600. }


  2601. static ngx_int_t
  2602. ngx_http_v2_parse_authority(ngx_http_request_t *r, ngx_str_t *value)
  2603. {
  2604.     ngx_table_elt_t            *h;
  2605.     ngx_http_header_t          *hh;
  2606.     ngx_http_core_main_conf_t  *cmcf;

  2607.     static ngx_str_t host = ngx_string("host");

  2608.     h = ngx_list_push(&r->headers_in.headers);
  2609.     if (h == NULL) {
  2610.         return NGX_ERROR;
  2611.     }

  2612.     h->hash = ngx_hash(ngx_hash(ngx_hash('h', 'o'), 's'), 't');

  2613.     h->key.len = host.len;
  2614.     h->key.data = host.data;

  2615.     h->value.len = value->len;
  2616.     h->value.data = value->data;

  2617.     h->lowcase_key = host.data;

  2618.     cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

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

  2621.     if (hh == NULL) {
  2622.         return NGX_ERROR;
  2623.     }

  2624.     if (hh->handler(r, h, hh->offset) != NGX_OK) {
  2625.         /*
  2626.          * request has been finalized already
  2627.          * in ngx_http_process_host()
  2628.          */
  2629.         return NGX_ABORT;
  2630.     }

  2631.     return NGX_OK;
  2632. }


  2633. static ngx_int_t
  2634. ngx_http_v2_construct_request_line(ngx_http_request_t *r)
  2635. {
  2636.     u_char  *p;

  2637.     static const u_char ending[] = " HTTP/2.0";

  2638.     if (r->method_name.len == 0
  2639.         || r->schema.len == 0
  2640.         || r->unparsed_uri.len == 0)
  2641.     {
  2642.         if (r->method_name.len == 0) {
  2643.             ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  2644.                           "client sent no :method header");

  2645.         } else if (r->schema.len == 0) {
  2646.             ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  2647.                           "client sent no :scheme header");

  2648.         } else {
  2649.             ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  2650.                           "client sent no :path header");
  2651.         }

  2652.         ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  2653.         return NGX_ERROR;
  2654.     }

  2655.     r->request_line.len = r->method_name.len + 1
  2656.                           + r->unparsed_uri.len
  2657.                           + sizeof(ending) - 1;

  2658.     p = ngx_pnalloc(r->pool, r->request_line.len + 1);
  2659.     if (p == NULL) {
  2660.         ngx_http_v2_close_stream(r->stream, NGX_HTTP_INTERNAL_SERVER_ERROR);
  2661.         return NGX_ERROR;
  2662.     }

  2663.     r->request_line.data = p;

  2664.     p = ngx_cpymem(p, r->method_name.data, r->method_name.len);

  2665.     *p++ = ' ';

  2666.     p = ngx_cpymem(p, r->unparsed_uri.data, r->unparsed_uri.len);

  2667.     ngx_memcpy(p, ending, sizeof(ending));

  2668.     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  2669.                    "http2 request line: \"%V\"", &r->request_line);

  2670.     return NGX_OK;
  2671. }


  2672. static ngx_int_t
  2673. ngx_http_v2_cookie(ngx_http_request_t *r, ngx_http_v2_header_t *header)
  2674. {
  2675.     ngx_str_t    *val;
  2676.     ngx_array_t  *cookies;

  2677.     cookies = r->stream->cookies;

  2678.     if (cookies == NULL) {
  2679.         cookies = ngx_array_create(r->pool, 2, sizeof(ngx_str_t));
  2680.         if (cookies == NULL) {
  2681.             return NGX_ERROR;
  2682.         }

  2683.         r->stream->cookies = cookies;
  2684.     }

  2685.     val = ngx_array_push(cookies);
  2686.     if (val == NULL) {
  2687.         return NGX_ERROR;
  2688.     }

  2689.     val->len = header->value.len;
  2690.     val->data = header->value.data;

  2691.     return NGX_OK;
  2692. }


  2693. static ngx_int_t
  2694. ngx_http_v2_construct_cookie_header(ngx_http_request_t *r)
  2695. {
  2696.     u_char                     *buf, *p, *end;
  2697.     size_t                      len;
  2698.     ngx_str_t                  *vals;
  2699.     ngx_uint_t                  i;
  2700.     ngx_array_t                *cookies;
  2701.     ngx_table_elt_t            *h;
  2702.     ngx_http_header_t          *hh;
  2703.     ngx_http_core_main_conf_t  *cmcf;

  2704.     static ngx_str_t cookie = ngx_string("cookie");

  2705.     cookies = r->stream->cookies;

  2706.     if (cookies == NULL) {
  2707.         return NGX_OK;
  2708.     }

  2709.     vals = cookies->elts;

  2710.     i = 0;
  2711.     len = 0;

  2712.     do {
  2713.         len += vals[i].len + 2;
  2714.     } while (++i != cookies->nelts);

  2715.     len -= 2;

  2716.     buf = ngx_pnalloc(r->pool, len + 1);
  2717.     if (buf == NULL) {
  2718.         ngx_http_v2_close_stream(r->stream, NGX_HTTP_INTERNAL_SERVER_ERROR);
  2719.         return NGX_ERROR;
  2720.     }

  2721.     p = buf;
  2722.     end = buf + len;

  2723.     for (i = 0; /* void */ ; i++) {

  2724.         p = ngx_cpymem(p, vals[i].data, vals[i].len);

  2725.         if (p == end) {
  2726.             *p = '\0';
  2727.             break;
  2728.         }

  2729.         *p++ = ';'; *p++ = ' ';
  2730.     }

  2731.     h = ngx_list_push(&r->headers_in.headers);
  2732.     if (h == NULL) {
  2733.         ngx_http_v2_close_stream(r->stream, NGX_HTTP_INTERNAL_SERVER_ERROR);
  2734.         return NGX_ERROR;
  2735.     }

  2736.     h->hash = ngx_hash(ngx_hash(ngx_hash(ngx_hash(
  2737.                                     ngx_hash('c', 'o'), 'o'), 'k'), 'i'), 'e');

  2738.     h->key.len = cookie.len;
  2739.     h->key.data = cookie.data;

  2740.     h->value.len = len;
  2741.     h->value.data = buf;

  2742.     h->lowcase_key = cookie.data;

  2743.     cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

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

  2746.     if (hh == NULL) {
  2747.         ngx_http_v2_close_stream(r->stream, NGX_HTTP_INTERNAL_SERVER_ERROR);
  2748.         return NGX_ERROR;
  2749.     }

  2750.     if (hh->handler(r, h, hh->offset) != NGX_OK) {
  2751.         /*
  2752.          * request has been finalized already
  2753.          * in ngx_http_process_multi_header_lines()
  2754.          */
  2755.         return NGX_ERROR;
  2756.     }

  2757.     return NGX_OK;
  2758. }


  2759. static void
  2760. ngx_http_v2_run_request(ngx_http_request_t *r)
  2761. {
  2762.     ngx_connection_t          *fc;
  2763.     ngx_http_v2_srv_conf_t    *h2scf;
  2764.     ngx_http_v2_connection_t  *h2c;

  2765.     fc = r->connection;

  2766.     h2scf = ngx_http_get_module_srv_conf(r, ngx_http_v2_module);

  2767.     if (!h2scf->enable && !r->http_connection->addr_conf->http2) {
  2768.         ngx_log_error(NGX_LOG_INFO, fc->log, 0,
  2769.                       "client attempted to request the server name "
  2770.                       "for which the negotiated protocol is disabled");

  2771.         ngx_http_finalize_request(r, NGX_HTTP_MISDIRECTED_REQUEST);
  2772.         goto failed;
  2773.     }

  2774.     if (ngx_http_v2_construct_request_line(r) != NGX_OK) {
  2775.         goto failed;
  2776.     }

  2777.     if (ngx_http_v2_construct_cookie_header(r) != NGX_OK) {
  2778.         goto failed;
  2779.     }

  2780.     r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE;

  2781.     if (ngx_http_process_request_header(r) != NGX_OK) {
  2782.         goto failed;
  2783.     }

  2784.     if (r->headers_in.content_length_n > 0 && r->stream->in_closed) {
  2785.         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  2786.                       "client prematurely closed stream");

  2787.         r->stream->skip_data = 1;

  2788.         ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
  2789.         goto failed;
  2790.     }

  2791.     if (r->headers_in.content_length_n == -1 && !r->stream->in_closed) {
  2792.         r->headers_in.chunked = 1;
  2793.     }

  2794.     h2c = r->stream->connection;

  2795.     h2c->payload_bytes += r->request_length;

  2796.     ngx_http_process_request(r);

  2797. failed:

  2798.     ngx_http_run_posted_requests(fc);
  2799. }


  2800. ngx_int_t
  2801. ngx_http_v2_read_request_body(ngx_http_request_t *r)
  2802. {
  2803.     off_t                      len;
  2804.     size_t                     size;
  2805.     ngx_buf_t                 *buf;
  2806.     ngx_int_t                  rc;
  2807.     ngx_http_v2_stream_t      *stream;
  2808.     ngx_http_v2_srv_conf_t    *h2scf;
  2809.     ngx_http_request_body_t   *rb;
  2810.     ngx_http_core_loc_conf_t  *clcf;
  2811.     ngx_http_v2_connection_t  *h2c;

  2812.     stream = r->stream;
  2813.     rb = r->request_body;

  2814.     if (stream->skip_data) {
  2815.         r->request_body_no_buffering = 0;
  2816.         rb->post_handler(r);
  2817.         return NGX_OK;
  2818.     }

  2819.     rb->rest = 1;

  2820.     /* set rb->filter_need_buffering */

  2821.     rc = ngx_http_top_request_body_filter(r, NULL);

  2822.     if (rc != NGX_OK) {
  2823.         stream->skip_data = 1;
  2824.         return rc;
  2825.     }

  2826.     h2scf = ngx_http_get_module_srv_conf(r, ngx_http_v2_module);
  2827.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  2828.     len = r->headers_in.content_length_n;

  2829.     if (len < 0 || len > (off_t) clcf->client_body_buffer_size) {
  2830.         len = clcf->client_body_buffer_size;

  2831.     } else {
  2832.         len++;
  2833.     }

  2834.     if (r->request_body_no_buffering || rb->filter_need_buffering) {

  2835.         /*
  2836.          * We need a room to store data up to the stream's initial window size,
  2837.          * at least until this window will be exhausted.
  2838.          */

  2839.         if (len < (off_t) h2scf->preread_size) {
  2840.             len = h2scf->preread_size;
  2841.         }

  2842.         if (len > NGX_HTTP_V2_MAX_WINDOW) {
  2843.             len = NGX_HTTP_V2_MAX_WINDOW;
  2844.         }
  2845.     }

  2846.     rb->buf = ngx_create_temp_buf(r->pool, (size_t) len);

  2847.     if (rb->buf == NULL) {
  2848.         stream->skip_data = 1;
  2849.         return NGX_HTTP_INTERNAL_SERVER_ERROR;
  2850.     }

  2851.     buf = stream->preread;

  2852.     if (stream->in_closed) {
  2853.         if (!rb->filter_need_buffering) {
  2854.             r->request_body_no_buffering = 0;
  2855.         }

  2856.         if (buf) {
  2857.             rc = ngx_http_v2_process_request_body(r, buf->pos,
  2858.                                                   buf->last - buf->pos, 1, 0);
  2859.             ngx_pfree(r->pool, buf->start);

  2860.         } else {
  2861.             rc = ngx_http_v2_process_request_body(r, NULL, 0, 1, 0);
  2862.         }

  2863.         if (rc != NGX_AGAIN) {
  2864.             return rc;
  2865.         }

  2866.         r->read_event_handler = ngx_http_v2_read_client_request_body_handler;
  2867.         r->write_event_handler = ngx_http_request_empty_handler;

  2868.         return NGX_AGAIN;
  2869.     }

  2870.     if (buf) {
  2871.         rc = ngx_http_v2_process_request_body(r, buf->pos,
  2872.                                               buf->last - buf->pos, 0, 0);

  2873.         ngx_pfree(r->pool, buf->start);

  2874.         if (rc != NGX_OK && rc != NGX_AGAIN) {
  2875.             stream->skip_data = 1;
  2876.             return rc;
  2877.         }
  2878.     }

  2879.     if (r->request_body_no_buffering || rb->filter_need_buffering) {
  2880.         size = (size_t) len - h2scf->preread_size;

  2881.     } else {
  2882.         stream->no_flow_control = 1;
  2883.         size = NGX_HTTP_V2_MAX_WINDOW - stream->recv_window;
  2884.     }

  2885.     if (size) {
  2886.         if (ngx_http_v2_send_window_update(stream->connection,
  2887.                                            stream->node->id, size)
  2888.             == NGX_ERROR)
  2889.         {
  2890.             stream->skip_data = 1;
  2891.             return NGX_HTTP_INTERNAL_SERVER_ERROR;
  2892.         }

  2893.         h2c = stream->connection;

  2894.         if (!h2c->blocked) {
  2895.             if (ngx_http_v2_send_output_queue(h2c) == NGX_ERROR) {
  2896.                 stream->skip_data = 1;
  2897.                 return NGX_HTTP_INTERNAL_SERVER_ERROR;
  2898.             }
  2899.         }

  2900.         stream->recv_window += size;
  2901.     }

  2902.     if (!buf) {
  2903.         ngx_add_timer(r->connection->read, clcf->client_body_timeout);
  2904.     }

  2905.     r->read_event_handler = ngx_http_v2_read_client_request_body_handler;
  2906.     r->write_event_handler = ngx_http_request_empty_handler;

  2907.     return NGX_AGAIN;
  2908. }


  2909. static ngx_int_t
  2910. ngx_http_v2_process_request_body(ngx_http_request_t *r, u_char *pos,
  2911.     size_t size, ngx_uint_t last, ngx_uint_t flush)
  2912. {
  2913.     size_t                     n;
  2914.     ngx_int_t                  rc;
  2915.     ngx_connection_t          *fc;
  2916.     ngx_http_request_body_t   *rb;
  2917.     ngx_http_core_loc_conf_t  *clcf;

  2918.     fc = r->connection;
  2919.     rb = r->request_body;

  2920.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
  2921.                    "http2 process request body");

  2922.     if (size == 0 && !last && !flush) {
  2923.         return NGX_AGAIN;
  2924.     }

  2925.     for ( ;; ) {
  2926.         for ( ;; ) {
  2927.             if (rb->buf->last == rb->buf->end && size) {

  2928.                 if (r->request_body_no_buffering) {

  2929.                     /* should never happen due to flow control */

  2930.                     ngx_log_error(NGX_LOG_ALERT, fc->log, 0,
  2931.                                   "no space in http2 body buffer");

  2932.                     return NGX_HTTP_INTERNAL_SERVER_ERROR;
  2933.                 }

  2934.                 /* update chains */

  2935.                 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
  2936.                                "http2 body update chains");

  2937.                 rc = ngx_http_v2_filter_request_body(r);

  2938.                 if (rc != NGX_OK) {
  2939.                     return rc;
  2940.                 }

  2941.                 if (rb->busy != NULL) {
  2942.                     ngx_log_error(NGX_LOG_ALERT, fc->log, 0,
  2943.                                   "busy buffers after request body flush");
  2944.                     return NGX_HTTP_INTERNAL_SERVER_ERROR;
  2945.                 }

  2946.                 rb->buf->pos = rb->buf->start;
  2947.                 rb->buf->last = rb->buf->start;
  2948.             }

  2949.             /* copy body data to the buffer */

  2950.             n = rb->buf->end - rb->buf->last;

  2951.             if (n > size) {
  2952.                 n = size;
  2953.             }

  2954.             if (n > 0) {
  2955.                 rb->buf->last = ngx_cpymem(rb->buf->last, pos, n);
  2956.             }

  2957.             ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
  2958.                            "http2 request body recv %uz", n);

  2959.             pos += n;
  2960.             size -= n;

  2961.             if (size == 0 && last) {
  2962.                 rb->rest = 0;
  2963.             }

  2964.             if (size == 0) {
  2965.                 break;
  2966.             }
  2967.         }

  2968.         ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
  2969.                        "http2 request body rest %O", rb->rest);

  2970.         if (flush) {
  2971.             rc = ngx_http_v2_filter_request_body(r);

  2972.             if (rc != NGX_OK) {
  2973.                 return rc;
  2974.             }
  2975.         }

  2976.         if (rb->rest == 0 && rb->last_saved) {
  2977.             break;
  2978.         }

  2979.         if (size == 0) {
  2980.             clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
  2981.             ngx_add_timer(fc->read, clcf->client_body_timeout);

  2982.             if (!flush) {
  2983.                 ngx_post_event(fc->read, &ngx_posted_events);
  2984.             }

  2985.             return NGX_AGAIN;
  2986.         }
  2987.     }

  2988.     if (fc->read->timer_set) {
  2989.         ngx_del_timer(fc->read);
  2990.     }

  2991.     if (r->request_body_no_buffering) {
  2992.         if (!flush) {
  2993.             ngx_post_event(fc->read, &ngx_posted_events);
  2994.         }

  2995.         return NGX_OK;
  2996.     }

  2997.     if (r->headers_in.chunked) {
  2998.         r->headers_in.content_length_n = rb->received;
  2999.     }

  3000.     r->read_event_handler = ngx_http_block_reading;
  3001.     rb->post_handler(r);

  3002.     return NGX_OK;
  3003. }


  3004. static ngx_int_t
  3005. ngx_http_v2_filter_request_body(ngx_http_request_t *r)
  3006. {
  3007.     ngx_buf_t                 *b, *buf;
  3008.     ngx_int_t                  rc;
  3009.     ngx_chain_t               *cl;
  3010.     ngx_http_request_body_t   *rb;
  3011.     ngx_http_core_loc_conf_t  *clcf;

  3012.     rb = r->request_body;
  3013.     buf = rb->buf;

  3014.     if (buf->pos == buf->last && (rb->rest || rb->last_sent)) {
  3015.         cl = NULL;
  3016.         goto update;
  3017.     }

  3018.     cl = ngx_chain_get_free_buf(r->pool, &rb->free);
  3019.     if (cl == NULL) {
  3020.         return NGX_HTTP_INTERNAL_SERVER_ERROR;
  3021.     }

  3022.     b = cl->buf;

  3023.     ngx_memzero(b, sizeof(ngx_buf_t));

  3024.     if (buf->pos != buf->last) {
  3025.         r->request_length += buf->last - buf->pos;
  3026.         rb->received += buf->last - buf->pos;

  3027.         if (r->headers_in.content_length_n != -1) {
  3028.             if (rb->received > r->headers_in.content_length_n) {
  3029.                 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  3030.                               "client intended to send body data "
  3031.                               "larger than declared");

  3032.                 return NGX_HTTP_BAD_REQUEST;
  3033.             }

  3034.         } else {
  3035.             clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  3036.             if (clcf->client_max_body_size
  3037.                 && rb->received > clcf->client_max_body_size)
  3038.             {
  3039.                 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  3040.                               "client intended to send too large chunked body: "
  3041.                               "%O bytes", rb->received);

  3042.                 return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE;
  3043.             }
  3044.         }

  3045.         b->temporary = 1;
  3046.         b->pos = buf->pos;
  3047.         b->last = buf->last;
  3048.         b->start = b->pos;
  3049.         b->end = b->last;

  3050.         buf->pos = buf->last;
  3051.     }

  3052.     if (!rb->rest) {
  3053.         if (r->headers_in.content_length_n != -1
  3054.             && r->headers_in.content_length_n != rb->received)
  3055.         {
  3056.             ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  3057.                           "client prematurely closed stream: "
  3058.                           "only %O out of %O bytes of request body received",
  3059.                           rb->received, r->headers_in.content_length_n);

  3060.             return NGX_HTTP_BAD_REQUEST;
  3061.         }

  3062.         b->last_buf = 1;
  3063.         rb->last_sent = 1;
  3064.     }

  3065.     b->tag = (ngx_buf_tag_t) &ngx_http_v2_filter_request_body;
  3066.     b->flush = r->request_body_no_buffering;

  3067. update:

  3068.     rc = ngx_http_top_request_body_filter(r, cl);

  3069.     ngx_chain_update_chains(r->pool, &rb->free, &rb->busy, &cl,
  3070.                             (ngx_buf_tag_t) &ngx_http_v2_filter_request_body);

  3071.     return rc;
  3072. }


  3073. static void
  3074. ngx_http_v2_read_client_request_body_handler(ngx_http_request_t *r)
  3075. {
  3076.     size_t                     window;
  3077.     ngx_buf_t                 *buf;
  3078.     ngx_int_t                  rc;
  3079.     ngx_connection_t          *fc;
  3080.     ngx_http_v2_stream_t      *stream;
  3081.     ngx_http_v2_connection_t  *h2c;

  3082.     fc = r->connection;

  3083.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
  3084.                    "http2 read client request body handler");

  3085.     if (fc->read->timedout) {
  3086.         ngx_log_error(NGX_LOG_INFO, fc->log, NGX_ETIMEDOUT, "client timed out");

  3087.         fc->timedout = 1;
  3088.         r->stream->skip_data = 1;

  3089.         ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT);
  3090.         return;
  3091.     }

  3092.     if (fc->error) {
  3093.         ngx_log_error(NGX_LOG_INFO, fc->log, 0,
  3094.                       "client prematurely closed stream");

  3095.         r->stream->skip_data = 1;

  3096.         ngx_http_finalize_request(r, NGX_HTTP_CLIENT_CLOSED_REQUEST);
  3097.         return;
  3098.     }

  3099.     rc = ngx_http_v2_process_request_body(r, NULL, 0, r->stream->in_closed, 1);

  3100.     if (rc != NGX_OK && rc != NGX_AGAIN) {
  3101.         r->stream->skip_data = 1;
  3102.         ngx_http_finalize_request(r, rc);
  3103.         return;
  3104.     }

  3105.     if (rc == NGX_OK) {
  3106.         return;
  3107.     }

  3108.     if (r->stream->no_flow_control) {
  3109.         return;
  3110.     }

  3111.     if (r->request_body->rest == 0) {
  3112.         return;
  3113.     }

  3114.     if (r->request_body->busy != NULL) {
  3115.         return;
  3116.     }

  3117.     stream = r->stream;
  3118.     h2c = stream->connection;

  3119.     buf = r->request_body->buf;

  3120.     buf->pos = buf->start;
  3121.     buf->last = buf->start;

  3122.     window = buf->end - buf->start;

  3123.     if (h2c->state.stream == stream) {
  3124.         window -= h2c->state.length;
  3125.     }

  3126.     if (window <= stream->recv_window) {
  3127.         if (window < stream->recv_window) {
  3128.             ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
  3129.                           "http2 negative window update");

  3130.             stream->skip_data = 1;

  3131.             ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  3132.             return;
  3133.         }

  3134.         return;
  3135.     }

  3136.     if (ngx_http_v2_send_window_update(h2c, stream->node->id,
  3137.                                        window - stream->recv_window)
  3138.         == NGX_ERROR)
  3139.     {
  3140.         stream->skip_data = 1;
  3141.         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  3142.         return;
  3143.     }

  3144.     stream->recv_window = window;

  3145.     if (ngx_http_v2_send_output_queue(h2c) == NGX_ERROR) {
  3146.         stream->skip_data = 1;
  3147.         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  3148.         return;
  3149.     }
  3150. }


  3151. ngx_int_t
  3152. ngx_http_v2_read_unbuffered_request_body(ngx_http_request_t *r)
  3153. {
  3154.     size_t                     window;
  3155.     ngx_buf_t                 *buf;
  3156.     ngx_int_t                  rc;
  3157.     ngx_connection_t          *fc;
  3158.     ngx_http_v2_stream_t      *stream;
  3159.     ngx_http_v2_connection_t  *h2c;

  3160.     stream = r->stream;
  3161.     fc = r->connection;

  3162.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
  3163.                    "http2 read unbuffered request body");

  3164.     if (fc->read->timedout) {
  3165.         if (stream->recv_window) {
  3166.             stream->skip_data = 1;
  3167.             fc->timedout = 1;

  3168.             return NGX_HTTP_REQUEST_TIME_OUT;
  3169.         }

  3170.         fc->read->timedout = 0;
  3171.     }

  3172.     if (fc->error) {
  3173.         stream->skip_data = 1;
  3174.         return NGX_HTTP_BAD_REQUEST;
  3175.     }

  3176.     rc = ngx_http_v2_process_request_body(r, NULL, 0, r->stream->in_closed, 1);

  3177.     if (rc != NGX_OK && rc != NGX_AGAIN) {
  3178.         stream->skip_data = 1;
  3179.         return rc;
  3180.     }

  3181.     if (rc == NGX_OK) {
  3182.         return NGX_OK;
  3183.     }

  3184.     if (r->request_body->rest == 0) {
  3185.         return NGX_AGAIN;
  3186.     }

  3187.     if (r->request_body->busy != NULL) {
  3188.         return NGX_AGAIN;
  3189.     }

  3190.     buf = r->request_body->buf;

  3191.     buf->pos = buf->start;
  3192.     buf->last = buf->start;

  3193.     window = buf->end - buf->start;
  3194.     h2c = stream->connection;

  3195.     if (h2c->state.stream == stream) {
  3196.         window -= h2c->state.length;
  3197.     }

  3198.     if (window <= stream->recv_window) {
  3199.         if (window < stream->recv_window) {
  3200.             ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
  3201.                           "http2 negative window update");
  3202.             stream->skip_data = 1;
  3203.             return NGX_HTTP_INTERNAL_SERVER_ERROR;
  3204.         }

  3205.         return NGX_AGAIN;
  3206.     }

  3207.     if (ngx_http_v2_send_window_update(h2c, stream->node->id,
  3208.                                        window - stream->recv_window)
  3209.         == NGX_ERROR)
  3210.     {
  3211.         stream->skip_data = 1;
  3212.         return NGX_HTTP_INTERNAL_SERVER_ERROR;
  3213.     }

  3214.     if (ngx_http_v2_send_output_queue(h2c) == NGX_ERROR) {
  3215.         stream->skip_data = 1;
  3216.         return NGX_HTTP_INTERNAL_SERVER_ERROR;
  3217.     }

  3218.     stream->recv_window = window;

  3219.     return NGX_AGAIN;
  3220. }


  3221. static ngx_int_t
  3222. ngx_http_v2_terminate_stream(ngx_http_v2_connection_t *h2c,
  3223.     ngx_http_v2_stream_t *stream, ngx_uint_t status)
  3224. {
  3225.     ngx_event_t       *rev;
  3226.     ngx_connection_t  *fc;

  3227.     if (stream->rst_sent) {
  3228.         return NGX_OK;
  3229.     }

  3230.     if (ngx_http_v2_send_rst_stream(h2c, stream->node->id, status)
  3231.         == NGX_ERROR)
  3232.     {
  3233.         return NGX_ERROR;
  3234.     }

  3235.     stream->rst_sent = 1;
  3236.     stream->skip_data = 1;

  3237.     fc = stream->request->connection;
  3238.     fc->error = 1;

  3239.     rev = fc->read;
  3240.     rev->handler(rev);

  3241.     return NGX_OK;
  3242. }


  3243. void
  3244. ngx_http_v2_close_stream(ngx_http_v2_stream_t *stream, ngx_int_t rc)
  3245. {
  3246.     ngx_pool_t                *pool;
  3247.     ngx_event_t               *ev;
  3248.     ngx_connection_t          *fc;
  3249.     ngx_http_v2_node_t        *node;
  3250.     ngx_http_v2_connection_t  *h2c;

  3251.     h2c = stream->connection;
  3252.     node = stream->node;

  3253.     ngx_log_debug3(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  3254.                    "http2 close stream %ui, queued %ui, processing %ui",
  3255.                    node->id, stream->queued, h2c->processing);

  3256.     fc = stream->request->connection;

  3257.     if (stream->queued) {
  3258.         fc->error = 1;
  3259.         fc->write->handler = ngx_http_v2_retry_close_stream_handler;
  3260.         fc->read->handler = ngx_http_v2_retry_close_stream_handler;
  3261.         return;
  3262.     }

  3263.     if (!stream->rst_sent && !h2c->connection->error) {

  3264.         if (!stream->out_closed) {
  3265.             if (ngx_http_v2_send_rst_stream(h2c, node->id,
  3266.                                       fc->timedout ? NGX_HTTP_V2_PROTOCOL_ERROR
  3267.                                                    : NGX_HTTP_V2_INTERNAL_ERROR)
  3268.                 != NGX_OK)
  3269.             {
  3270.                 h2c->connection->error = 1;
  3271.             }

  3272.         } else if (!stream->in_closed) {
  3273.             if (ngx_http_v2_send_rst_stream(h2c, node->id, NGX_HTTP_V2_NO_ERROR)
  3274.                 != NGX_OK)
  3275.             {
  3276.                 h2c->connection->error = 1;
  3277.             }
  3278.         }
  3279.     }

  3280.     if (h2c->state.stream == stream) {
  3281.         h2c->state.stream = NULL;
  3282.     }

  3283.     node->stream = NULL;

  3284.     ngx_queue_insert_tail(&h2c->closed, &node->reuse);
  3285.     h2c->closed_nodes++;

  3286.     /*
  3287.      * This pool keeps decoded request headers which can be used by log phase
  3288.      * handlers in ngx_http_free_request().
  3289.      *
  3290.      * The pointer is stored into local variable because the stream object
  3291.      * will be destroyed after a call to ngx_http_free_request().
  3292.      */
  3293.     pool = stream->pool;

  3294.     h2c->frames -= stream->frames;

  3295.     ngx_http_free_request(stream->request, rc);

  3296.     if (pool != h2c->state.pool) {
  3297.         ngx_destroy_pool(pool);

  3298.     } else {
  3299.         /* pool will be destroyed when the complete header is parsed */
  3300.         h2c->state.keep_pool = 0;
  3301.     }

  3302.     ev = fc->read;

  3303.     if (ev->timer_set) {
  3304.         ngx_del_timer(ev);
  3305.     }

  3306.     if (ev->posted) {
  3307.         ngx_delete_posted_event(ev);
  3308.     }

  3309.     ev = fc->write;

  3310.     if (ev->timer_set) {
  3311.         ngx_del_timer(ev);
  3312.     }

  3313.     if (ev->posted) {
  3314.         ngx_delete_posted_event(ev);
  3315.     }

  3316.     fc->data = h2c->free_fake_connections;
  3317.     h2c->free_fake_connections = fc;

  3318.     h2c->processing--;

  3319.     if (h2c->processing || h2c->blocked) {
  3320.         return;
  3321.     }

  3322.     ev = h2c->connection->read;

  3323.     ev->handler = ngx_http_v2_handle_connection_handler;
  3324.     ngx_post_event(ev, &ngx_posted_events);
  3325. }


  3326. static void
  3327. ngx_http_v2_close_stream_handler(ngx_event_t *ev)
  3328. {
  3329.     ngx_connection_t    *fc;
  3330.     ngx_http_request_t  *r;

  3331.     fc = ev->data;
  3332.     r = fc->data;

  3333.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
  3334.                    "http2 close stream handler");

  3335.     if (ev->timedout) {
  3336.         ngx_log_error(NGX_LOG_INFO, fc->log, NGX_ETIMEDOUT, "client timed out");

  3337.         fc->timedout = 1;

  3338.         ngx_http_v2_close_stream(r->stream, NGX_HTTP_REQUEST_TIME_OUT);
  3339.         return;
  3340.     }

  3341.     ngx_http_v2_close_stream(r->stream, 0);
  3342. }


  3343. static void
  3344. ngx_http_v2_retry_close_stream_handler(ngx_event_t *ev)
  3345. {
  3346.     ngx_connection_t    *fc;
  3347.     ngx_http_request_t  *r;

  3348.     fc = ev->data;
  3349.     r = fc->data;

  3350.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
  3351.                    "http2 retry close stream handler");

  3352.     ngx_http_v2_close_stream(r->stream, 0);
  3353. }


  3354. static void
  3355. ngx_http_v2_handle_connection_handler(ngx_event_t *rev)
  3356. {
  3357.     ngx_connection_t          *c;
  3358.     ngx_http_v2_connection_t  *h2c;

  3359.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0,
  3360.                    "http2 handle connection handler");

  3361.     c = rev->data;
  3362.     h2c = c->data;

  3363.     if (c->error) {
  3364.         ngx_http_v2_finalize_connection(h2c, 0);
  3365.         return;
  3366.     }

  3367.     rev->handler = ngx_http_v2_read_handler;

  3368.     if (rev->ready) {
  3369.         ngx_http_v2_read_handler(rev);
  3370.         return;
  3371.     }

  3372.     if (h2c->last_out && ngx_http_v2_send_output_queue(h2c) == NGX_ERROR) {
  3373.         ngx_http_v2_finalize_connection(h2c, 0);
  3374.         return;
  3375.     }

  3376.     ngx_http_v2_handle_connection(c->data);
  3377. }


  3378. static void
  3379. ngx_http_v2_idle_handler(ngx_event_t *rev)
  3380. {
  3381.     ngx_connection_t          *c;
  3382.     ngx_http_v2_srv_conf_t    *h2scf;
  3383.     ngx_http_v2_connection_t  *h2c;
  3384.     ngx_http_core_loc_conf_t  *clcf;

  3385.     c = rev->data;
  3386.     h2c = c->data;

  3387.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http2 idle handler");

  3388.     if (rev->timedout || c->close) {
  3389.         ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_NO_ERROR);
  3390.         return;
  3391.     }

  3392. #if (NGX_HAVE_KQUEUE)

  3393.     if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
  3394.         if (rev->pending_eof) {
  3395.             c->log->handler = NULL;
  3396.             ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno,
  3397.                           "kevent() reported that client %V closed "
  3398.                           "idle connection", &c->addr_text);
  3399. #if (NGX_HTTP_SSL)
  3400.             if (c->ssl) {
  3401.                 c->ssl->no_send_shutdown = 1;
  3402.             }
  3403. #endif
  3404.             ngx_http_close_connection(c);
  3405.             return;
  3406.         }
  3407.     }

  3408. #endif

  3409.     clcf = ngx_http_get_module_loc_conf(h2c->http_connection->conf_ctx,
  3410.                                         ngx_http_core_module);

  3411.     if (h2c->idle++ > 10 * clcf->keepalive_requests) {
  3412.         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
  3413.                       "http2 flood detected");
  3414.         ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_NO_ERROR);
  3415.         return;
  3416.     }

  3417.     c->destroyed = 0;
  3418.     ngx_reusable_connection(c, 0);

  3419.     h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
  3420.                                          ngx_http_v2_module);

  3421.     h2c->pool = ngx_create_pool(h2scf->pool_size, h2c->connection->log);
  3422.     if (h2c->pool == NULL) {
  3423.         ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
  3424.         return;
  3425.     }

  3426.     c->write->handler = ngx_http_v2_write_handler;

  3427.     rev->handler = ngx_http_v2_read_handler;
  3428.     ngx_http_v2_read_handler(rev);
  3429. }


  3430. static void
  3431. ngx_http_v2_finalize_connection(ngx_http_v2_connection_t *h2c,
  3432.     ngx_uint_t status)
  3433. {
  3434.     ngx_uint_t               i, size;
  3435.     ngx_event_t             *ev;
  3436.     ngx_connection_t        *c, *fc;
  3437.     ngx_http_request_t      *r;
  3438.     ngx_http_v2_node_t      *node;
  3439.     ngx_http_v2_stream_t    *stream;
  3440.     ngx_http_v2_srv_conf_t  *h2scf;

  3441.     c = h2c->connection;

  3442.     h2c->blocked = 1;

  3443.     if (!c->error && !h2c->goaway) {
  3444.         h2c->goaway = 1;

  3445.         if (ngx_http_v2_send_goaway(h2c, status) != NGX_ERROR) {
  3446.             (void) ngx_http_v2_send_output_queue(h2c);
  3447.         }
  3448.     }

  3449.     if (!h2c->processing) {
  3450.         goto done;
  3451.     }

  3452.     c->read->handler = ngx_http_empty_handler;
  3453.     c->write->handler = ngx_http_empty_handler;

  3454.     h2c->last_out = NULL;

  3455.     h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
  3456.                                          ngx_http_v2_module);

  3457.     size = ngx_http_v2_index_size(h2scf);

  3458.     for (i = 0; i < size; i++) {

  3459.         for (node = h2c->streams_index[i]; node; node = node->index) {
  3460.             stream = node->stream;

  3461.             if (stream == NULL) {
  3462.                 continue;
  3463.             }

  3464.             stream->waiting = 0;

  3465.             r = stream->request;
  3466.             fc = r->connection;

  3467.             fc->error = 1;

  3468.             if (stream->queued) {
  3469.                 stream->queued = 0;

  3470.                 ev = fc->write;
  3471.                 ev->active = 0;
  3472.                 ev->ready = 1;

  3473.             } else {
  3474.                 ev = fc->read;
  3475.             }

  3476.             ev->eof = 1;
  3477.             ev->handler(ev);
  3478.         }
  3479.     }

  3480.     h2c->blocked = 0;

  3481.     if (h2c->processing) {
  3482.         c->error = 1;
  3483.         return;
  3484.     }

  3485. done:

  3486.     if (c->error) {
  3487.         ngx_http_close_connection(c);
  3488.         return;
  3489.     }

  3490.     ngx_http_v2_lingering_close(c);
  3491. }


  3492. static ngx_int_t
  3493. ngx_http_v2_adjust_windows(ngx_http_v2_connection_t *h2c, ssize_t delta)
  3494. {
  3495.     ngx_uint_t               i, size;
  3496.     ngx_event_t             *wev;
  3497.     ngx_http_v2_node_t      *node;
  3498.     ngx_http_v2_stream_t    *stream;
  3499.     ngx_http_v2_srv_conf_t  *h2scf;

  3500.     h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
  3501.                                          ngx_http_v2_module);

  3502.     size = ngx_http_v2_index_size(h2scf);

  3503.     for (i = 0; i < size; i++) {

  3504.         for (node = h2c->streams_index[i]; node; node = node->index) {
  3505.             stream = node->stream;

  3506.             if (stream == NULL) {
  3507.                 continue;
  3508.             }

  3509.             if (delta > 0
  3510.                 && stream->send_window
  3511.                       > (ssize_t) (NGX_HTTP_V2_MAX_WINDOW - delta))
  3512.             {
  3513.                 if (ngx_http_v2_terminate_stream(h2c, stream,
  3514.                                                  NGX_HTTP_V2_FLOW_CTRL_ERROR)
  3515.                     == NGX_ERROR)
  3516.                 {
  3517.                     return NGX_ERROR;
  3518.                 }

  3519.                 continue;
  3520.             }

  3521.             stream->send_window += delta;

  3522.             ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
  3523.                            "http2:%ui adjusted window: %z",
  3524.                            node->id, stream->send_window);

  3525.             if (stream->send_window > 0 && stream->exhausted) {
  3526.                 stream->exhausted = 0;

  3527.                 wev = stream->request->connection->write;

  3528.                 wev->active = 0;
  3529.                 wev->ready = 1;

  3530.                 if (!wev->delayed) {
  3531.                     wev->handler(wev);
  3532.                 }
  3533.             }
  3534.         }
  3535.     }

  3536.     return NGX_OK;
  3537. }


  3538. static void
  3539. ngx_http_v2_set_dependency(ngx_http_v2_connection_t *h2c,
  3540.     ngx_http_v2_node_t *node, ngx_uint_t depend, ngx_uint_t exclusive)
  3541. {
  3542.     ngx_queue_t         *children, *q;
  3543.     ngx_http_v2_node_t  *parent, *child, *next;

  3544.     parent = depend ? ngx_http_v2_get_node_by_id(h2c, depend, 0) : NULL;

  3545.     if (parent == NULL) {
  3546.         parent = NGX_HTTP_V2_ROOT;

  3547.         if (depend != 0) {
  3548.             exclusive = 0;
  3549.         }

  3550.         node->rank = 1;
  3551.         node->rel_weight = (1.0 / 256) * node->weight;

  3552.         children = &h2c->dependencies;

  3553.     } else {
  3554.         if (node->parent != NULL) {

  3555.             for (next = parent->parent;
  3556.                  next != NGX_HTTP_V2_ROOT && next->rank >= node->rank;
  3557.                  next = next->parent)
  3558.             {
  3559.                 if (next != node) {
  3560.                     continue;
  3561.                 }

  3562.                 ngx_queue_remove(&parent->queue);
  3563.                 ngx_queue_insert_after(&node->queue, &parent->queue);

  3564.                 parent->parent = node->parent;

  3565.                 if (node->parent == NGX_HTTP_V2_ROOT) {
  3566.                     parent->rank = 1;
  3567.                     parent->rel_weight = (1.0 / 256) * parent->weight;

  3568.                 } else {
  3569.                     parent->rank = node->parent->rank + 1;
  3570.                     parent->rel_weight = (node->parent->rel_weight / 256)
  3571.                                          * parent->weight;
  3572.                 }

  3573.                 if (!exclusive) {
  3574.                     ngx_http_v2_node_children_update(parent);
  3575.                 }

  3576.                 break;
  3577.             }
  3578.         }

  3579.         node->rank = parent->rank + 1;
  3580.         node->rel_weight = (parent->rel_weight / 256) * node->weight;

  3581.         if (parent->stream == NULL) {
  3582.             ngx_queue_remove(&parent->reuse);
  3583.             ngx_queue_insert_tail(&h2c->closed, &parent->reuse);
  3584.         }

  3585.         children = &parent->children;
  3586.     }

  3587.     if (exclusive) {
  3588.         for (q = ngx_queue_head(children);
  3589.              q != ngx_queue_sentinel(children);
  3590.              q = ngx_queue_next(q))
  3591.         {
  3592.             child = ngx_queue_data(q, ngx_http_v2_node_t, queue);
  3593.             child->parent = node;
  3594.         }

  3595.         ngx_queue_add(&node->children, children);
  3596.         ngx_queue_init(children);
  3597.     }

  3598.     if (node->parent != NULL) {
  3599.         ngx_queue_remove(&node->queue);
  3600.     }

  3601.     ngx_queue_insert_tail(children, &node->queue);

  3602.     node->parent = parent;

  3603.     ngx_http_v2_node_children_update(node);
  3604. }


  3605. static void
  3606. ngx_http_v2_node_children_update(ngx_http_v2_node_t *node)
  3607. {
  3608.     ngx_queue_t         *q;
  3609.     ngx_http_v2_node_t  *child;

  3610.     for (q = ngx_queue_head(&node->children);
  3611.          q != ngx_queue_sentinel(&node->children);
  3612.          q = ngx_queue_next(q))
  3613.     {
  3614.         child = ngx_queue_data(q, ngx_http_v2_node_t, queue);

  3615.         child->rank = node->rank + 1;
  3616.         child->rel_weight = (node->rel_weight / 256) * child->weight;

  3617.         ngx_http_v2_node_children_update(child);
  3618.     }
  3619. }


  3620. static void
  3621. ngx_http_v2_pool_cleanup(void *data)
  3622. {
  3623.     ngx_http_v2_connection_t  *h2c = data;

  3624.     if (h2c->state.pool) {
  3625.         ngx_destroy_pool(h2c->state.pool);
  3626.     }

  3627.     if (h2c->pool) {
  3628.         ngx_destroy_pool(h2c->pool);
  3629.     }
  3630. }