lighttpd 1.4.x
https://www.lighttpd.net/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
176 lines
6.7 KiB
176 lines
6.7 KiB
#include "first.h" |
|
|
|
#include "http_kv.h" |
|
#include "buffer.h" |
|
|
|
#include <string.h> |
|
|
|
typedef struct { |
|
int key; |
|
const char *value; |
|
size_t vlen; |
|
} keyvalue; |
|
|
|
static const keyvalue http_versions[] = { |
|
{ HTTP_VERSION_1_1, CONST_STR_LEN("HTTP/1.1") }, |
|
{ HTTP_VERSION_1_0, CONST_STR_LEN("HTTP/1.0") }, |
|
{ HTTP_VERSION_UNSET, NULL, 0 } |
|
}; |
|
|
|
static const keyvalue http_methods[] = { |
|
{ HTTP_METHOD_GET, CONST_STR_LEN("GET") }, |
|
{ HTTP_METHOD_HEAD, CONST_STR_LEN("HEAD") }, |
|
{ HTTP_METHOD_POST, CONST_STR_LEN("POST") }, |
|
{ HTTP_METHOD_PUT, CONST_STR_LEN("PUT") }, |
|
{ HTTP_METHOD_DELETE, CONST_STR_LEN("DELETE") }, |
|
{ HTTP_METHOD_CONNECT, CONST_STR_LEN("CONNECT") }, |
|
{ HTTP_METHOD_OPTIONS, CONST_STR_LEN("OPTIONS") }, |
|
{ HTTP_METHOD_TRACE, CONST_STR_LEN("TRACE") }, |
|
{ HTTP_METHOD_ACL, CONST_STR_LEN("ACL") }, |
|
{ HTTP_METHOD_BASELINE_CONTROL, CONST_STR_LEN("BASELINE-CONTROL") }, |
|
{ HTTP_METHOD_BIND, CONST_STR_LEN("BIND") }, |
|
{ HTTP_METHOD_CHECKIN, CONST_STR_LEN("CHECKIN") }, |
|
{ HTTP_METHOD_CHECKOUT, CONST_STR_LEN("CHECKOUT") }, |
|
{ HTTP_METHOD_COPY, CONST_STR_LEN("COPY") }, |
|
{ HTTP_METHOD_LABEL, CONST_STR_LEN("LABEL") }, |
|
{ HTTP_METHOD_LINK, CONST_STR_LEN("LINK") }, |
|
{ HTTP_METHOD_LOCK, CONST_STR_LEN("LOCK") }, |
|
{ HTTP_METHOD_MERGE, CONST_STR_LEN("MERGE") }, |
|
{ HTTP_METHOD_MKACTIVITY, CONST_STR_LEN("MKACTIVITY") }, |
|
{ HTTP_METHOD_MKCALENDAR, CONST_STR_LEN("MKCALENDAR") }, |
|
{ HTTP_METHOD_MKCOL, CONST_STR_LEN("MKCOL") }, |
|
{ HTTP_METHOD_MKREDIRECTREF, CONST_STR_LEN("MKREDIRECTREF") }, |
|
{ HTTP_METHOD_MKWORKSPACE, CONST_STR_LEN("MKWORKSPACE") }, |
|
{ HTTP_METHOD_MOVE, CONST_STR_LEN("MOVE") }, |
|
{ HTTP_METHOD_ORDERPATCH, CONST_STR_LEN("ORDERPATCH") }, |
|
{ HTTP_METHOD_PATCH, CONST_STR_LEN("PATCH") }, |
|
{ HTTP_METHOD_PROPFIND, CONST_STR_LEN("PROPFIND") }, |
|
{ HTTP_METHOD_PROPPATCH, CONST_STR_LEN("PROPPATCH") }, |
|
{ HTTP_METHOD_REBIND, CONST_STR_LEN("REBIND") }, |
|
{ HTTP_METHOD_REPORT, CONST_STR_LEN("REPORT") }, |
|
{ HTTP_METHOD_SEARCH, CONST_STR_LEN("SEARCH") }, |
|
{ HTTP_METHOD_UNBIND, CONST_STR_LEN("UNBIND") }, |
|
{ HTTP_METHOD_UNCHECKOUT, CONST_STR_LEN("UNCHECKOUT") }, |
|
{ HTTP_METHOD_UNLINK, CONST_STR_LEN("UNLINK") }, |
|
{ HTTP_METHOD_UNLOCK, CONST_STR_LEN("UNLOCK") }, |
|
{ HTTP_METHOD_UPDATE, CONST_STR_LEN("UPDATE") }, |
|
{ HTTP_METHOD_UPDATEREDIRECTREF, CONST_STR_LEN("UPDATEREDIRECTREF") }, |
|
{ HTTP_METHOD_VERSION_CONTROL, CONST_STR_LEN("VERSION-CONTROL") }, |
|
|
|
{ HTTP_METHOD_UNSET, NULL, 0 } |
|
}; |
|
|
|
static const keyvalue http_status[] = { |
|
{ 100, CONST_STR_LEN("100 Continue") }, |
|
{ 101, CONST_STR_LEN("101 Switching Protocols") }, |
|
{ 102, CONST_STR_LEN("102 Processing") }, /* WebDAV */ |
|
{ 200, CONST_STR_LEN("200 OK") }, |
|
{ 201, CONST_STR_LEN("201 Created") }, |
|
{ 202, CONST_STR_LEN("202 Accepted") }, |
|
{ 203, CONST_STR_LEN("203 Non-Authoritative Information") }, |
|
{ 204, CONST_STR_LEN("204 No Content") }, |
|
{ 205, CONST_STR_LEN("205 Reset Content") }, |
|
{ 206, CONST_STR_LEN("206 Partial Content") }, |
|
{ 207, CONST_STR_LEN("207 Multi-status") }, /* WebDAV */ |
|
{ 300, CONST_STR_LEN("300 Multiple Choices") }, |
|
{ 301, CONST_STR_LEN("301 Moved Permanently") }, |
|
{ 302, CONST_STR_LEN("302 Found") }, |
|
{ 303, CONST_STR_LEN("303 See Other") }, |
|
{ 304, CONST_STR_LEN("304 Not Modified") }, |
|
{ 305, CONST_STR_LEN("305 Use Proxy") }, |
|
{ 306, CONST_STR_LEN("306 (Unused)") }, |
|
{ 307, CONST_STR_LEN("307 Temporary Redirect") }, |
|
{ 308, CONST_STR_LEN("308 Permanent Redirect") }, |
|
{ 400, CONST_STR_LEN("400 Bad Request") }, |
|
{ 401, CONST_STR_LEN("401 Unauthorized") }, |
|
{ 402, CONST_STR_LEN("402 Payment Required") }, |
|
{ 403, CONST_STR_LEN("403 Forbidden") }, |
|
{ 404, CONST_STR_LEN("404 Not Found") }, |
|
{ 405, CONST_STR_LEN("405 Method Not Allowed") }, |
|
{ 406, CONST_STR_LEN("406 Not Acceptable") }, |
|
{ 407, CONST_STR_LEN("407 Proxy Authentication Required") }, |
|
{ 408, CONST_STR_LEN("408 Request Timeout") }, |
|
{ 409, CONST_STR_LEN("409 Conflict") }, |
|
{ 410, CONST_STR_LEN("410 Gone") }, |
|
{ 411, CONST_STR_LEN("411 Length Required") }, |
|
{ 412, CONST_STR_LEN("412 Precondition Failed") }, |
|
{ 413, CONST_STR_LEN("413 Request Entity Too Large") }, |
|
{ 414, CONST_STR_LEN("414 Request-URI Too Long") }, |
|
{ 415, CONST_STR_LEN("415 Unsupported Media Type") }, |
|
{ 416, CONST_STR_LEN("416 Requested Range Not Satisfiable") }, |
|
{ 417, CONST_STR_LEN("417 Expectation Failed") }, |
|
{ 422, CONST_STR_LEN("422 Unprocessable Entity") }, /* WebDAV */ |
|
{ 423, CONST_STR_LEN("423 Locked") }, /* WebDAV */ |
|
{ 424, CONST_STR_LEN("424 Failed Dependency") }, /* WebDAV */ |
|
{ 426, CONST_STR_LEN("426 Upgrade Required") }, /* TLS */ |
|
{ 500, CONST_STR_LEN("500 Internal Server Error") }, |
|
{ 501, CONST_STR_LEN("501 Not Implemented") }, |
|
{ 502, CONST_STR_LEN("502 Bad Gateway") }, |
|
{ 503, CONST_STR_LEN("503 Service Not Available") }, |
|
{ 504, CONST_STR_LEN("504 Gateway Timeout") }, |
|
{ 505, CONST_STR_LEN("505 HTTP Version Not Supported") }, |
|
{ 507, CONST_STR_LEN("507 Insufficient Storage") }, /* WebDAV */ |
|
|
|
{ -1, NULL, 0 } |
|
}; |
|
|
|
|
|
static const char *keyvalue_get_value(const keyvalue *kv, int k) { |
|
int i; |
|
for (i = 0; kv[i].value; i++) { |
|
if (kv[i].key == k) return kv[i].value; |
|
} |
|
return NULL; |
|
} |
|
|
|
static int keyvalue_get_key(const keyvalue *kv, const char *s) { |
|
int i; |
|
for (i = 0; kv[i].value; i++) { |
|
if (0 == strcmp(kv[i].value, s)) return kv[i].key; |
|
} |
|
return -1; |
|
} |
|
|
|
|
|
const char *get_http_version_name(int i) { |
|
return keyvalue_get_value(http_versions, i); |
|
} |
|
|
|
const char *get_http_status_name(int i) { |
|
return keyvalue_get_value(http_status, i); |
|
} |
|
|
|
const char *get_http_method_name(http_method_t i) { |
|
return keyvalue_get_value(http_methods, i); |
|
} |
|
|
|
int get_http_version_key(const char *s) { |
|
return keyvalue_get_key(http_versions, s); |
|
} |
|
|
|
http_method_t get_http_method_key(const char *s) { |
|
return (http_method_t)keyvalue_get_key(http_methods, s); |
|
} |
|
|
|
|
|
void http_status_append(buffer * const b, const int status) { |
|
const keyvalue * const kv = http_status; |
|
int i; |
|
for (i = 0; kv[i].key != status && kv[i].value; ++i) ; |
|
if (kv[i].value) { |
|
buffer_append_string_len(b, kv[i].value, kv[i].vlen); |
|
} |
|
else { |
|
buffer_append_int(b, status); |
|
buffer_append_string_len(b, CONST_STR_LEN(" ")); |
|
} |
|
} |
|
|
|
void http_method_append(buffer * const b, const http_method_t method) { |
|
const keyvalue * const kv = http_methods; |
|
int i; |
|
for (i = 0; kv[i].key != method && kv[i].value; ++i) ; |
|
if (kv[i].value) { |
|
buffer_append_string_len(b, kv[i].value, kv[i].vlen); |
|
} |
|
}
|
|
|