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>