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_MAX_FRAME_SIZE       ((1 << 24) - 1)
0022 
0023 #define NGX_HTTP_V2_INT_OCTETS           4
0024 #define NGX_HTTP_V2_MAX_FIELD                                                 \
0025     (127 + (1 << (NGX_HTTP_V2_INT_OCTETS - 1) * 7) - 1)
0026 
0027 #define NGX_HTTP_V2_FRAME_HEADER_SIZE    9
0028 
0029 /* frame types */
0030 #define NGX_HTTP_V2_DATA_FRAME           0x0
0031 #define NGX_HTTP_V2_HEADERS_FRAME        0x1
0032 #define NGX_HTTP_V2_PRIORITY_FRAME       0x2
0033 #define NGX_HTTP_V2_RST_STREAM_FRAME     0x3
0034 #define NGX_HTTP_V2_SETTINGS_FRAME       0x4
0035 #define NGX_HTTP_V2_PUSH_PROMISE_FRAME   0x5
0036 #define NGX_HTTP_V2_PING_FRAME           0x6
0037 #define NGX_HTTP_V2_GOAWAY_FRAME         0x7
0038 #define NGX_HTTP_V2_WINDOW_UPDATE_FRAME  0x8
0039 #define NGX_HTTP_V2_CONTINUATION_FRAME   0x9
0040 
0041 /* frame flags */
0042 #define NGX_HTTP_V2_NO_FLAG              0x00
0043 #define NGX_HTTP_V2_ACK_FLAG             0x01
0044 #define NGX_HTTP_V2_END_STREAM_FLAG      0x01
0045 #define NGX_HTTP_V2_END_HEADERS_FLAG     0x04
0046 #define NGX_HTTP_V2_PADDED_FLAG          0x08
0047 #define NGX_HTTP_V2_PRIORITY_FLAG        0x20
0048 
0049 #define NGX_HTTP_V2_MAX_WINDOW           ((1U << 31) - 1)
0050 #define NGX_HTTP_V2_DEFAULT_WINDOW       65535
0051 
0052 
0053 typedef struct ngx_http_v2_connection_s   ngx_http_v2_connection_t;
0054 typedef struct ngx_http_v2_node_s         ngx_http_v2_node_t;
0055 typedef struct ngx_http_v2_out_frame_s    ngx_http_v2_out_frame_t;
0056 
0057 
0058 typedef u_char *(*ngx_http_v2_handler_pt) (ngx_http_v2_connection_t *h2c,
0059     u_char *pos, u_char *end);
0060 
0061 
0062 typedef struct {
0063     ngx_str_t                        name;
0064     ngx_str_t                        value;
0065 } ngx_http_v2_header_t;
0066 
0067 
0068 typedef struct {
0069     ngx_uint_t                       sid;
0070     size_t                           length;
0071     size_t                           padding;
0072     unsigned                         flags:8;
0073 
0074     unsigned                         incomplete:1;
0075     unsigned                         keep_pool:1;
0076 
0077     /* HPACK */
0078     unsigned                         parse_name:1;
0079     unsigned                         parse_value:1;
0080     unsigned                         index:1;
0081     ngx_http_v2_header_t             header;
0082     size_t                           header_limit;
0083     u_char                           field_state;
0084     u_char                          *field_start;
0085     u_char                          *field_end;
0086     size_t                           field_rest;
0087     ngx_pool_t                      *pool;
0088 
0089     ngx_http_v2_stream_t            *stream;
0090 
0091     u_char                           buffer[NGX_HTTP_V2_STATE_BUFFER_SIZE];
0092     size_t                           buffer_used;
0093     ngx_http_v2_handler_pt           handler;
0094 } ngx_http_v2_state_t;
0095 
0096 
0097 
0098 typedef struct {
0099     ngx_http_v2_header_t           **entries;
0100 
0101     ngx_uint_t                       added;
0102     ngx_uint_t                       deleted;
0103     ngx_uint_t                       reused;
0104     ngx_uint_t                       allocated;
0105 
0106     size_t                           size;
0107     size_t                           free;
0108     u_char                          *storage;
0109     u_char                          *pos;
0110 } ngx_http_v2_hpack_t;
0111 
0112 
0113 struct ngx_http_v2_connection_s {
0114     ngx_connection_t                *connection;
0115     ngx_http_connection_t           *http_connection;
0116 
0117     ngx_uint_t                       processing;
0118 
0119     size_t                           send_window;
0120     size_t                           recv_window;
0121     size_t                           init_window;
0122 
0123     size_t                           frame_size;
0124 
0125     ngx_queue_t                      waiting;
0126 
0127     ngx_http_v2_state_t              state;
0128 
0129     ngx_http_v2_hpack_t              hpack;
0130 
0131     ngx_pool_t                      *pool;
0132 
0133     ngx_http_v2_out_frame_t         *free_frames;
0134     ngx_connection_t                *free_fake_connections;
0135 
0136     ngx_http_v2_node_t             **streams_index;
0137 
0138     ngx_http_v2_out_frame_t         *last_out;
0139 
0140     ngx_queue_t                      dependencies;
0141     ngx_queue_t                      closed;
0142 
0143     ngx_uint_t                       last_sid;
0144 
0145     unsigned                         closed_nodes:8;
0146     unsigned                         settings_ack:1;
0147     unsigned                         blocked:1;
0148     unsigned                         goaway:1;
0149 };
0150 
0151 
0152 struct ngx_http_v2_node_s {
0153     ngx_uint_t                       id;
0154     ngx_http_v2_node_t              *index;
0155     ngx_http_v2_node_t              *parent;
0156     ngx_queue_t                      queue;
0157     ngx_queue_t                      children;
0158     ngx_queue_t                      reuse;
0159     ngx_uint_t                       rank;
0160     ngx_uint_t                       weight;
0161     double                           rel_weight;
0162     ngx_http_v2_stream_t            *stream;
0163 };
0164 
0165 
0166 struct ngx_http_v2_stream_s {
0167     ngx_http_request_t              *request;
0168     ngx_http_v2_connection_t        *connection;
0169     ngx_http_v2_node_t              *node;
0170 
0171     ngx_uint_t                       queued;
0172 
0173     /*
0174      * A change to SETTINGS_INITIAL_WINDOW_SIZE could cause the
0175      * send_window to become negative, hence it's signed.
0176      */
0177     ssize_t                          send_window;
0178     size_t                           recv_window;
0179 
0180     ngx_buf_t                       *preread;
0181 
0182     ngx_http_v2_out_frame_t         *free_frames;
0183     ngx_chain_t                     *free_frame_headers;
0184     ngx_chain_t                     *free_bufs;
0185 
0186     ngx_queue_t                      queue;
0187 
0188     ngx_array_t                     *cookies;
0189 
0190     size_t                           header_limit;
0191 
0192     ngx_pool_t                      *pool;
0193 
0194     unsigned                         waiting:1;
0195     unsigned                         blocked:1;
0196     unsigned                         exhausted:1;
0197     unsigned                         in_closed:1;
0198     unsigned                         out_closed:1;
0199     unsigned                         rst_sent:1;
0200     unsigned                         no_flow_control:1;
0201     unsigned                         skip_data:1;
0202 };
0203 
0204 
0205 struct ngx_http_v2_out_frame_s {
0206     ngx_http_v2_out_frame_t         *next;
0207     ngx_chain_t                     *first;
0208     ngx_chain_t                     *last;
0209     ngx_int_t                      (*handler)(ngx_http_v2_connection_t *h2c,
0210                                         ngx_http_v2_out_frame_t *frame);
0211 
0212     ngx_http_v2_stream_t            *stream;
0213     size_t                           length;
0214 
0215     unsigned                         blocked:1;
0216     unsigned                         fin:1;
0217 };
0218 
0219 
0220 static ngx_inline void
0221 ngx_http_v2_queue_frame(ngx_http_v2_connection_t *h2c,
0222     ngx_http_v2_out_frame_t *frame)
0223 {
0224     ngx_http_v2_out_frame_t  **out;
0225 
0226     for (out = &h2c->last_out; *out; out = &(*out)->next) {
0227 
0228         if ((*out)->blocked || (*out)->stream == NULL) {
0229             break;
0230         }
0231 
0232         if ((*out)->stream->node->rank < frame->stream->node->rank
0233             || ((*out)->stream->node->rank == frame->stream->node->rank
0234                 && (*out)->stream->node->rel_weight
0235                    >= frame->stream->node->rel_weight))
0236         {
0237             break;
0238         }
0239     }
0240 
0241     frame->next = *out;
0242     *out = frame;
0243 }
0244 
0245 
0246 static ngx_inline void
0247 ngx_http_v2_queue_blocked_frame(ngx_http_v2_connection_t *h2c,
0248     ngx_http_v2_out_frame_t *frame)
0249 {
0250     ngx_http_v2_out_frame_t  **out;
0251 
0252     for (out = &h2c->last_out; *out; out = &(*out)->next) {
0253 
0254         if ((*out)->blocked || (*out)->stream == NULL) {
0255             break;
0256         }
0257     }
0258 
0259     frame->next = *out;
0260     *out = frame;
0261 }
0262 
0263 
0264 void ngx_http_v2_init(ngx_event_t *rev);
0265 void ngx_http_v2_request_headers_init(void);
0266 
0267 ngx_int_t ngx_http_v2_read_request_body(ngx_http_request_t *r,
0268     ngx_http_client_body_handler_pt post_handler);
0269 ngx_int_t ngx_http_v2_read_unbuffered_request_body(ngx_http_request_t *r);
0270 
0271 void ngx_http_v2_close_stream(ngx_http_v2_stream_t *stream, ngx_int_t rc);
0272 
0273 ngx_int_t ngx_http_v2_send_output_queue(ngx_http_v2_connection_t *h2c);
0274 
0275 
0276 ngx_int_t ngx_http_v2_get_indexed_header(ngx_http_v2_connection_t *h2c,
0277     ngx_uint_t index, ngx_uint_t name_only);
0278 ngx_int_t ngx_http_v2_add_header(ngx_http_v2_connection_t *h2c,
0279     ngx_http_v2_header_t *header);
0280 ngx_int_t ngx_http_v2_table_size(ngx_http_v2_connection_t *h2c, size_t size);
0281 
0282 
0283 ngx_int_t ngx_http_v2_huff_decode(u_char *state, u_char *src, size_t len,
0284     u_char **dst, ngx_uint_t last, ngx_log_t *log);
0285 size_t ngx_http_v2_huff_encode(u_char *src, size_t len, u_char *dst,
0286     ngx_uint_t lower);
0287 
0288 
0289 #define ngx_http_v2_prefix(bits)  ((1 << (bits)) - 1)
0290 
0291 
0292 #if (NGX_HAVE_NONALIGNED)
0293 
0294 #define ngx_http_v2_parse_uint16(p)  ntohs(*(uint16_t *) (p))
0295 #define ngx_http_v2_parse_uint32(p)  ntohl(*(uint32_t *) (p))
0296 
0297 #else
0298 
0299 #define ngx_http_v2_parse_uint16(p)  ((p)[0] << 8 | (p)[1])
0300 #define ngx_http_v2_parse_uint32(p)                                           \
0301     ((uint32_t) (p)[0] << 24 | (p)[1] << 16 | (p)[2] << 8 | (p)[3])
0302 
0303 #endif
0304 
0305 #define ngx_http_v2_parse_length(p)  ((p) >> 8)
0306 #define ngx_http_v2_parse_type(p)    ((p) & 0xff)
0307 #define ngx_http_v2_parse_sid(p)     (ngx_http_v2_parse_uint32(p) & 0x7fffffff)
0308 #define ngx_http_v2_parse_window(p)  (ngx_http_v2_parse_uint32(p) & 0x7fffffff)
0309 
0310 
0311 #define ngx_http_v2_write_uint16_aligned(p, s)                                \
0312     (*(uint16_t *) (p) = htons((uint16_t) (s)), (p) + sizeof(uint16_t))
0313 #define ngx_http_v2_write_uint32_aligned(p, s)                                \
0314     (*(uint32_t *) (p) = htonl((uint32_t) (s)), (p) + sizeof(uint32_t))
0315 
0316 #if (NGX_HAVE_NONALIGNED)
0317 
0318 #define ngx_http_v2_write_uint16  ngx_http_v2_write_uint16_aligned
0319 #define ngx_http_v2_write_uint32  ngx_http_v2_write_uint32_aligned
0320 
0321 #else
0322 
0323 #define ngx_http_v2_write_uint16(p, s)                                        \
0324     ((p)[0] = (u_char) ((s) >> 8),                                            \
0325      (p)[1] = (u_char)  (s),                                                  \
0326      (p) + sizeof(uint16_t))
0327 
0328 #define ngx_http_v2_write_uint32(p, s)                                        \
0329     ((p)[0] = (u_char) ((s) >> 24),                                           \
0330      (p)[1] = (u_char) ((s) >> 16),                                           \
0331      (p)[2] = (u_char) ((s) >> 8),                                            \
0332      (p)[3] = (u_char)  (s),                                                  \
0333      (p) + sizeof(uint32_t))
0334 
0335 #endif
0336 
0337 #define ngx_http_v2_write_len_and_type(p, l, t)                               \
0338     ngx_http_v2_write_uint32_aligned(p, (l) << 8 | (t))
0339 
0340 #define ngx_http_v2_write_sid  ngx_http_v2_write_uint32
0341 
0342 #endif /* _NGX_HTTP_V2_H_INCLUDED_ */