Annotation of embedaddon/lighttpd/src/keyvalue.c, revision 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>