Back to home page

Nginx displayed by LXR

Source navigation ]
Diff markup ]
Identifier search ]
general search ]
 
 
Version: nginx-1.13.12 ]​[ nginx-1.12.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 
0124     ngx_uint_t                       pushing;
0125     ngx_uint_t                       concurrent_pushes;
0126 
0127     size_t                           send_window;
0128     size_t                           recv_window;
0129     size_t                           init_window;
0130 
0131     size_t                           frame_size;
0132 
0133     ngx_queue_t                      waiting;
0134 
0135     ngx_http_v2_state_t              state;
0136 
0137     ngx_http_v2_hpack_t              hpack;
0138 
0139     ngx_pool_t                      *pool;
0140 
0141     ngx_http_v2_out_frame_t         *free_frames;
0142     ngx_connection_t                *free_fake_connections;
0143 
0144     ngx_http_v2_node_t             **streams_index;
0145 
0146     ngx_http_v2_out_frame_t         *last_out;
0147 
0148     ngx_queue_t                      dependencies;
0149     ngx_queue_t                      closed;
0150 
0151     ngx_uint_t                       last_sid;
0152     ngx_uint_t                       last_push;
0153 
0154     unsigned                         closed_nodes:8;
0155     unsigned                         settings_ack:1;
0156     unsigned                         table_update:1;
0157     unsigned                         blocked:1;
0158     unsigned                         goaway:1;
0159     unsigned                         push_disabled:1;
0160 };
0161 
0162 
0163 struct ngx_http_v2_node_s {
0164     ngx_uint_t                       id;
0165     ngx_http_v2_node_t              *index;
0166     ngx_http_v2_node_t              *parent;
0167     ngx_queue_t                      queue;
0168     ngx_queue_t                      children;
0169     ngx_queue_t                      reuse;
0170     ngx_uint_t                       rank;
0171     ngx_uint_t                       weight;
0172     double                           rel_weight;
0173     ngx_http_v2_stream_t            *stream;
0174 };
0175 
0176 
0177 struct ngx_http_v2_stream_s {
0178     ngx_http_request_t              *request;
0179     ngx_http_v2_connection_t        *connection;
0180     ngx_http_v2_node_t              *node;
0181 
0182     ngx_uint_t                       queued;
0183 
0184     /*
0185      * A change to SETTINGS_INITIAL_WINDOW_SIZE could cause the
0186      * send_window to become negative, hence it's signed.
0187      */
0188     ssize_t                          send_window;
0189     size_t                           recv_window;
0190 
0191     ngx_buf_t                       *preread;
0192 
0193     ngx_http_v2_out_frame_t         *free_frames;
0194     ngx_chain_t                     *free_frame_headers;
0195     ngx_chain_t                     *free_bufs;
0196 
0197     ngx_queue_t                      queue;
0198 
0199     ngx_array_t                     *cookies;
0200 
0201     ngx_pool_t                      *pool;
0202 
0203     unsigned                         waiting:1;
0204     unsigned                         blocked:1;
0205     unsigned                         exhausted:1;
0206     unsigned                         in_closed:1;
0207     unsigned                         out_closed:1;
0208     unsigned                         rst_sent:1;
0209     unsigned                         no_flow_control:1;
0210     unsigned                         skip_data:1;
0211 };
0212 
0213 
0214 struct ngx_http_v2_out_frame_s {
0215     ngx_http_v2_out_frame_t         *next;
0216     ngx_chain_t                     *first;
0217     ngx_chain_t                     *last;
0218     ngx_int_t                      (*handler)(ngx_http_v2_connection_t *h2c,
0219                                         ngx_http_v2_out_frame_t *frame);
0220 
0221     ngx_http_v2_stream_t            *stream;
0222     size_t                           length;
0223 
0224     unsigned                         blocked:1;
0225     unsigned                         fin:1;
0226 };
0227 
0228 
0229 static ngx_inline void
0230 ngx_http_v2_queue_frame(ngx_http_v2_connection_t *h2c,
0231     ngx_http_v2_out_frame_t *frame)
0232 {
0233     ngx_http_v2_out_frame_t  **out;
0234 
0235     for (out = &h2c->last_out; *out; out = &(*out)->next) {
0236 
0237         if ((*out)->blocked || (*out)->stream == NULL) {
0238             break;
0239         }
0240 
0241         if ((*out)->stream->node->rank < frame->stream->node->rank
0242             || ((*out)->stream->node->rank == frame->stream->node->rank
0243                 && (*out)->stream->node->rel_weight
0244                    >= frame->stream->node->rel_weight))
0245         {
0246             break;
0247         }
0248     }
0249 
0250     frame->next = *out;
0251     *out = frame;
0252 }
0253 
0254 
0255 static ngx_inline void
0256 ngx_http_v2_queue_blocked_frame(ngx_http_v2_connection_t *h2c,
0257     ngx_http_v2_out_frame_t *frame)
0258 {
0259     ngx_http_v2_out_frame_t  **out;
0260 
0261     for (out = &h2c->last_out; *out; out = &(*out)->next) {
0262 
0263         if ((*out)->blocked || (*out)->stream == NULL) {
0264             break;
0265         }
0266     }
0267 
0268     frame->next = *out;
0269     *out = frame;
0270 }
0271 
0272 
0273 static ngx_inline void
0274 ngx_http_v2_queue_ordered_frame(ngx_http_v2_connection_t *h2c,
0275     ngx_http_v2_out_frame_t *frame)
0276 {
0277     frame->next = h2c->last_out;
0278     h2c->last_out = frame;
0279 }
0280 
0281 
0282 void ngx_http_v2_init(ngx_event_t *rev);
0283 
0284 ngx_int_t ngx_http_v2_read_request_body(ngx_http_request_t *r);
0285 ngx_int_t ngx_http_v2_read_unbuffered_request_body(ngx_http_request_t *r);
0286 
0287 ngx_http_v2_stream_t *ngx_http_v2_push_stream(ngx_http_v2_stream_t *parent,
0288     ngx_str_t *path);
0289 
0290 void ngx_http_v2_close_stream(ngx_http_v2_stream_t *stream, ngx_int_t rc);
0291 
0292 ngx_int_t ngx_http_v2_send_output_queue(ngx_http_v2_connection_t *h2c);
0293 
0294 
0295 ngx_str_t *ngx_http_v2_get_static_name(ngx_uint_t index);
0296 ngx_str_t *ngx_http_v2_get_static_value(ngx_uint_t index);
0297 
0298 ngx_int_t ngx_http_v2_get_indexed_header(ngx_http_v2_connection_t *h2c,
0299     ngx_uint_t index, ngx_uint_t name_only);
0300 ngx_int_t ngx_http_v2_add_header(ngx_http_v2_connection_t *h2c,
0301     ngx_http_v2_header_t *header);
0302 ngx_int_t ngx_http_v2_table_size(ngx_http_v2_connection_t *h2c, size_t size);
0303 
0304 
0305 ngx_int_t ngx_http_v2_huff_decode(u_char *state, u_char *src, size_t len,
0306     u_char **dst, ngx_uint_t last, ngx_log_t *log);
0307 size_t ngx_http_v2_huff_encode(u_char *src, size_t len, u_char *dst,
0308     ngx_uint_t lower);
0309 
0310 
0311 #define ngx_http_v2_prefix(bits)  ((1 << (bits)) - 1)
0312 
0313 
0314 #if (NGX_HAVE_NONALIGNED)
0315 
0316 #define ngx_http_v2_parse_uint16(p)  ntohs(*(uint16_t *) (p))
0317 #define ngx_http_v2_parse_uint32(p)  ntohl(*(uint32_t *) (p))
0318 
0319 #else
0320 
0321 #define ngx_http_v2_parse_uint16(p)  ((p)[0] << 8 | (p)[1])
0322 #define ngx_http_v2_parse_uint32(p)                                           \
0323     ((uint32_t) (p)[0] << 24 | (p)[1] << 16 | (p)[2] << 8 | (p)[3])
0324 
0325 #endif
0326 
0327 #define ngx_http_v2_parse_length(p)  ((p) >> 8)
0328 #define ngx_http_v2_parse_type(p)    ((p) & 0xff)
0329 #define ngx_http_v2_parse_sid(p)     (ngx_http_v2_parse_uint32(p) & 0x7fffffff)
0330 #define ngx_http_v2_parse_window(p)  (ngx_http_v2_parse_uint32(p) & 0x7fffffff)
0331 
0332 
0333 #define ngx_http_v2_write_uint16_aligned(p, s)                                \
0334     (*(uint16_t *) (p) = htons((uint16_t) (s)), (p) + sizeof(uint16_t))
0335 #define ngx_http_v2_write_uint32_aligned(p, s)                                \
0336     (*(uint32_t *) (p) = htonl((uint32_t) (s)), (p) + sizeof(uint32_t))
0337 
0338 #if (NGX_HAVE_NONALIGNED)
0339 
0340 #define ngx_http_v2_write_uint16  ngx_http_v2_write_uint16_aligned
0341 #define ngx_http_v2_write_uint32  ngx_http_v2_write_uint32_aligned
0342 
0343 #else
0344 
0345 #define ngx_http_v2_write_uint16(p, s)                                        \
0346     ((p)[0] = (u_char) ((s) >> 8),                                            \
0347      (p)[1] = (u_char)  (s),                                                  \
0348      (p) + sizeof(uint16_t))
0349 
0350 #define ngx_http_v2_write_uint32(p, s)                                        \
0351     ((p)[0] = (u_char) ((s) >> 24),                                           \
0352      (p)[1] = (u_char) ((s) >> 16),                                           \
0353      (p)[2] = (u_char) ((s) >> 8),                                            \
0354      (p)[3] = (u_char)  (s),                                                  \
0355      (p) + sizeof(uint32_t))
0356 
0357 #endif
0358 
0359 #define ngx_http_v2_write_len_and_type(p, l, t)                               \
0360     ngx_http_v2_write_uint32_aligned(p, (l) << 8 | (t))
0361 
0362 #define ngx_http_v2_write_sid  ngx_http_v2_write_uint32
0363 
0364 
0365 #define ngx_http_v2_indexed(i)      (128 + (i))
0366 #define ngx_http_v2_inc_indexed(i)  (64 + (i))
0367 
0368 #define ngx_http_v2_write_name(dst, src, len, tmp)                            \
0369     ngx_http_v2_string_encode(dst, src, len, tmp, 1)
0370 #define ngx_http_v2_write_value(dst, src, len, tmp)                           \
0371     ngx_http_v2_string_encode(dst, src, len, tmp, 0)
0372 
0373 #define NGX_HTTP_V2_ENCODE_RAW            0
0374 #define NGX_HTTP_V2_ENCODE_HUFF           0x80
0375 
0376 #define NGX_HTTP_V2_AUTHORITY_INDEX       1
0377 
0378 #define NGX_HTTP_V2_METHOD_INDEX          2
0379 #define NGX_HTTP_V2_METHOD_GET_INDEX      2
0380 #define NGX_HTTP_V2_METHOD_POST_INDEX     3
0381 
0382 #define NGX_HTTP_V2_PATH_INDEX            4
0383 #define NGX_HTTP_V2_PATH_ROOT_INDEX       4
0384 
0385 #define NGX_HTTP_V2_SCHEME_HTTP_INDEX     6
0386 #define NGX_HTTP_V2_SCHEME_HTTPS_INDEX    7
0387 
0388 #define NGX_HTTP_V2_STATUS_INDEX          8
0389 #define NGX_HTTP_V2_STATUS_200_INDEX      8
0390 #define NGX_HTTP_V2_STATUS_204_INDEX      9
0391 #define NGX_HTTP_V2_STATUS_206_INDEX      10
0392 #define NGX_HTTP_V2_STATUS_304_INDEX      11
0393 #define NGX_HTTP_V2_STATUS_400_INDEX      12
0394 #define NGX_HTTP_V2_STATUS_404_INDEX      13
0395 #define NGX_HTTP_V2_STATUS_500_INDEX      14
0396 
0397 #define NGX_HTTP_V2_ACCEPT_ENCODING_INDEX 16
0398 #define NGX_HTTP_V2_ACCEPT_LANGUAGE_INDEX 17
0399 #define NGX_HTTP_V2_CONTENT_LENGTH_INDEX  28
0400 #define NGX_HTTP_V2_CONTENT_TYPE_INDEX    31
0401 #define NGX_HTTP_V2_DATE_INDEX            33
0402 #define NGX_HTTP_V2_LAST_MODIFIED_INDEX   44
0403 #define NGX_HTTP_V2_LOCATION_INDEX        46
0404 #define NGX_HTTP_V2_SERVER_INDEX          54
0405 #define NGX_HTTP_V2_USER_AGENT_INDEX      58
0406 #define NGX_HTTP_V2_VARY_INDEX            59
0407 
0408 
0409 u_char *ngx_http_v2_string_encode(u_char *dst, u_char *src, size_t len,
0410     u_char *tmp, ngx_uint_t lower);
0411 
0412 
0413 #endif /* _NGX_HTTP_V2_H_INCLUDED_ */