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