10 static const keyvalue http_versions
[] = {
11 { HTTP_VERSION_1_1
, "HTTP/1.1" },
12 { HTTP_VERSION_1_0
, "HTTP/1.0" },
13 { HTTP_VERSION_UNSET
, NULL
}
16 static const keyvalue http_methods
[] = {
17 { HTTP_METHOD_GET
, "GET" },
18 { HTTP_METHOD_HEAD
, "HEAD" },
19 { HTTP_METHOD_POST
, "POST" },
20 { HTTP_METHOD_PUT
, "PUT" },
21 { HTTP_METHOD_DELETE
, "DELETE" },
22 { HTTP_METHOD_CONNECT
, "CONNECT" },
23 { HTTP_METHOD_OPTIONS
, "OPTIONS" },
24 { HTTP_METHOD_TRACE
, "TRACE" },
25 { HTTP_METHOD_ACL
, "ACL" },
26 { HTTP_METHOD_BASELINE_CONTROL
, "BASELINE-CONTROL" },
27 { HTTP_METHOD_BIND
, "BIND" },
28 { HTTP_METHOD_CHECKIN
, "CHECKIN" },
29 { HTTP_METHOD_CHECKOUT
, "CHECKOUT" },
30 { HTTP_METHOD_COPY
, "COPY" },
31 { HTTP_METHOD_LABEL
, "LABEL" },
32 { HTTP_METHOD_LINK
, "LINK" },
33 { HTTP_METHOD_LOCK
, "LOCK" },
34 { HTTP_METHOD_MERGE
, "MERGE" },
35 { HTTP_METHOD_MKACTIVITY
, "MKACTIVITY" },
36 { HTTP_METHOD_MKCALENDAR
, "MKCALENDAR" },
37 { HTTP_METHOD_MKCOL
, "MKCOL" },
38 { HTTP_METHOD_MKREDIRECTREF
, "MKREDIRECTREF" },
39 { HTTP_METHOD_MKWORKSPACE
, "MKWORKSPACE" },
40 { HTTP_METHOD_MOVE
, "MOVE" },
41 { HTTP_METHOD_ORDERPATCH
, "ORDERPATCH" },
42 { HTTP_METHOD_PATCH
, "PATCH" },
43 { HTTP_METHOD_PROPFIND
, "PROPFIND" },
44 { HTTP_METHOD_PROPPATCH
, "PROPPATCH" },
45 { HTTP_METHOD_REBIND
, "REBIND" },
46 { HTTP_METHOD_REPORT
, "REPORT" },
47 { HTTP_METHOD_SEARCH
, "SEARCH" },
48 { HTTP_METHOD_UNBIND
, "UNBIND" },
49 { HTTP_METHOD_UNCHECKOUT
, "UNCHECKOUT" },
50 { HTTP_METHOD_UNLINK
, "UNLINK" },
51 { HTTP_METHOD_UNLOCK
, "UNLOCK" },
52 { HTTP_METHOD_UPDATE
, "UPDATE" },
53 { HTTP_METHOD_UPDATEREDIRECTREF
, "UPDATEREDIRECTREF" },
54 { HTTP_METHOD_VERSION_CONTROL
, "VERSION-CONTROL" },
56 { HTTP_METHOD_UNSET
, NULL
}
59 static const keyvalue http_status
[] = {
61 { 101, "Switching Protocols" },
62 { 102, "Processing" }, /* WebDAV */
66 { 203, "Non-Authoritative Information" },
67 { 204, "No Content" },
68 { 205, "Reset Content" },
69 { 206, "Partial Content" },
70 { 207, "Multi-status" }, /* WebDAV */
71 { 300, "Multiple Choices" },
72 { 301, "Moved Permanently" },
75 { 304, "Not Modified" },
78 { 307, "Temporary Redirect" },
79 { 308, "Permanent Redirect" },
80 { 400, "Bad Request" },
81 { 401, "Unauthorized" },
82 { 402, "Payment Required" },
85 { 405, "Method Not Allowed" },
86 { 406, "Not Acceptable" },
87 { 407, "Proxy Authentication Required" },
88 { 408, "Request Timeout" },
91 { 411, "Length Required" },
92 { 412, "Precondition Failed" },
93 { 413, "Request Entity Too Large" },
94 { 414, "Request-URI Too Long" },
95 { 415, "Unsupported Media Type" },
96 { 416, "Requested Range Not Satisfiable" },
97 { 417, "Expectation Failed" },
98 { 422, "Unprocessable Entity" }, /* WebDAV */
99 { 423, "Locked" }, /* WebDAV */
100 { 424, "Failed Dependency" }, /* WebDAV */
101 { 426, "Upgrade Required" }, /* TLS */
102 { 500, "Internal Server Error" },
103 { 501, "Not Implemented" },
104 { 502, "Bad Gateway" },
105 { 503, "Service Not Available" },
106 { 504, "Gateway Timeout" },
107 { 505, "HTTP Version Not Supported" },
108 { 507, "Insufficient Storage" }, /* WebDAV */
113 static const keyvalue http_status_body
[] = {
129 const char *keyvalue_get_value(const keyvalue
*kv
, int k
) {
131 for (i
= 0; kv
[i
].value
; i
++) {
132 if (kv
[i
].key
== k
) return kv
[i
].value
;
137 int keyvalue_get_key(const keyvalue
*kv
, const char *s
) {
139 for (i
= 0; kv
[i
].value
; i
++) {
140 if (0 == strcmp(kv
[i
].value
, s
)) return kv
[i
].key
;
146 const char *get_http_version_name(int i
) {
147 return keyvalue_get_value(http_versions
, i
);
150 const char *get_http_status_name(int i
) {
151 return keyvalue_get_value(http_status
, i
);
154 const char *get_http_method_name(http_method_t i
) {
155 return keyvalue_get_value(http_methods
, i
);
158 const char *get_http_status_body_name(int i
) {
159 return keyvalue_get_value(http_status_body
, i
);
162 int get_http_version_key(const char *s
) {
163 return keyvalue_get_key(http_versions
, s
);
166 http_method_t
get_http_method_key(const char *s
) {
167 return (http_method_t
)keyvalue_get_key(http_methods
, s
);
173 pcre_keyvalue_buffer
*pcre_keyvalue_buffer_init(void) {
174 pcre_keyvalue_buffer
*kvb
;
176 kvb
= calloc(1, sizeof(*kvb
));
177 force_assert(NULL
!= kvb
);
182 int pcre_keyvalue_buffer_append(server
*srv
, pcre_keyvalue_buffer
*kvb
, const char *key
, const char *value
) {
193 if (kvb
->size
== 0) {
197 kvb
->kv
= malloc(kvb
->size
* sizeof(*kvb
->kv
));
198 force_assert(NULL
!= kvb
->kv
);
200 for(i
= 0; i
< kvb
->size
; i
++) {
201 kvb
->kv
[i
] = calloc(1, sizeof(**kvb
->kv
));
202 force_assert(NULL
!= kvb
->kv
[i
]);
204 } else if (kvb
->used
== kvb
->size
) {
207 kvb
->kv
= realloc(kvb
->kv
, kvb
->size
* sizeof(*kvb
->kv
));
208 force_assert(NULL
!= kvb
->kv
);
210 for(i
= kvb
->used
; i
< kvb
->size
; i
++) {
211 kvb
->kv
[i
] = calloc(1, sizeof(**kvb
->kv
));
212 force_assert(NULL
!= kvb
->kv
[i
]);
216 kv
= kvb
->kv
[kvb
->used
];
217 if (NULL
== (kv
->key
= pcre_compile(key
,
218 0, &errptr
, &erroff
, NULL
))) {
220 log_error_write(srv
, __FILE__
, __LINE__
, "SS",
221 "rexexp compilation error at ", errptr
);
225 if (NULL
== (kv
->key_extra
= pcre_study(kv
->key
, 0, &errptr
)) &&
230 kv
->value
= buffer_init_string(value
);
243 void pcre_keyvalue_buffer_free(pcre_keyvalue_buffer
*kvb
) {
248 for (i
= 0; i
< kvb
->size
; i
++) {
250 if (kv
->key
) pcre_free(kv
->key
);
251 if (kv
->key_extra
) pcre_free(kv
->key_extra
);
252 if (kv
->value
) buffer_free(kv
->value
);
256 if (kvb
->kv
) free(kvb
->kv
);