Back to home page

Nginx displayed by LXR

Source navigation ]
Diff markup ]
Identifier search ]
general search ]
 
 
Version: nginx-1.15.11 ]​[ nginx-1.14.2 ]​

0001 /*
0002  * Copyright (C) Nginx, Inc.
0003  * Copyright (C) Valentin V. Bartenev
0004  */
0005 
0006 
0007 #ifndef _NGX_HTTP_V2_H_INCLUDED_
0008 #define _NGX_HTTP_V2_H_INCLUDED_
0009 
0010 
0011 #include <ngx_config.h>
0012 #include <ngx_core.h>
0013 #include <ngx_http.h>
0014 
0015 
0016 #define NGX_HTTP_V2_ALPN_ADVERTISE       "\x02h2"
0017 #define NGX_HTTP_V2_NPN_ADVERTISE        NGX_HTTP_V2_ALPN_ADVERTISE
0018 
0019 #define NGX_HTTP_V2_STATE_BUFFER_SIZE    16
0020 
0021 #define NGX_HTTP_V2_DEFAULT_FRAME_SIZE   (1 << 14)
0022 #define NGX_HTTP_V2_MAX_FRAME_SIZE       ((1 << 24) - 1)
0023 
0024 #define NGX_HTTP_V2_INT_OCTETS           4
0025 #define NGX_HTTP_V2_MAX_FIELD                                                 \
0026     (127 + (1 << (NGX_HTTP_V2_INT_OCTETS - 1) * 7) - 1)
0027 
0028 #define NGX_HTTP_V2_STREAM_ID_SIZE       4
0029 
0030 #define NGX_HTTP_V2_FRAME_HEADER_SIZE    9
0031 
0032 /* frame types */
0033 #define NGX_HTTP_V2_DATA_FRAME           0x0
0034 #define NGX_HTTP_V2_HEADERS_FRAME        0x1
0035 #define NGX_HTTP_V2_PRIORITY_FRAME       0x2
0036 #define NGX_HTTP_V2_RST_STREAM_FRAME     0x3
0037 #define NGX_HTTP_V2_SETTINGS_FRAME       0x4
0038 #define NGX_HTTP_V2_PUSH_PROMISE_FRAME   0x5
0039 #define NGX_HTTP_V2_PING_FRAME           0x6
0040 #define NGX_HTTP_V2_GOAWAY_FRAME         0x7
0041 #define NGX_HTTP_V2_WINDOW_UPDATE_FRAME  0x8
0042 #define NGX_HTTP_V2_CONTINUATION_FRAME   0x9
0043 
0044 /* frame flags */
0045 #define NGX_HTTP_V2_NO_FLAG              0x00
0046 #define NGX_HTTP_V2_ACK_FLAG             0x01
0047 #define NGX_HTTP_V2_END_STREAM_FLAG      0x01
0048 #define NGX_HTTP_V2_END_HEADERS_FLAG     0x04
0049 #define NGX_HTTP_V2_PADDED_FLAG          0x08
0050 #define NGX_HTTP_V2_PRIORITY_FLAG        0x20
0051 
0052 #define NGX_HTTP_V2_MAX_WINDOW           ((1U << 31) - 1)
0053 #define NGX_HTTP_V2_DEFAULT_WINDOW       65535
0054 
0055 #define NGX_HTTP_V2_DEFAULT_WEIGHT       16
0056 
0057 
0058 typedef struct ngx_http_v2_connection_s   ngx_http_v2_connection_t;
0059 typedef struct ngx_http_v2_node_s         ngx_http_v2_node_t;
0060 typedef struct ngx_http_v2_out_frame_s    ngx_http_v2_out_frame_t;
0061 
0062 
0063 typedef u_char *(*ngx_http_v2_handler_pt) (ngx_http_v2_connection_t *h2c,
0064     u_char *pos, u_char *end);
0065 
0066 
0067 typedef struct {
0068     ngx_str_t                        name;
0069     ngx_str_t                        value;
0070 } ngx_http_v2_header_t;
0071 
0072 
0073 typedef struct {
0074     ngx_uint_t                       sid;
0075     size_t                           length;
0076     size_t                           padding;
0077     unsigned                         flags:8;
0078 
0079     unsigned                         incomplete:1;
0080     unsigned                         keep_pool:1;
0081 
0082     /* HPACK */
0083     unsigned                         parse_name:1;
0084     unsigned                         parse_value:1;
0085     unsigned                         index:1;
0086     ngx_http_v2_header_t             header;
0087     size_t                           header_limit;
0088     u_char                           field_state;
0089     u_char                          *field_start;
0090     u_char                          *field_end;
0091     size_t                           field_rest;
0092     ngx_pool_t                      *pool;
0093 
0094     ngx_http_v2_stream_t            *stream;
0095 
0096     u_char                           buffer[NGX_HTTP_V2_STATE_BUFFER_SIZE];
0097     size_t                           buffer_used;
0098     ngx_http_v2_handler_pt           handler;
0099 } ngx_http_v2_state_t;
0100 
0101 
0102 
0103 typedef struct {
0104     ngx_http_v2_header_t           **entries;
0105 
0106     ngx_uint_t                       added;
0107     ngx_uint_t                       deleted;
0108     ngx_uint_t                       reused;
0109     ngx_uint_t                       allocated;
0110 
0111     size_t                           size;
0112     size_t                           free;
0113     u_char                          *storage;
0114     u_char                          *pos;
0115 } ngx_http_v2_hpack_t;
0116 
0117 
0118 struct ngx_http_v2_connection_s {
0119     ngx_connection_t                *connection;
0120     ngx_http_connection_t           *http_connection;
0121 
0122     ngx_uint_t                       processing;
0123     ngx_uint_t                       frames;
0124     ngx_uint_t                       idle;
0125 
0126     ngx_uint_t                       pushing;
0127     ngx_uint_t                       concurrent_pushes;
0128 
0129     size_t                           send_window;
0130     size_t                           recv_window;
0131     size_t                           init_window;
0132 
0133     size_t                           frame_size;
0134 
0135     ngx_queue_t                      waiting;
0136 
0137     ngx_http_v2_state_t              state;
0138 
0139     ngx_http_v2_hpack_t              hpack;
0140 
0141     ngx_pool_t                      *pool;
0142 
0143     ngx_http_v2_out_frame_t         *free_frames;
0144     ngx_connection_t                *free_fake_connections;
0145 
0146     ngx_http_v2_node_t             **streams_index;
0147 
0148     ngx_http_v2_out_frame_t         *last_out;
0149 
0150     ngx_queue_t                      dependencies;
0151     ngx_queue_t                      closed;
0152 
0153     ngx_uint_t                       last_sid;
0154     ngx_uint_t                       last_push;
0155 
0156     unsigned                         closed_nodes:8;
0157     unsigned                         settings_ack:1;
0158     unsigned                         table_update:1;
0159     unsigned                         blocked:1;
0160     unsigned                         goaway:1;
0161     unsigned                         push_disabled:1;
0162 };
0163 
0164 
0165 struct ngx_http_v2_node_s {
0166     ngx_uint_t                       id;
0167     ngx_http_v2_node_t              *index;
0168     ngx_http_v2_node_t              *parent;
0169     ngx_queue_t                      queue;
0170     ngx_queue_t                      children;
0171     ngx_queue_t                      reuse;
0172     ngx_uint_t                       rank;
0173     ngx_uint_t                       weight;
0174     double                           rel_weight;
0175     ngx_http_v2_stream_t            *stream;
0176 };
0177 
0178 
0179 struct ngx_http_v2_stream_s {
0180     ngx_http_request_t              *request;
0181     ngx_http_v2_connection_t        *connection;
0182     ngx_http_v2_node_t              *node;
0183 
0184     ngx_uint_t                       queued;
0185 
0186     /*
0187      * A change to SETTINGS_INITIAL_WINDOW_SIZE could cause the
0188      * send_window to become negative, hence it's signed.
0189      */
0190     ssize_t                          send_window;
0191     size_t                           recv_window;
0192 
0193     ngx_buf_t                       *preread;
0194 
0195     ngx_http_v2_out_frame_t         *free_frames;
0196     ngx_chain_t                     *free_frame_headers;
0197     ngx_chain_t                     *free_bufs;
0198 
0199     ngx_queue_t                      queue;
0200 
0201     ngx_array_t                     *cookies;
0202 
0203     ngx_pool_t                      *pool;
0204 
0205     unsigned                         waiting:1;
0206     unsigned                         blocked:1;
0207     unsigned                         exhausted:1;
0208     unsigned                         in_closed:1;
0209     unsigned                         out_closed:1;
0210     unsigned                         rst_sent:1;
0211     unsigned                         no_flow_control:1;
0212     unsigned                         skip_data:1;
0213 };
0214 
0215 
0216 struct ngx_http_v2_out_frame_s {
0217     ngx_http_v2_out_frame_t         *next;
0218     ngx_chain_t                     *first;
0219     ngx_chain_t                     *last;
0220     ngx_int_t                      (*handler)(ngx_http_v2_connection_t *h2c,
0221                                         ngx_http_v2_out_frame_t *frame);
0222 
0223     ngx_http_v2_stream_t            *stream;
0224     size_t                           length;
0225 
0226     unsigned                         blocked:1;
0227     unsigned                         fin:1;
0228 };
0229 
0230 
0231 static ngx_inline void
0232 ngx_http_v2_queue_frame(ngx_http_v2_connection_t *h2c,
0233     ngx_http_v2_out_frame_t *frame)
0234 {
0235     ngx_http_v2_out_frame_t  **out;
0236 
0237     for (out = &h2c->last_out; *out; out = &(*out)->next) {
0238 
0239         if ((*out)->blocked || (*out)->stream == NULL) {
0240             break;
0241         }
0242 
0243         if ((*out)->stream->node->rank < frame->stream->node->rank
0244             || ((*out)->stream->node->rank == frame->stream->node->rank
0245                 && (*out)->stream->node->rel_weight
0246                    >= frame->stream->node->rel_weight))
0247         {
0248             break;
0249         }
0250     }
0251 
0252     frame->next = *out;
0253     *out = frame;
0254 }
0255 
0256 
0257 static ngx_inline void
0258 ngx_http_v2_queue_blocked_frame(ngx_http_v2_connection_t *h2c,
0259     ngx_http_v2_out_frame_t *frame)
0260 {
0261     ngx_http_v2_out_frame_t  **out;
0262 
0263     for (out = &h2c->last_out; *out; out = &(*out)->next) {
0264 
0265         if ((*out)->blocked || (*out)->stream == NULL) {
0266             break;
0267         }
0268     }
0269 
0270     frame->next = *out;
0271     *out = frame;
0272 }
0273 
0274 
0275 static ngx_inline void
0276 ngx_http_v2_queue_ordered_frame(ngx_http_v2_connection_t *h2c,
0277     ngx_http_v2_out_frame_t *frame)
0278 {
0279     frame->next = h2c->last_out;
0280     h2c->last_out = frame;
0281 }
0282 
0283 
0284 void ngx_http_v2_init(ngx_event_t *rev);
0285 
0286 ngx_int_t ngx_http_v2_read_request_body(ngx_http_request_t *r);
0287 ngx_int_t ngx_http_v2_read_unbuffered_request_body(ngx_http_request_t *r);
0288 
0289 ngx_http_v2_stream_t *ngx_http_v2_push_stream(ngx_http_v2_stream_t *parent,
0290     ngx_str_t *path);
0291 
0292 void ngx_http_v2_close_stream(ngx_http_v2_stream_t *stream, ngx_int_t rc);
0293 
0294 ngx_int_t ngx_http_v2_send_output_queue(ngx_http_v2_connection_t *h2c);
0295 
0296 
0297 ngx_str_t *ngx_http_v2_get_static_name(ngx_uint_t index);
0298 ngx_str_t *ngx_http_v2_get_static_value(ngx_uint_t index);
0299 
0300 ngx_int_t ngx_http_v2_get_indexed_header(ngx_http_v2_connection_t *h2c,
0301     ngx_uint_t index, ngx_uint_t name_only);
0302 ngx_int_t ngx_http_v2_add_header(ngx_http_v2_connection_t *h2c,
0303     ngx_http_v2_header_t *header);
0304 ngx_int_t ngx_http_v2_table_size(ngx_http_v2_connection_t *h2c, size_t size);
0305 
0306 
0307 ngx_int_t ngx_http_v2_huff_decode(u_char *state, u_char *src, size_t len,
0308     u_char **dst, ngx_uint_t last, ngx_log_t *log);
0309 size_t ngx_http_v2_huff_encode(u_char *src, size_t len, u_char *dst,
0310     ngx_uint_t lower);
0311 
0312 
0313 #define ngx_http_v2_prefix(bits)  ((1 << (bits)) - 1)
0314 
0315 
0316 #if (NGX_HAVE_NONALIGNED)
0317 
0318 #define ngx_http_v2_parse_uint16(p)  ntohs(*(uint16_t *) (p))
0319 #define ngx_http_v2_parse_uint32(p)  ntohl(*(uint32_t *) (p))
0320 
0321 #else
0322 
0323 #define ngx_http_v2_parse_uint16(p)  ((p)[0] << 8 | (p)[1])
0324 #define ngx_http_v2_parse_uint32(p)                                           \
0325     ((uint32_t) (p)[0] << 24 | (p)[1] << 16 | (p)[2] << 8 | (p)[3])
0326 
0327 #endif
0328 
0329 #define ngx_http_v2_parse_length(p)  ((p) >> 8)
0330 #define ngx_http_v2_parse_type(p)    ((p) & 0xff)
0331 #define ngx_http_v2_parse_sid(p)     (ngx_http_v2_parse_uint32(p) & 0x7fffffff)
0332 #define ngx_http_v2_parse_window(p)  (ngx_http_v2_parse_uint32(p) & 0x7fffffff)
0333 
0334 
0335 #define ngx_http_v2_write_uint16_aligned(p, s)                                \
0336     (*(uint16_t *) (p) = htons((uint16_t) (s)), (p) + sizeof(uint16_t))
0337 #define ngx_http_v2_write_uint32_aligned(p, s)                                \
0338     (*(uint32_t *) (p) = htonl((uint32_t) (s)), (p) + sizeof(uint32_t))
0339 
0340 #if (NGX_HAVE_NONALIGNED)
0341 
0342 #define ngx_http_v2_write_uint16  ngx_http_v2_write_uint16_aligned
0343 #define ngx_http_v2_write_uint32  ngx_http_v2_write_uint32_aligned
0344 
0345 #else
0346 
0347 #define ngx_http_v2_write_uint16(p, s)                                        \
0348     ((p)[0] = (u_char) ((s) >> 8),                                            \
0349      (p)[1] = (u_char)  (s),                                                  \
0350      (p) + sizeof(uint16_t))
0351 
0352 #define ngx_http_v2_write_uint32(p, s)                                        \
0353     ((p)[0] = (u_char) ((s) >> 24),                                           \
0354      (p)[1] = (u_char) ((s) >> 16),                                           \
0355      (p)[2] = (u_char) ((s) >> 8),                                            \
0356      (p)[3] = (u_char)  (s),                                                  \
0357      (p) + sizeof(uint32_t))
0358 
0359 #endif
0360 
0361 #define ngx_http_v2_write_len_and_type(p, l, t)                               \
0362     ngx_http_v2_write_uint32_aligned(p, (l) << 8 | (t))
0363 
0364 #define ngx_http_v2_write_sid  ngx_http_v2_write_uint32
0365 
0366 
0367 #define ngx_http_v2_indexed(i)      (128 + (i))
0368 #define ngx_http_v2_inc_indexed(i)  (64 + (i))
0369 
0370 #define ngx_http_v2_write_name(dst, src, len, tmp)                            \
0371     ngx_http_v2_string_encode(dst, src, len, tmp, 1)
0372 #define ngx_http_v2_write_value(dst, src, len, tmp)                           \
0373     ngx_http_v2_string_encode(dst, src, len, tmp, 0)
0374 
0375 #define NGX_HTTP_V2_ENCODE_RAW            0
0376 #define NGX_HTTP_V2_ENCODE_HUFF           0x80
0377 
0378 #define NGX_HTTP_V2_AUTHORITY_INDEX       1
0379 
0380 #define NGX_HTTP_V2_METHOD_INDEX          2
0381 #define NGX_HTTP_V2_METHOD_GET_INDEX      2
0382 #define NGX_HTTP_V2_METHOD_POST_INDEX     3
0383 
0384 #define NGX_HTTP_V2_PATH_INDEX            4
0385 #define NGX_HTTP_V2_PATH_ROOT_INDEX       4
0386 
0387 #define NGX_HTTP_V2_SCHEME_HTTP_INDEX     6
0388 #define NGX_HTTP_V2_SCHEME_HTTPS_INDEX    7
0389 
0390 #define NGX_HTTP_V2_STATUS_INDEX          8
0391 #define NGX_HTTP_V2_STATUS_200_INDEX      8
0392 #define NGX_HTTP_V2_STATUS_204_INDEX      9
0393 #define NGX_HTTP_V2_STATUS_206_INDEX      10
0394 #define NGX_HTTP_V2_STATUS_304_INDEX      11
0395 #define NGX_HTTP_V2_STATUS_400_INDEX      12
0396 #define NGX_HTTP_V2_STATUS_404_INDEX      13
0397 #define NGX_HTTP_V2_STATUS_500_INDEX      14
0398 
0399 #define NGX_HTTP_V2_ACCEPT_ENCODING_INDEX 16
0400 #define NGX_HTTP_V2_ACCEPT_LANGUAGE_INDEX 17
0401 #define NGX_HTTP_V2_CONTENT_LENGTH_INDEX  28
0402 #define NGX_HTTP_V2_CONTENT_TYPE_INDEX    31
0403 #define NGX_HTTP_V2_DATE_INDEX            33
0404 #define NGX_HTTP_V2_LAST_MODIFIED_INDEX   44
0405 #define NGX_HTTP_V2_LOCATION_INDEX        46
0406 #define NGX_HTTP_V2_SERVER_INDEX          54
0407 #define NGX_HTTP_V2_USER_AGENT_INDEX      58
0408 #define NGX_HTTP_V2_VARY_INDEX            59
0409 
0410 
0411 u_char *ngx_http_v2_string_encode(u_char *dst, u_char *src, size_t len,
0412     u_char *tmp, ngx_uint_t lower);
0413 
0414 
0415 #endif /* _NGX_HTTP_V2_H_INCLUDED_ */