1 /* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
2 
3 #include "lib.h"
4 #include "array.h"
5 #include "ioloop.h"
6 #include "ostream.h"
7 #include "istream-private.h"
8 #include "str-sanitize.h"
9 
10 #include "http-server-private.h"
11 
12 /*
13  * Logging
14  */
15 
16 static inline void
17 http_server_request_client_error(struct http_server_request *req,
18 				 const char *format, ...) ATTR_FORMAT(2, 3);
19 
20 static inline void
http_server_request_client_error(struct http_server_request * req,const char * format,...)21 http_server_request_client_error(struct http_server_request *req,
22 				 const char *format, ...)
23 {
24 	va_list args;
25 
26 	va_start(args, format);
27 	e_info(req->event, "%s", t_strdup_vprintf(format, args));
28 	va_end(args);
29 }
30 
31 /*
32  * Request
33  */
34 
http_server_request_label(struct http_server_request * req)35 const char *http_server_request_label(struct http_server_request *req)
36 {
37 	if (req->req.target_raw == NULL) {
38 		if (req->req.method == NULL)
39 			return t_strdup_printf("[Req%u: <NEW>]", req->id);
40 		return t_strdup_printf("[Req%u: %s <INCOMPLETE>]",
41 			req->id, req->req.method);
42 	}
43 	return t_strdup_printf("[Req%u: %s %s]", req->id,
44 		req->req.method, req->req.target_raw);
45 }
46 
http_server_request_update_event(struct http_server_request * req)47 void http_server_request_update_event(struct http_server_request *req)
48 {
49 	if (req->req.method != NULL)
50 		event_add_str(req->event, "method", req->req.method);
51 	if (req->req.target_raw != NULL)
52 		event_add_str(req->event, "target", req->req.target_raw);
53 	event_set_append_log_prefix(
54 		req->event, t_strdup_printf("request %s: ",
55 			str_sanitize(http_server_request_label(req), 256)));
56 }
57 
58 struct http_server_request *
http_server_request_new(struct http_server_connection * conn)59 http_server_request_new(struct http_server_connection *conn)
60 {
61 	static unsigned int id_counter = 0;
62 	pool_t pool;
63 	struct http_server_request *req;
64 
65 	pool = pool_alloconly_create(
66 		MEMPOOL_GROWING"http_server_request", 4096);
67 	req = p_new(pool, struct http_server_request, 1);
68 	req->pool = pool;
69 	req->refcount = 1;
70 	req->conn = conn;
71 	req->server = conn->server;
72 	req->id = ++id_counter;
73 	req->event = event_create(conn->event);
74 	http_server_request_update_event(req);
75 
76 	http_server_connection_add_request(conn, req);
77 	return req;
78 }
79 
http_server_request_ref(struct http_server_request * req)80 void http_server_request_ref(struct http_server_request *req)
81 {
82 	i_assert(req->refcount > 0);
83 	req->refcount++;
84 }
85 
http_server_request_unref(struct http_server_request ** _req)86 bool http_server_request_unref(struct http_server_request **_req)
87 {
88 	struct http_server_request *req = *_req;
89 	struct http_server_connection *conn = req->conn;
90 
91 	i_assert(req->refcount > 0);
92 
93 	*_req = NULL;
94 	if (--req->refcount > 0)
95 		return TRUE;
96 
97 	e_debug(req->event, "Free");
98 
99 	if (req->state < HTTP_SERVER_REQUEST_STATE_FINISHED) {
100 		req->state = HTTP_SERVER_REQUEST_STATE_ABORTED;
101 		http_server_connection_remove_request(conn, req);
102 	}
103 
104 	if (req->destroy_callback != NULL) {
105 		req->destroy_callback(req->destroy_context);
106 		req->destroy_callback = NULL;
107 	}
108 
109 	if (req->response != NULL)
110 		http_server_response_request_free(req->response);
111 	event_unref(&req->event);
112 	pool_unref(&req->pool);
113 	return FALSE;
114 }
115 
http_server_request_connection_close(struct http_server_request * req,bool close)116 void http_server_request_connection_close(struct http_server_request *req,
117 					  bool close)
118 {
119 	i_assert(req->state < HTTP_SERVER_REQUEST_STATE_SENT_RESPONSE);
120 	req->connection_close = close;
121 }
122 
http_server_request_destroy(struct http_server_request ** _req)123 void http_server_request_destroy(struct http_server_request **_req)
124 {
125 	struct http_server_request *req = *_req;
126 	struct http_server *server = req->server;
127 
128 	e_debug(req->event, "Destroy");
129 
130 	/* Just make sure the request ends in a proper state */
131 	if (req->state < HTTP_SERVER_REQUEST_STATE_FINISHED)
132 		req->state = HTTP_SERVER_REQUEST_STATE_ABORTED;
133 
134 	if (server->ioloop != NULL)
135 		io_loop_stop(server->ioloop);
136 
137 	if (req->immune_refcount > 0) {
138 		req->destroy_pending = TRUE;
139 		http_server_request_unref(_req);
140 		return;
141 	}
142 
143 	if (req->response != NULL)
144 		http_server_response_request_destroy(req->response);
145 
146 	if (req->destroy_callback != NULL) {
147 		void (*callback)(void *) = req->destroy_callback;
148 
149 		req->destroy_callback = NULL;
150 		callback(req->destroy_context);
151 	}
152 
153 	http_server_request_unref(_req);
154 }
155 
156 #undef http_server_request_set_destroy_callback
http_server_request_set_destroy_callback(struct http_server_request * req,void (* callback)(void *),void * context)157 void http_server_request_set_destroy_callback(struct http_server_request *req,
158 					      void (*callback)(void *),
159 					      void *context)
160 {
161 	req->destroy_callback = callback;
162 	req->destroy_context = context;
163 }
164 
http_server_request_abort(struct http_server_request ** _req,const char * reason)165 void http_server_request_abort(struct http_server_request **_req,
166 			       const char *reason)
167 {
168 	struct http_server_request *req = *_req;
169 	struct http_server_connection *conn = req->conn;
170 
171 	if (req->state >= HTTP_SERVER_REQUEST_STATE_FINISHED)
172 		return;
173 
174 	if (reason == NULL)
175 		e_debug(req->event, "Abort");
176 	else
177 		e_debug(req->event, "Abort: %s", reason);
178 
179 	if (req->response != NULL)
180 		http_server_response_request_abort(req->response, reason);
181 
182 	req->conn = NULL;
183 	if (req->state < HTTP_SERVER_REQUEST_STATE_FINISHED) {
184 		if (conn != NULL) {
185 			http_server_connection_remove_request(conn, req);
186 
187 			if (!conn->closed) {
188 				/* Send best-effort response if appropriate */
189 				if (!conn->output_locked &&
190 				    req->state >= HTTP_SERVER_REQUEST_STATE_PROCESSING &&
191 				    req->state < HTTP_SERVER_REQUEST_STATE_SENT_RESPONSE) {
192 					static const char *response =
193 						"HTTP/1.1 500 Internal Server Error\r\n"
194 						"Content-Length: 0\r\n"
195 						"\r\n";
196 
197 					o_stream_nsend(conn->conn.output,
198 						       response, strlen(response));
199 					(void)o_stream_flush(conn->conn.output);
200 				}
201 
202 				/* Close the connection */
203 				http_server_connection_close(&conn, reason);
204 			}
205 		}
206 
207 		req->state = HTTP_SERVER_REQUEST_STATE_ABORTED;
208 	}
209 
210 	http_server_request_destroy(_req);
211 }
212 
http_server_request_immune_ref(struct http_server_request * req)213 void http_server_request_immune_ref(struct http_server_request *req)
214 {
215 	http_server_request_ref(req);
216 	req->immune_refcount++;
217 }
218 
http_server_request_immune_unref(struct http_server_request ** _req)219 void http_server_request_immune_unref(struct http_server_request **_req)
220 {
221 	struct http_server_request *req = *_req;
222 
223 	i_assert(req->immune_refcount > 0);
224 
225 	*_req = NULL;
226 	if (--req->immune_refcount == 0 && req->destroy_pending)
227 		http_server_request_destroy(&req);
228 	else
229 		http_server_request_unref(&req);
230 }
231 
232 const struct http_request *
http_server_request_get(struct http_server_request * req)233 http_server_request_get(struct http_server_request *req)
234 {
235 	return &req->req;
236 }
237 
http_server_request_get_pool(struct http_server_request * req)238 pool_t http_server_request_get_pool(struct http_server_request *req)
239 {
240 	return req->pool;
241 }
242 
243 struct http_server_response *
http_server_request_get_response(struct http_server_request * req)244 http_server_request_get_response(struct http_server_request *req)
245 {
246 	return req->response;
247 }
248 
http_server_request_get_auth(struct http_server_request * req,struct http_auth_credentials * credentials)249 int http_server_request_get_auth(struct http_server_request *req,
250 				 struct http_auth_credentials *credentials)
251 {
252 	const char *auth;
253 
254 	auth = http_request_header_get(&req->req, "Authorization");
255 	if (auth == NULL)
256 		return 0;
257 
258 	if (http_auth_parse_credentials((const unsigned char *)auth,
259 					strlen(auth), credentials) < 0)
260 		return -1;
261 
262 	return 1;
263 }
264 
http_server_request_is_finished(struct http_server_request * req)265 bool http_server_request_is_finished(struct http_server_request *req)
266 {
267 	return (req->response != NULL ||
268 		req->state == HTTP_SERVER_REQUEST_STATE_ABORTED);
269 }
270 
http_server_request_is_complete(struct http_server_request * req)271 bool http_server_request_is_complete(struct http_server_request *req)
272 {
273 	return (req->failed || req->conn->input_broken ||
274 		(req->next != NULL && !http_server_request_is_new(req->next)) ||
275 		!http_server_connection_pending_payload(req->conn));
276 }
277 
http_server_request_halt_payload(struct http_server_request * req)278 void http_server_request_halt_payload(struct http_server_request *req)
279 {
280 	i_assert(req->state <= HTTP_SERVER_REQUEST_STATE_QUEUED);
281 	req->payload_halted = TRUE;
282 }
283 
http_server_request_continue_payload(struct http_server_request * req)284 void http_server_request_continue_payload(struct http_server_request *req)
285 {
286 	i_assert(req->state <= HTTP_SERVER_REQUEST_STATE_QUEUED);
287 	req->payload_halted = FALSE;
288 	if (req->req.expect_100_continue && !req->sent_100_continue)
289 		http_server_connection_output_trigger(req->conn);
290 }
291 
292 static void
http_server_request_connect_callback(struct http_server_request * req)293 http_server_request_connect_callback(struct http_server_request *req)
294 {
295 	struct http_server_connection *conn = req->conn;
296 
297 	if (conn->callbacks->handle_connect_request == NULL) {
298 		http_server_request_fail(req, 505, "Not Implemented");
299 		return;
300 	}
301 
302 	if (req->req.target.format !=
303 	    HTTP_REQUEST_TARGET_FORMAT_AUTHORITY) {
304 		http_server_request_fail(req, 400, "Bad Request");
305 		return;
306 	}
307 
308 	conn->callbacks->handle_connect_request(conn->context, req,
309 						req->req.target.url);
310 }
311 
312 static void
http_server_request_default_handler(struct http_server_request * req)313 http_server_request_default_handler(struct http_server_request *req)
314 {
315 	const struct http_request *hreq = &req->req;
316 	struct http_server_response *resp;
317 
318 	if (strcmp(hreq->method, "OPTIONS") == 0 &&
319 	    hreq->target.format == HTTP_REQUEST_TARGET_FORMAT_ASTERISK) {
320 		resp = http_server_response_create(req, 200, "OK");
321 		http_server_response_submit(resp);
322 		return;
323 	}
324 
325 	http_server_request_fail(req, 404, "Not Found");
326 	return;
327 }
328 
http_server_request_callback(struct http_server_request * req)329 void http_server_request_callback(struct http_server_request *req)
330 {
331 	struct http_server_connection *conn = req->conn;
332 
333 	if (strcmp(req->req.method, "CONNECT") == 0) {
334 		/* CONNECT method */
335 		http_server_request_connect_callback(req);
336 		return;
337 	}
338 
339 	if (http_server_resource_callback(req))
340 		return;
341 
342 	if (array_count(&req->server->resources) > 0)
343 		e_debug(req->event, "No matching resource found");
344 
345 	if (conn->callbacks->handle_request == NULL) {
346 		http_server_request_default_handler(req);
347 		return;
348 	}
349 	conn->callbacks->handle_request(conn->context, req);
350 }
351 
http_server_request_ready_to_respond(struct http_server_request * req)352 void http_server_request_ready_to_respond(struct http_server_request *req)
353 {
354 	e_debug(req->event, "Ready to respond");
355 
356 	req->state = HTTP_SERVER_REQUEST_STATE_READY_TO_RESPOND;
357 	http_server_connection_output_trigger(req->conn);
358 }
359 
http_server_request_submit_response(struct http_server_request * req)360 void http_server_request_submit_response(struct http_server_request *req)
361 {
362 	struct http_server_connection *conn = req->conn;
363 
364 	i_assert(conn != NULL && req->response != NULL &&
365 		 req->response->submitted);
366 
367 	http_server_request_ref(req);
368 
369 	if (conn->payload_handler != NULL && conn->payload_handler->req == req)
370 		http_server_payload_handler_destroy(&conn->payload_handler);
371 
372 	switch (req->state) {
373 	case HTTP_SERVER_REQUEST_STATE_NEW:
374 	case HTTP_SERVER_REQUEST_STATE_QUEUED:
375 	case HTTP_SERVER_REQUEST_STATE_PAYLOAD_IN:
376 	case HTTP_SERVER_REQUEST_STATE_PROCESSING:
377 	case HTTP_SERVER_REQUEST_STATE_SUBMITTED_RESPONSE:
378 		if (!http_server_request_is_complete(req)) {
379 			e_debug(req->event, "Not ready to respond");
380 			req->state = HTTP_SERVER_REQUEST_STATE_SUBMITTED_RESPONSE;
381 			http_server_connection_input_resume(req->conn);
382 			http_server_connection_input_set_pending(req->conn);
383 			break;
384 		}
385 		http_server_request_ready_to_respond(req);
386 		break;
387 	case HTTP_SERVER_REQUEST_STATE_READY_TO_RESPOND:
388 		http_server_connection_output_trigger(req->conn);
389 		break;
390 	case HTTP_SERVER_REQUEST_STATE_ABORTED:
391 		break;
392 	default:
393 		i_unreached();
394 	}
395 
396 	http_server_request_unref(&req);
397 }
398 
http_server_request_finished(struct http_server_request * req)399 void http_server_request_finished(struct http_server_request *req)
400 {
401 	struct http_server_connection *conn = req->conn;
402 	struct http_server_response *resp = req->response;
403 	http_server_tunnel_callback_t tunnel_callback = resp->tunnel_callback;
404 	void *tunnel_context = resp->tunnel_context;
405 
406 	e_debug(req->event, "Finished");
407 
408 	i_assert(req->state < HTTP_SERVER_REQUEST_STATE_FINISHED);
409 	req->state = HTTP_SERVER_REQUEST_STATE_FINISHED;
410 
411 	http_server_connection_remove_request(conn, req);
412 	conn->stats.response_count++;
413 
414 	if (req->response != NULL)
415 		http_server_response_request_finished(req->response);
416 
417 	if (tunnel_callback == NULL) {
418 		if (req->connection_close) {
419 			http_server_connection_close(&conn,
420 				t_strdup_printf(
421 					"Server closed connection: %u %s",
422 					resp->status, resp->reason));
423 			http_server_request_destroy(&req);
424 			return;
425 		} else if (req->conn->input_broken) {
426 			http_server_connection_close(
427 				&conn, "Connection input is broken");
428 			http_server_request_destroy(&req);
429 			return;
430 		} else if (req->req.connection_close) {
431 			http_server_connection_close(
432 				&conn, "Client requested connection close");
433 			http_server_request_destroy(&req);
434 			return;
435 		}
436 	}
437 
438 	http_server_request_destroy(&req);
439 	if (tunnel_callback != NULL) {
440 		http_server_connection_tunnel(&conn, tunnel_callback,
441 					      tunnel_context);
442 		return;
443 	}
444 
445 	http_server_connection_output_trigger(conn);
446 }
447 
448 static struct http_server_response *
http_server_request_create_fail_response(struct http_server_request * req,unsigned int status,const char * reason,const char * text)449 http_server_request_create_fail_response(struct http_server_request *req,
450 					 unsigned int status,
451 					 const char *reason, const char *text)
452 					 ATTR_NULL(4)
453 {
454 	struct http_server_response *resp;
455 
456 	req->failed = TRUE;
457 
458 	i_assert(status / 100 != 1 && status != 204 && status != 304);
459 
460 	resp = http_server_response_create(req, status, reason);
461 	if (!http_request_method_is(&req->req, "HEAD")) {
462 		http_server_response_add_header(resp, "Content-Type",
463 						"text/plain; charset=utf-8");
464 		if (text == NULL)
465 			text = reason;
466 		text = t_strconcat(text, "\r\n", NULL);
467 		http_server_response_set_payload_data(
468 			resp, (const unsigned char *)text, strlen(text));
469 	}
470 
471 	return resp;
472 }
473 
474 static void
http_server_request_fail_full(struct http_server_request * req,unsigned int status,const char * reason,const char * text)475 http_server_request_fail_full(struct http_server_request *req,
476 			      unsigned int status, const char *reason,
477 			      const char *text) ATTR_NULL(4)
478 {
479 	struct http_server_response *resp;
480 
481 	req->failed = TRUE;
482 	resp = http_server_request_create_fail_response(req, status, reason,
483 							text);
484 	http_server_response_submit(resp);
485 	if (req->conn->input_broken)
486 		req->connection_close = TRUE;
487 }
488 
http_server_request_fail(struct http_server_request * req,unsigned int status,const char * reason)489 void http_server_request_fail(struct http_server_request *req,
490 			      unsigned int status, const char *reason)
491 {
492 	http_server_request_fail_full(req, status, reason, NULL);
493 }
494 
http_server_request_fail_close(struct http_server_request * req,unsigned int status,const char * reason)495 void http_server_request_fail_close(struct http_server_request *req,
496 				    unsigned int status, const char *reason)
497 {
498 	http_server_request_connection_close(req, TRUE);
499 	http_server_request_fail_full(req, status, reason, NULL);
500 }
501 
http_server_request_fail_text(struct http_server_request * req,unsigned int status,const char * reason,const char * format,...)502 void http_server_request_fail_text(struct http_server_request *req,
503 				   unsigned int status, const char *reason,
504 				   const char *format, ...)
505 {
506 	va_list args;
507 
508 	va_start(args, format);
509 	http_server_request_fail_full(req, status, reason,
510 		t_strdup_vprintf(format, args));
511 	va_end(args);
512 }
513 
http_server_request_fail_auth(struct http_server_request * req,const char * reason,const struct http_auth_challenge * chlng)514 void http_server_request_fail_auth(struct http_server_request *req,
515 				   const char *reason,
516 				   const struct http_auth_challenge *chlng)
517 {
518 	struct http_server_response *resp;
519 
520 	req->failed = TRUE;
521 
522 	if (reason == NULL)
523 		reason = "Unauthenticated";
524 
525 	resp = http_server_request_create_fail_response(req, 401, reason,
526 							reason);
527 	http_server_response_add_auth(resp, chlng);
528 	http_server_response_submit(resp);
529 }
530 
http_server_request_fail_auth_basic(struct http_server_request * req,const char * reason,const char * realm)531 void http_server_request_fail_auth_basic(struct http_server_request *req,
532 					 const char *reason, const char *realm)
533 {
534 	struct http_auth_challenge chlng;
535 
536 	http_auth_basic_challenge_init(&chlng, realm);
537 	http_server_request_fail_auth(req, reason, &chlng);
538 }
539 
http_server_request_fail_bad_method(struct http_server_request * req,const char * allow)540 void http_server_request_fail_bad_method(struct http_server_request *req,
541 					 const char *allow)
542 {
543 	struct http_server_response *resp;
544 	const char *reason = "Method Not Allowed";
545 
546 	req->failed = TRUE;
547 
548 	resp = http_server_request_create_fail_response(req, 405, reason,
549 							reason);
550 	http_server_response_add_header(resp, "Allow", allow);
551 	http_server_response_submit(resp);
552 }
553 
554 /*
555  * Payload input stream
556  */
557 
558 struct http_server_istream {
559 	struct istream_private istream;
560 
561 	struct http_server_request *req;
562 
563 	ssize_t read_status;
564 };
565 
566 static void
http_server_istream_switch_ioloop_to(struct istream_private * stream,struct ioloop * ioloop)567 http_server_istream_switch_ioloop_to(struct istream_private *stream,
568 				     struct ioloop *ioloop)
569 {
570 	struct http_server_istream *hsristream =
571 		(struct http_server_istream *)stream;
572 
573 	if (hsristream->istream.istream.blocking)
574 		return;
575 
576 	i_assert(ioloop == current_ioloop);
577 	http_server_connection_switch_ioloop(hsristream->req->conn);
578 }
579 
580 static void
http_server_istream_read_any(struct http_server_istream * hsristream)581 http_server_istream_read_any(struct http_server_istream *hsristream)
582 {
583 	struct istream_private *stream = &hsristream->istream;
584 	struct http_server *server = hsristream->req->server;
585 	ssize_t ret;
586 
587 	if ((ret = i_stream_read_copy_from_parent(&stream->istream)) != 0) {
588 		hsristream->read_status = ret;
589 		io_loop_stop(server->ioloop);
590 	}
591 }
592 
593 static ssize_t
http_server_istream_read(struct istream_private * stream)594 http_server_istream_read(struct istream_private *stream)
595 {
596 	struct http_server_istream *hsristream =
597 		(struct http_server_istream *)stream;
598 	struct http_server_request *req = hsristream->req;
599 	struct http_server *server;
600 	struct http_server_connection *conn;
601 	bool blocking = stream->istream.blocking;
602 	ssize_t ret;
603 
604 	if (req == NULL) {
605 		/* Request already gone (we shouldn't get here) */
606 		stream->istream.stream_errno = EINVAL;
607 		return -1;
608 	}
609 
610 	i_stream_seek(stream->parent, stream->parent_start_offset +
611 		      stream->istream.v_offset);
612 
613 	server = hsristream->req->server;
614 	conn = hsristream->req->conn;
615 
616 	ret = i_stream_read_copy_from_parent(&stream->istream);
617 	if (ret == 0 && blocking) {
618 		struct ioloop *prev_ioloop = current_ioloop;
619 		struct io *io;
620 
621 		http_server_connection_ref(conn);
622 		http_server_request_ref(req);
623 
624 		i_assert(server->ioloop == NULL);
625 		server->ioloop = io_loop_create();
626 		http_server_connection_switch_ioloop(conn);
627 
628 		if (blocking && req->req.expect_100_continue &&
629 		    !req->sent_100_continue)
630 			http_server_connection_output_trigger(conn);
631 
632 		hsristream->read_status = 0;
633 		io = io_add_istream(&stream->istream,
634 				    http_server_istream_read_any, hsristream);
635 		while (req->state < HTTP_SERVER_REQUEST_STATE_FINISHED &&
636 			hsristream->read_status == 0) {
637 			io_loop_run(server->ioloop);
638 		}
639 		io_remove(&io);
640 
641 		io_loop_set_current(prev_ioloop);
642 		http_server_connection_switch_ioloop(conn);
643 		io_loop_set_current(server->ioloop);
644 		io_loop_destroy(&server->ioloop);
645 
646 		ret = hsristream->read_status;
647 
648 		if (!http_server_request_unref(&req))
649 			hsristream->req = NULL;
650 		http_server_connection_unref(&conn);
651 	}
652 
653 	return ret;
654 }
655 
656 static void
http_server_istream_destroy(struct iostream_private * stream)657 http_server_istream_destroy(struct iostream_private *stream)
658 {
659 	struct http_server_istream *hsristream =
660 		(struct http_server_istream *)stream;
661 	uoff_t v_offset;
662 
663 	v_offset = hsristream->istream.parent_start_offset +
664 		hsristream->istream.istream.v_offset;
665 	if (hsristream->istream.parent->seekable ||
666 	    v_offset > hsristream->istream.parent->v_offset) {
667 		/* Get to same position in parent stream */
668 		i_stream_seek(hsristream->istream.parent, v_offset);
669 	}
670 }
671 
672 struct istream *
http_server_request_get_payload_input(struct http_server_request * req,bool blocking)673 http_server_request_get_payload_input(struct http_server_request *req,
674 				      bool blocking)
675 {
676 	struct http_server_istream *hsristream;
677 	struct istream *payload = req->req.payload;
678 
679 	i_assert(req->payload_input == NULL);
680 
681 	hsristream = i_new(struct http_server_istream, 1);
682 	hsristream->req = req;
683 	hsristream->istream.max_buffer_size =
684 		payload->real_stream->max_buffer_size;
685 	hsristream->istream.stream_size_passthrough = TRUE;
686 
687 	hsristream->istream.read = http_server_istream_read;
688 	hsristream->istream.switch_ioloop_to =
689 		http_server_istream_switch_ioloop_to;
690 	hsristream->istream.iostream.destroy = http_server_istream_destroy;
691 
692 	hsristream->istream.istream.readable_fd = FALSE;
693 	hsristream->istream.istream.blocking = blocking;
694 	hsristream->istream.istream.seekable = FALSE;
695 
696 	req->payload_input = i_stream_create(&hsristream->istream, payload,
697 					     i_stream_get_fd(payload), 0);
698 	i_stream_unref(&req->req.payload);
699 	return req->payload_input;
700 }
701 
702 /*
703  * Payload handling
704  */
705 
706 static void
http_server_payload_handler_init(struct http_server_payload_handler * handler,struct http_server_request * req)707 http_server_payload_handler_init(struct http_server_payload_handler *handler,
708 				 struct http_server_request *req)
709 {
710 	struct http_server_connection *conn = req->conn;
711 
712 	i_assert(conn->payload_handler == NULL);
713 	i_assert(conn->in_req_callback);
714 
715 	conn->payload_handler = handler;
716 
717 	handler->req = req;
718 }
719 
http_server_payload_handler_destroy(struct http_server_payload_handler ** _handler)720 void http_server_payload_handler_destroy(
721 	struct http_server_payload_handler **_handler)
722 {
723 	struct http_server_payload_handler *handler = *_handler;
724 	struct http_server_connection *conn = handler->req->conn;
725 
726 	if (handler->in_callback) {
727 		/* Don't destroy handler while in callback */
728 		return;
729 	}
730 
731 	*_handler = NULL;
732 	i_assert(conn->payload_handler == NULL);
733 
734 	if (handler->destroy != NULL)
735 		handler->destroy(handler);
736 }
737 
http_server_payload_handler_switch_ioloop(struct http_server_payload_handler * handler,struct ioloop * ioloop)738 void http_server_payload_handler_switch_ioloop(
739 	struct http_server_payload_handler *handler, struct ioloop *ioloop)
740 {
741 	if (handler->switch_ioloop != NULL)
742 		handler->switch_ioloop(handler, ioloop);
743 }
744 
745 /* Pump-based */
746 
747 struct http_server_payload_handler_pump {
748 	struct http_server_payload_handler handler;
749 
750 	struct iostream_pump *pump;
751 
752 	void (*callback)(void *);
753 	void *context;
754 };
755 
756 static void
payload_handler_pump_destroy(struct http_server_payload_handler * handler)757 payload_handler_pump_destroy(struct http_server_payload_handler *handler)
758 {
759 	struct http_server_payload_handler_pump *phandler =
760 		(struct http_server_payload_handler_pump *)handler;
761 
762 	iostream_pump_unref(&phandler->pump);
763 }
764 
765 static void
payload_handler_pump_switch_ioloop(struct http_server_payload_handler * handler,struct ioloop * ioloop)766 payload_handler_pump_switch_ioloop(struct http_server_payload_handler *handler,
767 				   struct ioloop *ioloop)
768 {
769 	struct http_server_payload_handler_pump *phandler =
770 		(struct http_server_payload_handler_pump *)handler;
771 
772 	iostream_pump_switch_ioloop_to(phandler->pump, ioloop);
773 }
774 
775 static void
payload_handler_pump_callback(enum iostream_pump_status status,struct http_server_payload_handler_pump * phandler)776 payload_handler_pump_callback(enum iostream_pump_status status,
777 			      struct http_server_payload_handler_pump *phandler)
778 {
779 	struct http_server_payload_handler *handler = &phandler->handler;
780 	struct http_server_request *req = handler->req;
781 	struct http_server_connection *conn = req->conn;
782 	struct istream *input = iostream_pump_get_input(phandler->pump);
783 	struct ostream *output = iostream_pump_get_output(phandler->pump);
784 
785 	switch (status) {
786 	case IOSTREAM_PUMP_STATUS_INPUT_EOF:
787 		if (!i_stream_read_eof(conn->incoming_payload)) {
788 			http_server_request_fail_close(req, 413,
789 						       "Payload Too Large");
790 		} else {
791 			unsigned int old_refcount = req->refcount;
792 
793 			handler->in_callback = TRUE;
794 			phandler->callback(phandler->context);
795 			req->callback_refcount += req->refcount - old_refcount;
796 			handler->in_callback = FALSE;
797 
798 			i_assert(req->callback_refcount > 0 ||
799 				 (req->response != NULL &&
800 				  req->response->submitted));
801 		}
802 		break;
803 	case IOSTREAM_PUMP_STATUS_INPUT_ERROR:
804 		http_server_request_client_error(
805 			req, "iostream_pump: read(%s) failed: %s",
806 			i_stream_get_name(input), i_stream_get_error(input));
807 		http_server_request_fail_close(req, 400, "Bad Request");
808 		break;
809 	case IOSTREAM_PUMP_STATUS_OUTPUT_ERROR:
810 		if (output->stream_errno != 0) {
811 			e_error(req->event,
812 				"iostream_pump: write(%s) failed: %s",
813 				o_stream_get_name(output),
814 				o_stream_get_error(output));
815 		}
816 		http_server_request_fail_close(req, 500,
817 					       "Internal Server Error");
818 		break;
819 	}
820 
821 	if (conn->payload_handler != NULL)
822 		http_server_payload_handler_destroy(&conn->payload_handler);
823 }
824 
825 #undef http_server_request_forward_payload
http_server_request_forward_payload(struct http_server_request * req,struct ostream * output,uoff_t max_size,void (* callback)(void *),void * context)826 void http_server_request_forward_payload(struct http_server_request *req,
827 					 struct ostream *output,
828 					 uoff_t max_size,
829 					 void (*callback)(void *),
830 					 void *context)
831 {
832 	struct http_server_connection *conn = req->conn;
833 	struct istream *input = conn->incoming_payload;
834 	struct http_server_payload_handler_pump *phandler;
835 	uoff_t payload_size;
836 	int ret;
837 
838 	i_assert(req->req.payload != NULL);
839 
840 	if (max_size == UOFF_T_MAX) {
841 		i_stream_ref(input);
842 	} else {
843 		if ((ret = i_stream_get_size(input, TRUE,
844 					     &payload_size)) != 0) {
845 			if (ret < 0) {
846 				e_error(req->event,
847 					"i_stream_get_size(%s) failed: %s",
848 					i_stream_get_name(input),
849 					i_stream_get_error(input));
850 				http_server_request_fail_close(
851 					req, 500, "Internal Server Error");
852 				return;
853 			}
854 			if (payload_size > max_size) {
855 				http_server_request_fail_close(
856 					req, 413, "Payload Too Large");
857 				return;
858 			}
859 		}
860 		input = i_stream_create_limit(input, max_size);
861 	}
862 
863 	phandler = p_new(req->pool, struct http_server_payload_handler_pump, 1);
864 	http_server_payload_handler_init(&phandler->handler, req);
865 	phandler->handler.switch_ioloop = payload_handler_pump_switch_ioloop;
866 	phandler->handler.destroy = payload_handler_pump_destroy;
867 	phandler->callback = callback;
868 	phandler->context = context;
869 
870 	phandler->pump = iostream_pump_create(input, output);
871 	iostream_pump_set_completion_callback(phandler->pump,
872 					      payload_handler_pump_callback,
873 					      phandler);
874 	iostream_pump_start(phandler->pump);
875 	i_stream_unref(&input);
876 }
877 
878 #undef http_server_request_buffer_payload
http_server_request_buffer_payload(struct http_server_request * req,buffer_t * buffer,uoff_t max_size,void (* callback)(void *),void * context)879 void http_server_request_buffer_payload(struct http_server_request *req,
880 					buffer_t *buffer, uoff_t max_size,
881 					void (*callback)(void *),
882 					void *context)
883 {
884 	struct ostream *output;
885 
886 	output = o_stream_create_buffer(buffer);
887 	http_server_request_forward_payload(req,
888 		output, max_size, callback, context);
889 	o_stream_unref(&output);
890 }
891 
892 /* Raw */
893 
894 struct http_server_payload_handler_raw {
895 	struct http_server_payload_handler handler;
896 
897 	struct io *io;
898 
899 	void (*callback)(void *context);
900 	void *context;
901 };
902 
903 static void
payload_handler_raw_destroy(struct http_server_payload_handler * handler)904 payload_handler_raw_destroy(struct http_server_payload_handler *handler)
905 {
906 	struct http_server_payload_handler_raw *rhandler =
907 		(struct http_server_payload_handler_raw *)handler;
908 
909 	io_remove(&rhandler->io);
910 }
911 
912 static void
payload_handler_raw_switch_ioloop(struct http_server_payload_handler * handler,struct ioloop * ioloop)913 payload_handler_raw_switch_ioloop(struct http_server_payload_handler *handler,
914 				  struct ioloop *ioloop)
915 {
916 	struct http_server_payload_handler_raw *rhandler =
917 		(struct http_server_payload_handler_raw *)handler;
918 
919 	rhandler->io = io_loop_move_io_to(ioloop, &rhandler->io);
920 }
921 
922 static void
payload_handler_raw_input(struct http_server_payload_handler_raw * rhandler)923 payload_handler_raw_input(struct http_server_payload_handler_raw *rhandler)
924 {
925 	struct http_server_payload_handler *handler = &rhandler->handler;
926 	struct http_server_request *req = handler->req;
927 	struct http_server_connection *conn = req->conn;
928 	struct istream *input = conn->incoming_payload;
929 	unsigned int old_refcount = req->refcount;
930 
931 	handler->in_callback = TRUE;
932 	rhandler->callback(rhandler->context);
933 	req->callback_refcount += req->refcount - old_refcount;
934 	handler->in_callback = FALSE;
935 
936 	if (input != NULL && input->stream_errno != 0) {
937 		if (req->response == NULL) {
938 			http_server_request_client_error(
939 				req, "read(%s) failed: %s",
940 				i_stream_get_name(input),
941 				i_stream_get_error(input));
942 			http_server_request_fail_close(req, 400, "Bad Request");
943 		}
944 	} else if (input == NULL || !i_stream_have_bytes_left(input)) {
945 		i_assert(req->callback_refcount > 0 ||
946 			 (req->response != NULL && req->response->submitted));
947 	} else {
948 		return;
949 	}
950 
951 	if (conn->payload_handler != NULL)
952 		http_server_payload_handler_destroy(&conn->payload_handler);
953 
954 }
955 
956 #undef http_server_request_handle_payload
http_server_request_handle_payload(struct http_server_request * req,void (* callback)(void * context),void * context)957 void http_server_request_handle_payload(struct http_server_request *req,
958 					void (*callback)(void *context),
959 					void *context)
960 {
961 	struct http_server_payload_handler_raw *rhandler;
962 	struct http_server_connection *conn = req->conn;
963 
964 	rhandler = p_new(req->pool, struct http_server_payload_handler_raw, 1);
965 	http_server_payload_handler_init(&rhandler->handler, req);
966 	rhandler->handler.switch_ioloop = payload_handler_raw_switch_ioloop;
967 	rhandler->handler.destroy = payload_handler_raw_destroy;
968 	rhandler->callback = callback;
969 	rhandler->context = context;
970 
971 	rhandler->io = io_add_istream(conn->incoming_payload,
972 				      payload_handler_raw_input, rhandler);
973 	i_stream_set_input_pending(conn->incoming_payload, TRUE);
974 }
975 
http_server_request_add_response_header(struct http_server_request * req,const char * key,const char * value)976 void http_server_request_add_response_header(struct http_server_request *req,
977 					     const char *key, const char *value)
978 {
979 	struct http_server_response *resp;
980 
981 	resp = http_server_response_create(req, 0, "");
982 	http_server_response_add_permanent_header(resp, key, value);
983 }
984