http-server-request.c revision 564e117d86ce5b659f9b9570edddc566f9ebb5df
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch/* Copyright (c) 2013-2014 Dovecot authors, see the included COPYING file */
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch#include "lib.h"
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch#include "http-server-private.h"
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschstruct http_server_request *
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschhttp_server_request_new(struct http_server_connection *conn)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch{
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch pool_t pool;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch struct http_server_request *req;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch pool = pool_alloconly_create("http_message", 4096);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch req = p_new(pool, struct http_server_request, 1);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch req->pool = pool;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch req->refcount = 1;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch req->conn = conn;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch req->server = conn->server;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
833bed942977673526c72e79bccc09314fc57104Phil Carmody http_server_connection_add_request(conn, req);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch return req;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch}
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschvoid http_server_request_ref(struct http_server_request *req)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch{
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch req->refcount++;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch}
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
1e9296de32c9ddda40f33c06556cd568ddadf71fTimo Sirainenbool http_server_request_unref(struct http_server_request **_req)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch{
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch struct http_server_request *req = *_req;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch struct http_server_connection *conn = req->conn;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch i_assert(req->refcount > 0);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch if (--req->refcount > 0)
1e9296de32c9ddda40f33c06556cd568ddadf71fTimo Sirainen return TRUE;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
833bed942977673526c72e79bccc09314fc57104Phil Carmody if (req->state < HTTP_SERVER_REQUEST_STATE_FINISHED) {
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch req->state = HTTP_SERVER_REQUEST_STATE_ABORTED;
833bed942977673526c72e79bccc09314fc57104Phil Carmody http_server_connection_remove_request(conn, req);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch }
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch if (req->destroy_callback != NULL) {
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch req->destroy_callback(req->destroy_context);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch req->destroy_callback = NULL;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch }
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch if (req->response != NULL)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch http_server_response_free(req->response);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch pool_unref(&req->pool);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch *_req = NULL;
1e9296de32c9ddda40f33c06556cd568ddadf71fTimo Sirainen return FALSE;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch}
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
faa8995f1d300e7a8917407a52bbd1b98e10bf25Timo Sirainenvoid http_server_request_destroy(struct http_server_request **_req)
faa8995f1d300e7a8917407a52bbd1b98e10bf25Timo Sirainen{
faa8995f1d300e7a8917407a52bbd1b98e10bf25Timo Sirainen struct http_server_request *req = *_req;
faa8995f1d300e7a8917407a52bbd1b98e10bf25Timo Sirainen
14bd2410de3a0261d9c53c6120915027262216bdTimo Sirainen if (req->delay_destroy) {
14bd2410de3a0261d9c53c6120915027262216bdTimo Sirainen req->destroy_pending = TRUE;
14bd2410de3a0261d9c53c6120915027262216bdTimo Sirainen } else if (req->destroy_callback != NULL) {
9f8cef4cbc49797053c343209ea13022fdbc5a63Stephan Bosch void (*callback)(void *) = req->destroy_callback;
9f8cef4cbc49797053c343209ea13022fdbc5a63Stephan Bosch
faa8995f1d300e7a8917407a52bbd1b98e10bf25Timo Sirainen req->destroy_callback = NULL;
9f8cef4cbc49797053c343209ea13022fdbc5a63Stephan Bosch callback(req->destroy_context);
faa8995f1d300e7a8917407a52bbd1b98e10bf25Timo Sirainen }
faa8995f1d300e7a8917407a52bbd1b98e10bf25Timo Sirainen http_server_request_unref(_req);
faa8995f1d300e7a8917407a52bbd1b98e10bf25Timo Sirainen}
faa8995f1d300e7a8917407a52bbd1b98e10bf25Timo Sirainen
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschvoid http_server_request_set_destroy_callback(struct http_server_request *req,
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch void (*callback)(void *),
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch void *context)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch{
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch req->destroy_callback = callback;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch req->destroy_context = context;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch}
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschvoid http_server_request_abort(struct http_server_request **_req)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch{
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch struct http_server_request *req = *_req;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch struct http_server_connection *conn = req->conn;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
833bed942977673526c72e79bccc09314fc57104Phil Carmody if (req->state < HTTP_SERVER_REQUEST_STATE_FINISHED) {
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch req->state = HTTP_SERVER_REQUEST_STATE_ABORTED;
833bed942977673526c72e79bccc09314fc57104Phil Carmody http_server_connection_remove_request(conn, req);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch }
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch if (req->response != NULL)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch http_server_response_free(req->response);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch req->response = NULL;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch req->conn = conn;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
91a482473f200152d6713181c0e36f7a4f03ef6dTimo Sirainen http_server_request_destroy(_req);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch}
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschconst struct http_request *
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschhttp_server_request_get(struct http_server_request *req)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch{
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch return &req->req;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch}
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschpool_t
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschhttp_server_request_get_pool(struct http_server_request *req)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch{
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch return req->pool;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch}
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
85f3bd5926fff0e70b6d259a5c8074bd8cdeb9adTimo Sirainenstruct http_server_response *
85f3bd5926fff0e70b6d259a5c8074bd8cdeb9adTimo Sirainenhttp_server_request_get_response(struct http_server_request *req)
85f3bd5926fff0e70b6d259a5c8074bd8cdeb9adTimo Sirainen{
85f3bd5926fff0e70b6d259a5c8074bd8cdeb9adTimo Sirainen return req->response;
85f3bd5926fff0e70b6d259a5c8074bd8cdeb9adTimo Sirainen}
85f3bd5926fff0e70b6d259a5c8074bd8cdeb9adTimo Sirainen
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Boschint http_server_request_get_auth(struct http_server_request *req,
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch struct http_auth_credentials *credentials)
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch{
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch const char *auth;
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch auth = http_request_header_get(&req->req, "Authorization");
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch if (auth == NULL)
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch return 0;
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch if (http_auth_parse_credentials
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch ((const unsigned char *)auth, strlen(auth), credentials) < 0)
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch return -1;
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch return 1;
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch}
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch
93ed69606237a08623f8294c060fa148880058f8Timo Sirainenbool http_server_request_is_finished(struct http_server_request *req)
93ed69606237a08623f8294c060fa148880058f8Timo Sirainen{
93ed69606237a08623f8294c060fa148880058f8Timo Sirainen return req->response != NULL ||
93ed69606237a08623f8294c060fa148880058f8Timo Sirainen req->state == HTTP_SERVER_REQUEST_STATE_ABORTED;
93ed69606237a08623f8294c060fa148880058f8Timo Sirainen}
93ed69606237a08623f8294c060fa148880058f8Timo Sirainen
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschvoid http_server_request_halt_payload(struct http_server_request *req)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch{
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch i_assert(req->state <= HTTP_SERVER_REQUEST_STATE_QUEUED);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch req->payload_halted = TRUE;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch}
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschvoid http_server_request_continue_payload(struct http_server_request *req)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch{
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch i_assert(req->state <= HTTP_SERVER_REQUEST_STATE_QUEUED);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch req->payload_halted = FALSE;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch if (req->req.expect_100_continue && !req->sent_100_continue)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch http_server_connection_send_responses(req->conn);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch}
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschvoid http_server_request_ready_to_respond(struct http_server_request *req)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch{
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch req->state = HTTP_SERVER_REQUEST_STATE_READY_TO_RESPOND;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch http_server_connection_send_responses(req->conn);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch}
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschvoid http_server_request_submit_response(struct http_server_request *req)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch{
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch struct http_server_connection *conn = req->conn;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch i_assert(conn != NULL && req->response != NULL && req->response->submitted);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch switch (req->state) {
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch case HTTP_SERVER_REQUEST_STATE_NEW:
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch case HTTP_SERVER_REQUEST_STATE_QUEUED:
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch case HTTP_SERVER_REQUEST_STATE_PAYLOAD_IN:
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch case HTTP_SERVER_REQUEST_STATE_PROCESSING:
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch if (!http_server_request_is_complete(req)) {
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch req->state = HTTP_SERVER_REQUEST_STATE_SUBMITTED_RESPONSE;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch break;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch }
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch http_server_request_ready_to_respond(req);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch break;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch case HTTP_SERVER_REQUEST_STATE_ABORTED:
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch break;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch default:
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch i_unreached();
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch }
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch}
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschvoid http_server_request_finished(struct http_server_request *req)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch{
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch struct http_server_connection *conn = req->conn;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch struct http_server_response *resp = req->response;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch http_server_tunnel_callback_t tunnel_callback = resp->tunnel_callback;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch void *tunnel_context = resp->tunnel_context;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch i_assert(req->state < HTTP_SERVER_REQUEST_STATE_FINISHED);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch req->state = HTTP_SERVER_REQUEST_STATE_FINISHED;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
833bed942977673526c72e79bccc09314fc57104Phil Carmody http_server_connection_remove_request(conn, req);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch conn->stats.response_count++;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch if (tunnel_callback == NULL && (req->req.connection_close || resp->close)) {
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch if (resp->close) {
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch http_server_connection_close(&conn,
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch t_strdup_printf("Server closed connection: %u %s",
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch resp->status, resp->reason));
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch } else {
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch http_server_connection_close(&conn,
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch "Client requested connection close");
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch }
faa8995f1d300e7a8917407a52bbd1b98e10bf25Timo Sirainen http_server_request_destroy(&req);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch return;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch }
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
faa8995f1d300e7a8917407a52bbd1b98e10bf25Timo Sirainen http_server_request_destroy(&req);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch if (tunnel_callback != NULL) {
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch http_server_connection_tunnel(&conn, tunnel_callback, tunnel_context);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch return;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch }
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch http_server_connection_send_responses(conn);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch}
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Boschstatic struct http_server_response *
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Boschhttp_server_request_create_fail_response(struct http_server_request *req,
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch unsigned int status, const char *reason)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch{
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch struct http_server_response *resp;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
b37e11d37fb1ebf50511eef5d9d96d1205818458Stephan Bosch req->failed = TRUE;
b37e11d37fb1ebf50511eef5d9d96d1205818458Stephan Bosch
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch resp = http_server_response_create(req, status, reason);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch http_server_response_add_header
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch (resp, "Content-Type", "text/plain; charset=utf-8");
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch reason = t_strconcat(reason, "\r\n", NULL);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch http_server_response_set_payload_data
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch (resp, (const unsigned char *)reason, strlen(reason));
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch return resp;
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch}
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Boschstatic void
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Boschhttp_server_request_fail_full(struct http_server_request *req,
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch unsigned int status, const char *reason, bool close)
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch{
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch struct http_server_response *resp;
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch req->failed = TRUE;
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch resp = http_server_request_create_fail_response(req, status, reason);
95e0b82fdff1bb511067d703bb8b67c22f242c38Timo Sirainen if (close)
95e0b82fdff1bb511067d703bb8b67c22f242c38Timo Sirainen http_server_response_submit_close(resp);
95e0b82fdff1bb511067d703bb8b67c22f242c38Timo Sirainen else
95e0b82fdff1bb511067d703bb8b67c22f242c38Timo Sirainen http_server_response_submit(resp);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch}
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch
95e0b82fdff1bb511067d703bb8b67c22f242c38Timo Sirainenvoid http_server_request_fail(struct http_server_request *req,
95e0b82fdff1bb511067d703bb8b67c22f242c38Timo Sirainen unsigned int status, const char *reason)
95e0b82fdff1bb511067d703bb8b67c22f242c38Timo Sirainen{
95e0b82fdff1bb511067d703bb8b67c22f242c38Timo Sirainen http_server_request_fail_full(req, status, reason,
95e0b82fdff1bb511067d703bb8b67c22f242c38Timo Sirainen req->conn->input_broken);
95e0b82fdff1bb511067d703bb8b67c22f242c38Timo Sirainen}
95e0b82fdff1bb511067d703bb8b67c22f242c38Timo Sirainen
95e0b82fdff1bb511067d703bb8b67c22f242c38Timo Sirainenvoid http_server_request_fail_close(struct http_server_request *req,
95e0b82fdff1bb511067d703bb8b67c22f242c38Timo Sirainen unsigned int status, const char *reason)
95e0b82fdff1bb511067d703bb8b67c22f242c38Timo Sirainen{
95e0b82fdff1bb511067d703bb8b67c22f242c38Timo Sirainen http_server_request_fail_full(req, status, reason, TRUE);
95e0b82fdff1bb511067d703bb8b67c22f242c38Timo Sirainen}
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Boschvoid http_server_request_fail_auth(struct http_server_request *req,
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch const char *reason, const struct http_auth_challenge *chlng)
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch{
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch struct http_server_response *resp;
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch req->failed = TRUE;
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch if (reason == NULL)
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch reason = "Unauthenticated";
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch resp = http_server_request_create_fail_response(req, 401, reason);
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch http_server_response_add_auth(resp, chlng);
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch http_server_response_submit(resp);
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch}
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Boschvoid http_server_request_fail_auth_basic(struct http_server_request *req,
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch const char *reason, const char *realm)
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch{
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch struct http_auth_challenge chlng;
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch http_auth_basic_challenge_init(&chlng, realm);
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch http_server_request_fail_auth(req, reason, &chlng);
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch}
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch