xref: /unit/src/nxt_http.h (revision 1131:ec7d924d8dfb)
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 
11 typedef enum {
12     NXT_HTTP_INVALID = 0,
13 
14     NXT_HTTP_CONTINUE = 100,
15     NXT_HTTP_SWITCHING_PROTOCOLS = 101,
16 
17     NXT_HTTP_OK = 200,
18     NXT_HTTP_NO_CONTENT = 204,
19 
20     NXT_HTTP_MULTIPLE_CHOICES = 300,
21     NXT_HTTP_MOVED_PERMANENTLY = 301,
22     NXT_HTTP_FOUND = 302,
23     NXT_HTTP_SEE_OTHER = 303,
24     NXT_HTTP_NOT_MODIFIED = 304,
25 
26     NXT_HTTP_BAD_REQUEST = 400,
27     NXT_HTTP_NOT_FOUND = 404,
28     NXT_HTTP_REQUEST_TIMEOUT = 408,
29     NXT_HTTP_LENGTH_REQUIRED = 411,
30     NXT_HTTP_PAYLOAD_TOO_LARGE = 413,
31     NXT_HTTP_URI_TOO_LONG = 414,
32     NXT_HTTP_UPGRADE_REQUIRED = 426,
33     NXT_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
34 
35     NXT_HTTP_TO_HTTPS = 497,
36 
37     NXT_HTTP_INTERNAL_SERVER_ERROR = 500,
38     NXT_HTTP_NOT_IMPLEMENTED = 501,
39     NXT_HTTP_BAD_GATEWAY = 502,
40     NXT_HTTP_SERVICE_UNAVAILABLE = 503,
41     NXT_HTTP_GATEWAY_TIMEOUT = 504,
42     NXT_HTTP_VERSION_NOT_SUPPORTED = 505,
43 } nxt_http_status_t;
44 
45 
46 typedef enum {
47     NXT_HTTP_TE_NONE = 0,
48     NXT_HTTP_TE_CHUNKED = 1,
49     NXT_HTTP_TE_UNSUPPORTED = 2,
50 } nxt_http_te_t;
51 
52 
53 typedef enum {
54     NXT_HTTP_PROTO_H1 = 0,
55     NXT_HTTP_PROTO_H2,
56     NXT_HTTP_PROTO_DEVNULL,
57 } nxt_http_protocol_t;
58 
59 
60 typedef struct {
61     nxt_work_handler_t              ready_handler;
62     nxt_work_handler_t              error_handler;
63 } nxt_http_request_state_t;
64 
65 
66 typedef struct nxt_h1proto_s        nxt_h1proto_t;
67 
68 struct nxt_h1p_websocket_timer_s {
69     nxt_timer_t                     timer;
70     nxt_h1proto_t                   *h1p;
71     nxt_msec_t                      keepalive_interval;
72 };
73 
74 
75 typedef union {
76     void                            *any;
77     nxt_h1proto_t                   *h1;
78 } nxt_http_proto_t;
79 
80 
81 #define nxt_http_field_name_set(_field, _name)                                \
82     do {                                                                      \
83          (_field)->name_length = nxt_length(_name);                           \
84          (_field)->name = (u_char *) _name;                                   \
85     } while (0)
86 
87 
88 #define nxt_http_field_set(_field, _name, _value)                             \
89     do {                                                                      \
90          (_field)->name_length = nxt_length(_name);                           \
91          (_field)->value_length = nxt_length(_value);                         \
92          (_field)->name = (u_char *) _name;                                   \
93          (_field)->value = (u_char *) _value;                                 \
94     } while (0)
95 
96 
97 typedef struct {
98     nxt_list_t                      *fields;
99     nxt_http_field_t                *date;
100     nxt_http_field_t                *content_type;
101     nxt_http_field_t                *content_length;
102     nxt_off_t                       content_length_n;
103 } nxt_http_response_t;
104 
105 
106 struct nxt_http_request_s {
107     nxt_http_proto_t                proto;
108     nxt_socket_conf_joint_t         *conf;
109 
110     nxt_mp_t                        *mem_pool;
111 
112     nxt_buf_t                       *body;
113     nxt_buf_t                       *ws_frame;
114     nxt_buf_t                       *out;
115     const nxt_http_request_state_t  *state;
116 
117     nxt_str_t                       host;
118     nxt_str_t                       server_name;
119     nxt_str_t                       target;
120     nxt_str_t                       version;
121     nxt_str_t                       *method;
122     nxt_str_t                       *path;
123     nxt_str_t                       *args;
124 
125     nxt_array_t                     *arguments;  /* of nxt_http_name_value_t */
126     nxt_array_t                     *cookies;    /* of nxt_http_name_value_t */
127     nxt_list_t                      *fields;
128     nxt_http_field_t                *content_type;
129     nxt_http_field_t                *content_length;
130     nxt_http_field_t                *cookie;
131     nxt_http_field_t                *referer;
132     nxt_http_field_t                *user_agent;
133     nxt_off_t                       content_length_n;
134 
135     nxt_sockaddr_t                  *remote;
136     nxt_sockaddr_t                  *local;
137     void                            *tls;
138 
139     nxt_timer_t                     timer;
140     void                            *timer_data;
141 
142     void                            *req_rpc_data;
143 
144     nxt_buf_t                       *last;
145 
146     nxt_http_response_t             resp;
147 
148     nxt_http_status_t               status:16;
149 
150     uint8_t                         pass_count;   /* 8 bits */
151     nxt_http_protocol_t             protocol:8;   /* 2 bits */
152     uint8_t                         logged;       /* 1 bit  */
153     uint8_t                         header_sent;  /* 1 bit  */
154     uint8_t                         error;        /* 1 bit  */
155     uint8_t                         websocket_handshake;  /* 1 bit */
156 };
157 
158 
159 typedef struct nxt_http_route_s     nxt_http_route_t;
160 
161 
162 struct nxt_http_pass_s {
163     nxt_http_pass_t                 *(*handler)(nxt_task_t *task,
164                                         nxt_http_request_t *r,
165                                         nxt_http_pass_t *pass);
166     union {
167         nxt_http_route_t            *route;
168         nxt_app_t                   *application;
169     } u;
170 
171     nxt_str_t                       name;
172 };
173 
174 
175 typedef struct {
176     void (*body_read)(nxt_task_t *task, nxt_http_request_t *r);
177     void (*local_addr)(nxt_task_t *task, nxt_http_request_t *r);
178     void (*header_send)(nxt_task_t *task, nxt_http_request_t *r);
179     void (*send)(nxt_task_t *task, nxt_http_request_t *r, nxt_buf_t *out);
180     nxt_off_t (*body_bytes_sent)(nxt_task_t *task, nxt_http_proto_t proto);
181     void (*discard)(nxt_task_t *task, nxt_http_request_t *r, nxt_buf_t *last);
182     void (*close)(nxt_task_t *task, nxt_http_proto_t proto,
183         nxt_socket_conf_joint_t *joint);
184     void (*ws_frame_start)(nxt_task_t *task, nxt_http_request_t *r,
185         nxt_buf_t *ws_frame);
186 } nxt_http_proto_table_t;
187 
188 
189 nxt_int_t nxt_http_init(nxt_task_t *task, nxt_runtime_t *rt);
190 nxt_int_t nxt_h1p_init(nxt_task_t *task, nxt_runtime_t *rt);
191 nxt_int_t nxt_http_response_hash_init(nxt_task_t *task, nxt_runtime_t *rt);
192 
193 void nxt_http_conn_init(nxt_task_t *task, void *obj, void *data);
194 nxt_http_request_t *nxt_http_request_create(nxt_task_t *task);
195 void nxt_http_request_error(nxt_task_t *task, nxt_http_request_t *r,
196     nxt_http_status_t status);
197 void nxt_http_request_read_body(nxt_task_t *task, nxt_http_request_t *r);
198 void nxt_http_request_header_send(nxt_task_t *task, nxt_http_request_t *r);
199 void nxt_http_request_ws_frame_start(nxt_task_t *task, nxt_http_request_t *r,
200     nxt_buf_t *ws_frame);
201 void nxt_http_request_send(nxt_task_t *task, nxt_http_request_t *r,
202     nxt_buf_t *out);
203 nxt_buf_t *nxt_http_buf_mem(nxt_task_t *task, nxt_http_request_t *r,
204     size_t size);
205 nxt_buf_t *nxt_http_buf_last(nxt_http_request_t *r);
206 void nxt_http_request_error_handler(nxt_task_t *task, void *obj, void *data);
207 void nxt_http_request_close_handler(nxt_task_t *task, void *obj, void *data);
208 
209 nxt_int_t nxt_http_request_host(void *ctx, nxt_http_field_t *field,
210     uintptr_t data);
211 nxt_int_t nxt_http_request_field(void *ctx, nxt_http_field_t *field,
212     uintptr_t offset);
213 nxt_int_t nxt_http_request_content_length(void *ctx, nxt_http_field_t *field,
214     uintptr_t data);
215 
216 nxt_http_routes_t *nxt_http_routes_create(nxt_task_t *task,
217     nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *routes_conf);
218 nxt_http_pass_t *nxt_http_pass_create(nxt_task_t *task,
219     nxt_router_temp_conf_t *tmcf, nxt_str_t *name);
220 void nxt_http_routes_resolve(nxt_task_t *task, nxt_router_temp_conf_t *tmcf);
221 nxt_http_pass_t *nxt_http_pass_application(nxt_task_t *task,
222     nxt_router_temp_conf_t *tmcf, nxt_str_t *name);
223 void nxt_http_routes_cleanup(nxt_task_t *task, nxt_http_routes_t *routes);
224 void nxt_http_pass_cleanup(nxt_task_t *task, nxt_http_pass_t *pass);
225 
226 nxt_http_pass_t *nxt_http_request_application(nxt_task_t *task,
227     nxt_http_request_t *r, nxt_http_pass_t *pass);
228 
229 extern nxt_time_string_t  nxt_http_date_cache;
230 
231 extern nxt_lvlhsh_t                        nxt_response_fields_hash;
232 
233 extern const nxt_http_proto_table_t  nxt_http_proto[];
234 
235 void nxt_h1p_websocket_first_frame_start(nxt_task_t *task,
236     nxt_http_request_t *r, nxt_buf_t *ws_frame);
237 void nxt_h1p_websocket_frame_start(nxt_task_t *task, nxt_http_request_t *r,
238     nxt_buf_t *ws_frame);
239 void nxt_h1p_complete_buffers(nxt_task_t *task, nxt_h1proto_t *h1p);
240 nxt_msec_t nxt_h1p_conn_request_timer_value(nxt_conn_t *c, uintptr_t data);
241 
242 extern const nxt_conn_state_t  nxt_h1p_idle_close_state;
243 
244 #endif  /* _NXT_HTTP_H_INCLUDED_ */
245