1 /*
2  * nghttp3
3  *
4  * Copyright (c) 2019 nghttp3 contributors
5  * Copyright (c) 2015 nghttp2 contributors
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining
8  * a copy of this software and associated documentation files (the
9  * "Software"), to deal in the Software without restriction, including
10  * without limitation the rights to use, copy, modify, merge, publish,
11  * distribute, sublicense, and/or sell copies of the Software, and to
12  * permit persons to whom the Software is furnished to do so, subject to
13  * the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be
16  * included in all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  */
26 #ifndef NGHTTP3_HTTP_H
27 #define NGHTTP3_HTTP_H
28 
29 #ifdef HAVE_CONFIG_H
30 #  include <config.h>
31 #endif /* HAVE_CONFIG_H */
32 
33 #include <nghttp3/nghttp3.h>
34 
35 typedef struct nghttp3_stream nghttp3_stream;
36 
37 typedef struct nghttp3_http_state nghttp3_http_state;
38 
39 /* HTTP related flags to enforce HTTP semantics */
40 
41 /* NGHTTP3_HTTP_FLAG_NONE indicates that no flag is set. */
42 #define NGHTTP3_HTTP_FLAG_NONE 0x00
43 /* header field seen so far */
44 #define NGHTTP3_HTTP_FLAG__AUTHORITY 0x01
45 #define NGHTTP3_HTTP_FLAG__PATH 0x02
46 #define NGHTTP3_HTTP_FLAG__METHOD 0x04
47 #define NGHTTP3_HTTP_FLAG__SCHEME 0x08
48 /* host is not pseudo header, but we require either host or
49    :authority */
50 #define NGHTTP3_HTTP_FLAG_HOST 0x10
51 #define NGHTTP3_HTTP_FLAG__STATUS 0x20
52 /* required header fields for HTTP request except for CONNECT
53    method. */
54 #define NGHTTP3_HTTP_FLAG_REQ_HEADERS                                          \
55   (NGHTTP3_HTTP_FLAG__METHOD | NGHTTP3_HTTP_FLAG__PATH |                       \
56    NGHTTP3_HTTP_FLAG__SCHEME)
57 #define NGHTTP3_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED 0x40
58 /* HTTP method flags */
59 #define NGHTTP3_HTTP_FLAG_METH_CONNECT 0x80
60 #define NGHTTP3_HTTP_FLAG_METH_HEAD 0x0100
61 #define NGHTTP3_HTTP_FLAG_METH_OPTIONS 0x0200
62 #define NGHTTP3_HTTP_FLAG_METH_ALL                                             \
63   (NGHTTP3_HTTP_FLAG_METH_CONNECT | NGHTTP3_HTTP_FLAG_METH_HEAD |              \
64    NGHTTP3_HTTP_FLAG_METH_OPTIONS)
65 /* :path category */
66 /* path starts with "/" */
67 #define NGHTTP3_HTTP_FLAG_PATH_REGULAR 0x0400
68 /* path "*" */
69 #define NGHTTP3_HTTP_FLAG_PATH_ASTERISK 0x0800
70 /* scheme */
71 /* "http" or "https" scheme */
72 #define NGHTTP3_HTTP_FLAG_SCHEME_HTTP 0x1000
73 /* set if final response is expected */
74 #define NGHTTP3_HTTP_FLAG_EXPECT_FINAL_RESPONSE 0x2000
75 /* NGHTTP3_HTTP_FLAG__PROTOCOL is set when :protocol pseudo header
76    field is seen. */
77 #define NGHTTP3_HTTP_FLAG__PROTOCOL 0x4000
78 
79 /*
80  * This function is called when HTTP header field |nv| received for
81  * |http|.  This function will validate |nv| against the current state
82  * of stream.  Pass nonzero if this is request headers. Pass nonzero
83  * to |trailers| if |nv| is included in trailers.  |connect_protocol|
84  * is nonzero if Extended CONNECT Method is enabled.
85  *
86  * This function returns 0 if it succeeds, or one of the following
87  * negative error codes:
88  *
89  * NGHTTP3_ERR_MALFORMED_HTTP_HEADER
90  *     Invalid HTTP header field was received.
91  * NGHTTP3_ERR_REMOVE_HTTP_HEADER
92  *     Invalid HTTP header field was received but it can be treated as
93  *     if it was not received because of compatibility reasons.
94  */
95 int nghttp3_http_on_header(nghttp3_http_state *http, nghttp3_qpack_nv *nv,
96                            int request, int trailers, int connect_protocol);
97 
98 /*
99  * This function is called when request header is received.  This
100  * function performs validation and returns 0 if it succeeds, or one
101  * of the following negative error codes:
102  *
103  * NGHTTP3_ERR_MALFORMED_HTTP_HEADER
104  *     Required HTTP header field was not received; or an invalid
105  *     header field was received.
106  */
107 int nghttp3_http_on_request_headers(nghttp3_http_state *http);
108 
109 /*
110  * This function is called when response header is received.  This
111  * function performs validation and returns 0 if it succeeds, or one
112  * of the following negative error codes:
113  *
114  * NGHTTP3_ERR_MALFORMED_HTTP_HEADER
115  *     Required HTTP header field was not received; or an invalid
116  *     header field was received.
117  */
118 int nghttp3_http_on_response_headers(nghttp3_http_state *http);
119 
120 /*
121  * This function is called when read side stream is closed.  This
122  *  function performs validation and returns 0 if it succeeds, or one
123  *  of the following negative error codes:
124  *
125  * NGHTTP3_ERR_MALFORMED_HTTP_MESSAGING
126  *     HTTP messaging is violated.
127  */
128 int nghttp3_http_on_remote_end_stream(nghttp3_stream *stream);
129 
130 /*
131  * This function is called when chunk of data is received.  This
132  * function performs validation and returns 0 if it succeeds, or one
133  * of the following negative error codes:
134  *
135  * NGHTTP3_ERR_MALFORMED_HTTP_MESSAGING
136  *     HTTP messaging is violated.
137  */
138 int nghttp3_http_on_data_chunk(nghttp3_stream *stream, size_t n);
139 
140 /*
141  * This function inspects header fields in |nva| of length |nvlen| and
142  * records its method in stream->http_flags.
143  */
144 void nghttp3_http_record_request_method(nghttp3_stream *stream,
145                                         const nghttp3_nv *nva, size_t nvlen);
146 
147 /*
148  * RFC 8941 Structured Field Values.
149  */
150 typedef enum nghttp3_sf_value_type {
151   NGHTTP3_SF_VALUE_TYPE_BOOLEAN,
152   NGHTTP3_SF_VALUE_TYPE_INTEGER,
153   NGHTTP3_SF_VALUE_TYPE_DECIMAL,
154   NGHTTP3_SF_VALUE_TYPE_STRING,
155   NGHTTP3_SF_VALUE_TYPE_TOKEN,
156   NGHTTP3_SF_VALUE_TYPE_BYTESEQ,
157   NGHTTP3_SF_VALUE_TYPE_INNER_LIST,
158 } nghttp3_sf_value_type;
159 
160 /*
161  * nghttp3_sf_value stores Structured Field Values item.  For Inner
162  * List, only type is set to NGHTTP3_SF_VALUE_TYPE_INNER_LIST.
163  */
164 typedef struct nghttp3_sf_value {
165   uint8_t type;
166   union {
167     int b;
168     int64_t i;
169     double d;
170     struct {
171       const uint8_t *base;
172       size_t len;
173     } s;
174   };
175 } nghttp3_sf_value;
176 
177 /*
178  * nghttp3_sf_parse_item parses the input sequence [|begin|, |end|)
179  * and stores the parsed an Item in |dest|.  It returns the number of
180  * bytes consumed if it succeeds, or -1.  This function is declared
181  * here for unit tests.
182  */
183 nghttp3_ssize nghttp3_sf_parse_item(nghttp3_sf_value *dest,
184                                     const uint8_t *begin, const uint8_t *end);
185 
186 /*
187  * nghttp3_sf_parse_inner_list parses the input sequence [|begin|, |end|)
188  * and stores the parsed an Inner List in |dest|.  It returns the number of
189  * bytes consumed if it succeeds, or -1.  This function is declared
190  * here for unit tests.
191  */
192 nghttp3_ssize nghttp3_sf_parse_inner_list(nghttp3_sf_value *dest,
193                                           const uint8_t *begin,
194                                           const uint8_t *end);
195 
196 #endif /* NGHTTP3_HTTP_H */
197