From 383f325547f80d0d905ce0f3d8e71ab436b314d1 Mon Sep 17 00:00:00 2001 From: Jianhui Zhao Date: Sun, 12 Nov 2017 19:23:12 +0800 Subject: [PATCH] Optimize code Signed-off-by: Jianhui Zhao --- example/helloworld.c | 2 +- src/uhttp.c | 88 +++++++++++++++++++++++++++++++++++--------- src/uhttp.h | 63 +++++++++++++++++++++++++++++++ src/uhttp_internal.h | 4 +- 4 files changed, 137 insertions(+), 20 deletions(-) diff --git a/example/helloworld.c b/example/helloworld.c index 787db25..5976d5c 100755 --- a/example/helloworld.c +++ b/example/helloworld.c @@ -14,7 +14,7 @@ void route_test(struct uh_connection *con) struct uh_value *header_host = uh_get_header(con, "Host"); struct uh_value *header_ua = uh_get_header(con, "User-Agent"); - uh_send_head(con, 200, -1, NULL); + uh_send_head(con, UH_STATUS_OK, -1, NULL); uh_printf_chunk(con, "

Hello World

"); uh_printf_chunk(con, "

Libuhttp v%s

", uh_version()); uh_printf_chunk(con, "

Url: %.*s

", (int)url->len, url->at); diff --git a/src/uhttp.c b/src/uhttp.c index 32adf2a..f2d5a99 100755 --- a/src/uhttp.c +++ b/src/uhttp.c @@ -13,18 +13,65 @@ static struct { int code; const char *reason; } http_status_message[] = { - {200, "OK"}, - {301, "Moved"}, - {302, "Found"}, - {400, "Bad Request"}, - {401, "Unauthorized"}, - {403, "Forbidden"}, - {404, "Not Found"}, - {500, "Internal Server Error"}, - {501, "Not Implemented"}, - {502, "Bad Gateway"}, - {503, "Service Unavailable"}, - {-1, NULL} + {UH_STATUS_CONTINUE, "Continue"}, + {UH_STATUS_SWITCHING_PROTOCOLS, "Switching Protocols"}, + {UH_STATUS_PROCESSING, "Processing"}, + {UH_STATUS_OK, "OK"}, + {UH_STATUS_CREATED, "Created"}, + {UH_STATUS_ACCEPTED, "Accepted"}, + {UH_STATUS_NON_AUTHORITATIVE_INFORMATION, "Non-Authoritative Information"}, + {UH_STATUS_NO_CONTENT, "No Content"}, + {UH_STATUS_RESET_CONTENT, "Reset Content"}, + {UH_STATUS_PARTIAL_CONTENT, "Partial Content"}, + {UH_STATUS_MULTI_STATUS, "Multi-Status"}, + {UH_STATUS_ALREADY_REPORTED, "Already Reported"}, + {UH_STATUS_IM_USED, "IM Used"}, + {UH_STATUS_MULTIPLE_CHOICES, "Multiple Choices"}, + {UH_STATUS_MOVED_PERMANENTLY, "Moved Permanently"}, + {UH_STATUS_FOUND, "Found"}, + {UH_STATUS_SEE_OTHER, "See Other"}, + {UH_STATUS_NOT_MODIFIED, "Not Modified"}, + {UH_STATUS_USE_PROXY, "Use Proxy"}, + {UH_STATUS_TEMPORARY_REDIRECT, "Temporary Redirect"}, + {UH_STATUS_PERMANENT_REDIRECT, "Permanent Redirect"}, + {UH_STATUS_BAD_REQUEST, "Bad Request"}, + {UH_STATUS_UNAUTHORIZED, "Unauthorized"}, + {UH_STATUS_PAYMENT_REQUIRED, "Payment Required"}, + {UH_STATUS_FORBIDDEN, "Forbidden"}, + {UH_STATUS_NOT_FOUND, "Not Found"}, + {UH_STATUS_METHOD_NOT_ALLOWED, "Method Not Allowed"}, + {UH_STATUS_NOT_ACCEPTABLE, "Not Acceptable"}, + {UH_STATUS_PROXY_AUTHENTICATION_REQUIRED, "Proxy Authentication Required"}, + {UH_STATUS_REQUEST_TIMEOUT, "Request Timeout"}, + {UH_STATUS_CONFLICT, "Conflict"}, + {UH_STATUS_GONE, "Gone"}, + {UH_STATUS_LENGTH_REQUIRED, "Length Required"}, + {UH_STATUS_PRECONDITION_FAILED, "Precondition Failed"}, + {UH_STATUS_PAYLOAD_TOO_LARGE, "Payload Too Large"}, + {UH_STATUS_URI_TOO_LONG, "URI Too Long"}, + {UH_STATUS_UNSUPPORTED_MEDIA_TYPE, "Unsupported Media Type"}, + {UH_STATUS_RANGE_NOT_SATISFIABLE, "Range Not Satisfiable"}, + {UH_STATUS_EXPECTATION_FAILED, "Expectation Failed"}, + {UH_STATUS_MISDIRECTED_REQUEST, "Misdirected Request"}, + {UH_STATUS_UNPROCESSABLE_ENTITY, "Unprocessable Entity"}, + {UH_STATUS_LOCKED, "Locked"}, + {UH_STATUS_FAILED_DEPENDENCY, "Failed Dependency"}, + {UH_STATUS_UPGRADE_REQUIRED, "Upgrade Required"}, + {UH_STATUS_PRECONDITION_REQUIRED, "Precondition Required"}, + {UH_STATUS_TOO_MANY_REQUESTS, "Too Many Requests"}, + {UH_STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE, "Request Header Fields Too Large"}, + {UH_STATUS_UNAVAILABLE_FOR_LEGAL_REASONS, "Unavailable For Legal Reasons"}, + {UH_STATUS_INTERNAL_SERVER_ERROR, "Internal Server Error"}, + {UH_STATUS_NOT_IMPLEMENTED, "Not Implemented"}, + {UH_STATUS_BAD_GATEWAY, "Bad Gateway"}, + {UH_STATUS_SERVICE_UNAVAILABLE, "Service Unavailable"}, + {UH_STATUS_GATEWAY_TIMEOUT, "Gateway Timeout"}, + {UH_STATUS_HTTP_VERSION_NOT_SUPPORTED, "HTTP Version Not Supported"}, + {UH_STATUS_VARIANT_ALSO_NEGOTIATES, "Variant Also Negotiates"}, + {UH_STATUS_INSUFFICIENT_STORAGE, "Insufficient Storage"}, + {UH_STATUS_LOOP_DETECTED, "Loop Detected"}, + {UH_STATUS_NOT_EXTENDED, "Not Extended"}, + {UH_STATUS_NETWORK_AUTHENTICATION_REQUIRED, "Network Authentication Required"} }; const char *uh_version() @@ -70,6 +117,7 @@ static void connection_timeout_cb(struct ev_loop *loop, ev_timer *w, int revents { struct uh_connection *con = container_of(w, struct uh_connection, timer_watcher); uh_log_info("connection(%p) timeout", con); + uh_send_error(con, UH_STATUS_REQUEST_TIMEOUT, NULL); uh_connection_destroy(con); } @@ -161,7 +209,7 @@ static int on_message_complete(http_parser *parser) } } - uh_send_error(con, 404, NULL); + uh_send_error(con, UH_STATUS_NOT_FOUND, NULL); return 0; } @@ -214,19 +262,23 @@ handshake_done: #endif if (!(con->flags & UH_CON_PARSERING)) { - if (!memmem(buf->base, buf->len, "\r\n\r\n", 4)) + if (!memmem(buf->base, buf->len, "\r\n\r\n", 4)) { + if (buf->len > UH_MAX_HTTP_HEAD_SIZE) { + uh_log_err("HTTP head size too big"); + uh_send_error(con, UH_STATUS_BAD_REQUEST, NULL); + } return; - - con->flags |= UH_CON_PARSERING; + } base = buf->base; len = buf->len; + con->flags |= UH_CON_PARSERING; } parsered = http_parser_execute(&con->parser, &parser_settings, base, len); if (unlikely(parsered != len)){ uh_log_err("http parser failed:%s", http_errno_description(HTTP_PARSER_ERRNO(&con->parser))); - uh_send_error(con, 400, NULL); + uh_send_error(con, UH_STATUS_BAD_REQUEST, NULL); } else { ev_timer_mode(loop, &con->timer_watcher, UH_CONNECTION_TIMEOUT, 0); } @@ -435,7 +487,7 @@ void uh_send_error(struct uh_connection *con, int code, const char *reason) if (!reason) reason = get_http_status_message(code); - if (http_should_keep_alive(parser) && code < 400) { + if (http_should_keep_alive(parser) && code < UH_STATUS_BAD_REQUEST) { uh_send_head(con, code, strlen(reason), "Content-Type: text/plain\r\nConnection: keep-alive\r\n"); } else { uh_send_head(con, code, strlen(reason), "Content-Type: text/plain\r\nConnection: close\r\n"); diff --git a/src/uhttp.h b/src/uhttp.h index ec04cc6..33f7136 100755 --- a/src/uhttp.h +++ b/src/uhttp.h @@ -6,6 +6,69 @@ #include "uhttp_log.h" #include "uhttp_buf.h" +/* HTTP Status Codes */ +enum uh_status { + UH_STATUS_CONTINUE = 100, + UH_STATUS_SWITCHING_PROTOCOLS = 101, + UH_STATUS_PROCESSING = 102, + UH_STATUS_OK = 200, + UH_STATUS_CREATED = 201, + UH_STATUS_ACCEPTED = 202, + UH_STATUS_NON_AUTHORITATIVE_INFORMATION = 203, + UH_STATUS_NO_CONTENT = 204, + UH_STATUS_RESET_CONTENT = 205, + UH_STATUS_PARTIAL_CONTENT = 206, + UH_STATUS_MULTI_STATUS = 207, + UH_STATUS_ALREADY_REPORTED = 208, + UH_STATUS_IM_USED = 226, + UH_STATUS_MULTIPLE_CHOICES = 300, + UH_STATUS_MOVED_PERMANENTLY = 301, + UH_STATUS_FOUND = 302, + UH_STATUS_SEE_OTHER = 303, + UH_STATUS_NOT_MODIFIED = 304, + UH_STATUS_USE_PROXY = 305, + UH_STATUS_TEMPORARY_REDIRECT = 307, + UH_STATUS_PERMANENT_REDIRECT = 308, + UH_STATUS_BAD_REQUEST = 400, + UH_STATUS_UNAUTHORIZED = 401, + UH_STATUS_PAYMENT_REQUIRED = 402, + UH_STATUS_FORBIDDEN = 403, + UH_STATUS_NOT_FOUND = 404, + UH_STATUS_METHOD_NOT_ALLOWED = 405, + UH_STATUS_NOT_ACCEPTABLE = 406, + UH_STATUS_PROXY_AUTHENTICATION_REQUIRED = 407, + UH_STATUS_REQUEST_TIMEOUT = 408, + UH_STATUS_CONFLICT = 409, + UH_STATUS_GONE = 410, + UH_STATUS_LENGTH_REQUIRED = 411, + UH_STATUS_PRECONDITION_FAILED = 412, + UH_STATUS_PAYLOAD_TOO_LARGE = 413, + UH_STATUS_URI_TOO_LONG = 414, + UH_STATUS_UNSUPPORTED_MEDIA_TYPE = 415, + UH_STATUS_RANGE_NOT_SATISFIABLE = 416, + UH_STATUS_EXPECTATION_FAILED = 417, + UH_STATUS_MISDIRECTED_REQUEST = 421, + UH_STATUS_UNPROCESSABLE_ENTITY = 422, + UH_STATUS_LOCKED = 423, + UH_STATUS_FAILED_DEPENDENCY = 424, + UH_STATUS_UPGRADE_REQUIRED = 426, + UH_STATUS_PRECONDITION_REQUIRED = 428, + UH_STATUS_TOO_MANY_REQUESTS = 429, + UH_STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE = 431, + UH_STATUS_UNAVAILABLE_FOR_LEGAL_REASONS = 451, + UH_STATUS_INTERNAL_SERVER_ERROR = 500, + UH_STATUS_NOT_IMPLEMENTED = 501, + UH_STATUS_BAD_GATEWAY = 502, + UH_STATUS_SERVICE_UNAVAILABLE = 503, + UH_STATUS_GATEWAY_TIMEOUT = 504, + UH_STATUS_HTTP_VERSION_NOT_SUPPORTED = 505, + UH_STATUS_VARIANT_ALSO_NEGOTIATES = 506, + UH_STATUS_INSUFFICIENT_STORAGE = 507, + UH_STATUS_LOOP_DETECTED = 508, + UH_STATUS_NOT_EXTENDED = 510, + UH_STATUS_NETWORK_AUTHENTICATION_REQUIRED = 511 +}; + struct uh_server; struct uh_connection; diff --git a/src/uhttp_internal.h b/src/uhttp_internal.h index 199e745..90bdc14 100755 --- a/src/uhttp_internal.h +++ b/src/uhttp_internal.h @@ -8,6 +8,8 @@ #define UH_BUFFER_SIZE 2048 #define UH_CONNECTION_TIMEOUT 30 +#define UH_MAX_HTTP_HEAD_SIZE 1024 +#define UH_MAX_HTTP_BODY_SIZE (2 * 1024 * 1024) #define UH_MAX_HTTP_HEADERS 20 #define UH_CON_CLOSE (1 << 0) @@ -69,4 +71,4 @@ struct uh_connection { struct uh_server *srv; }; -#endif \ No newline at end of file +#endif