xref: /unit/src/nxt_http.h (revision 2512:5e9e70378c1d)
1 
2 /*
3  * Copyright (C) Igor Sysoev
4  * Copyright (C) NGINX, Inc.
5  */
6 
7 #ifndef _NXT_HTTP_H_INCLUDED_
8 #define _NXT_HTTP_H_INCLUDED_
9 
10 #include <nxt_regex.h>
11 
12 
13 typedef enum {
14     NXT_HTTP_UNSET = -1,
15     NXT_HTTP_INVALID = 0,
16 
17     NXT_HTTP_CONTINUE = 100,
18     NXT_HTTP_SWITCHING_PROTOCOLS = 101,
19 
20     NXT_HTTP_OK = 200,
21     NXT_HTTP_NO_CONTENT = 204,
22 
23     NXT_HTTP_MULTIPLE_CHOICES = 300,
24     NXT_HTTP_MOVED_PERMANENTLY = 301,
25     NXT_HTTP_FOUND = 302,
26     NXT_HTTP_SEE_OTHER = 303,
27     NXT_HTTP_NOT_MODIFIED = 304,
28     NXT_HTTP_TEMPORARY_REDIRECT = 307,
29     NXT_HTTP_PERMANENT_REDIRECT = 308,
30 
31     NXT_HTTP_BAD_REQUEST = 400,
32     NXT_HTTP_FORBIDDEN = 403,
33     NXT_HTTP_NOT_FOUND = 404,
34     NXT_HTTP_METHOD_NOT_ALLOWED = 405,
35     NXT_HTTP_REQUEST_TIMEOUT = 408,
36     NXT_HTTP_LENGTH_REQUIRED = 411,
37     NXT_HTTP_PAYLOAD_TOO_LARGE = 413,
38     NXT_HTTP_URI_TOO_LONG = 414,
39     NXT_HTTP_UPGRADE_REQUIRED = 426,
40     NXT_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
41 
42     NXT_HTTP_TO_HTTPS = 497,
43 
44     NXT_HTTP_INTERNAL_SERVER_ERROR = 500,
45     NXT_HTTP_NOT_IMPLEMENTED = 501,
46     NXT_HTTP_BAD_GATEWAY = 502,
47     NXT_HTTP_SERVICE_UNAVAILABLE = 503,
48     NXT_HTTP_GATEWAY_TIMEOUT = 504,
49     NXT_HTTP_VERSION_NOT_SUPPORTED = 505,
50     NXT_HTTP_SERVER_ERROR_MAX = 599,
51 
52     NXT_HTTP_STATUS_MAX = 999,
53 } nxt_http_status_t;
54 
55 
56 typedef enum {
57     NXT_HTTP_TE_NONE = 0,
58     NXT_HTTP_TE_CHUNKED = 1,
59     NXT_HTTP_TE_UNSUPPORTED = 2,
60 } nxt_http_te_t;
61 
62 
63 typedef enum {
64     NXT_HTTP_PROTO_H1 = 0,
65     NXT_HTTP_PROTO_H2,
66     NXT_HTTP_PROTO_DEVNULL,
67 } nxt_http_protocol_t;
68 
69 
70 typedef struct {
71     nxt_work_handler_t              ready_handler;
72     nxt_work_handler_t              error_handler;
73 } nxt_http_request_state_t;
74 
75 
76 typedef struct nxt_h1proto_s        nxt_h1proto_t;
77 
78 struct nxt_h1p_websocket_timer_s {
79     nxt_timer_t                     timer;
80     nxt_h1proto_t                   *h1p;
81     nxt_msec_t                      keepalive_interval;
82 };
83 
84 
85 typedef union {
86     void                            *any;
87     nxt_h1proto_t                   *h1;
88 } nxt_http_proto_t;
89 
90 
91 #define nxt_http_field_name_set(_field, _name)                                \
92     do {                                                                      \
93         (_field)->name_length = nxt_length(_name);                            \
94         (_field)->name = (u_char *) _name;                                    \
95     } while (0)
96 
97 
98 #define nxt_http_field_set(_field, _name, _value)                             \
99     do {                                                                      \
100         (_field)->name_length = nxt_length(_name);                            \
101         (_field)->value_length = nxt_length(_value);                          \
102         (_field)->name = (u_char *) _name;                                    \
103         (_field)->value = (u_char *) _value;                                  \
104     } while (0)
105 
106 
107 typedef struct {
108     nxt_list_t                      *fields;
109     nxt_http_field_t                *date;
110     nxt_http_field_t                *content_type;
111     nxt_http_field_t                *content_length;
112     nxt_off_t                       content_length_n;
113 } nxt_http_response_t;
114 
115 
116 typedef struct nxt_upstream_server_s  nxt_upstream_server_t;
117 
118 typedef struct {
119     nxt_http_proto_t                proto;
120     nxt_http_request_t              *request;
121     nxt_upstream_server_t           *server;
122     nxt_list_t                      *fields;
123     nxt_buf_t                       *body;
124 
125     nxt_http_status_t               status:16;
126     nxt_http_protocol_t             protocol:8;       /* 2 bits */
127     uint8_t                         header_received;  /* 1 bit  */
128     uint8_t                         closed;           /* 1 bit  */
129 } nxt_http_peer_t;
130 
131 
132 struct nxt_http_request_s {
133     nxt_http_proto_t                proto;
134     nxt_socket_conf_joint_t         *conf;
135 
136     nxt_mp_t                        *mem_pool;
137 
138     nxt_buf_t                       *body;
139     nxt_buf_t                       *ws_frame;
140     nxt_buf_t                       *out;
141     const nxt_http_request_state_t  *state;
142 
143     nxt_nsec_t                      start_time;
144 
145     nxt_str_t                       host;
146     nxt_str_t                       server_name;
147     nxt_str_t                       request_line;
148     nxt_str_t                       target;
149     nxt_str_t                       version;
150     nxt_str_t                       *method;
151     nxt_str_t                       *path;
152     nxt_str_t                       *args;
153 
154     nxt_str_t                       args_decoded;
155     nxt_array_t                     *arguments;  /* of nxt_http_name_value_t */
156     nxt_array_t                     *cookies;    /* of nxt_http_name_value_t */
157     nxt_list_t                      *fields;
158     nxt_http_field_t                *content_type;
159     nxt_http_field_t                *content_length;
160     nxt_http_field_t                *cookie;
161     nxt_http_field_t                *referer;
162     nxt_http_field_t                *user_agent;
163     nxt_http_field_t                *authorization;
164     nxt_off_t                       content_length_n;
165 
166     nxt_sockaddr_t                  *remote;
167     nxt_sockaddr_t                  *local;
168     nxt_task_t                      task;
169 
170     nxt_timer_t                     timer;
171     void                            *timer_data;
172 
173     nxt_tstr_query_t                *tstr_query;
174     nxt_tstr_cache_t                tstr_cache;
175 
176     nxt_http_action_t               *action;
177     void                            *req_rpc_data;
178 
179 #if (NXT_HAVE_REGEX)
180     nxt_regex_match_t               *regex_match;
181 #endif
182 
183     nxt_http_peer_t                 *peer;
184     nxt_buf_t                       *last;
185 
186     nxt_queue_link_t                app_link;   /* nxt_app_t.ack_waiting_req */
187     nxt_event_engine_t              *engine;
188     nxt_work_t                      err_work;
189 
190     nxt_http_response_t             resp;
191 
192     nxt_http_status_t               status:16;
193 
194     uint8_t                         log_route;    /* 1 bit */
195 
196     uint8_t                         pass_count;   /* 8 bits */
197     uint8_t                         app_target;
198     nxt_http_protocol_t             protocol:8;   /* 2 bits */
199     uint8_t                         tls;          /* 1 bit  */
200     uint8_t                         logged;       /* 1 bit  */
201     uint8_t                         header_sent;  /* 1 bit  */
202     uint8_t                         inconsistent; /* 1 bit  */
203     uint8_t                         error;        /* 1 bit  */
204     uint8_t                         websocket_handshake;  /* 1 bit */
205 };
206 
207 
208 typedef struct {
209     uint16_t                        hash;
210     uint16_t                        name_length;
211     uint32_t                        value_length;
212     u_char                          *name;
213     u_char                          *value;
214 } nxt_http_name_value_t;
215 
216 
217 typedef enum {
218     NXT_HTTP_URI_ENCODING_NONE = 0,
219     NXT_HTTP_URI_ENCODING,
220     NXT_HTTP_URI_ENCODING_PLUS
221 } nxt_http_uri_encoding_t;
222 
223 
224 typedef struct nxt_http_route_s            nxt_http_route_t;
225 typedef struct nxt_http_route_rule_s       nxt_http_route_rule_t;
226 typedef struct nxt_http_route_addr_rule_s  nxt_http_route_addr_rule_t;
227 
228 
229 typedef struct {
230     nxt_conf_value_t                *rewrite;
231     nxt_conf_value_t                *set_headers;
232     nxt_conf_value_t                *pass;
233     nxt_conf_value_t                *ret;
234     nxt_conf_value_t                *location;
235     nxt_conf_value_t                *proxy;
236     nxt_conf_value_t                *share;
237     nxt_conf_value_t                *index;
238     nxt_str_t                       chroot;
239     nxt_conf_value_t                *follow_symlinks;
240     nxt_conf_value_t                *traverse_mounts;
241     nxt_conf_value_t                *types;
242     nxt_conf_value_t                *fallback;
243 } nxt_http_action_conf_t;
244 
245 
246 struct nxt_http_action_s {
247     nxt_http_action_t               *(*handler)(nxt_task_t *task,
248                                         nxt_http_request_t *r,
249                                         nxt_http_action_t *action);
250     union {
251         void                        *conf;
252         nxt_http_route_t            *route;
253         nxt_upstream_t              *upstream;
254         uint32_t                    upstream_number;
255         nxt_tstr_t                  *tstr;
256         nxt_str_t                   *pass;
257     } u;
258 
259     nxt_tstr_t                      *rewrite;
260     nxt_array_t                     *set_headers;  /* of nxt_http_field_t */
261     nxt_http_action_t               *fallback;
262 };
263 
264 
265 typedef struct {
266     void (*body_read)(nxt_task_t *task, nxt_http_request_t *r);
267     void (*local_addr)(nxt_task_t *task, nxt_http_request_t *r);
268     void (*header_send)(nxt_task_t *task, nxt_http_request_t *r,
269         nxt_work_handler_t body_handler, void *data);
270     void (*send)(nxt_task_t *task, nxt_http_request_t *r, nxt_buf_t *out);
271     nxt_off_t (*body_bytes_sent)(nxt_task_t *task, nxt_http_proto_t proto);
272     void (*discard)(nxt_task_t *task, nxt_http_request_t *r, nxt_buf_t *last);
273     void (*close)(nxt_task_t *task, nxt_http_proto_t proto,
274         nxt_socket_conf_joint_t *joint);
275 
276     void (*peer_connect)(nxt_task_t *task, nxt_http_peer_t *peer);
277     void (*peer_header_send)(nxt_task_t *task, nxt_http_peer_t *peer);
278     void (*peer_header_read)(nxt_task_t *task, nxt_http_peer_t *peer);
279     void (*peer_read)(nxt_task_t *task, nxt_http_peer_t *peer);
280     void (*peer_close)(nxt_task_t *task, nxt_http_peer_t *peer);
281 
282     void (*ws_frame_start)(nxt_task_t *task, nxt_http_request_t *r,
283         nxt_buf_t *ws_frame);
284 } nxt_http_proto_table_t;
285 
286 
287 typedef struct {
288     nxt_str_t                   *header;
289     uint32_t                    header_hash;
290 } nxt_http_forward_header_t;
291 
292 
293 struct nxt_http_forward_s {
294     nxt_http_forward_header_t   client_ip;
295     nxt_http_forward_header_t   protocol;
296     nxt_http_route_addr_rule_t  *source;
297     uint8_t                     recursive;    /* 1 bit */
298 };
299 
300 
301 #define NXT_HTTP_DATE_LEN  nxt_length("Wed, 31 Dec 1986 16:40:00 GMT")
302 
303 nxt_inline u_char *
nxt_http_date(u_char * buf,struct tm * tm)304 nxt_http_date(u_char *buf, struct tm *tm)
305 {
306     static const char  *week[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri",
307                                    "Sat" };
308 
309     static const char  *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
310                                     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
311 
312     return nxt_sprintf(buf, buf + NXT_HTTP_DATE_LEN,
313                        "%s, %02d %s %4d %02d:%02d:%02d GMT",
314                        week[tm->tm_wday], tm->tm_mday,
315                        month[tm->tm_mon], tm->tm_year + 1900,
316                        tm->tm_hour, tm->tm_min, tm->tm_sec);
317 }
318 
319 
320 nxt_int_t nxt_http_init(nxt_task_t *task);
321 nxt_int_t nxt_h1p_init(nxt_task_t *task);
322 nxt_int_t nxt_http_response_hash_init(nxt_task_t *task);
323 
324 void nxt_http_conn_init(nxt_task_t *task, void *obj, void *data);
325 nxt_http_request_t *nxt_http_request_create(nxt_task_t *task);
326 void nxt_http_request_error(nxt_task_t *task, nxt_http_request_t *r,
327     nxt_http_status_t status);
328 void nxt_http_request_read_body(nxt_task_t *task, nxt_http_request_t *r);
329 void nxt_http_request_header_send(nxt_task_t *task, nxt_http_request_t *r,
330     nxt_work_handler_t body_handler, void *data);
331 void nxt_http_request_ws_frame_start(nxt_task_t *task, nxt_http_request_t *r,
332     nxt_buf_t *ws_frame);
333 void nxt_http_request_send(nxt_task_t *task, nxt_http_request_t *r,
334     nxt_buf_t *out);
335 nxt_buf_t *nxt_http_buf_mem(nxt_task_t *task, nxt_http_request_t *r,
336     size_t size);
337 nxt_buf_t *nxt_http_buf_last(nxt_http_request_t *r);
338 void nxt_http_request_error_handler(nxt_task_t *task, void *obj, void *data);
339 void nxt_http_request_close_handler(nxt_task_t *task, void *obj, void *data);
340 
341 nxt_int_t nxt_http_request_host(void *ctx, nxt_http_field_t *field,
342     uintptr_t data);
343 nxt_int_t nxt_http_request_field(void *ctx, nxt_http_field_t *field,
344     uintptr_t offset);
345 nxt_int_t nxt_http_request_content_length(void *ctx, nxt_http_field_t *field,
346     uintptr_t data);
347 
348 nxt_array_t *nxt_http_arguments_parse(nxt_http_request_t *r);
349 nxt_array_t *nxt_http_cookies_parse(nxt_http_request_t *r);
350 
351 int64_t nxt_http_field_hash(nxt_mp_t *mp, nxt_str_t *name,
352     nxt_bool_t case_sensitive, uint8_t encoding);
353 int64_t nxt_http_argument_hash(nxt_mp_t *mp, nxt_str_t *name);
354 int64_t nxt_http_header_hash(nxt_mp_t *mp, nxt_str_t *name);
355 int64_t nxt_http_cookie_hash(nxt_mp_t *mp, nxt_str_t *name);
356 
357 nxt_http_routes_t *nxt_http_routes_create(nxt_task_t *task,
358     nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *routes_conf);
359 nxt_http_action_t *nxt_http_action_create(nxt_task_t *task,
360     nxt_router_temp_conf_t *tmcf, nxt_str_t *pass);
361 nxt_int_t nxt_http_routes_resolve(nxt_task_t *task,
362     nxt_router_temp_conf_t *tmcf);
363 nxt_int_t nxt_http_pass_segments(nxt_mp_t *mp, nxt_str_t *pass,
364     nxt_str_t *segments, nxt_uint_t n);
365 nxt_http_action_t *nxt_http_pass_application(nxt_task_t *task,
366     nxt_router_conf_t *rtcf, nxt_str_t *name);
367 nxt_http_route_addr_rule_t *nxt_http_route_addr_rule_create(
368     nxt_task_t *task, nxt_mp_t *mp, nxt_conf_value_t *cv);
369 nxt_int_t nxt_http_route_addr_rule(nxt_http_request_t *r,
370     nxt_http_route_addr_rule_t *addr_rule, nxt_sockaddr_t *sockaddr);
371 nxt_http_route_rule_t *nxt_http_route_types_rule_create(nxt_task_t *task,
372     nxt_mp_t *mp, nxt_conf_value_t *types);
373 nxt_int_t nxt_http_route_test_rule(nxt_http_request_t *r,
374     nxt_http_route_rule_t *rule, u_char *start, size_t length);
375 
376 nxt_int_t nxt_http_action_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
377     nxt_conf_value_t *cv, nxt_http_action_t *action);
378 void nxt_http_request_action(nxt_task_t *task, nxt_http_request_t *r,
379     nxt_http_action_t *action);
380 
381 nxt_int_t nxt_upstreams_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
382     nxt_conf_value_t *conf);
383 nxt_int_t nxt_upstreams_joint_create(nxt_router_temp_conf_t *tmcf,
384     nxt_upstream_t ***upstream_joint);
385 
386 nxt_int_t nxt_http_rewrite_init(nxt_router_conf_t *rtcf,
387     nxt_http_action_t *action, nxt_http_action_conf_t *acf);
388 nxt_int_t nxt_http_rewrite(nxt_task_t *task, nxt_http_request_t *r);
389 
390 nxt_int_t nxt_http_set_headers_init(nxt_router_conf_t *rtcf,
391     nxt_http_action_t *action, nxt_http_action_conf_t *acf);
392 nxt_int_t nxt_http_set_headers(nxt_http_request_t *r);
393 
394 nxt_int_t nxt_http_return_init(nxt_router_conf_t *rtcf,
395     nxt_http_action_t *action, nxt_http_action_conf_t *acf);
396 
397 nxt_int_t nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
398     nxt_http_action_t *action, nxt_http_action_conf_t *acf);
399 nxt_int_t nxt_http_static_mtypes_init(nxt_mp_t *mp, nxt_lvlhsh_t *hash);
400 nxt_int_t nxt_http_static_mtypes_hash_add(nxt_mp_t *mp, nxt_lvlhsh_t *hash,
401     const nxt_str_t *exten, nxt_str_t *type);
402 nxt_str_t *nxt_http_static_mtype_get(nxt_lvlhsh_t *hash,
403     const nxt_str_t *exten);
404 
405 nxt_http_action_t *nxt_http_application_handler(nxt_task_t *task,
406     nxt_http_request_t *r, nxt_http_action_t *action);
407 nxt_int_t nxt_upstream_find(nxt_upstreams_t *upstreams, nxt_str_t *name,
408     nxt_http_action_t *action);
409 nxt_http_action_t *nxt_upstream_proxy_handler(nxt_task_t *task,
410     nxt_http_request_t *r, nxt_upstream_t *upstream);
411 
412 nxt_int_t nxt_http_proxy_init(nxt_mp_t *mp, nxt_http_action_t *action,
413     nxt_http_action_conf_t *acf);
414 nxt_int_t nxt_http_proxy_date(void *ctx, nxt_http_field_t *field,
415     uintptr_t data);
416 nxt_int_t nxt_http_proxy_content_length(void *ctx, nxt_http_field_t *field,
417     uintptr_t data);
418 nxt_int_t nxt_http_proxy_skip(void *ctx, nxt_http_field_t *field,
419     uintptr_t data);
420 nxt_buf_t *nxt_http_proxy_buf_mem_alloc(nxt_task_t *task, nxt_http_request_t *r,
421     size_t size);
422 void nxt_http_proxy_buf_mem_free(nxt_task_t *task, nxt_http_request_t *r,
423     nxt_buf_t *b);
424 
425 extern nxt_time_string_t  nxt_http_date_cache;
426 
427 extern nxt_lvlhsh_t                        nxt_response_fields_hash;
428 
429 extern const nxt_http_proto_table_t  nxt_http_proto[];
430 
431 void nxt_h1p_websocket_first_frame_start(nxt_task_t *task,
432     nxt_http_request_t *r, nxt_buf_t *ws_frame);
433 void nxt_h1p_websocket_frame_start(nxt_task_t *task, nxt_http_request_t *r,
434     nxt_buf_t *ws_frame);
435 void nxt_h1p_complete_buffers(nxt_task_t *task, nxt_h1proto_t *h1p,
436     nxt_bool_t all);
437 nxt_msec_t nxt_h1p_conn_request_timer_value(nxt_conn_t *c, uintptr_t data);
438 
439 extern const nxt_conn_state_t  nxt_h1p_idle_close_state;
440 
441 #endif  /* _NXT_HTTP_H_INCLUDED_ */
442