From 4ba4cf4969f923c2f80a1a7fc3989e62ce6ba79e Mon Sep 17 00:00:00 2001 From: Sean McBride Date: Tue, 25 Jan 2022 17:40:52 +0000 Subject: [PATCH] feat: Add new HTTP codes --- runtime/include/http.h | 66 +++++++++++++++++++++++------------ runtime/src/listener_thread.c | 7 ++-- 2 files changed, 48 insertions(+), 25 deletions(-) diff --git a/runtime/include/http.h b/runtime/include/http.h index a0c0ac8..fc05dec 100644 --- a/runtime/include/http.h +++ b/runtime/include/http.h @@ -9,37 +9,47 @@ #define HTTP_MAX_HEADER_LENGTH 32 #define HTTP_MAX_HEADER_VALUE_LENGTH 64 +#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" \ "Connection: close\r\n" \ "\r\n" - #define HTTP_RESPONSE_413_PAYLOAD_TOO_LARGE \ "HTTP/1.1 413 Payload Too Large\r\n" \ "Server: SLEdge\r\n" \ "Connection: close\r\n" \ "\r\n" +#define HTTP_RESPONSE_429_TOO_MANY_REQUESTS \ + "HTTP/1.1 429 Too Many Requests\r\n" \ + "Server: SLEdge\r\n" \ + "Connection: close\r\n" \ + "\r\n" + +#define HTTP_RESPONSE_500_INTERNAL_SERVER_ERROR \ + "HTTP/1.1 500 Internal Server Error\r\n" \ + "Server: SLEdge\r\n" \ + "Connection: close\r\n" \ + "\r\n" + #define HTTP_RESPONSE_503_SERVICE_UNAVAILABLE \ "HTTP/1.1 503 Service Unavailable\r\n" \ "Server: SLEdge\r\n" \ "Connection: close\r\n" \ "\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 - - static inline int http_header_200_write(int fd, const char *content_type, size_t content_length) { @@ -52,18 +62,26 @@ http_header_build(int status_code) const char *response; int rc; switch (status_code) { - case 503: - response = HTTP_RESPONSE_503_SERVICE_UNAVAILABLE; - http_total_increment_5XX(); + case 400: + response = HTTP_RESPONSE_400_BAD_REQUEST; + http_total_increment_4XX(); break; case 413: response = HTTP_RESPONSE_413_PAYLOAD_TOO_LARGE; http_total_increment_4XX(); break; - case 400: - response = HTTP_RESPONSE_400_BAD_REQUEST; + case 429: + response = HTTP_RESPONSE_429_TOO_MANY_REQUESTS; http_total_increment_4XX(); break; + case 500: + response = HTTP_RESPONSE_500_INTERNAL_SERVER_ERROR; + http_total_increment_5XX(); + break; + case 503: + response = HTTP_RESPONSE_503_SERVICE_UNAVAILABLE; + http_total_increment_5XX(); + break; default: panic("%d is not a valid status code\n", status_code); } @@ -75,12 +93,16 @@ static inline int http_header_len(int status_code) { switch (status_code) { - case 503: - return strlen(HTTP_RESPONSE_503_SERVICE_UNAVAILABLE); - case 413: - return strlen(HTTP_RESPONSE_413_PAYLOAD_TOO_LARGE); case 400: return strlen(HTTP_RESPONSE_400_BAD_REQUEST); + case 413: + return strlen(HTTP_RESPONSE_413_PAYLOAD_TOO_LARGE); + case 429: + return strlen(HTTP_RESPONSE_429_TOO_MANY_REQUESTS); + case 500: + return strlen(HTTP_RESPONSE_500_INTERNAL_SERVER_ERROR); + case 503: + return strlen(HTTP_RESPONSE_503_SERVICE_UNAVAILABLE); default: panic("%d is not a valid status code\n", status_code); } diff --git a/runtime/src/listener_thread.c b/runtime/src/listener_thread.c index e4b2da6..9ab1826 100644 --- a/runtime/src/listener_thread.c +++ b/runtime/src/listener_thread.c @@ -166,12 +166,13 @@ listener_thread_main(void *dummy) /* * Perform admissions control. - * If 0, workload was rejected, so close with 503 and continue + * If 0, workload was rejected, so close with 429 "Too Many Requests" and continue + * TODO: Consider providing a Retry-After header */ uint64_t work_admitted = admissions_control_decide(module->admissions_info.estimate); if (work_admitted == 0) { - client_socket_send_oneshot(client_socket, http_header_build(503), - http_header_len(503)); + client_socket_send_oneshot(client_socket, http_header_build(429), + http_header_len(429)); if (unlikely(close(client_socket) < 0)) debuglog("Error closing client socket - %s", strerror(errno));