refactor: restore content-length and content-type in response

master
Sean McBride 3 years ago
parent b32503b350
commit 9de83c5ac3

@ -13,12 +13,17 @@
#define HTTP_MAX_QUERY_PARAM_COUNT 16
#define HTTP_MAX_QUERY_PARAM_LENGTH 32
#define HTTP_RESPONSE_200_OK \
"HTTP/1.1 200 OK\r\n" \
"Server: SLEdge\r\n" \
"Connection: close\r\n" \
#define HTTP_RESPONSE_200_TEMPLATE \
"HTTP/1.1 200 OK\r\n" \
"Server: SLEdge\r\n" \
"Connection: close\r\n" \
"Content-Type: %s\r\n" \
"Content-Length: %lu\r\n" \
"\r\n"
/* The sum of format specifier characters in the template above */
#define HTTP_RESPONSE_200_TEMPLATE_FORMAT_SPECIFIER_LENGTH 5
#define HTTP_RESPONSE_400_BAD_REQUEST \
"HTTP/1.1 400 Bad Request\r\n" \
"Server: SLEdge\r\n" \
@ -61,10 +66,6 @@ http_header_build(int status_code)
const char *response;
int rc;
switch (status_code) {
case 200:
response = HTTP_RESPONSE_200_OK;
http_total_increment_2XX();
break;
case 400:
response = HTTP_RESPONSE_400_BAD_REQUEST;
http_total_increment_4XX();
@ -100,8 +101,6 @@ static inline size_t
http_header_len(int status_code)
{
switch (status_code) {
case 200:
return strlen(HTTP_RESPONSE_200_OK);
case 400:
return strlen(HTTP_RESPONSE_400_BAD_REQUEST);
case 404:

@ -38,6 +38,8 @@ enum http_session_state
HTTP_SESSION_SENT_RESPONSE
};
#define HTTP_SESSION_RESPONSE_HEADER_CAPACITY 256
struct http_session {
enum http_session_state state;
struct sockaddr client_address; /* client requesting connection! */
@ -45,7 +47,7 @@ struct http_session {
struct http_parser http_parser;
struct http_request http_request;
struct vec_u8 request_buffer;
const char *response_header;
char response_header[HTTP_SESSION_RESPONSE_HEADER_CAPACITY];
size_t response_header_length;
size_t response_header_written;
struct vec_u8 response_buffer;
@ -161,13 +163,25 @@ http_session_free(struct http_session *session)
* @param status_code
*/
static inline void
http_session_set_response_header(struct http_session *session, int status_code)
http_session_set_response_header(struct http_session *session, int status_code, const char *content_type,
size_t content_length)
{
assert(session != NULL);
assert(status_code >= 100 && status_code <= 599);
session->response_header = http_header_build(status_code);
session->response_header_length = http_header_len(status_code);
assert(status_code >= 200 && status_code <= 599);
if (status_code == 200) {
session->response_header_length = snprintf(session->response_header,
HTTP_SESSION_RESPONSE_HEADER_CAPACITY,
HTTP_RESPONSE_200_TEMPLATE, content_type, content_length);
} else {
size_t header_len = http_header_len(status_code);
size_t to_copy = HTTP_SESSION_RESPONSE_HEADER_CAPACITY < header_len
? HTTP_SESSION_RESPONSE_HEADER_CAPACITY
: header_len;
strncpy(session->response_header, http_header_build(status_code), to_copy - 1);
session->response_header_length = to_copy;
}
}
static inline void
@ -215,7 +229,6 @@ static inline int
http_session_send_response_body(struct http_session *session, void_star_cb on_eagain)
{
assert(session != NULL);
assert(session->response_buffer.buffer != NULL);
while (session->response_buffer_written < session->response_buffer.length) {
ssize_t sent =
@ -367,11 +380,14 @@ http_session_receive_request(struct http_session *session, void_star_cb on_eagai
(char *)&session->request_buffer.buffer[session->request_buffer.length],
session->request_buffer.capacity - session->request_buffer.length, on_eagain,
session);
if (bytes_received == -EAGAIN) goto err_eagain;
if (bytes_received == -3) goto err_eagain;
if (bytes_received == -1) goto err;
/* If we received an EOF before we were able to parse a complete HTTP message, request is malformed */
if (bytes_received == 0 && !session->http_request.message_end) goto err;
assert(bytes_received > 0);
assert(session->request_buffer.length < session->request_buffer.capacity);
session->request_buffer.length += bytes_received;
ssize_t bytes_parsed = http_session_parse(session, bytes_received);

@ -59,7 +59,7 @@ sandbox_set_as_error(struct sandbox *sandbox, sandbox_state_t last_state)
admissions_control_subtract(sandbox->admissions_estimate);
/* Return HTTP session to listener core to be written back to client */
http_session_set_response_header(sandbox->http, 500);
http_session_set_response_header(sandbox->http, 500, NULL, 0);
sandbox->http->state = HTTP_SESSION_EXECUTION_COMPLETE;
http_session_send_response(sandbox->http, (void_star_cb)listener_thread_register_http_session);
sandbox->http = NULL;

@ -51,7 +51,8 @@ sandbox_set_as_returned(struct sandbox *sandbox, sandbox_state_t last_state)
sandbox_state_totals_increment(SANDBOX_RETURNED);
sandbox_state_totals_decrement(last_state);
http_session_set_response_header(sandbox->http, 200);
http_session_set_response_header(sandbox->http, 200, sandbox->route->response_content_type,
sandbox->http->response_buffer.length);
sandbox->http->state = HTTP_SESSION_EXECUTION_COMPLETE;
http_session_send_response(sandbox->http, (void_star_cb)listener_thread_register_http_session);
sandbox->http = NULL;

@ -164,7 +164,7 @@ on_client_request_arrival(int client_socket, const struct sockaddr *client_addre
/* Failed to allocate memory */
debuglog("Failed to allocate http session\n");
session->state = HTTP_SESSION_EXECUTION_COMPLETE;
http_session_set_response_header(session, 500);
http_session_set_response_header(session, 500, NULL, 0);
on_client_response_header_sending(session);
return;
}
@ -185,13 +185,13 @@ on_client_request_receiving(struct http_session *session)
/* Failed to grow request buffer */
debuglog("Failed to grow http request buffer\n");
session->state = HTTP_SESSION_EXECUTION_COMPLETE;
http_session_set_response_header(session, 500);
http_session_set_response_header(session, 500, NULL, 0);
on_client_response_header_sending(session);
return;
} else if (rc == -1) {
debuglog("Failed to receive or parse request\n");
session->state = HTTP_SESSION_EXECUTION_COMPLETE;
http_session_set_response_header(session, 400);
http_session_set_response_header(session, 400, NULL, 0);
on_client_response_header_sending(session);
return;
}
@ -208,7 +208,7 @@ on_client_request_received(struct http_session *session)
if (route == NULL) {
debuglog("Did not match any routes\n");
session->state = HTTP_SESSION_EXECUTION_COMPLETE;
http_session_set_response_header(session, 404);
http_session_set_response_header(session, 404, NULL, 0);
on_client_response_header_sending(session);
return;
}
@ -221,7 +221,7 @@ on_client_request_received(struct http_session *session)
uint64_t work_admitted = admissions_control_decide(route->admissions_info.estimate);
if (work_admitted == 0) {
session->state = HTTP_SESSION_EXECUTION_COMPLETE;
http_session_set_response_header(session, 429);
http_session_set_response_header(session, 429, NULL, 0);
on_client_response_header_sending(session);
return;
}
@ -232,7 +232,7 @@ on_client_request_received(struct http_session *session)
if (unlikely(sandbox == NULL)) {
debuglog("Failed to allocate sandbox\n");
session->state = HTTP_SESSION_EXECUTION_COMPLETE;
http_session_set_response_header(session, 500);
http_session_set_response_header(session, 500, NULL, 0);
on_client_response_header_sending(session);
return;
}
@ -242,7 +242,7 @@ on_client_request_received(struct http_session *session)
debuglog("Failed to add sandbox to global queue\n");
sandbox_free(sandbox);
session->state = HTTP_SESSION_EXECUTION_COMPLETE;
http_session_set_response_header(session, 429);
http_session_set_response_header(session, 429, NULL, 0);
on_client_response_header_sending(session);
}
}

Loading…
Cancel
Save