diff --git a/src/response.c b/src/response.c index 5571c2d..c9e7cb7 100644 --- a/src/response.c +++ b/src/response.c @@ -1,5 +1,6 @@ #include "base.h" +#include "utils.h" void response_init(response *resp) { resp->headers = http_headers_new(); @@ -30,7 +31,7 @@ void response_send_headers(server *srv, connection *con) { if (0 == con->out->length && con->content_handler == NULL && con->response.http_status >= 400 && con->response.http_status < 600) { - + chunkqueue_append_mem(con->out, CONST_STR_LEN("Custom error\r\n")); } @@ -72,7 +73,7 @@ void response_send_headers(server *srv, connection *con) { if (con->keep_alive) http_header_overwrite(con->response.headers, CONST_STR_LEN("Connection"), CONST_STR_LEN("keep-alive")); } - g_string_append_printf(head, "%i XXX\r\n", con->response.http_status); /* TODO: use status name */ + g_string_append_printf(head, "%i %s\r\n", con->response.http_status, http_status_string(con->response.http_status)); /* Append headers */ { diff --git a/src/response.h b/src/response.h index ec2d3f7..cc450d1 100644 --- a/src/response.h +++ b/src/response.h @@ -8,7 +8,7 @@ typedef struct response response; struct response { http_headers *headers; - int http_status; + gint http_status; transfer_encoding_t transfer_encoding; }; diff --git a/src/utils.c b/src/utils.c index 3a11ff4..d68b1c0 100644 --- a/src/utils.c +++ b/src/utils.c @@ -168,3 +168,71 @@ void path_simplify(GString *path) { g_string_set_size(path, out - start); } + + +gchar *http_status_string(guint status_code) { + /* RFC 2616 (as well as RFC 2518, RFC 2817, RFC 2295, RFC 2774, RFC 4918) */ + switch (status_code) { + /* 1XX information */ + case 100: return "Continue"; + case 101: return "Switching Protocols"; + case 102: return "Processing"; + /* 2XX successful operation */ + case 200: return "OK"; + case 201: return "Created"; + case 202: return "Accepted"; + case 203: return "Non-Authoritative Information"; + case 204: return "No Content"; + case 205: return "Reset Content"; + case 206: return "Partial Content"; + case 207: return "Multi-Status"; + /* 3XX redirect */ + case 300: return "Multiple Choice"; + case 301: return "Moved Permanently"; + case 302: return "Found"; + case 303: return "See Other"; + case 304: return "Not Modified"; + case 305: return "Use Proxy"; + case 306: return "(reserved)"; + case 307: return "Temporary Redirect"; + /* 4XX client error */ + case 400: return "Bad Request"; + case 401: return "Unauthorized"; + case 402: return "Payment Required"; + case 403: return "Forbidden"; + case 404: return "Not Found"; + case 405: return "Method Not Allowed"; + case 406: return "Not Acceptable"; + case 407: return "Proxy Authentication Required"; + case 408: return "Request Time-out"; + case 409: return "Conflict"; + case 410: return "Gone"; + case 411: return "Length Required"; + case 412: return "Precondition Failed"; + case 413: return "Request Entity Too Large"; + case 414: return "Request-URI Too Long"; + case 415: return "Unsupported Media Type"; + case 416: return "Request range not satisfiable"; + case 417: return "Expectation Failed"; + case 421: return "There are too many connections from your internet address"; + case 422: return "Unprocessable Entity"; + case 423: return "Locked"; + case 424: return "Failed Dependency"; + case 425: return "Unordered Collection"; + case 426: return "Upgrade Required"; + /* 5XX server error */ + case 500: return "Internal Server Error"; + case 501: return "Not Implemented"; + case 502: return "Bad Gateway"; + case 503: return "Service Unavailable"; + case 504: return "Gateway Time-out"; + case 505: return "HTTP Version not supported"; + case 506: return "Variant Also Negotiates"; + case 507: return "Insufficient Storage"; + case 509: return "Bandwidth Limit Exceeded"; + case 510: return "Not Extended"; + + /* unknown */ + default: return "unknown status"; + } +} diff --git a/src/utils.h b/src/utils.h index 2f6ca61..d86cb2c 100644 --- a/src/utils.h +++ b/src/utils.h @@ -17,4 +17,6 @@ LI_API void url_decode(GString *path); LI_API void path_simplify(GString *path); +LI_API gchar *http_status_string(guint status_code); + #endif