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
9static 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
15static keyvalue http_methods[] = {
16	{ HTTP_METHOD_GET, "GET" },
17	{ HTTP_METHOD_HEAD, "HEAD" },
18	{ HTTP_METHOD_POST, "POST" },
19	{ HTTP_METHOD_PUT, "PUT" },
20	{ HTTP_METHOD_DELETE, "DELETE" },
21	{ HTTP_METHOD_CONNECT, "CONNECT" },
22	{ HTTP_METHOD_OPTIONS, "OPTIONS" },
23	{ HTTP_METHOD_TRACE, "TRACE" },
24	{ HTTP_METHOD_ACL, "ACL" },
25	{ HTTP_METHOD_BASELINE_CONTROL, "BASELINE-CONTROL" },
26	{ HTTP_METHOD_BIND, "BIND" },
27	{ HTTP_METHOD_CHECKIN, "CHECKIN" },
28	{ HTTP_METHOD_CHECKOUT, "CHECKOUT" },
29	{ HTTP_METHOD_COPY, "COPY" },
30	{ HTTP_METHOD_LABEL, "LABEL" },
31	{ HTTP_METHOD_LINK, "LINK" },
32	{ HTTP_METHOD_LOCK, "LOCK" },
33	{ HTTP_METHOD_MERGE, "MERGE" },
34	{ HTTP_METHOD_MKACTIVITY, "MKACTIVITY" },
35	{ HTTP_METHOD_MKCALENDAR, "MKCALENDAR" },
36	{ HTTP_METHOD_MKCOL, "MKCOL" },
37	{ HTTP_METHOD_MKREDIRECTREF, "MKREDIRECTREF" },
38	{ HTTP_METHOD_MKWORKSPACE, "MKWORKSPACE" },
39	{ HTTP_METHOD_MOVE, "MOVE" },
40	{ HTTP_METHOD_ORDERPATCH, "ORDERPATCH" },
41	{ HTTP_METHOD_PATCH, "PATCH" },
42	{ HTTP_METHOD_PROPFIND, "PROPFIND" },
43	{ HTTP_METHOD_PROPPATCH, "PROPPATCH" },
44	{ HTTP_METHOD_REBIND, "REBIND" },
45	{ HTTP_METHOD_REPORT, "REPORT" },
46	{ HTTP_METHOD_SEARCH, "SEARCH" },
47	{ HTTP_METHOD_UNBIND, "UNBIND" },
48	{ HTTP_METHOD_UNCHECKOUT, "UNCHECKOUT" },
49	{ HTTP_METHOD_UNLINK, "UNLINK" },
50	{ HTTP_METHOD_UNLOCK, "UNLOCK" },
51	{ HTTP_METHOD_UPDATE, "UPDATE" },
52	{ HTTP_METHOD_UPDATEREDIRECTREF, "UPDATEREDIRECTREF" },
53	{ HTTP_METHOD_VERSION_CONTROL, "VERSION-CONTROL" },
54
55	/*Sungmin add*/
56	{ HTTP_METHOD_OAUTH, "OAUTH" },
57	{ HTTP_METHOD_WOL, "WOL" },
58	{ HTTP_METHOD_GSL, "GSL" },
59	{ HTTP_METHOD_LOGOUT, "LOGOUT" },
60	{ HTTP_METHOD_GETSRVTIME, "GETSRVTIME" },
61	{ HTTP_METHOD_RESCANSMBPC, "RESCANSMBPC" },
62	{ HTTP_METHOD_GETROUTERMAC, "GETROUTERMAC" },
63	{ HTTP_METHOD_GETFIRMVER, "GETFIRMVER" },
64	{ HTTP_METHOD_GETROUTERINFO, "GETROUTERINFO" },
65	{ HTTP_METHOD_GETNOTICE, "GETNOTICE" },
66	{ HTTP_METHOD_GSLL, "GSLL" },
67	{ HTTP_METHOD_REMOVESL, "REMOVESL" },
68	{ HTTP_METHOD_GETLATESTVER, "GETLATESTVER" },
69	{ HTTP_METHOD_GETDISKSPACE, "GETDISKSPACE" },
70	{ HTTP_METHOD_PROPFINDMEDIALIST, "PROPFINDMEDIALIST" },
71	{ HTTP_METHOD_GETMUSICCLASSIFICATION, "GETMUSICCLASSIFICATION" },
72	{ HTTP_METHOD_GETTHUMBIMAGE, "GETTHUMBIMAGE" },
73	{ HTTP_METHOD_GETMUSICPLAYLIST, "GETMUSICPLAYLIST" },
74	{ HTTP_METHOD_GETPRODUCTICON, "GETPRODUCTICON" },
75	{ HTTP_METHOD_GETVIDEOSUBTITLE, "GETVIDEOSUBTITLE" },
76	{ HTTP_METHOD_UPLOADTOFACEBOOK, "UPLOADTOFACEBOOK" },
77	{ HTTP_METHOD_UPLOADTOFLICKR, "UPLOADTOFLICKR" },
78	{ HTTP_METHOD_UPLOADTOPICASA, "UPLOADTOPICASA" },
79	{ HTTP_METHOD_UPLOADTOTWITTER, "UPLOADTOTWITTER" },
80	{ HTTP_METHOD_GENROOTCERTIFICATE, "GENROOTCERTIFICATE" },
81	{ HTTP_METHOD_SETROOTCERTIFICATE, "SETROOTCERTIFICATE" },
82	{ HTTP_METHOD_GETX509CERTINFO, "GETX509CERTINFO" },
83	{ HTTP_METHOD_APPLYAPP, "APPLYAPP" },
84	{ HTTP_METHOD_NVRAMGET, "NVRAMGET" },
85	{ HTTP_METHOD_GETCPUUSAGE, "GETCPUUSAGE" },
86	{ HTTP_METHOD_GETMEMORYUSAGE, "GETMEMORYUSAGE" },
87	{ HTTP_METHOD_UPDATEACCOUNT, "UPDATEACCOUNT" },
88	{ HTTP_METHOD_GETACCOUNTINFO, "GETACCOUNTINFO" },
89	{ HTTP_METHOD_GETACCOUNTLIST, "GETACCOUNTLIST" },
90	{ HTTP_METHOD_DELETEACCOUNT, "DELETEACCOUNT" },
91	{ HTTP_METHOD_UPDATEACCOUNTINVITE, "UPDATEACCOUNTINVITE" },
92	{ HTTP_METHOD_GETACCOUNTINVITEINFO, "GETACCOUNTINVITEINFO" },
93	{ HTTP_METHOD_GETACCOUNTINVITELIST, "GETACCOUNTINVITELIST" },
94	{ HTTP_METHOD_DELETEACCOUNTINVITE, "DELETEACCOUNTINVITE" },
95	{ HTTP_METHOD_OPENSTREAMINGPORT, "OPENSTREAMINGPORT" },
96
97	{ HTTP_METHOD_UNSET, NULL }
98};
99
100static keyvalue http_status[] = {
101	{ 100, "Continue" },
102	{ 101, "Switching Protocols" },
103	{ 102, "Processing" }, /* WebDAV */
104	{ 200, "OK" },
105	{ 201, "Created" },
106	{ 202, "Accepted" },
107	{ 203, "Non-Authoritative Information" },
108	{ 204, "No Content" },
109	{ 205, "Reset Content" },
110	{ 206, "Partial Content" },
111	{ 207, "Multi-status" }, /* WebDAV */
112	{ 300, "Multiple Choices" },
113	{ 301, "Moved Permanently" },
114	{ 302, "Found" },
115	{ 303, "See Other" },
116	{ 304, "Not Modified" },
117	{ 305, "Use Proxy" },
118	{ 306, "(Unused)" },
119	{ 307, "Temporary Redirect" },
120	{ 400, "Bad Request" },
121	{ 401, "Unauthorized" },
122	{ 402, "Payment Required" },
123	{ 403, "Forbidden" },
124	{ 404, "Not Found" },
125	{ 405, "Method Not Allowed" },
126	{ 406, "Not Acceptable" },
127	{ 407, "Proxy Authentication Required" },
128	{ 408, "Request Timeout" },
129	{ 409, "Conflict" },
130	{ 410, "Gone" },
131	{ 411, "Length Required" },
132	{ 412, "Precondition Failed" },
133	{ 413, "Request Entity Too Large" },
134	{ 414, "Request-URI Too Long" },
135	{ 415, "Unsupported Media Type" },
136	{ 416, "Requested Range Not Satisfiable" },
137	{ 417, "Expectation Failed" },
138	{ 422, "Unprocessable Entity" }, /* WebDAV */
139	{ 423, "Locked" }, /* WebDAV */
140	{ 424, "Failed Dependency" }, /* WebDAV */
141	{ 426, "Upgrade Required" }, /* TLS */
142	{ 500, "Internal Server Error" },
143	{ 501, "Not Implemented" },
144	{ 502, "Bad Gateway" },
145	{ 503, "Service Not Available" },
146	{ 504, "Gateway Timeout" },
147	{ 505, "HTTP Version Not Supported" },
148	{ 507, "Insufficient Storage" }, /* WebDAV */
149
150	{ -1, NULL }
151};
152
153static keyvalue http_status_body[] = {
154	{ 400, "400.html" },
155	{ 401, "401.html" },
156	{ 403, "403.html" },
157	{ 404, "404.html" },
158	{ 411, "411.html" },
159	{ 416, "416.html" },
160	{ 500, "500.html" },
161	{ 501, "501.html" },
162	{ 503, "503.html" },
163	{ 505, "505.html" },
164
165	{ -1, NULL }
166};
167
168
169const char *keyvalue_get_value(keyvalue *kv, int k) {
170	int i;
171	for (i = 0; kv[i].value; i++) {
172		if (kv[i].key == k) return kv[i].value;
173	}
174	return NULL;
175}
176
177int keyvalue_get_key(keyvalue *kv, const char *s) {
178	int i;
179	for (i = 0; kv[i].value; i++) {
180		if (0 == strcmp(kv[i].value, s)) return kv[i].key;
181	}
182	return -1;
183}
184
185keyvalue_buffer *keyvalue_buffer_init(void) {
186	keyvalue_buffer *kvb;
187
188	kvb = calloc(1, sizeof(*kvb));
189
190	return kvb;
191}
192
193int keyvalue_buffer_append(keyvalue_buffer *kvb, int key, const char *value) {
194	size_t i;
195	if (kvb->size == 0) {
196		kvb->size = 4;
197
198		kvb->kv = malloc(kvb->size * sizeof(*kvb->kv));
199
200		for(i = 0; i < kvb->size; i++) {
201			kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
202		}
203	} else if (kvb->used == kvb->size) {
204		kvb->size += 4;
205
206		kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
207
208		for(i = kvb->used; i < kvb->size; i++) {
209			kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
210		}
211	}
212
213	kvb->kv[kvb->used]->key = key;
214	kvb->kv[kvb->used]->value = strdup(value);
215
216	kvb->used++;
217
218	return 0;
219}
220
221void keyvalue_buffer_free(keyvalue_buffer *kvb) {
222	size_t i;
223
224	for (i = 0; i < kvb->size; i++) {
225		if (kvb->kv[i]->value) free(kvb->kv[i]->value);
226		free(kvb->kv[i]);
227	}
228
229	if (kvb->kv) free(kvb->kv);
230
231	free(kvb);
232}
233
234
235s_keyvalue_buffer *s_keyvalue_buffer_init(void) {
236	s_keyvalue_buffer *kvb;
237
238	kvb = calloc(1, sizeof(*kvb));
239
240	return kvb;
241}
242
243int s_keyvalue_buffer_append(s_keyvalue_buffer *kvb, const char *key, const char *value) {
244	size_t i;
245	if (kvb->size == 0) {
246		kvb->size = 4;
247		kvb->used = 0;
248
249		kvb->kv = malloc(kvb->size * sizeof(*kvb->kv));
250
251		for(i = 0; i < kvb->size; i++) {
252			kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
253		}
254	} else if (kvb->used == kvb->size) {
255		kvb->size += 4;
256
257		kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
258
259		for(i = kvb->used; i < kvb->size; i++) {
260			kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
261		}
262	}
263
264	kvb->kv[kvb->used]->key = key ? strdup(key) : NULL;
265	kvb->kv[kvb->used]->value = strdup(value);
266
267	kvb->used++;
268
269	return 0;
270}
271
272void s_keyvalue_buffer_free(s_keyvalue_buffer *kvb) {
273	size_t i;
274
275	for (i = 0; i < kvb->size; i++) {
276		if (kvb->kv[i]->key) free(kvb->kv[i]->key);
277		if (kvb->kv[i]->value) free(kvb->kv[i]->value);
278		free(kvb->kv[i]);
279	}
280
281	if (kvb->kv) free(kvb->kv);
282
283	free(kvb);
284}
285
286
287httpauth_keyvalue_buffer *httpauth_keyvalue_buffer_init(void) {
288	httpauth_keyvalue_buffer *kvb;
289
290	kvb = calloc(1, sizeof(*kvb));
291
292	return kvb;
293}
294
295int httpauth_keyvalue_buffer_append(httpauth_keyvalue_buffer *kvb, const char *key, const char *realm, httpauth_type type) {
296	size_t i;
297	if (kvb->size == 0) {
298		kvb->size = 4;
299
300		kvb->kv = malloc(kvb->size * sizeof(*kvb->kv));
301
302		for(i = 0; i < kvb->size; i++) {
303			kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
304		}
305	} else if (kvb->used == kvb->size) {
306		kvb->size += 4;
307
308		kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
309
310		for(i = kvb->used; i < kvb->size; i++) {
311			kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
312		}
313	}
314
315	kvb->kv[kvb->used]->key = strdup(key);
316	kvb->kv[kvb->used]->realm = strdup(realm);
317	kvb->kv[kvb->used]->type = type;
318
319	kvb->used++;
320
321	return 0;
322}
323
324void httpauth_keyvalue_buffer_free(httpauth_keyvalue_buffer *kvb) {
325	size_t i;
326
327	for (i = 0; i < kvb->size; i++) {
328		if (kvb->kv[i]->key) free(kvb->kv[i]->key);
329		if (kvb->kv[i]->realm) free(kvb->kv[i]->realm);
330		free(kvb->kv[i]);
331	}
332
333	if (kvb->kv) free(kvb->kv);
334
335	free(kvb);
336}
337
338
339const char *get_http_version_name(int i) {
340	return keyvalue_get_value(http_versions, i);
341}
342
343const char *get_http_status_name(int i) {
344	return keyvalue_get_value(http_status, i);
345}
346
347const char *get_http_method_name(http_method_t i) {
348	return keyvalue_get_value(http_methods, i);
349}
350
351const char *get_http_status_body_name(int i) {
352	return keyvalue_get_value(http_status_body, i);
353}
354
355int get_http_version_key(const char *s) {
356	return keyvalue_get_key(http_versions, s);
357}
358
359http_method_t get_http_method_key(const char *s) {
360	return (http_method_t)keyvalue_get_key(http_methods, s);
361}
362
363
364
365
366pcre_keyvalue_buffer *pcre_keyvalue_buffer_init(void) {
367	pcre_keyvalue_buffer *kvb;
368
369	kvb = calloc(1, sizeof(*kvb));
370
371	return kvb;
372}
373
374int pcre_keyvalue_buffer_append(server *srv, pcre_keyvalue_buffer *kvb, const char *key, const char *value) {
375#ifdef HAVE_PCRE_H
376	size_t i;
377	const char *errptr;
378	int erroff;
379	pcre_keyvalue *kv;
380#endif
381
382	if (!key) return -1;
383
384#ifdef HAVE_PCRE_H
385	if (kvb->size == 0) {
386		kvb->size = 4;
387		kvb->used = 0;
388
389		kvb->kv = malloc(kvb->size * sizeof(*kvb->kv));
390
391		for(i = 0; i < kvb->size; i++) {
392			kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
393		}
394	} else if (kvb->used == kvb->size) {
395		kvb->size += 4;
396
397		kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
398
399		for(i = kvb->used; i < kvb->size; i++) {
400			kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
401		}
402	}
403
404	kv = kvb->kv[kvb->used];
405	if (NULL == (kv->key = pcre_compile(key,
406					  0, &errptr, &erroff, NULL))) {
407
408		log_error_write(srv, __FILE__, __LINE__, "SS",
409			"rexexp compilation error at ", errptr);
410		return -1;
411	}
412
413	if (NULL == (kv->key_extra = pcre_study(kv->key, 0, &errptr)) &&
414			errptr != NULL) {
415		return -1;
416	}
417
418	kv->value = buffer_init_string(value);
419
420	kvb->used++;
421
422	return 0;
423#else
424	UNUSED(kvb);
425	UNUSED(value);
426
427	return -1;
428#endif
429}
430
431void pcre_keyvalue_buffer_free(pcre_keyvalue_buffer *kvb) {
432#ifdef HAVE_PCRE_H
433	size_t i;
434	pcre_keyvalue *kv;
435
436	for (i = 0; i < kvb->size; i++) {
437		kv = kvb->kv[i];
438		if (kv->key) pcre_free(kv->key);
439		if (kv->key_extra) pcre_free(kv->key_extra);
440		if (kv->value) buffer_free(kv->value);
441		free(kv);
442	}
443
444	if (kvb->kv) free(kvb->kv);
445#endif
446
447	free(kvb);
448}
449