diff options
| author | 2024-05-27 16:25:20 +0200 | |
|---|---|---|
| committer | 2024-05-27 19:01:04 +0200 | |
| commit | 26fbda787d0d5c8ba9259f79f4d2f937bd6c8ead (patch) | |
| tree | 8615eda88a882eb4959abf707a693374f22d9752 | |
| parent | Use ISO C99 __func__ instead of GNU __FUNCTION__ (diff) | |
| download | penes-snac2-26fbda787d0d5c8ba9259f79f4d2f937bd6c8ead.tar.gz penes-snac2-26fbda787d0d5c8ba9259f79f4d2f937bd6c8ead.tar.xz penes-snac2-26fbda787d0d5c8ba9259f79f4d2f937bd6c8ead.zip | |
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.
| -rw-r--r-- | http_codes.h | 45 | ||||
| -rw-r--r-- | httpd.c | 2 | ||||
| -rw-r--r-- | snac.c | 12 | ||||
| -rw-r--r-- | snac.h | 51 | ||||
| -rw-r--r-- | xs_httpd.h | 6 |
5 files changed, 66 insertions, 50 deletions
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 @@ | |||
| 1 | HTTP_STATUS(100, CONTINUE, Continue) | ||
| 2 | HTTP_STATUS(101, SWITCHING_PROTOCOLS, Switching Protocols) | ||
| 3 | HTTP_STATUS(102, PROCESSING, Processing) | ||
| 4 | HTTP_STATUS(103, EARLY_HINTS, Early Hints) | ||
| 5 | HTTP_STATUS(200, OK, OK) | ||
| 6 | HTTP_STATUS(201, CREATED, Created) | ||
| 7 | HTTP_STATUS(202, ACCEPTED, Accepted) | ||
| 8 | HTTP_STATUS(203, NON_AUTHORITATIVE_INFORMATION, Non Authoritative Information) | ||
| 9 | HTTP_STATUS(204, NO_CONTENT, No Content) | ||
| 10 | HTTP_STATUS(205, RESET_CONTENT, Reset Content) | ||
| 11 | HTTP_STATUS(206, PARTIAL_CONTENT, Partial Content) | ||
| 12 | HTTP_STATUS(207, MULTI_STATUS, Multi Status) | ||
| 13 | HTTP_STATUS(208, ALREADY_REPORTED, Already Reported) | ||
| 14 | HTTP_STATUS(218, THIS_IS_FINE, This Is Fine) | ||
| 15 | HTTP_STATUS(226, IM_USED, IM Used) | ||
| 16 | HTTP_STATUS(300, MULTIPLE_CHOICES, Multiple Choices) | ||
| 17 | HTTP_STATUS(301, MOVED_PERMANENTLY, Moved Permanently) | ||
| 18 | HTTP_STATUS(302, FOUND, Found) | ||
| 19 | HTTP_STATUS(303, SEE_OTHER, See Other) | ||
| 20 | HTTP_STATUS(304, NOT_MODIFIED, Not Modified) | ||
| 21 | HTTP_STATUS(305, USE_PROXY, Use Proxy) | ||
| 22 | HTTP_STATUS(306, SWITCH_PROXY, Switch Proxy) | ||
| 23 | HTTP_STATUS(307, TEMPORARY_REDIRECT, Temporary Redirect) | ||
| 24 | HTTP_STATUS(308, PERMANENT_REDIRECT, Permanent Redirect) | ||
| 25 | HTTP_STATUS(400, BAD_REQUEST, Bad Request) | ||
| 26 | HTTP_STATUS(401, UNAUTHORIZED, Unauthorized) | ||
| 27 | HTTP_STATUS(402, PAYMENT_REQUIRED, Payment Required) | ||
| 28 | HTTP_STATUS(403, FORBIDDEN, Forbidden) | ||
| 29 | HTTP_STATUS(404, NOT_FOUND, Not Found) | ||
| 30 | HTTP_STATUS(405, METHOD_NOT_ALLOWED, Method Not Allowed) | ||
| 31 | HTTP_STATUS(406, NOT_ACCEPTABLE, Not Acceptable) | ||
| 32 | HTTP_STATUS(407, PROXY_AUTHENTICATION_REQUIRED, Proxy Authentication Required) | ||
| 33 | HTTP_STATUS(408, REQUEST_TIMEOUT, Request Timeout) | ||
| 34 | HTTP_STATUS(409, CONFLICT, Conflict) | ||
| 35 | HTTP_STATUS(410, GONE, Gone) | ||
| 36 | HTTP_STATUS(421, MISDIRECTED_REQUEST, Misdirected Request) | ||
| 37 | HTTP_STATUS(422, UNPROCESSABLE_CONTENT, Unprocessable Content) | ||
| 38 | HTTP_STATUS(499, CLIENT_CLOSED_REQUEST, Client Closed Request) | ||
| 39 | HTTP_STATUS(500, INTERNAL_SERVER_ERROR, Internal Server Error) | ||
| 40 | HTTP_STATUS(501, NOT_IMPLEMENTED, Not Implemented) | ||
| 41 | HTTP_STATUS(502, BAD_GATEWAY, Bad Gateway) | ||
| 42 | HTTP_STATUS(503, SERVICE_UNAVAILABLE, Service Unavailable) | ||
| 43 | HTTP_STATUS(504, GATEWAY_TIMEOUT, Gateway Timeout) | ||
| 44 | HTTP_STATUS(505, HTTP_VERSION_NOT_SUPPORTED, HTTP Version Not Supported) | ||
| 45 | HTTP_STATUS(507, INSUFFICIENT_STORAGE, Insufficient Storage) \ No newline at end of file | ||
| @@ -442,7 +442,7 @@ void httpd_connection(FILE *f) | |||
| 442 | if (p_state->use_fcgi) | 442 | if (p_state->use_fcgi) |
| 443 | xs_fcgi_response(f, status, headers, body, b_size, fcgi_id); | 443 | xs_fcgi_response(f, status, headers, body, b_size, fcgi_id); |
| 444 | else | 444 | else |
| 445 | xs_httpd_response(f, status, headers, body, b_size); | 445 | xs_httpd_response(f, status, http_status_text(status), headers, body, b_size); |
| 446 | 446 | ||
| 447 | fclose(f); | 447 | fclose(f); |
| 448 | 448 | ||
| @@ -170,3 +170,15 @@ int check_password(const char *uid, const char *passwd, const char *hash) | |||
| 170 | 170 | ||
| 171 | return ret; | 171 | return ret; |
| 172 | } | 172 | } |
| 173 | |||
| 174 | |||
| 175 | const char *http_status_text(int status) | ||
| 176 | /* translate status codes to canonical status texts */ | ||
| 177 | { | ||
| 178 | switch (status) { | ||
| 179 | #define HTTP_STATUS(code, name, text) case HTTP_STATUS_ ## name: return #text; | ||
| 180 | #include "http_codes.h" | ||
| 181 | #undef HTTP_STATUS | ||
| 182 | default: return "Unknown"; | ||
| 183 | } | ||
| 184 | } | ||
| @@ -367,52 +367,11 @@ void mastoapi_purge(void); | |||
| 367 | 367 | ||
| 368 | void verify_links(snac *user); | 368 | void verify_links(snac *user); |
| 369 | 369 | ||
| 370 | /* HTTP responses RFC 9110 plus some extensions */ | ||
| 371 | 370 | ||
| 372 | typedef enum { | 371 | typedef enum { |
| 373 | HTTP_STATUS_CONTINUE = 100, | 372 | #define HTTP_STATUS(code, name, text) HTTP_STATUS_ ## name = code, |
| 374 | HTTP_STATUS_SWITCHTING_PROTOCOLS = 101, | 373 | #include "http_codes.h" |
| 375 | HTTP_STATUS_PROCESSING = 102, | 374 | #undef HTTP_STATUS |
| 376 | HTTP_STATUS_EARLY_HINTS = 103, | ||
| 377 | HTTP_STATUS_OK = 200, | ||
| 378 | HTTP_STATUS_CREATED = 201, | ||
| 379 | HTTP_STATUS_ACCEPTED = 202, | ||
| 380 | HTTP_STATUS_NON_AUTHORITATIVE_INFORMATION = 203, | ||
| 381 | HTTP_STATUS_NO_CONTENT = 204, | ||
| 382 | HTTP_STATUS_RESET_CONTENT = 205, | ||
| 383 | HTTP_STATUS_PARTIAL_CONTENT = 206, | ||
| 384 | HTTP_STATUS_MULTI_STATUS = 207, | ||
| 385 | HTTP_STATUS_ALREADY_REPORTED = 208, | ||
| 386 | HTTP_STATUS_THIS_IS_FINE = 218, | ||
| 387 | HTTP_STATUS_IM_USED = 226, | ||
| 388 | HTTP_STATUS_MULTIPLE_CHOICES = 300, | ||
| 389 | HTTP_STATUS_MOVED_PERMANENTLY = 301, | ||
| 390 | HTTP_STATUS_FOUND = 302, | ||
| 391 | HTTP_STATUS_SEE_OTHER = 303, | ||
| 392 | HTTP_STATUS_NOT_MODIFIED = 304, | ||
| 393 | HTTP_STATUS_USE_PROXY = 305, | ||
| 394 | HTTP_STATUS_SWITCH_PROXY = 306, | ||
| 395 | HTTP_STATUS_TEMPORARY_REDIRECT = 307, | ||
| 396 | HTTP_STATUS_PERMANENT_REDIRECT = 308, | ||
| 397 | HTTP_STATUS_BAD_REQUEST = 400, | ||
| 398 | HTTP_STATUS_UNAUTHORIZED = 401, | ||
| 399 | HTTP_STATUS_PAYMENT_REQUIRED = 402, | ||
| 400 | HTTP_STATUS_FORBIDDEN = 403, | ||
| 401 | HTTP_STATUS_NOT_FOUND = 404, | ||
| 402 | HTTP_STATUS_METHOD_NOT_ALLOWED = 405, | ||
| 403 | HTTP_STATUS_NOT_ACCEPTABLE = 406, | ||
| 404 | HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED = 407, | ||
| 405 | HTTP_STATUS_REQUEST_TIMEOUT = 408, | ||
| 406 | HTTP_STATUS_CONFLICT = 409, | ||
| 407 | HTTP_STATUS_GONE = 410, | ||
| 408 | HTTP_STATUS_MISDIRECTED_REQUEST = 421, | ||
| 409 | HTTP_STATUS_UNPROCESSABLE_CONTENT = 422, | ||
| 410 | HTTP_STATUS_CLIENT_CLOSED_REQUEST = 499, | ||
| 411 | HTTP_STATUS_INTERNAL_SERVER_ERROR = 500, | ||
| 412 | HTTP_STATUS_NOT_IMPLEMENTED = 501, | ||
| 413 | HTTP_STATUS_BAD_GATEWAY = 502, | ||
| 414 | HTTP_STATUS_SERVICE_UNAVAILABLE = 503, | ||
| 415 | HTTP_STATUS_GATEWAY_TIMEOUT = 504, | ||
| 416 | HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED = 505, | ||
| 417 | HTTP_STATUS_INSUFFICIENT_STORAGE = 507 | ||
| 418 | } http_status; | 375 | } http_status; |
| 376 | |||
| 377 | const char *http_status_text(int status); | ||
| @@ -5,7 +5,7 @@ | |||
| 5 | #define _XS_HTTPD_H | 5 | #define _XS_HTTPD_H |
| 6 | 6 | ||
| 7 | xs_dict *xs_httpd_request(FILE *f, xs_str **payload, int *p_size); | 7 | xs_dict *xs_httpd_request(FILE *f, xs_str **payload, int *p_size); |
| 8 | void xs_httpd_response(FILE *f, int status, xs_dict *headers, xs_str *body, int b_size); | 8 | void xs_httpd_response(FILE *f, int status, const char *status_text, xs_dict *headers, xs_str *body, int b_size); |
| 9 | 9 | ||
| 10 | 10 | ||
| 11 | #ifdef XS_IMPLEMENTATION | 11 | #ifdef XS_IMPLEMENTATION |
| @@ -95,14 +95,14 @@ xs_dict *xs_httpd_request(FILE *f, xs_str **payload, int *p_size) | |||
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | 97 | ||
| 98 | void xs_httpd_response(FILE *f, int status, xs_dict *headers, xs_str *body, int b_size) | 98 | void xs_httpd_response(FILE *f, int status, const char *status_text, xs_dict *headers, xs_str *body, int b_size) |
| 99 | /* sends an httpd response */ | 99 | /* sends an httpd response */ |
| 100 | { | 100 | { |
| 101 | xs *proto; | 101 | xs *proto; |
| 102 | const xs_str *k; | 102 | const xs_str *k; |
| 103 | const xs_val *v; | 103 | const xs_val *v; |
| 104 | 104 | ||
| 105 | proto = xs_fmt("HTTP/1.1 %d %s", status, status / 100 == 2 ? "OK" : "ERROR"); | 105 | proto = xs_fmt("HTTP/1.1 %d %s", status, status_text); |
| 106 | fprintf(f, "%s\r\n", proto); | 106 | fprintf(f, "%s\r\n", proto); |
| 107 | 107 | ||
| 108 | int c = 0; | 108 | int c = 0; |