Annotation of embedaddon/lighttpd/src/keyvalue.c, revision 1.1.1.2
1.1.1.2 ! misho 1: #include "first.h"
! 2:
1.1 misho 3: #include "server.h"
4: #include "keyvalue.h"
5: #include "log.h"
6:
7: #include <stdlib.h>
8: #include <string.h>
9: #include <stdio.h>
10:
11: static keyvalue http_versions[] = {
12: { HTTP_VERSION_1_1, "HTTP/1.1" },
13: { HTTP_VERSION_1_0, "HTTP/1.0" },
14: { HTTP_VERSION_UNSET, NULL }
15: };
16:
17: static keyvalue http_methods[] = {
18: { HTTP_METHOD_GET, "GET" },
19: { HTTP_METHOD_HEAD, "HEAD" },
20: { HTTP_METHOD_POST, "POST" },
21: { HTTP_METHOD_PUT, "PUT" },
22: { HTTP_METHOD_DELETE, "DELETE" },
23: { HTTP_METHOD_CONNECT, "CONNECT" },
24: { HTTP_METHOD_OPTIONS, "OPTIONS" },
25: { HTTP_METHOD_TRACE, "TRACE" },
26: { HTTP_METHOD_ACL, "ACL" },
27: { HTTP_METHOD_BASELINE_CONTROL, "BASELINE-CONTROL" },
28: { HTTP_METHOD_BIND, "BIND" },
29: { HTTP_METHOD_CHECKIN, "CHECKIN" },
30: { HTTP_METHOD_CHECKOUT, "CHECKOUT" },
31: { HTTP_METHOD_COPY, "COPY" },
32: { HTTP_METHOD_LABEL, "LABEL" },
33: { HTTP_METHOD_LINK, "LINK" },
34: { HTTP_METHOD_LOCK, "LOCK" },
35: { HTTP_METHOD_MERGE, "MERGE" },
36: { HTTP_METHOD_MKACTIVITY, "MKACTIVITY" },
37: { HTTP_METHOD_MKCALENDAR, "MKCALENDAR" },
38: { HTTP_METHOD_MKCOL, "MKCOL" },
39: { HTTP_METHOD_MKREDIRECTREF, "MKREDIRECTREF" },
40: { HTTP_METHOD_MKWORKSPACE, "MKWORKSPACE" },
41: { HTTP_METHOD_MOVE, "MOVE" },
42: { HTTP_METHOD_ORDERPATCH, "ORDERPATCH" },
43: { HTTP_METHOD_PATCH, "PATCH" },
44: { HTTP_METHOD_PROPFIND, "PROPFIND" },
45: { HTTP_METHOD_PROPPATCH, "PROPPATCH" },
46: { HTTP_METHOD_REBIND, "REBIND" },
47: { HTTP_METHOD_REPORT, "REPORT" },
48: { HTTP_METHOD_SEARCH, "SEARCH" },
49: { HTTP_METHOD_UNBIND, "UNBIND" },
50: { HTTP_METHOD_UNCHECKOUT, "UNCHECKOUT" },
51: { HTTP_METHOD_UNLINK, "UNLINK" },
52: { HTTP_METHOD_UNLOCK, "UNLOCK" },
53: { HTTP_METHOD_UPDATE, "UPDATE" },
54: { HTTP_METHOD_UPDATEREDIRECTREF, "UPDATEREDIRECTREF" },
55: { HTTP_METHOD_VERSION_CONTROL, "VERSION-CONTROL" },
56:
57: { HTTP_METHOD_UNSET, NULL }
58: };
59:
60: static keyvalue http_status[] = {
61: { 100, "Continue" },
62: { 101, "Switching Protocols" },
63: { 102, "Processing" }, /* WebDAV */
64: { 200, "OK" },
65: { 201, "Created" },
66: { 202, "Accepted" },
67: { 203, "Non-Authoritative Information" },
68: { 204, "No Content" },
69: { 205, "Reset Content" },
70: { 206, "Partial Content" },
71: { 207, "Multi-status" }, /* WebDAV */
72: { 300, "Multiple Choices" },
73: { 301, "Moved Permanently" },
74: { 302, "Found" },
75: { 303, "See Other" },
76: { 304, "Not Modified" },
77: { 305, "Use Proxy" },
78: { 306, "(Unused)" },
79: { 307, "Temporary Redirect" },
80: { 400, "Bad Request" },
81: { 401, "Unauthorized" },
82: { 402, "Payment Required" },
83: { 403, "Forbidden" },
84: { 404, "Not Found" },
85: { 405, "Method Not Allowed" },
86: { 406, "Not Acceptable" },
87: { 407, "Proxy Authentication Required" },
88: { 408, "Request Timeout" },
89: { 409, "Conflict" },
90: { 410, "Gone" },
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 */
109:
110: { -1, NULL }
111: };
112:
113: static keyvalue http_status_body[] = {
114: { 400, "400.html" },
115: { 401, "401.html" },
116: { 403, "403.html" },
117: { 404, "404.html" },
118: { 411, "411.html" },
119: { 416, "416.html" },
120: { 500, "500.html" },
121: { 501, "501.html" },
122: { 503, "503.html" },
123: { 505, "505.html" },
124:
125: { -1, NULL }
126: };
127:
128:
129: const char *keyvalue_get_value(keyvalue *kv, int k) {
130: int i;
131: for (i = 0; kv[i].value; i++) {
132: if (kv[i].key == k) return kv[i].value;
133: }
134: return NULL;
135: }
136:
137: int keyvalue_get_key(keyvalue *kv, const char *s) {
138: int i;
139: for (i = 0; kv[i].value; i++) {
140: if (0 == strcmp(kv[i].value, s)) return kv[i].key;
141: }
142: return -1;
143: }
144:
145:
146: const char *get_http_version_name(int i) {
147: return keyvalue_get_value(http_versions, i);
148: }
149:
150: const char *get_http_status_name(int i) {
151: return keyvalue_get_value(http_status, i);
152: }
153:
154: const char *get_http_method_name(http_method_t i) {
155: return keyvalue_get_value(http_methods, i);
156: }
157:
158: const char *get_http_status_body_name(int i) {
159: return keyvalue_get_value(http_status_body, i);
160: }
161:
162: int get_http_version_key(const char *s) {
163: return keyvalue_get_key(http_versions, s);
164: }
165:
166: http_method_t get_http_method_key(const char *s) {
167: return (http_method_t)keyvalue_get_key(http_methods, s);
168: }
169:
170:
171:
172:
173: pcre_keyvalue_buffer *pcre_keyvalue_buffer_init(void) {
174: pcre_keyvalue_buffer *kvb;
175:
176: kvb = calloc(1, sizeof(*kvb));
1.1.1.2 ! misho 177: force_assert(NULL != kvb);
1.1 misho 178:
179: return kvb;
180: }
181:
182: int pcre_keyvalue_buffer_append(server *srv, pcre_keyvalue_buffer *kvb, const char *key, const char *value) {
183: #ifdef HAVE_PCRE_H
184: size_t i;
185: const char *errptr;
186: int erroff;
187: pcre_keyvalue *kv;
188: #endif
189:
190: if (!key) return -1;
191:
192: #ifdef HAVE_PCRE_H
193: if (kvb->size == 0) {
194: kvb->size = 4;
195: kvb->used = 0;
196:
197: kvb->kv = malloc(kvb->size * sizeof(*kvb->kv));
1.1.1.2 ! misho 198: force_assert(NULL != kvb->kv);
1.1 misho 199:
200: for(i = 0; i < kvb->size; i++) {
201: kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
1.1.1.2 ! misho 202: force_assert(NULL != kvb->kv[i]);
1.1 misho 203: }
204: } else if (kvb->used == kvb->size) {
205: kvb->size += 4;
206:
207: kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
1.1.1.2 ! misho 208: force_assert(NULL != kvb->kv);
1.1 misho 209:
210: for(i = kvb->used; i < kvb->size; i++) {
211: kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
1.1.1.2 ! misho 212: force_assert(NULL != kvb->kv[i]);
1.1 misho 213: }
214: }
215:
216: kv = kvb->kv[kvb->used];
217: if (NULL == (kv->key = pcre_compile(key,
218: 0, &errptr, &erroff, NULL))) {
219:
220: log_error_write(srv, __FILE__, __LINE__, "SS",
221: "rexexp compilation error at ", errptr);
222: return -1;
223: }
224:
225: if (NULL == (kv->key_extra = pcre_study(kv->key, 0, &errptr)) &&
226: errptr != NULL) {
227: return -1;
228: }
229:
230: kv->value = buffer_init_string(value);
231:
232: kvb->used++;
233:
234: return 0;
235: #else
236: UNUSED(kvb);
237: UNUSED(value);
238:
239: return -1;
240: #endif
241: }
242:
243: void pcre_keyvalue_buffer_free(pcre_keyvalue_buffer *kvb) {
244: #ifdef HAVE_PCRE_H
245: size_t i;
246: pcre_keyvalue *kv;
247:
248: for (i = 0; i < kvb->size; i++) {
249: kv = kvb->kv[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);
253: free(kv);
254: }
255:
256: if (kvb->kv) free(kvb->kv);
257: #endif
258:
259: free(kvb);
260: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>