8 #define CONST_LEN_STR(x) (unsigned int)sizeof(x)-1, (x)
16 static const keyvalue http_versions
[] = {
17 { HTTP_VERSION_1_1
, CONST_LEN_STR("HTTP/1.1") },
18 { HTTP_VERSION_1_0
, CONST_LEN_STR("HTTP/1.0") },
19 { HTTP_VERSION_UNSET
, 0, NULL
}
22 static const keyvalue http_methods
[] = {
23 { HTTP_METHOD_GET
, CONST_LEN_STR("GET") },
24 { HTTP_METHOD_HEAD
, CONST_LEN_STR("HEAD") },
25 { HTTP_METHOD_POST
, CONST_LEN_STR("POST") },
26 { HTTP_METHOD_PUT
, CONST_LEN_STR("PUT") },
27 { HTTP_METHOD_DELETE
, CONST_LEN_STR("DELETE") },
28 { HTTP_METHOD_CONNECT
, CONST_LEN_STR("CONNECT") },
29 { HTTP_METHOD_OPTIONS
, CONST_LEN_STR("OPTIONS") },
30 { HTTP_METHOD_TRACE
, CONST_LEN_STR("TRACE") },
31 { HTTP_METHOD_ACL
, CONST_LEN_STR("ACL") },
32 { HTTP_METHOD_BASELINE_CONTROL
, CONST_LEN_STR("BASELINE-CONTROL") },
33 { HTTP_METHOD_BIND
, CONST_LEN_STR("BIND") },
34 { HTTP_METHOD_CHECKIN
, CONST_LEN_STR("CHECKIN") },
35 { HTTP_METHOD_CHECKOUT
, CONST_LEN_STR("CHECKOUT") },
36 { HTTP_METHOD_COPY
, CONST_LEN_STR("COPY") },
37 { HTTP_METHOD_LABEL
, CONST_LEN_STR("LABEL") },
38 { HTTP_METHOD_LINK
, CONST_LEN_STR("LINK") },
39 { HTTP_METHOD_LOCK
, CONST_LEN_STR("LOCK") },
40 { HTTP_METHOD_MERGE
, CONST_LEN_STR("MERGE") },
41 { HTTP_METHOD_MKACTIVITY
, CONST_LEN_STR("MKACTIVITY") },
42 { HTTP_METHOD_MKCALENDAR
, CONST_LEN_STR("MKCALENDAR") },
43 { HTTP_METHOD_MKCOL
, CONST_LEN_STR("MKCOL") },
44 { HTTP_METHOD_MKREDIRECTREF
, CONST_LEN_STR("MKREDIRECTREF") },
45 { HTTP_METHOD_MKWORKSPACE
, CONST_LEN_STR("MKWORKSPACE") },
46 { HTTP_METHOD_MOVE
, CONST_LEN_STR("MOVE") },
47 { HTTP_METHOD_ORDERPATCH
, CONST_LEN_STR("ORDERPATCH") },
48 { HTTP_METHOD_PATCH
, CONST_LEN_STR("PATCH") },
49 { HTTP_METHOD_PROPFIND
, CONST_LEN_STR("PROPFIND") },
50 { HTTP_METHOD_PROPPATCH
, CONST_LEN_STR("PROPPATCH") },
51 { HTTP_METHOD_REBIND
, CONST_LEN_STR("REBIND") },
52 { HTTP_METHOD_REPORT
, CONST_LEN_STR("REPORT") },
53 { HTTP_METHOD_SEARCH
, CONST_LEN_STR("SEARCH") },
54 { HTTP_METHOD_UNBIND
, CONST_LEN_STR("UNBIND") },
55 { HTTP_METHOD_UNCHECKOUT
, CONST_LEN_STR("UNCHECKOUT") },
56 { HTTP_METHOD_UNLINK
, CONST_LEN_STR("UNLINK") },
57 { HTTP_METHOD_UNLOCK
, CONST_LEN_STR("UNLOCK") },
58 { HTTP_METHOD_UPDATE
, CONST_LEN_STR("UPDATE") },
59 { HTTP_METHOD_UPDATEREDIRECTREF
, CONST_LEN_STR("UPDATEREDIRECTREF") },
60 { HTTP_METHOD_VERSION_CONTROL
, CONST_LEN_STR("VERSION-CONTROL") },
62 { HTTP_METHOD_UNSET
, 0, NULL
}
65 static const keyvalue http_status
[] = {
66 { 100, CONST_LEN_STR("100 Continue") },
67 { 101, CONST_LEN_STR("101 Switching Protocols") },
68 { 102, CONST_LEN_STR("102 Processing") }, /* WebDAV */
69 { 200, CONST_LEN_STR("200 OK") },
70 { 201, CONST_LEN_STR("201 Created") },
71 { 202, CONST_LEN_STR("202 Accepted") },
72 { 203, CONST_LEN_STR("203 Non-Authoritative Information") },
73 { 204, CONST_LEN_STR("204 No Content") },
74 { 205, CONST_LEN_STR("205 Reset Content") },
75 { 206, CONST_LEN_STR("206 Partial Content") },
76 { 207, CONST_LEN_STR("207 Multi-status") }, /* WebDAV */
77 { 300, CONST_LEN_STR("300 Multiple Choices") },
78 { 301, CONST_LEN_STR("301 Moved Permanently") },
79 { 302, CONST_LEN_STR("302 Found") },
80 { 303, CONST_LEN_STR("303 See Other") },
81 { 304, CONST_LEN_STR("304 Not Modified") },
82 { 305, CONST_LEN_STR("305 Use Proxy") },
83 { 306, CONST_LEN_STR("306 (Unused)") },
84 { 307, CONST_LEN_STR("307 Temporary Redirect") },
85 { 308, CONST_LEN_STR("308 Permanent Redirect") },
86 { 400, CONST_LEN_STR("400 Bad Request") },
87 { 401, CONST_LEN_STR("401 Unauthorized") },
88 { 402, CONST_LEN_STR("402 Payment Required") },
89 { 403, CONST_LEN_STR("403 Forbidden") },
90 { 404, CONST_LEN_STR("404 Not Found") },
91 { 405, CONST_LEN_STR("405 Method Not Allowed") },
92 { 406, CONST_LEN_STR("406 Not Acceptable") },
93 { 407, CONST_LEN_STR("407 Proxy Authentication Required") },
94 { 408, CONST_LEN_STR("408 Request Timeout") },
95 { 409, CONST_LEN_STR("409 Conflict") },
96 { 410, CONST_LEN_STR("410 Gone") },
97 { 411, CONST_LEN_STR("411 Length Required") },
98 { 412, CONST_LEN_STR("412 Precondition Failed") },
99 { 413, CONST_LEN_STR("413 Request Entity Too Large") },
100 { 414, CONST_LEN_STR("414 Request-URI Too Long") },
101 { 415, CONST_LEN_STR("415 Unsupported Media Type") },
102 { 416, CONST_LEN_STR("416 Requested Range Not Satisfiable") },
103 { 417, CONST_LEN_STR("417 Expectation Failed") },
104 { 422, CONST_LEN_STR("422 Unprocessable Entity") }, /* WebDAV */
105 { 423, CONST_LEN_STR("423 Locked") }, /* WebDAV */
106 { 424, CONST_LEN_STR("424 Failed Dependency") }, /* WebDAV */
107 { 426, CONST_LEN_STR("426 Upgrade Required") }, /* TLS */
108 { 500, CONST_LEN_STR("500 Internal Server Error") },
109 { 501, CONST_LEN_STR("501 Not Implemented") },
110 { 502, CONST_LEN_STR("502 Bad Gateway") },
111 { 503, CONST_LEN_STR("503 Service Not Available") },
112 { 504, CONST_LEN_STR("504 Gateway Timeout") },
113 { 505, CONST_LEN_STR("505 HTTP Version Not Supported") },
114 { 507, CONST_LEN_STR("507 Insufficient Storage") }, /* WebDAV */
120 static const char *keyvalue_get_value(const keyvalue
*kv
, int k
) {
122 for (i
= 0; kv
[i
].value
; i
++) {
123 if (kv
[i
].key
== k
) return kv
[i
].value
;
128 static int keyvalue_get_key(const keyvalue
*kv
, const char *s
, unsigned int slen
) {
129 for (int i
= 0; kv
[i
].vlen
; ++i
) {
130 if (kv
[i
].vlen
== slen
&& 0 == memcmp(kv
[i
].value
, s
, slen
))
137 const char *get_http_version_name(int i
) {
138 return keyvalue_get_value(http_versions
, i
);
141 const char *get_http_status_name(int i
) {
142 return keyvalue_get_value(http_status
, i
);
145 const char *get_http_method_name(http_method_t i
) {
146 return keyvalue_get_value(http_methods
, i
);
149 int get_http_version_key(const char *s
, size_t slen
) {
150 return keyvalue_get_key(http_versions
, s
, (unsigned int)slen
);
153 http_method_t
get_http_method_key(const char *s
, size_t slen
) {
154 return (http_method_t
)keyvalue_get_key(http_methods
, s
, (unsigned int)slen
);
158 void http_status_append(buffer
* const b
, const int status
) {
159 const keyvalue
* const kv
= http_status
;
161 for (i
= 0; kv
[i
].key
!= status
&& kv
[i
].vlen
; ++i
) ;
163 buffer_append_string_len(b
, kv
[i
].value
, kv
[i
].vlen
);
166 buffer_append_int(b
, status
);
167 buffer_append_string_len(b
, CONST_STR_LEN(" "));
171 void http_method_append(buffer
* const b
, const http_method_t method
) {
172 const keyvalue
* const kv
= http_methods
;
174 for (i
= 0; kv
[i
].key
!= method
&& kv
[i
].vlen
; ++i
) ;
176 buffer_append_string_len(b
, kv
[i
].value
, kv
[i
].vlen
);