src/http/v2/ngx_http_v2.h - nginx-1.31.9 nginx/ @ 2a3a19c6f

Data types defined

Functions defined

Macros defined

Source code

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


  5. #ifndef _NGX_HTTP_V2_H_INCLUDED_
  6. ‌#define _NGX_HTTP_V2_H_INCLUDED_


  7. #include <ngx_config.h>
  8. #include <ngx_core.h>
  9. #include <ngx_http.h>


  10. ‌#define NGX_HTTP_V2_ALPN_PROTO           "\x02h2"

  11. ‌#define NGX_HTTP_V2_STATE_BUFFER_SIZE    16

  12. ‌#define NGX_HTTP_V2_DEFAULT_FRAME_SIZE   (1 << 14)
  13. ‌#define NGX_HTTP_V2_MAX_FRAME_SIZE       ((1 << 24) - 1)

  14. ‌#define NGX_HTTP_V2_INT_OCTETS           4
  15. ‌#define NGX_HTTP_V2_MAX_FIELD                                                 \
  16.     (127 + (1 << (NGX_HTTP_V2_INT_OCTETS - 1) * 7) - 1)

  17. ‌#define NGX_HTTP_V2_FRAME_HEADER_SIZE    9

  18. /* frame types */
  19. ‌#define NGX_HTTP_V2_DATA_FRAME             0x00
  20. ‌#define NGX_HTTP_V2_HEADERS_FRAME          0x01
  21. ‌#define NGX_HTTP_V2_PRIORITY_FRAME         0x02
  22. ‌#define NGX_HTTP_V2_RST_STREAM_FRAME       0x03
  23. ‌#define NGX_HTTP_V2_SETTINGS_FRAME         0x04
  24. ‌#define NGX_HTTP_V2_PUSH_PROMISE_FRAME     0x05
  25. ‌#define NGX_HTTP_V2_PING_FRAME             0x06
  26. ‌#define NGX_HTTP_V2_GOAWAY_FRAME           0x07
  27. ‌#define NGX_HTTP_V2_WINDOW_UPDATE_FRAME    0x08
  28. ‌#define NGX_HTTP_V2_CONTINUATION_FRAME     0x09
  29. ‌#define NGX_HTTP_V2_PRIORITY_UPDATE_FRAME  0x10

  30. /* frame flags */
  31. ‌#define NGX_HTTP_V2_NO_FLAG              0x00
  32. ‌#define NGX_HTTP_V2_ACK_FLAG             0x01
  33. ‌#define NGX_HTTP_V2_END_STREAM_FLAG      0x01
  34. ‌#define NGX_HTTP_V2_END_HEADERS_FLAG     0x04
  35. ‌#define NGX_HTTP_V2_PADDED_FLAG          0x08
  36. ‌#define NGX_HTTP_V2_PRIORITY_FLAG        0x20

  37. ‌#define NGX_HTTP_V2_MAX_WINDOW           ((1U << 31) - 1)
  38. ‌#define NGX_HTTP_V2_DEFAULT_WINDOW       65535


  39. ‌typedef struct ngx_http_v2_connection_s   ngx_http_v2_connection_t;
  40. ‌typedef struct ngx_http_v2_node_s         ngx_http_v2_node_t;
  41. ‌typedef struct ngx_http_v2_out_frame_s    ngx_http_v2_out_frame_t;


  42. ‌typedef u_char *(*ngx_http_v2_handler_pt) (ngx_http_v2_connection_t *h2c,
  43.     u_char *pos, u_char *end);


  44. ‌typedef struct {
  45.     ngx_flag_t                       enable;
  46.     size_t                           pool_size;
  47.     ngx_uint_t                       concurrent_streams;
  48.     size_t                           preread_size;
  49.     ngx_uint_t                       streams_index_mask;
  50. ‌} ngx_http_v2_srv_conf_t;


  51. ‌typedef struct {
  52.     ngx_str_t                        name;
  53.     ngx_str_t                        value;
  54. ‌} ngx_http_v2_header_t;


  55. ‌typedef struct {
  56.     ngx_uint_t                       sid;
  57.     size_t                           length;
  58.     size_t                           padding;
  59.     ssize_t                          window_delta;
  60.     unsigned                         flags:8;

  61.     unsigned                         incomplete:1;
  62.     unsigned                         keep_pool:1;

  63.     /* HPACK */
  64.     unsigned                         parse_name:1;
  65.     unsigned                         parse_value:1;
  66.     unsigned                         index:1;
  67.     ngx_http_v2_header_t             header;
  68.     size_t                           header_limit;
  69.     u_char                           field_state;
  70.     u_char                          *field_start;
  71.     u_char                          *field_end;
  72.     size_t                           field_rest;
  73.     ngx_pool_t                      *pool;

  74.     ngx_http_v2_stream_t            *stream;

  75.     u_char                           buffer[NGX_HTTP_V2_STATE_BUFFER_SIZE];
  76.     size_t                           buffer_used;
  77.     ngx_http_v2_handler_pt           handler;
  78. ‌} ngx_http_v2_state_t;



  79. ‌typedef struct {
  80.     ngx_http_v2_header_t           **entries;

  81.     ngx_uint_t                       added;
  82.     ngx_uint_t                       deleted;
  83.     ngx_uint_t                       reused;
  84.     ngx_uint_t                       allocated;

  85.     size_t                           size;
  86.     size_t                           free;
  87.     u_char                          *storage;
  88.     u_char                          *pos;
  89. ‌} ngx_http_v2_hpack_t;


  90. ‌struct ngx_http_v2_connection_s {
  91.     ngx_connection_t                *connection;
  92.     ngx_http_connection_t           *http_connection;

  93.     off_t                            total_bytes;
  94.     off_t                            payload_bytes;

  95.     ngx_uint_t                       processing;
  96.     ngx_uint_t                       frames;
  97.     ngx_uint_t                       idle;
  98.     ngx_uint_t                       new_streams;
  99.     ngx_uint_t                       refused_streams;

  100.     size_t                           send_window;
  101.     size_t                           recv_window;
  102.     size_t                           init_window;

  103.     size_t                           frame_size;

  104.     ngx_queue_t                      waiting;

  105.     ngx_http_v2_state_t              state;

  106.     ngx_http_v2_hpack_t              hpack;

  107.     ngx_pool_t                      *pool;

  108.     ngx_http_v2_out_frame_t         *free_frames;
  109.     ngx_connection_t                *free_fake_connections;

  110.     ngx_http_v2_node_t             **streams_index;

  111.     ngx_http_v2_out_frame_t         *last_out;

  112.     ngx_queue_t                      closed;

  113.     ngx_uint_t                       closed_nodes;
  114.     ngx_uint_t                       last_sid;

  115.     time_t                           lingering_time;

  116.     unsigned                         settings_ack:1;
  117.     unsigned                         table_update:1;
  118.     unsigned                         blocked:1;
  119.     unsigned                         goaway:1;
  120. };


  121. ‌struct ngx_http_v2_node_s {
  122.     ngx_uint_t                       id;
  123.     ngx_http_v2_node_t              *index;
  124.     ngx_queue_t                      reuse;
  125.     ngx_http_v2_stream_t            *stream;
  126.     ngx_http_priority_t              priority;
  127.     ngx_uint_t                       priority_set; /* unsigned priority_set:1 */
  128. };


  129. ‌struct ngx_http_v2_stream_s {
  130.     ngx_http_request_t              *request;
  131.     ngx_http_v2_connection_t        *connection;
  132.     ngx_http_v2_node_t              *node;

  133.     ngx_uint_t                       queued;

  134.     /*
  135.      * A change to SETTINGS_INITIAL_WINDOW_SIZE could cause the
  136.      * send_window to become negative, hence it's signed.
  137.      */
  138.     ssize_t                          send_window;
  139.     size_t                           recv_window;

  140.     ngx_buf_t                       *preread;

  141.     ngx_uint_t                       frames;

  142.     ngx_http_v2_out_frame_t         *free_frames;
  143.     ngx_chain_t                     *free_frame_headers;
  144.     ngx_chain_t                     *free_bufs;

  145.     ngx_queue_t                      queue;

  146.     ngx_array_t                     *cookies;
  147.     ngx_array_t                     *priorities;

  148.     ngx_http_priority_state_t        priority;

  149.     ngx_pool_t                      *pool;

  150.     unsigned                         initialized:1;
  151.     unsigned                         waiting:1;
  152.     unsigned                         blocked:1;
  153.     unsigned                         exhausted:1;
  154.     unsigned                         in_closed:1;
  155.     unsigned                         out_closed:1;
  156.     unsigned                         rst_sent:1;
  157.     unsigned                         no_flow_control:1;
  158.     unsigned                         skip_data:1;
  159.     unsigned                         priority_update:1;
  160. };


  161. ‌struct ngx_http_v2_out_frame_s {
  162.     ngx_http_v2_out_frame_t         *next;
  163.     ngx_chain_t                     *first;
  164.     ngx_chain_t                     *last;
  165.     ngx_int_t                      (*handler)(ngx_http_v2_connection_t *h2c,
  166.                                         ngx_http_v2_out_frame_t *frame);

  167.     ngx_http_v2_stream_t            *stream;
  168.     size_t                           length;

  169.     unsigned                         blocked:1;
  170.     unsigned                         fin:1;
  171. };


  172. /* a non-incremental response completes sooner, equal priority is FIFO */

  173. static ngx_inline ngx_uint_t
  174. ‌ngx_http_v2_stream_precedes(ngx_http_v2_stream_t *s,
  175.     ngx_http_v2_stream_t *stream)
  176. {
  177.     ngx_http_priority_t  *a, *b;

  178.     a = &s->priority.effective;
  179.     b = &stream->priority.effective;

  180.     if (a->urgency != b->urgency) {
  181.         return a->urgency < b->urgency;
  182.     }

  183.     if (a->incremental != b->incremental) {
  184.         return !a->incremental;
  185.     }

  186.     return s->node->id <= stream->node->id;
  187. }


  188. /* all frames of a stream are queued at the same position */

  189. static ngx_inline ngx_http_v2_out_frame_t **
  190. ‌ngx_http_v2_queue_position(ngx_http_v2_connection_t *h2c,
  191.     ngx_http_v2_stream_t *stream)
  192. {
  193.     ngx_http_v2_out_frame_t  **out;

  194.     for (out = &h2c->last_out; *out; out = &(*out)->next) {

  195.         if ((*out)->blocked || (*out)->stream == NULL) {
  196.             break;
  197.         }

  198.         if (ngx_http_v2_stream_precedes((*out)->stream, stream)) {
  199.             break;
  200.         }
  201.     }

  202.     return out;
  203. }


  204. static ngx_inline void
  205. ‌ngx_http_v2_queue_frame(ngx_http_v2_out_frame_t **out,
  206.     ngx_http_v2_out_frame_t *frame)
  207. {
  208.     frame->next = *out;
  209.     *out = frame;
  210. }


  211. static ngx_inline void
  212. ‌ngx_http_v2_queue_blocked_frame(ngx_http_v2_connection_t *h2c,
  213.     ngx_http_v2_out_frame_t *frame)
  214. {
  215.     ngx_http_v2_out_frame_t  **out;

  216.     for (out = &h2c->last_out; *out; out = &(*out)->next) {

  217.         if ((*out)->blocked || (*out)->stream == NULL) {
  218.             break;
  219.         }
  220.     }

  221.     frame->next = *out;
  222.     *out = frame;
  223. }


  224. static ngx_inline void
  225. ‌ngx_http_v2_queue_ordered_frame(ngx_http_v2_connection_t *h2c,
  226.     ngx_http_v2_out_frame_t *frame)
  227. {
  228.     frame->next = h2c->last_out;
  229.     h2c->last_out = frame;
  230. }


  231. void ngx_http_v2_init(ngx_event_t *rev);

  232. ngx_int_t ngx_http_v2_read_request_body(ngx_http_request_t *r);
  233. ngx_int_t ngx_http_v2_read_unbuffered_request_body(ngx_http_request_t *r);

  234. void ngx_http_v2_close_stream(ngx_http_v2_stream_t *stream, ngx_int_t rc);

  235. ngx_int_t ngx_http_v2_send_output_queue(ngx_http_v2_connection_t *h2c);


  236. ngx_str_t *ngx_http_v2_get_static_name(ngx_uint_t index);
  237. ngx_str_t *ngx_http_v2_get_static_value(ngx_uint_t index);

  238. ngx_int_t ngx_http_v2_get_indexed_header(ngx_http_v2_connection_t *h2c,
  239.     ngx_uint_t index, ngx_uint_t name_only);
  240. ngx_int_t ngx_http_v2_add_header(ngx_http_v2_connection_t *h2c,
  241.     ngx_http_v2_header_t *header);
  242. ngx_int_t ngx_http_v2_table_size(ngx_http_v2_connection_t *h2c, size_t size);


  243. ‌#define ngx_http_v2_prefix(bits)  ((1 << (bits)) - 1)


  244. #if (NGX_HAVE_NONALIGNED)

  245. ‌#define ngx_http_v2_parse_uint16(p)  ntohs(*(uint16_t *) (p))
  246. ‌#define ngx_http_v2_parse_uint32(p)  ntohl(*(uint32_t *) (p))

  247. #else

  248. ‌#define ngx_http_v2_parse_uint16(p)  ((p)[0] << 8 | (p)[1])
  249. ‌#define ngx_http_v2_parse_uint32(p)                                           \
  250.     ((uint32_t) (p)[0] << 24 | (p)[1] << 16 | (p)[2] << 8 | (p)[3])

  251. #endif

  252. ‌#define ngx_http_v2_parse_length(p)  ((p) >> 8)
  253. ‌#define ngx_http_v2_parse_type(p)    ((p) & 0xff)
  254. ‌#define ngx_http_v2_parse_sid(p)     (ngx_http_v2_parse_uint32(p) & 0x7fffffff)
  255. ‌#define ngx_http_v2_parse_window(p)  (ngx_http_v2_parse_uint32(p) & 0x7fffffff)


  256. ‌#define ngx_http_v2_write_uint16_aligned(p, s)                                \
  257.     (*(uint16_t *) (p) = htons((uint16_t) (s)), (p) + sizeof(uint16_t))
  258. ‌#define ngx_http_v2_write_uint32_aligned(p, s)                                \
  259.     (*(uint32_t *) (p) = htonl((uint32_t) (s)), (p) + sizeof(uint32_t))

  260. #if (NGX_HAVE_NONALIGNED)

  261. ‌#define ngx_http_v2_write_uint16  ngx_http_v2_write_uint16_aligned
  262. ‌#define ngx_http_v2_write_uint32  ngx_http_v2_write_uint32_aligned

  263. #else

  264. ‌#define ngx_http_v2_write_uint16(p, s)                                        \
  265.     ((p)[0] = (u_char) ((s) >> 8),                                            \
  266.      (p)[1] = (u_char)  (s),                                                  \
  267.      (p) + sizeof(uint16_t))

  268. ‌#define ngx_http_v2_write_uint32(p, s)                                        \
  269.     ((p)[0] = (u_char) ((s) >> 24),                                           \
  270.      (p)[1] = (u_char) ((s) >> 16),                                           \
  271.      (p)[2] = (u_char) ((s) >> 8),                                            \
  272.      (p)[3] = (u_char)  (s),                                                  \
  273.      (p) + sizeof(uint32_t))

  274. #endif

  275. ‌#define ngx_http_v2_write_len_and_type(p, l, t)                               \
  276.     ngx_http_v2_write_uint32_aligned(p, (l) << 8 | (t))

  277. ‌#define ngx_http_v2_write_sid  ngx_http_v2_write_uint32


  278. ‌#define ngx_http_v2_indexed(i)      (128 + (i))
  279. ‌#define ngx_http_v2_inc_indexed(i)  (64 + (i))

  280. ‌#define ngx_http_v2_write_name(dst, src, len, tmp)                            \
  281.     ngx_http_v2_string_encode(dst, src, len, tmp, 1)
  282. ‌#define ngx_http_v2_write_value(dst, src, len, tmp)                           \
  283.     ngx_http_v2_string_encode(dst, src, len, tmp, 0)

  284. ‌#define NGX_HTTP_V2_ENCODE_RAW            0
  285. ‌#define NGX_HTTP_V2_ENCODE_HUFF           0x80

  286. ‌#define NGX_HTTP_V2_AUTHORITY_INDEX       1

  287. ‌#define NGX_HTTP_V2_METHOD_INDEX          2
  288. ‌#define NGX_HTTP_V2_METHOD_GET_INDEX      2
  289. ‌#define NGX_HTTP_V2_METHOD_POST_INDEX     3

  290. ‌#define NGX_HTTP_V2_PATH_INDEX            4
  291. ‌#define NGX_HTTP_V2_PATH_ROOT_INDEX       4

  292. ‌#define NGX_HTTP_V2_SCHEME_HTTP_INDEX     6
  293. ‌#define NGX_HTTP_V2_SCHEME_HTTPS_INDEX    7

  294. ‌#define NGX_HTTP_V2_STATUS_INDEX          8
  295. ‌#define NGX_HTTP_V2_STATUS_200_INDEX      8
  296. ‌#define NGX_HTTP_V2_STATUS_204_INDEX      9
  297. ‌#define NGX_HTTP_V2_STATUS_206_INDEX      10
  298. ‌#define NGX_HTTP_V2_STATUS_304_INDEX      11
  299. ‌#define NGX_HTTP_V2_STATUS_400_INDEX      12
  300. ‌#define NGX_HTTP_V2_STATUS_404_INDEX      13
  301. ‌#define NGX_HTTP_V2_STATUS_500_INDEX      14

  302. ‌#define NGX_HTTP_V2_CONTENT_LENGTH_INDEX  28
  303. ‌#define NGX_HTTP_V2_CONTENT_TYPE_INDEX    31
  304. ‌#define NGX_HTTP_V2_DATE_INDEX            33
  305. ‌#define NGX_HTTP_V2_LAST_MODIFIED_INDEX   44
  306. ‌#define NGX_HTTP_V2_LOCATION_INDEX        46
  307. ‌#define NGX_HTTP_V2_SERVER_INDEX          54
  308. ‌#define NGX_HTTP_V2_VARY_INDEX            59

  309. ‌#define NGX_HTTP_V2_PREFACE_START         "PRI * HTTP/2.0\r\n"
  310. ‌#define NGX_HTTP_V2_PREFACE_END           "\r\nSM\r\n\r\n"
  311. ‌#define NGX_HTTP_V2_PREFACE               NGX_HTTP_V2_PREFACE_START           \
  312.                                           NGX_HTTP_V2_PREFACE_END


  313. u_char *ngx_http_v2_string_encode(u_char *dst, u_char *src, size_t len,
  314.     u_char *tmp, ngx_uint_t lower);


  315. extern ngx_module_t  ngx_http_v2_module;


  316. #endif /* _NGX_HTTP_V2_H_INCLUDED_ */