File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / lighttpd / src / keyvalue.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:35:00 2016 UTC (7 years, 8 months ago) by misho
Branches: lighttpd, MAIN
CVS tags: v1_4_41p8, HEAD
lighttpd 1.4.41

    1: #include "first.h"
    2: 
    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));
  177: 	force_assert(NULL != kvb);
  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));
  198: 		force_assert(NULL != kvb->kv);
  199: 
  200: 		for(i = 0; i < kvb->size; i++) {
  201: 			kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
  202: 			force_assert(NULL != kvb->kv[i]);
  203: 		}
  204: 	} else if (kvb->used == kvb->size) {
  205: 		kvb->size += 4;
  206: 
  207: 		kvb->kv = realloc(kvb->kv, kvb->size * sizeof(*kvb->kv));
  208: 		force_assert(NULL != kvb->kv);
  209: 
  210: 		for(i = kvb->used; i < kvb->size; i++) {
  211: 			kvb->kv[i] = calloc(1, sizeof(**kvb->kv));
  212: 			force_assert(NULL != kvb->kv[i]);
  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>