http-server-request.c revision 38af46387e565053adf6c47f7f6871676d685de8
5a580c3a38ced62d4bcc95b8ac7c4f2935b5d294Timo Sirainen/* Copyright (c) 2013-2017 Dovecot authors, see the included COPYING file */
94d8e51119003d2bc5a100c663f90141f297385dTimo Sirainenstatic inline void
9393445a6dabd17ce62ebfc12fd73545b0065824Timo Sirainenhttp_server_request_debug(struct http_server_request *req,
37847ec8eaec9ad55c9df10ae109efe7b37ac573Timo Sirainenstatic inline void
ef50336eefcb9ba99f73c6af37420eaf8857a39bTimo Sirainenhttp_server_request_debug(struct http_server_request *req,
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen const char *format, ...)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic inline void
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenhttp_server_request_error(struct http_server_request *req,
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenstatic inline void
220e21750948941dc6e33b8f11b552fa21d7f81eTimo Sirainenhttp_server_request_error(struct http_server_request *req,
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen const char *format, ...)
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainenstatic inline void
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenhttp_server_request_client_error(struct http_server_request *req,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic inline void
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenhttp_server_request_client_error(struct http_server_request *req,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen const char *format, ...)
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainenhttp_server_request_new(struct http_server_connection *conn)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen static unsigned int id_counter = 0;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen pool = pool_alloconly_create(MEMPOOL_GROWING"http_server_request", 4096);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen req = p_new(pool, struct http_server_request, 1);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen http_server_connection_add_request(conn, req);
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainenvoid http_server_request_ref(struct http_server_request *req)
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainenbool http_server_request_unref(struct http_server_request **_req)
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen struct http_server_connection *conn = req->conn;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (req->state < HTTP_SERVER_REQUEST_STATE_FINISHED) {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen req->state = HTTP_SERVER_REQUEST_STATE_ABORTED;
db8b0a3f74a20528d66a3c4be7df920e5c4554c2Timo Sirainen http_server_connection_remove_request(conn, req);
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainenvoid http_server_request_destroy(struct http_server_request **_req)
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen /* just make sure the request ends in a proper state */
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen if (req->state < HTTP_SERVER_REQUEST_STATE_FINISHED)
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen req->state = HTTP_SERVER_REQUEST_STATE_ABORTED;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen void (*callback)(void *) = req->destroy_callback;
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen#undef http_server_request_set_destroy_callback
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainenvoid http_server_request_set_destroy_callback(struct http_server_request *req,
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen void (*callback)(void *),
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainenvoid http_server_request_abort(struct http_server_request **_req,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen struct http_server_connection *conn = req->conn;
5214b67a7dabab87da74e04bb8b227f94b95bce4Timo Sirainen if (req->state >= HTTP_SERVER_REQUEST_STATE_FINISHED)
12b4dbf933ee54f7b96968ba150095baa985fdafTimo Sirainen if (req->state < HTTP_SERVER_REQUEST_STATE_FINISHED) {
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen http_server_connection_remove_request(conn, req);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen /* send best-effort response if appropriate */
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen req->state >= HTTP_SERVER_REQUEST_STATE_PROCESSING &&
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen req->state < HTTP_SERVER_REQUEST_STATE_SENT_RESPONSE) {
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen static const char *response =
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen "HTTP/1.1 500 Internal Server Error\r\n"
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen "Content-Length: 0\r\n"
917498e6f84969d2b93410c1e479735abe8e0ed7Timo Sirainen /* close the connection */
db8b0a3f74a20528d66a3c4be7df920e5c4554c2Timo Sirainenhttp_server_request_get(struct http_server_request *req)
0bf25546c91ccafff9e2cc93368d2d25acb5c39eTimo Sirainenhttp_server_request_get_pool(struct http_server_request *req)
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainenhttp_server_request_get_response(struct http_server_request *req)
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainenint http_server_request_get_auth(struct http_server_request *req,
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen auth = http_request_header_get(&req->req, "Authorization");
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen ((const unsigned char *)auth, strlen(auth), credentials) < 0)
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainenbool http_server_request_is_finished(struct http_server_request *req)
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen req->state == HTTP_SERVER_REQUEST_STATE_ABORTED;
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainenbool http_server_request_is_complete(struct http_server_request *req)
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen return (req->failed || req->conn->input_broken ||
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen (req->next != NULL && !http_server_request_is_new(req->next)) ||
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen !http_server_connection_pending_payload(req->conn));
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainenvoid http_server_request_halt_payload(struct http_server_request *req)
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen i_assert(req->state <= HTTP_SERVER_REQUEST_STATE_QUEUED);
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainenvoid http_server_request_continue_payload(struct http_server_request *req)
0bf25546c91ccafff9e2cc93368d2d25acb5c39eTimo Sirainen i_assert(req->state <= HTTP_SERVER_REQUEST_STATE_QUEUED);
0bf25546c91ccafff9e2cc93368d2d25acb5c39eTimo Sirainen if (req->req.expect_100_continue && !req->sent_100_continue)
0bf25546c91ccafff9e2cc93368d2d25acb5c39eTimo Sirainen http_server_connection_trigger_responses(req->conn);
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainenvoid http_server_request_ready_to_respond(struct http_server_request *req)
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen http_server_request_debug(req, "Ready to respond");
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainen req->state = HTTP_SERVER_REQUEST_STATE_READY_TO_RESPOND;
5214b67a7dabab87da74e04bb8b227f94b95bce4Timo Sirainen http_server_connection_trigger_responses(req->conn);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenvoid http_server_request_submit_response(struct http_server_request *req)
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen struct http_server_connection *conn = req->conn;
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen i_assert(conn != NULL && req->response != NULL && req->response->submitted);
02e61e13a8360a9d3ec92c5fa5ae60c0f0181b71Timo Sirainen if (conn->payload_handler != NULL && conn->payload_handler->req == req)
02e61e13a8360a9d3ec92c5fa5ae60c0f0181b71Timo Sirainen http_server_payload_handler_destroy(&conn->payload_handler);
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen http_server_request_debug(req, "Not ready to respond");
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen req->state = HTTP_SERVER_REQUEST_STATE_SUBMITTED_RESPONSE;
1c1cecd3dfaf71b0c9499b044023e631841e88aaTimo Sirainen case HTTP_SERVER_REQUEST_STATE_READY_TO_RESPOND:
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen http_server_connection_trigger_responses(req->conn);
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainenvoid http_server_request_finished(struct http_server_request *req)
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen struct http_server_connection *conn = req->conn;
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen struct http_server_response *resp = req->response;
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen http_server_tunnel_callback_t tunnel_callback = resp->tunnel_callback;
360123b1b41b7aa8af6c4a91c39046be646cd349Timo Sirainen i_assert(req->state < HTTP_SERVER_REQUEST_STATE_FINISHED);
360123b1b41b7aa8af6c4a91c39046be646cd349Timo Sirainen req->state = HTTP_SERVER_REQUEST_STATE_FINISHED;
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainen http_server_connection_remove_request(conn, req);
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen if (tunnel_callback == NULL && (req->req.connection_close || resp->close)) {
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainen t_strdup_printf("Server closed connection: %u %s",
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen "Client requested connection close");
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen http_server_connection_tunnel(&conn, tunnel_callback, tunnel_context);
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen http_server_connection_trigger_responses(conn);
0bf25546c91ccafff9e2cc93368d2d25acb5c39eTimo Sirainenhttp_server_request_create_fail_response(struct http_server_request *req,
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen i_assert(status / 100 != 1 && status != 204 && status != 304);
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen resp = http_server_response_create(req, status, reason);
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen if (!http_request_method_is(&req->req, "HEAD")) {
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen (resp, "Content-Type", "text/plain; charset=utf-8");
94d8e51119003d2bc5a100c663f90141f297385dTimo Sirainen (resp, (const unsigned char *)reason, strlen(reason));
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainenhttp_server_request_fail_full(struct http_server_request *req,
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen unsigned int status, const char *reason, bool close)
94d8e51119003d2bc5a100c663f90141f297385dTimo Sirainen resp = http_server_request_create_fail_response(req, status, reason);
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainenvoid http_server_request_fail(struct http_server_request *req,
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen http_server_request_fail_full(req, status, reason,
9fc97c8aa8190df87624d214bcc5d0b5362bec93Timo Sirainenvoid http_server_request_fail_close(struct http_server_request *req,
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen http_server_request_fail_full(req, status, reason, TRUE);
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainenvoid http_server_request_fail_auth(struct http_server_request *req,
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen const char *reason, const struct http_auth_challenge *chlng)
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen resp = http_server_request_create_fail_response(req, 401, reason);
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainenvoid http_server_request_fail_auth_basic(struct http_server_request *req,
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen http_auth_basic_challenge_init(&chlng, realm);
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen http_server_request_fail_auth(req, reason, &chlng);
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen * Payload input stream
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainenhttp_server_istream_switch_ioloop(struct istream_private *stream)
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen http_server_connection_switch_ioloop(hsristream->req->conn);
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainenhttp_server_istream_read_any(struct http_server_istream *hsristream)
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen struct istream_private *stream = &hsristream->istream;
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen struct http_server *server = hsristream->req->server;
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainenhttp_server_istream_read(struct istream_private *stream)
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen struct http_server_request *req = hsristream->req;
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen /* request already gone (we shouldn't get here) */
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen i_stream_seek(stream->parent, stream->parent_start_offset +
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen ret = i_stream_read_copy_from_parent(&stream->istream);
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen if (blocking && req->req.expect_100_continue &&
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen http_server_connection_trigger_responses(conn);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen while (req->state < HTTP_SERVER_REQUEST_STATE_FINISHED &&
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainenhttp_server_istream_destroy(struct iostream_private *stream)
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen v_offset = hsristream->istream.parent_start_offset +
1c1cecd3dfaf71b0c9499b044023e631841e88aaTimo Sirainen v_offset > hsristream->istream.parent->v_offset) {
1c1cecd3dfaf71b0c9499b044023e631841e88aaTimo Sirainen /* get to same position in parent stream */
1c1cecd3dfaf71b0c9499b044023e631841e88aaTimo Sirainen i_stream_seek(hsristream->istream.parent, v_offset);
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainenhttp_server_request_get_payload_input(struct http_server_request *req,
e4cb3bfcd42f1f2c9e676ece6f7f53803f5c6a16Timo Sirainen hsristream = i_new(struct http_server_istream, 1);
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen hsristream->istream.stream_size_passthrough = TRUE;
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen hsristream->istream.read = http_server_istream_read;
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen hsristream->istream.switch_ioloop = http_server_istream_switch_ioloop;
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen hsristream->istream.iostream.destroy = http_server_istream_destroy;
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen hsristream->istream.istream.readable_fd = FALSE;
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen hsristream->istream.istream.blocking = blocking;
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen (&hsristream->istream, payload, i_stream_get_fd(payload));
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen * Payload handling
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen struct http_server_connection *conn = req->conn;
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen struct http_server_payload_handler **_handler)
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen struct http_server_payload_handler *handler = *_handler;
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen struct http_server_connection *conn = handler->req->conn;
8f70c97f7ab7b7e1683ed5cfcd96721a899c2520Timo Sirainen /* don't destroy handler while in callback */
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainenvoid http_server_payload_handler_switch_ioloop(
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen/* pump-based */
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen void (*callback)(void *);
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen struct http_server_payload_handler_pump *phandler =
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen (struct http_server_payload_handler_pump *)handler;
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen struct http_server_payload_handler_pump *phandler =
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen (struct http_server_payload_handler_pump *)handler;
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen struct http_server_payload_handler_pump *phandler)
1f4399a277b861419b82758ab0462e90c00a4c41Timo Sirainen struct http_server_payload_handler *handler = &phandler->handler;
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen struct http_server_request *req = handler->req;
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen struct http_server_connection *conn = req->conn;
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen struct istream *input = iostream_pump_get_input(phandler->pump);
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen struct ostream *output = iostream_pump_get_output(phandler->pump);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen if (!i_stream_is_eof(conn->incoming_payload)) {
9b00ecffbe74fd864d0d72e6112ec53b86f619baTimo Sirainen req->callback_refcount += req->refcount - old_refcount;
9b00ecffbe74fd864d0d72e6112ec53b86f619baTimo Sirainen (req->response != NULL && req->response->submitted));
3e0bae44b65f5c46989fcef3d1e07203f496327eTimo Sirainen "iostream_pump: read(%s) failed: %s",
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen "iostream_pump: write(%s) failed: %s",
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainen http_server_payload_handler_destroy(&conn->payload_handler);
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainenvoid http_server_request_forward_payload(struct http_server_request *req,
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen struct http_server_connection *conn = req->conn;
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen struct istream *input = conn->incoming_payload;
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen struct http_server_payload_handler_pump *phandler;
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen if ((ret = i_stream_get_size(input, TRUE, &payload_size)) != 0) {
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen "i_stream_get_size(%s) failed: %s",
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen i_stream_get_name(input), i_stream_get_error(input));
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen input = i_stream_create_limit(input, max_size);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen phandler = p_new(req->pool, struct http_server_payload_handler_pump, 1);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen http_server_payload_handler_init(&phandler->handler, req);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen phandler->handler.switch_ioloop = payload_handler_pump_switch_ioloop;
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen phandler->handler.destroy = payload_handler_pump_destroy;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen phandler->pump = iostream_pump_create(input, output);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen iostream_pump_set_completion_callback(phandler->pump,
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainenvoid http_server_request_buffer_payload(struct http_server_request *req,
c58906589cafc32df4c04ffbef933baadd3f2276Timo Sirainen struct http_server_payload_handler_raw *rhandler =
c58906589cafc32df4c04ffbef933baadd3f2276Timo Sirainen (struct http_server_payload_handler_raw *)handler;
6dd77763f5451269ace733579cf58f2f3b18bca4Timo Sirainen struct http_server_payload_handler_raw *rhandler =
6dd77763f5451269ace733579cf58f2f3b18bca4Timo Sirainen (struct http_server_payload_handler_raw *)handler;
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen rhandler->io = io_loop_move_io(&rhandler->io);
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen struct http_server_payload_handler_raw *rhandler)
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen struct http_server_payload_handler *handler = &rhandler->handler;
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen struct http_server_request *req = handler->req;
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen struct http_server_connection *conn = req->conn;
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen struct istream *input = conn->incoming_payload;
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen req->callback_refcount += req->refcount - old_refcount;
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen if (input != NULL && input->stream_errno != 0) {
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen "read(%s) failed: %s",
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen (req->response != NULL && req->response->submitted));
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen http_server_payload_handler_destroy(&conn->payload_handler);
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainenvoid http_server_request_handle_payload(struct http_server_request *req,
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen void (*callback)(void *context), void *context)
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen struct http_server_payload_handler_raw *rhandler;
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen struct http_server_connection *conn = req->conn;
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen rhandler = p_new(req->pool, struct http_server_payload_handler_raw, 1);
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen http_server_payload_handler_init(&rhandler->handler, req);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen rhandler->handler.switch_ioloop = payload_handler_raw_switch_ioloop;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen rhandler->handler.destroy = payload_handler_raw_destroy;
949fa97a4ab5c62e4db73c3973e35ae3b73a2b23Timo Sirainen rhandler->io = io_add_istream(conn->incoming_payload,