1 #ifndef HTTP_SERVER_PRIVATE_H
2 #define HTTP_SERVER_PRIVATE_H
3
4 #include "connection.h"
5
6 #include "iostream-pump.h"
7 #include "http-server.h"
8 #include "llist.h"
9
10 struct http_server_ostream;
11 struct http_server_payload_handler;
12 struct http_server_request;
13 struct http_server_connection;
14
15 /*
16 * Defaults
17 */
18
19 #define HTTP_SERVER_REQUEST_MAX_TARGET_LENGTH 4096
20
21 /*
22 * Types
23 */
24
25 enum http_server_request_state {
26 /* New request; request header is still being parsed. */
27 HTTP_SERVER_REQUEST_STATE_NEW = 0,
28 /* Queued request; callback to request handler executing. */
29 HTTP_SERVER_REQUEST_STATE_QUEUED,
30 /* Reading request payload; request handler still needs to read more
31 payload. */
32 HTTP_SERVER_REQUEST_STATE_PAYLOAD_IN,
33 /* This request is being processed; request payload is fully read, but
34 no response is yet submitted */
35 HTTP_SERVER_REQUEST_STATE_PROCESSING,
36 /* A response is submitted for this request. If not all request payload
37 was read by the handler, it is first skipped on the input. */
38 HTTP_SERVER_REQUEST_STATE_SUBMITTED_RESPONSE,
39 /* Request is ready for response; a response is submitted and the
40 request payload is fully read */
41 HTTP_SERVER_REQUEST_STATE_READY_TO_RESPOND,
42 /* The response for the request is sent (apart from payload) */
43 HTTP_SERVER_REQUEST_STATE_SENT_RESPONSE,
44 /* Sending response payload to client */
45 HTTP_SERVER_REQUEST_STATE_PAYLOAD_OUT,
46 /* Request is finished; still lingering due to references */
47 HTTP_SERVER_REQUEST_STATE_FINISHED,
48 /* Request is aborted; still lingering due to references */
49 HTTP_SERVER_REQUEST_STATE_ABORTED
50 };
51
52 /*
53 * Objects
54 */
55
56 struct http_server_payload_handler {
57 struct http_server_request *req;
58
59 void (*switch_ioloop)(struct http_server_payload_handler *handler,
60 struct ioloop *ioloop);
61 void (*destroy)(struct http_server_payload_handler *handler);
62
63 bool in_callback:1;
64 };
65
66 struct http_server_response {
67 struct http_server_request *request;
68 struct event *event;
69
70 unsigned int status;
71 const char *reason;
72
73 string_t *headers;
74 ARRAY_TYPE(string) perm_headers;
75 time_t date;
76 ARRAY_TYPE(http_auth_challenge) auth_challenges;
77
78 struct istream *payload_input;
79 uoff_t payload_size, payload_offset;
80 struct ostream *payload_output;
81 struct http_server_ostream *payload_stream;
82
83 http_server_tunnel_callback_t tunnel_callback;
84 void *tunnel_context;
85
86 bool have_hdr_connection:1;
87 bool have_hdr_date:1;
88 bool have_hdr_body_spec:1;
89
90 bool payload_chunked:1;
91 bool payload_finished:1;
92 bool payload_corked:1;
93 bool submitted:1;
94 };
95
96 struct http_server_request {
97 struct http_request req;
98 pool_t pool;
99 unsigned int refcount, immune_refcount;
100 unsigned int id;
101 int callback_refcount;
102 struct event *event;
103
104 enum http_server_request_state state;
105
106 struct http_server_request *prev, *next;
107
108 struct http_server *server;
109 struct http_server_connection *conn;
110
111 struct istream *payload_input;
112
113 struct http_server_response *response;
114
115 void (*destroy_callback)(void *);
116 void *destroy_context;
117
118 bool payload_halted:1;
119 bool sent_100_continue:1;
120 bool destroy_pending:1;
121 bool failed:1;
122 bool connection_close:1;
123 };
124
125 struct http_server_connection {
126 struct connection conn;
127 struct http_server *server;
128 struct ioloop *ioloop, *ioloop_switching;
129 struct event *event;
130 unsigned int refcount;
131
132 const struct http_server_callbacks *callbacks;
133 void *context;
134
135 struct timeout *to_input, *to_idle;
136 struct ssl_iostream *ssl_iostream;
137 struct http_request_parser *http_parser;
138
139 struct http_server_request *request_queue_head, *request_queue_tail;
140 unsigned int request_queue_count;
141
142 struct istream *incoming_payload;
143 struct http_server_payload_handler *payload_handler;
144
145 struct io *io_resp_payload;
146
147 char *disconnect_reason;
148
149 struct http_server_stats stats;
150
151 bool ssl:1;
152 bool closed:1;
153 bool close_indicated:1;
154 bool input_broken:1;
155 bool output_locked:1;
156 bool output_halted:1;
157 bool in_req_callback:1; /* performing request callback (busy) */
158 };
159
160 struct http_server_location {
161 const char *path;
162
163 struct http_server_resource *resource;
164 };
165
166 struct http_server_resource {
167 pool_t pool;
168 struct http_server *server;
169 struct event *event;
170
171 http_server_resource_callback_t *callback;
172 void *context;
173
174 void (*destroy_callback)(void *);
175 void *destroy_context;
176
177 ARRAY(struct http_server_location *) locations;
178 };
179
180 struct http_server {
181 pool_t pool;
182
183 struct http_server_settings set;
184
185 struct ioloop *ioloop;
186 struct event *event;
187 struct ssl_iostream_context *ssl_ctx;
188
189 struct connection_list *conn_list;
190
191 ARRAY(struct http_server_resource *) resources;
192 ARRAY(struct http_server_location *) locations;
193
194 bool shutting_down:1; /* shutting down server */
195 };
196
197 /*
198 * Response output stream
199 */
200
201 struct ostream *
202 http_server_ostream_create(struct http_server_response *resp,
203 size_t max_buffer_size, bool blocking);
204 bool http_server_ostream_get_size(struct http_server_ostream *hsostream,
205 uoff_t *size_r);
206 int http_server_ostream_continue(struct http_server_ostream *hsostream);
207
208 void http_server_ostream_output_available(
209 struct http_server_ostream *hsostream);
210 void http_server_ostream_response_finished(
211 struct http_server_ostream *hsostream);
212 void http_server_ostream_response_destroyed(
213 struct http_server_ostream *hsostream);
214
215 struct ostream *
216 http_server_ostream_get_output(struct http_server_ostream *hsostream);
217
218 void http_server_ostream_set_error(struct http_server_ostream *hsostream,
219 int stream_errno, const char *stream_error);
220
221 /*
222 * Response
223 */
224
225 void http_server_response_request_free(struct http_server_response *resp);
226 void http_server_response_request_destroy(struct http_server_response *resp);
227 void http_server_response_request_abort(struct http_server_response *resp,
228 const char *reason);
229 void http_server_response_request_finished(struct http_server_response *resp);
230
231 int http_server_response_send(struct http_server_response *resp);
232 int http_server_response_send_more(struct http_server_response *resp);
233 int http_server_response_finish_payload_out(struct http_server_response *resp);
234
235 /*
236 * Request
237 */
238
239 static inline bool
http_server_request_is_new(struct http_server_request * req)240 http_server_request_is_new(struct http_server_request *req)
241 {
242 return (req->state == HTTP_SERVER_REQUEST_STATE_NEW);
243 }
244
245 static inline bool
http_server_request_version_equals(struct http_server_request * req,unsigned int major,unsigned int minor)246 http_server_request_version_equals(struct http_server_request *req,
247 unsigned int major, unsigned int minor)
248 {
249 return (req->req.version_major == major &&
250 req->req.version_minor == minor);
251 }
252
253 const char *http_server_request_label(struct http_server_request *req);
254
255 void http_server_request_update_event(struct http_server_request *req);
256
257 struct http_server_request *
258 http_server_request_new(struct http_server_connection *conn);
259 void http_server_request_destroy(struct http_server_request **_req);
260 void http_server_request_abort(struct http_server_request **_req,
261 const char *reason) ATTR_NULL(2);
262
263 void http_server_request_immune_ref(struct http_server_request *req);
264 void http_server_request_immune_unref(struct http_server_request **_req);
265
266 bool http_server_request_is_complete(struct http_server_request *req);
267
268 void http_server_request_callback(struct http_server_request *req);
269
270 void http_server_request_halt_payload(struct http_server_request *req);
271 void http_server_request_continue_payload(struct http_server_request *req);
272
273 void http_server_request_submit_response(struct http_server_request *req);
274
275 void http_server_request_ready_to_respond(struct http_server_request *req);
276 void http_server_request_finished(struct http_server_request *req);
277
278 /* Payload handler */
279
280 void http_server_payload_handler_destroy(
281 struct http_server_payload_handler **_handler);
282 void http_server_payload_handler_switch_ioloop(
283 struct http_server_payload_handler *handler, struct ioloop *ioloop);
284
285 /*
286 * Connection
287 */
288
289 static inline void
http_server_connection_add_request(struct http_server_connection * conn,struct http_server_request * sreq)290 http_server_connection_add_request(struct http_server_connection *conn,
291 struct http_server_request *sreq)
292 {
293 DLLIST2_APPEND(&conn->request_queue_head, &conn->request_queue_tail,
294 sreq);
295 conn->request_queue_count++;
296 }
297 static inline void
http_server_connection_remove_request(struct http_server_connection * conn,struct http_server_request * sreq)298 http_server_connection_remove_request(struct http_server_connection *conn,
299 struct http_server_request *sreq)
300 {
301 DLLIST2_REMOVE(&conn->request_queue_head, &conn->request_queue_tail,
302 sreq);
303 conn->request_queue_count--;
304 }
305
306 struct connection_list *http_server_connection_list_init(void);
307
308 bool http_server_connection_shut_down(struct http_server_connection *conn);
309
310 void http_server_connection_input_set_pending(
311 struct http_server_connection *conn);
312 void http_server_connection_input_halt(struct http_server_connection *conn);
313 void http_server_connection_input_resume(struct http_server_connection *conn);
314
315 void http_server_connection_start_idle_timeout(
316 struct http_server_connection *conn);
317 void http_server_connection_reset_idle_timeout(
318 struct http_server_connection *conn);
319 void http_server_connection_stop_idle_timeout(
320 struct http_server_connection *conn);
321
322 void http_server_connection_handle_output_error(
323 struct http_server_connection *conn);
324
325 void http_server_connection_output_trigger(struct http_server_connection *conn);
326 void http_server_connection_output_halt(struct http_server_connection *conn);
327 void http_server_connection_output_resume(struct http_server_connection *conn);
328
329 int http_server_connection_flush(struct http_server_connection *conn);
330 int http_server_connection_output(struct http_server_connection *conn);
331
332 void http_server_connection_tunnel(struct http_server_connection **_conn,
333 http_server_tunnel_callback_t callback,
334 void *context);
335
336 bool http_server_connection_pending_payload(
337 struct http_server_connection *conn);
338
339 /*
340 * Resource
341 */
342
343 int http_server_resource_find(struct http_server *server, const char *path,
344 struct http_server_resource **res_r,
345 const char **sub_path_r) ATTR_NULL(2);
346
347 bool http_server_resource_callback(struct http_server_request *req);
348
349 /*
350 * Server
351 */
352
353 int http_server_init_ssl_ctx(struct http_server *server, const char **error_r);
354
355 #endif
356