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