1 #include "server.h"
2 #include "keyvalue.h"
3 #include "log.h"
4
5 #include <stdlib.h>
6 #include <string.h>
7 #include <stdio.h>
8
9 static const keyvalue http_versions[] = {
10 { HTTP_VERSION_1_1, "HTTP/1.1" },
11 { HTTP_VERSION_1_0, "HTTP/1.0" },
12 { HTTP_VERSION_UNSET, NULL }
13 };
14
15 static const keyvalue http_methods[] = {
16 { HTTP_METHOD_GET, "GET" },
17 { HTTP_METHOD_POST, "POST" },
18 { HTTP_METHOD_HEAD, "HEAD" },
19 { HTTP_METHOD_PROPFIND, "PROPFIND" },
20 { HTTP_METHOD_PROPPATCH, "PROPPATCH" },
21 { HTTP_METHOD_REPORT, "REPORT" },
22 { HTTP_METHOD_OPTIONS, "OPTIONS" },
23 { HTTP_METHOD_MKCOL, "MKCOL" },
24 { HTTP_METHOD_PUT, "PUT" },
25 { HTTP_METHOD_PATCH, "PATCH" },
26 { HTTP_METHOD_DELETE, "DELETE" },
27 { HTTP_METHOD_COPY, "COPY" },
28 { HTTP_METHOD_MOVE, "MOVE" },
29 { HTTP_METHOD_LABEL, "LABEL" },
30 { HTTP_METHOD_CHECKOUT, "CHECKOUT" },
31 { HTTP_METHOD_CHECKIN, "CHECKIN" },
32 { HTTP_METHOD_MERGE, "MERGE" },
33 { HTTP_METHOD_LOCK, "LOCK" },
34 { HTTP_METHOD_UNLOCK, "UNLOCK" },
35 { HTTP_METHOD_MKACTIVITY, "MKACTIVITY" },
36 { HTTP_METHOD_UNCHECKOUT, "UNCHECKOUT" },
37 { HTTP_METHOD_VERSION_CONTROL, "VERSION-CONTROL" },
38 { HTTP_METHOD_CONNECT, "CONNECT" },
39
40 { HTTP_METHOD_UNSET, NULL }
41 };
42
43 static const keyvalue http_status[] = {
44 { 100, "Continue" },
45 { 101, "Switching Protocols" },
46 { 102, "Processing" }, /* WebDAV */
47 { 200, "OK" },
48 { 201, "Created" },
49 { 202, "Accepted" },
50 { 203, "Non-Authoritative Information" },
51 { 204, "No Content" },
52 { 205, "Reset Content" },
53 { 206, "Partial Content" },
54 { 207, "Multi-status" }, /* WebDAV */
55 { 300, "Multiple Choices" },
56 { 301, "Moved Permanently" },
57 { 302, "Found" },
58 { 303, "See Other" },
59 { 304, "Not Modified" },
60 { 305, "Use Proxy" },
61 { 306, "(Unused)" },
62 { 307, "Temporary Redirect" },
63 { 400, "Bad Request" },
64 { 401, "Unauthorized" },
65 { 402, "Payment Required" },
66 { 403, "Forbidden" },
67 { 404, "Not Found At All" },
68 { 405, "Method Not Allowed" },
69 { 406, "Not Acceptable" },
70 { 407, "Proxy Authentication Required" },
71 { 408, "Request Timeout" },
72 { 409, "Conflict" },
73 { 410, "Gone" },
74 { 411, "Length Required" },
75 { 412, "Precondition Failed" },
76 { 413, "Request Entity Too Large" },
77 { 414, "Request-URI Too Long" },
78 { 415, "Unsupported Media Type" },
79 { 416, "Requested Range Not Satisfiable" },
80 { 417, "Expectation Failed" },
81 { 422, "Unprocessable Entity" }, /* WebDAV */
82 { 423, "Locked" }, /* WebDAV */
83 { 424, "Failed Dependency" }, /* WebDAV */
84 { 426, "Upgrade Required" }, /* TLS */
85 { 500, "Internal Server Error" },
86 { 501, "Not Implemented" },
87 { 502, "Bad Gateway" },
88 { 503, "Service Not Available" },
89 { 504, "Gateway Timeout" },
90 { 505, "HTTP Version Not Supported" },
91 { 507, "Insufficient Storage" }, /* WebDAV */
92
93 { -1, NULL }
94 };
95
96 static const keyvalue http_status_body[] = {
97 { 400, "400.html" },
98 { 401, "401.html" },
99 { 403, "403.html" },
100 { 404, "404.html" },
101 { 411, "411.html" },
102 { 416, "416.html" },
103 { 500, "500.html" },
104 { 501, "501.html" },
105 { 503, "503.html" },
106 { 505, "505.html" },
107
108 { -1, NULL }
109 };
110
111
keyvalue_get_value(const keyvalue * kv,int k)112 const char *keyvalue_get_value(const keyvalue *kv, int k) {
113 int i;
114 for (i = 0; kv[i].value; i++) {
115 if (kv[i].key == k) return kv[i].value;
116 }
117 return NULL;
118 }
119
keyvalue_get_key(const keyvalue * kv,const char * s)120 int keyvalue_get_key(const keyvalue *kv, const char *s) {
121 int i;
122 for (i = 0; kv[i].value; i++) {
123 if (0 == strcmp(kv[i].value, s)) return kv[i].key;
124 }
125 return -1;
126 }
127
keyvalue_buffer_init(void)128 keyvalue_buffer *keyvalue_buffer_init(void) {
129 keyvalue_buffer *kvb;
130
131 kvb = calloc(1, sizeof(*kvb));
132
133 return kvb;
134 }
135
keyvalue_buffer_append(keyvalue_buffer * kvb,int key,const char * value)136 int keyvalue_buffer_append(keyvalue_buffer *kvb, int key, const char *value) {
137 size_t i;
138 if (kvb->size == 0) {
139 kvb->size = 4;
140
141 kvb->kv = malloc(kvb->size * sizeof(*kvb->kv));
142
143 for(i = 0; i < kvb->size; i++) {
144 kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
145 }
146 } else if (kvb->used == kvb->size) {
147 kvb->size += 4;
148
149 kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
150
151 for(i = kvb->used; i < kvb->size; i++) {
152 kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
153 }
154 }
155
156 kvb->kv[kvb->used]->key = key;
157 kvb->kv[kvb->used]->value = strdup(value);
158
159 kvb->used++;
160
161 return 0;
162 }
163
keyvalue_buffer_free(keyvalue_buffer * kvb)164 void keyvalue_buffer_free(keyvalue_buffer *kvb) {
165 size_t i;
166
167 for (i = 0; i < kvb->size; i++) {
168 if (kvb->kv[i]->value) free(kvb->kv[i]->value);
169 free(kvb->kv[i]);
170 }
171
172 if (kvb->kv) free(kvb->kv);
173
174 free(kvb);
175 }
176
177
s_keyvalue_buffer_init(void)178 s_keyvalue_buffer *s_keyvalue_buffer_init(void) {
179 s_keyvalue_buffer *kvb;
180
181 kvb = calloc(1, sizeof(*kvb));
182
183 return kvb;
184 }
185
s_keyvalue_buffer_append(s_keyvalue_buffer * kvb,const char * key,const char * value)186 int s_keyvalue_buffer_append(s_keyvalue_buffer *kvb, const char *key, const char *value) {
187 size_t i;
188 if (kvb->size == 0) {
189 kvb->size = 4;
190 kvb->used = 0;
191
192 kvb->kv = malloc(kvb->size * sizeof(*kvb->kv));
193
194 for(i = 0; i < kvb->size; i++) {
195 kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
196 }
197 } else if (kvb->used == kvb->size) {
198 kvb->size += 4;
199
200 kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
201
202 for(i = kvb->used; i < kvb->size; i++) {
203 kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
204 }
205 }
206
207 kvb->kv[kvb->used]->key = key ? strdup(key) : NULL;
208 kvb->kv[kvb->used]->value = strdup(value);
209
210 kvb->used++;
211
212 return 0;
213 }
214
s_keyvalue_buffer_free(s_keyvalue_buffer * kvb)215 void s_keyvalue_buffer_free(s_keyvalue_buffer *kvb) {
216 size_t i;
217
218 for (i = 0; i < kvb->size; i++) {
219 if (kvb->kv[i]->key) free(kvb->kv[i]->key);
220 if (kvb->kv[i]->value) free(kvb->kv[i]->value);
221 free(kvb->kv[i]);
222 }
223
224 if (kvb->kv) free(kvb->kv);
225
226 free(kvb);
227 }
228
229
httpauth_keyvalue_buffer_init(void)230 httpauth_keyvalue_buffer *httpauth_keyvalue_buffer_init(void) {
231 httpauth_keyvalue_buffer *kvb;
232
233 kvb = calloc(1, sizeof(*kvb));
234
235 return kvb;
236 }
237
httpauth_keyvalue_buffer_append(httpauth_keyvalue_buffer * kvb,const char * key,const char * realm,httpauth_type type)238 int httpauth_keyvalue_buffer_append(httpauth_keyvalue_buffer *kvb, const char *key, const char *realm, httpauth_type type) {
239 size_t i;
240 if (kvb->size == 0) {
241 kvb->size = 4;
242
243 kvb->kv = malloc(kvb->size * sizeof(*kvb->kv));
244
245 for(i = 0; i < kvb->size; i++) {
246 kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
247 }
248 } else if (kvb->used == kvb->size) {
249 kvb->size += 4;
250
251 kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
252
253 for(i = kvb->used; i < kvb->size; i++) {
254 kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
255 }
256 }
257
258 kvb->kv[kvb->used]->key = strdup(key);
259 kvb->kv[kvb->used]->realm = strdup(realm);
260 kvb->kv[kvb->used]->type = type;
261
262 kvb->used++;
263
264 return 0;
265 }
266
httpauth_keyvalue_buffer_free(httpauth_keyvalue_buffer * kvb)267 void httpauth_keyvalue_buffer_free(httpauth_keyvalue_buffer *kvb) {
268 size_t i;
269
270 for (i = 0; i < kvb->size; i++) {
271 if (kvb->kv[i]->key) free(kvb->kv[i]->key);
272 if (kvb->kv[i]->realm) free(kvb->kv[i]->realm);
273 free(kvb->kv[i]);
274 }
275
276 if (kvb->kv) free(kvb->kv);
277
278 free(kvb);
279 }
280
281
get_http_version_name(int i)282 const char *get_http_version_name(int i) {
283 return keyvalue_get_value(http_versions, i);
284 }
285
get_http_status_name(int i)286 const char *get_http_status_name(int i) {
287 return keyvalue_get_value(http_status, i);
288 }
289
get_http_method_name(http_method_t i)290 const char *get_http_method_name(http_method_t i) {
291 return keyvalue_get_value(http_methods, i);
292 }
293
get_http_status_body_name(int i)294 const char *get_http_status_body_name(int i) {
295 return keyvalue_get_value(http_status_body, i);
296 }
297
get_http_version_key(const char * s)298 int get_http_version_key(const char *s) {
299 return keyvalue_get_key(http_versions, s);
300 }
301
get_http_method_key(const char * s)302 http_method_t get_http_method_key(const char *s) {
303 return (http_method_t)keyvalue_get_key(http_methods, s);
304 }
305
306
307
308
pcre_keyvalue_buffer_init(void)309 pcre_keyvalue_buffer *pcre_keyvalue_buffer_init(void) {
310 pcre_keyvalue_buffer *kvb;
311
312 kvb = calloc(1, sizeof(*kvb));
313
314 return kvb;
315 }
316
pcre_keyvalue_buffer_append(server * srv,pcre_keyvalue_buffer * kvb,const char * key,const char * value)317 int pcre_keyvalue_buffer_append(server *srv, pcre_keyvalue_buffer *kvb, const char *key, const char *value) {
318 #ifdef HAVE_PCRE_H
319 size_t i;
320 const char *errptr;
321 int erroff;
322 pcre_keyvalue *kv;
323 #endif
324
325 if (!key) return -1;
326
327 #ifdef HAVE_PCRE_H
328 if (kvb->size == 0) {
329 kvb->size = 4;
330 kvb->used = 0;
331
332 kvb->kv = malloc(kvb->size * sizeof(*kvb->kv));
333
334 for(i = 0; i < kvb->size; i++) {
335 kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
336 }
337 } else if (kvb->used == kvb->size) {
338 kvb->size += 4;
339
340 kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
341
342 for(i = kvb->used; i < kvb->size; i++) {
343 kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
344 }
345 }
346
347 kv = kvb->kv[kvb->used];
348 if (NULL == (kv->key = pcre_compile(key,
349 0, &errptr, &erroff, NULL))) {
350
351 log_error_write(srv, __FILE__, __LINE__, "SS",
352 "rexexp compilation error at ", errptr);
353 return -1;
354 }
355
356 if (NULL == (kv->key_extra = pcre_study(kv->key, 0, &errptr)) &&
357 errptr != NULL) {
358 return -1;
359 }
360
361 kv->value = buffer_init_string(value);
362
363 kvb->used++;
364
365 return 0;
366 #else
367 UNUSED(kvb);
368 UNUSED(value);
369
370 return -1;
371 #endif
372 }
373
pcre_keyvalue_buffer_free(pcre_keyvalue_buffer * kvb)374 void pcre_keyvalue_buffer_free(pcre_keyvalue_buffer *kvb) {
375 #ifdef HAVE_PCRE_H
376 size_t i;
377 pcre_keyvalue *kv;
378
379 for (i = 0; i < kvb->size; i++) {
380 kv = kvb->kv[i];
381 if (kv->key) pcre_free(kv->key);
382 if (kv->key_extra) pcre_free(kv->key_extra);
383 if (kv->value) buffer_free(kv->value);
384 free(kv);
385 }
386
387 if (kvb->kv) free(kvb->kv);
388 #endif
389
390 free(kvb);
391 }
392