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