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