conn->input_broken = TRUE;
http_server_connection_client_error(conn,
"Client sent excessively large request");
- http_server_request_fail(req, 413, "Payload Too Large", TRUE);
+ http_server_request_fail_close(req, 413, "Payload Too Large");
return;
case EIO:
conn->input_broken = TRUE;
http_server_connection_client_error(conn,
"Client sent invalid request payload");
- http_server_request_fail(req, 400, "Bad Request", conn->input_broken);
+ http_server_request_fail_close(req, 400, "Bad Request");
return;
default:
break;
/* CONNECT method */
if (strcmp(req->req.method, "CONNECT") == 0) {
if (conn->callbacks->handle_connect_request == NULL) {
- http_server_request_fail(req, 505, "Not Implemented", FALSE);
+ http_server_request_fail(req, 505, "Not Implemented");
return;
}
if (req->req.target.format != HTTP_REQUEST_TARGET_FORMAT_AUTHORITY) {
- http_server_request_fail(req, 400, "Bad Request", FALSE);
+ http_server_request_fail(req, 400, "Bad Request");
return;
}
conn->callbacks->handle_connect_request
/* other methods */
} else {
if (conn->callbacks->handle_request == NULL) {
- http_server_request_fail(req, 505, "Not Implemented", FALSE);
+ http_server_request_fail(req, 505, "Not Implemented");
return;
} else {
conn->callbacks->handle_request(conn->context, req);
i_assert(conn->incoming_payload == NULL);
if (req->req.version_major != 1) {
- http_server_request_fail(req, 505, "HTTP Version Not Supported", FALSE);
+ http_server_request_fail(req, 505, "HTTP Version Not Supported");
return TRUE;
}
case HTTP_REQUEST_PARSE_ERROR_BROKEN_REQUEST:
conn->input_broken = TRUE;
case HTTP_REQUEST_PARSE_ERROR_BAD_REQUEST:
- http_server_request_fail(req, 400, "Bad Request", conn->input_broken);
+ http_server_request_fail(req, 400, "Bad Request");
break;
- case HTTP_REQUEST_PARSE_ERROR_METHOD_TOO_LONG:
+ case HTTP_REQUEST_PARSE_ERROR_METHOD_TOO_LONG:
conn->input_broken = TRUE;
case HTTP_REQUEST_PARSE_ERROR_NOT_IMPLEMENTED:
- http_server_request_fail(req,
- 501, "Not Implemented", conn->input_broken);
+ http_server_request_fail(req, 501, "Not Implemented");
break;
case HTTP_REQUEST_PARSE_ERROR_TARGET_TOO_LONG:
- http_server_request_fail(req, 414, "URI Too Long", TRUE);
conn->input_broken = TRUE;
+ http_server_request_fail_close(req, 414, "URI Too Long");
break;
case HTTP_REQUEST_PARSE_ERROR_EXPECTATION_FAILED:
- http_server_request_fail(req, 417, "Expectation Failed", FALSE);
+ http_server_request_fail(req, 417, "Expectation Failed");
break;
case HTTP_REQUEST_PARSE_ERROR_PAYLOAD_TOO_LARGE:
- http_server_request_fail(req, 413, "Payload Too Large", TRUE);
conn->input_broken = TRUE;
+ http_server_request_fail_close(req, 413, "Payload Too Large");
break;
return;
default:
http_server_connection_send_responses(conn);
}
-void http_server_request_fail(struct http_server_request *req,
+static void
+http_server_request_fail_full(struct http_server_request *req,
unsigned int status, const char *reason, bool close)
{
struct http_server_response *resp;
reason = t_strconcat(reason, "\r\n", NULL);
http_server_response_set_payload_data
(resp, (const unsigned char *)reason, strlen(reason));
- http_server_response_submit(resp, close);
+ if (close)
+ http_server_response_submit_close(resp);
+ else
+ http_server_response_submit(resp);
}
+void http_server_request_fail(struct http_server_request *req,
+ unsigned int status, const char *reason)
+{
+ http_server_request_fail_full(req, status, reason,
+ req->conn->input_broken);
+}
+
+void http_server_request_fail_close(struct http_server_request *req,
+ unsigned int status, const char *reason)
+{
+ http_server_request_fail_full(req, status, reason, TRUE);
+}
http_server_request_submit_response(resp->request);
}
-void http_server_response_submit(struct http_server_response *resp,
- bool close)
+void http_server_response_submit(struct http_server_response *resp)
+{
+ i_assert(!resp->submitted);
+ http_server_response_debug(resp, "Submitted");
+
+ http_server_response_do_submit(resp, FALSE);
+}
+
+void http_server_response_submit_close(struct http_server_response *resp)
{
i_assert(!resp->submitted);
http_server_response_debug(resp, "Submitted");
- http_server_response_do_submit(resp, close);
+ http_server_response_do_submit(resp, TRUE);
}
void http_server_response_submit_tunnel(struct http_server_response *resp,
const struct http_request *
http_server_request_get(struct http_server_request *req);
pool_t http_server_request_get_pool(struct http_server_request *req);
+/* Send a failure response to the request with given status/reason. */
void http_server_request_fail(struct http_server_request *req,
- unsigned int status, const char *reason, bool close);
+ unsigned int status, const char *reason);
+/* Send a failure response to the request with given status/reason
+ and close the connection. */
+void http_server_request_fail_close(struct http_server_request *req,
+ unsigned int status, const char *reason);
/* Call the specified callback when HTTP request is destroyed. */
void http_server_request_set_destroy_callback(struct http_server_request *req,
struct istream *input);
void http_server_response_set_payload_data(struct http_server_response *resp,
const unsigned char *data, size_t size);
-void http_server_response_submit(struct http_server_response *resp, bool close);
+void http_server_response_submit(struct http_server_response *resp);
+/* Submit response and close the connection. */
+void http_server_response_submit_close(struct http_server_response *resp);
void http_server_response_submit_tunnel(struct http_server_response *resp,
http_server_tunnel_callback_t callback, void *context);