From 26fbda787d0d5c8ba9259f79f4d2f937bd6c8ead Mon Sep 17 00:00:00 2001 From: Louis Brauer Date: Mon, 27 May 2024 16:25:20 +0200 Subject: [PATCH] Translate status codes to canonical status texts Use those in HTTP responses instead of "OK"/"ERROR". Apps like Tokodon show only the status text in unexpected responses. --- http_codes.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ httpd.c | 2 +- snac.c | 12 ++++++++++++ snac.h | 51 +++++---------------------------------------------- xs_httpd.h | 6 +++--- 5 files changed, 66 insertions(+), 50 deletions(-) create mode 100644 http_codes.h diff --git a/http_codes.h b/http_codes.h new file mode 100644 index 0000000..795f92a --- /dev/null +++ b/http_codes.h @@ -0,0 +1,45 @@ +HTTP_STATUS(100, CONTINUE, Continue) +HTTP_STATUS(101, SWITCHING_PROTOCOLS, Switching Protocols) +HTTP_STATUS(102, PROCESSING, Processing) +HTTP_STATUS(103, EARLY_HINTS, Early Hints) +HTTP_STATUS(200, OK, OK) +HTTP_STATUS(201, CREATED, Created) +HTTP_STATUS(202, ACCEPTED, Accepted) +HTTP_STATUS(203, NON_AUTHORITATIVE_INFORMATION, Non Authoritative Information) +HTTP_STATUS(204, NO_CONTENT, No Content) +HTTP_STATUS(205, RESET_CONTENT, Reset Content) +HTTP_STATUS(206, PARTIAL_CONTENT, Partial Content) +HTTP_STATUS(207, MULTI_STATUS, Multi Status) +HTTP_STATUS(208, ALREADY_REPORTED, Already Reported) +HTTP_STATUS(218, THIS_IS_FINE, This Is Fine) +HTTP_STATUS(226, IM_USED, IM Used) +HTTP_STATUS(300, MULTIPLE_CHOICES, Multiple Choices) +HTTP_STATUS(301, MOVED_PERMANENTLY, Moved Permanently) +HTTP_STATUS(302, FOUND, Found) +HTTP_STATUS(303, SEE_OTHER, See Other) +HTTP_STATUS(304, NOT_MODIFIED, Not Modified) +HTTP_STATUS(305, USE_PROXY, Use Proxy) +HTTP_STATUS(306, SWITCH_PROXY, Switch Proxy) +HTTP_STATUS(307, TEMPORARY_REDIRECT, Temporary Redirect) +HTTP_STATUS(308, PERMANENT_REDIRECT, Permanent Redirect) +HTTP_STATUS(400, BAD_REQUEST, Bad Request) +HTTP_STATUS(401, UNAUTHORIZED, Unauthorized) +HTTP_STATUS(402, PAYMENT_REQUIRED, Payment Required) +HTTP_STATUS(403, FORBIDDEN, Forbidden) +HTTP_STATUS(404, NOT_FOUND, Not Found) +HTTP_STATUS(405, METHOD_NOT_ALLOWED, Method Not Allowed) +HTTP_STATUS(406, NOT_ACCEPTABLE, Not Acceptable) +HTTP_STATUS(407, PROXY_AUTHENTICATION_REQUIRED, Proxy Authentication Required) +HTTP_STATUS(408, REQUEST_TIMEOUT, Request Timeout) +HTTP_STATUS(409, CONFLICT, Conflict) +HTTP_STATUS(410, GONE, Gone) +HTTP_STATUS(421, MISDIRECTED_REQUEST, Misdirected Request) +HTTP_STATUS(422, UNPROCESSABLE_CONTENT, Unprocessable Content) +HTTP_STATUS(499, CLIENT_CLOSED_REQUEST, Client Closed Request) +HTTP_STATUS(500, INTERNAL_SERVER_ERROR, Internal Server Error) +HTTP_STATUS(501, NOT_IMPLEMENTED, Not Implemented) +HTTP_STATUS(502, BAD_GATEWAY, Bad Gateway) +HTTP_STATUS(503, SERVICE_UNAVAILABLE, Service Unavailable) +HTTP_STATUS(504, GATEWAY_TIMEOUT, Gateway Timeout) +HTTP_STATUS(505, HTTP_VERSION_NOT_SUPPORTED, HTTP Version Not Supported) +HTTP_STATUS(507, INSUFFICIENT_STORAGE, Insufficient Storage) \ No newline at end of file diff --git a/httpd.c b/httpd.c index 1c60a56..d566b1e 100644 --- a/httpd.c +++ b/httpd.c @@ -442,7 +442,7 @@ void httpd_connection(FILE *f) if (p_state->use_fcgi) xs_fcgi_response(f, status, headers, body, b_size, fcgi_id); else - xs_httpd_response(f, status, headers, body, b_size); + xs_httpd_response(f, status, http_status_text(status), headers, body, b_size); fclose(f); diff --git a/snac.c b/snac.c index 5ba98e1..0df8691 100644 --- a/snac.c +++ b/snac.c @@ -170,3 +170,15 @@ int check_password(const char *uid, const char *passwd, const char *hash) return ret; } + + +const char *http_status_text(int status) +/* translate status codes to canonical status texts */ +{ + switch (status) { +#define HTTP_STATUS(code, name, text) case HTTP_STATUS_ ## name: return #text; +#include "http_codes.h" +#undef HTTP_STATUS + default: return "Unknown"; + } +} diff --git a/snac.h b/snac.h index a821b18..2561b6c 100644 --- a/snac.h +++ b/snac.h @@ -367,52 +367,11 @@ void mastoapi_purge(void); void verify_links(snac *user); -/* HTTP responses RFC 9110 plus some extensions */ typedef enum { - HTTP_STATUS_CONTINUE = 100, - HTTP_STATUS_SWITCHTING_PROTOCOLS = 101, - HTTP_STATUS_PROCESSING = 102, - HTTP_STATUS_EARLY_HINTS = 103, - HTTP_STATUS_OK = 200, - HTTP_STATUS_CREATED = 201, - HTTP_STATUS_ACCEPTED = 202, - HTTP_STATUS_NON_AUTHORITATIVE_INFORMATION = 203, - HTTP_STATUS_NO_CONTENT = 204, - HTTP_STATUS_RESET_CONTENT = 205, - HTTP_STATUS_PARTIAL_CONTENT = 206, - HTTP_STATUS_MULTI_STATUS = 207, - HTTP_STATUS_ALREADY_REPORTED = 208, - HTTP_STATUS_THIS_IS_FINE = 218, - HTTP_STATUS_IM_USED = 226, - HTTP_STATUS_MULTIPLE_CHOICES = 300, - HTTP_STATUS_MOVED_PERMANENTLY = 301, - HTTP_STATUS_FOUND = 302, - HTTP_STATUS_SEE_OTHER = 303, - HTTP_STATUS_NOT_MODIFIED = 304, - HTTP_STATUS_USE_PROXY = 305, - HTTP_STATUS_SWITCH_PROXY = 306, - HTTP_STATUS_TEMPORARY_REDIRECT = 307, - HTTP_STATUS_PERMANENT_REDIRECT = 308, - HTTP_STATUS_BAD_REQUEST = 400, - HTTP_STATUS_UNAUTHORIZED = 401, - HTTP_STATUS_PAYMENT_REQUIRED = 402, - HTTP_STATUS_FORBIDDEN = 403, - HTTP_STATUS_NOT_FOUND = 404, - HTTP_STATUS_METHOD_NOT_ALLOWED = 405, - HTTP_STATUS_NOT_ACCEPTABLE = 406, - HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED = 407, - HTTP_STATUS_REQUEST_TIMEOUT = 408, - HTTP_STATUS_CONFLICT = 409, - HTTP_STATUS_GONE = 410, - HTTP_STATUS_MISDIRECTED_REQUEST = 421, - HTTP_STATUS_UNPROCESSABLE_CONTENT = 422, - HTTP_STATUS_CLIENT_CLOSED_REQUEST = 499, - HTTP_STATUS_INTERNAL_SERVER_ERROR = 500, - HTTP_STATUS_NOT_IMPLEMENTED = 501, - HTTP_STATUS_BAD_GATEWAY = 502, - HTTP_STATUS_SERVICE_UNAVAILABLE = 503, - HTTP_STATUS_GATEWAY_TIMEOUT = 504, - HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED = 505, - HTTP_STATUS_INSUFFICIENT_STORAGE = 507 +#define HTTP_STATUS(code, name, text) HTTP_STATUS_ ## name = code, +#include "http_codes.h" +#undef HTTP_STATUS } http_status; + +const char *http_status_text(int status); diff --git a/xs_httpd.h b/xs_httpd.h index 4195b81..d080b39 100644 --- a/xs_httpd.h +++ b/xs_httpd.h @@ -5,7 +5,7 @@ #define _XS_HTTPD_H xs_dict *xs_httpd_request(FILE *f, xs_str **payload, int *p_size); -void xs_httpd_response(FILE *f, int status, xs_dict *headers, xs_str *body, int b_size); +void xs_httpd_response(FILE *f, int status, const char *status_text, xs_dict *headers, xs_str *body, int b_size); #ifdef XS_IMPLEMENTATION @@ -95,14 +95,14 @@ xs_dict *xs_httpd_request(FILE *f, xs_str **payload, int *p_size) } -void xs_httpd_response(FILE *f, int status, xs_dict *headers, xs_str *body, int b_size) +void xs_httpd_response(FILE *f, int status, const char *status_text, xs_dict *headers, xs_str *body, int b_size) /* sends an httpd response */ { xs *proto; const xs_str *k; const xs_val *v; - proto = xs_fmt("HTTP/1.1 %d %s", status, status / 100 == 2 ? "OK" : "ERROR"); + proto = xs_fmt("HTTP/1.1 %d %s", status, status_text); fprintf(f, "%s\r\n", proto); int c = 0;