From ee31e3f1faf9d0be256c7c59a092cb56e72a2102 Mon Sep 17 00:00:00 2001 From: Jianhui Zhao Date: Mon, 13 Nov 2017 20:51:42 +0800 Subject: [PATCH] In order to be compatible with different editor, convert all Tab to spaces Signed-off-by: Jianhui Zhao --- example/helloworld.c | 86 ++--- src/uhttp.c | 820 +++++++++++++++++++++--------------------- src/uhttp.h | 128 +++---- src/uhttp_buf.c | 72 ++-- src/uhttp_buf.h | 6 +- src/uhttp_config.h.in | 6 +- src/uhttp_internal.h | 80 ++--- src/uhttp_log.c | 32 +- src/uhttp_log.h | 6 +- src/uhttp_ssl.c | 256 ++++++------- src/uhttp_ssl.h | 2 +- 11 files changed, 747 insertions(+), 747 deletions(-) diff --git a/example/helloworld.c b/example/helloworld.c index 5976d5c..3d65237 100755 --- a/example/helloworld.c +++ b/example/helloworld.c @@ -4,67 +4,67 @@ static void signal_cb(struct ev_loop *loop, ev_signal *w, int revents) { - printf("Got signal: %d\n", w->signum); - ev_break(loop, EVBREAK_ALL); + printf("Got signal: %d\n", w->signum); + ev_break(loop, EVBREAK_ALL); } void route_test(struct uh_connection *con) { - struct uh_value *url = uh_get_url(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, 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); + struct uh_value *url = uh_get_url(con); + struct uh_value *header_host = uh_get_header(con, "Host"); + struct uh_value *header_ua = uh_get_header(con, "User-Agent"); - if (header_host) - uh_printf_chunk(con, "

Host: %.*s

", (int)header_host->len, header_host->at); + 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); - if (header_ua) - uh_printf_chunk(con, "

User-Agent: %.*s

", (int)header_ua->len, header_ua->at); - - uh_send_chunk(con, NULL, 0); + if (header_host) + uh_printf_chunk(con, "

Host: %.*s

", (int)header_host->len, header_host->at); + + if (header_ua) + uh_printf_chunk(con, "

User-Agent: %.*s

", (int)header_ua->len, header_ua->at); + + uh_send_chunk(con, NULL, 0); } int main(int argc, char **argv) { - struct ev_loop *loop = EV_DEFAULT; - ev_signal *sig_watcher = NULL; - struct uh_server *srv = NULL; + struct ev_loop *loop = EV_DEFAULT; + ev_signal *sig_watcher = NULL; + struct uh_server *srv = NULL; - uh_log_info("libuhttp version: %s\n", uh_version()); + uh_log_info("libuhttp version: %s\n", uh_version()); - sig_watcher = calloc(1, sizeof(ev_signal)); - if (!sig_watcher) - return -1; - - ev_signal_init(sig_watcher, signal_cb, SIGINT); - ev_signal_start(loop, sig_watcher); + sig_watcher = calloc(1, sizeof(ev_signal)); + if (!sig_watcher) + return -1; + + ev_signal_init(sig_watcher, signal_cb, SIGINT); + ev_signal_start(loop, sig_watcher); - srv = uh_server_new(loop, "0.0.0.0", 8000); - if (!srv) { - uh_log_err("uh_server_new failed\n"); - goto err; - } + srv = uh_server_new(loop, "0.0.0.0", 8000); + if (!srv) { + uh_log_err("uh_server_new failed\n"); + goto err; + } #if (UHTTP_SSL_ENABLED) - if (uh_ssl_init(srv, "server-cert.pem", "server-key.pem") < 0) - goto err; + if (uh_ssl_init(srv, "server-cert.pem", "server-key.pem") < 0) + goto err; #endif - uh_register_route(srv, "/test", route_test); - - uh_log_info("Listen on 8000...\n"); - - ev_run(loop, 0); - + uh_register_route(srv, "/test", route_test); + + uh_log_info("Listen on 8000...\n"); + + ev_run(loop, 0); + err: - free(sig_watcher); - uh_server_free(srv); - - return 0; + free(sig_watcher); + uh_server_free(srv); + + return 0; } diff --git a/src/uhttp.c b/src/uhttp.c index 6983601..0fc14c6 100755 --- a/src/uhttp.c +++ b/src/uhttp.c @@ -10,178 +10,178 @@ #include "uhttp_ssl.h" static struct { - int code; - const char *reason; + int code; + const char *reason; } http_status_message[] = { - {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"} + {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() { - return UHTTP_VERSION_STRING; + return UHTTP_VERSION_STRING; } static const char *get_http_status_message(int code) { - int i; - const char *reason = "OK"; + int i; + const char *reason = "OK"; - for (i = 0; http_status_message[i].reason; i++) { - if (code == http_status_message[i].code) - reason = http_status_message[i].reason; - } - return reason; + for (i = 0; http_status_message[i].reason; i++) { + if (code == http_status_message[i].code) + reason = http_status_message[i].reason; + } + return reason; } static void uh_connection_destroy(struct uh_connection *con) { - if (con) { - struct ev_loop *loop = con->srv->loop; - - if (con->sock > 0) - close(con->sock); - - uh_buf_free(&con->read_buf); - uh_buf_free(&con->write_buf); - - ev_io_stop(loop, &con->read_watcher); - ev_io_stop(loop, &con->write_watcher); - ev_timer_stop(loop, &con->timer_watcher); + if (con) { + struct ev_loop *loop = con->srv->loop; + + if (con->sock > 0) + close(con->sock); + + uh_buf_free(&con->read_buf); + uh_buf_free(&con->write_buf); + + ev_io_stop(loop, &con->read_watcher); + ev_io_stop(loop, &con->write_watcher); + ev_timer_stop(loop, &con->timer_watcher); - list_del(&con->list); + list_del(&con->list); - uh_ssl_free(con); - free(con); - } + uh_ssl_free(con); + free(con); + } } 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); + 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); } static int on_message_begin(http_parser *parser) { - struct uh_connection *con = container_of(parser, struct uh_connection, parser); + struct uh_connection *con = container_of(parser, struct uh_connection, parser); - memset(&con->req, 0, sizeof(struct uh_request)); - - return 0; + memset(&con->req, 0, sizeof(struct uh_request)); + + return 0; } static int on_url(http_parser *parser, const char *at, size_t len) { - struct uh_connection *con = container_of(parser, struct uh_connection, parser); - - con->req.url.at = at; - con->req.url.len = len; - + struct uh_connection *con = container_of(parser, struct uh_connection, parser); + + con->req.url.at = at; + con->req.url.len = len; + return 0; } static int on_header_field(http_parser *parser, const char *at, size_t len) { - struct uh_connection *con = container_of(parser, struct uh_connection, parser); - struct uh_header *header = con->req.header; + struct uh_connection *con = container_of(parser, struct uh_connection, parser); + struct uh_header *header = con->req.header; - header[con->req.header_num].field.at = at; - header[con->req.header_num].field.len = len; - + header[con->req.header_num].field.at = at; + header[con->req.header_num].field.len = len; + return 0; } static int on_header_value(http_parser *parser, const char *at, size_t len) { - struct uh_connection *con = container_of(parser, struct uh_connection, parser); - struct uh_header *header = con->req.header; - - header[con->req.header_num].value.at = at; - header[con->req.header_num].value.len = len; - con->req.header_num += 1; - + struct uh_connection *con = container_of(parser, struct uh_connection, parser); + struct uh_header *header = con->req.header; + + header[con->req.header_num].value.at = at; + header[con->req.header_num].value.len = len; + con->req.header_num += 1; + return 0; } static int on_headers_complete(http_parser *parser) { - struct uh_connection *con = container_of(parser, struct uh_connection, parser); - - if (parser->method != HTTP_GET && parser->method != HTTP_POST) { - uh_send_error(con, UH_STATUS_METHOD_NOT_ALLOWED, NULL); - return -1; - } - return 0; + struct uh_connection *con = container_of(parser, struct uh_connection, parser); + + if (parser->method != HTTP_GET && parser->method != HTTP_POST) { + uh_send_error(con, UH_STATUS_METHOD_NOT_ALLOWED, NULL); + return -1; + } + return 0; } static int on_body(http_parser *parser, const char *at, size_t len) { - struct uh_connection *con = container_of(parser, struct uh_connection, parser); - - if (!con->req.body.at) - con->req.body.at = at; + struct uh_connection *con = container_of(parser, struct uh_connection, parser); + + if (!con->req.body.at) + con->req.body.at = at; - con->req.body.len += len; + con->req.body.len += len; return 0; } @@ -189,415 +189,415 @@ static int on_body(http_parser *parser, const char *at, size_t len) /* Return 1 for equal */ static int uh_value_cmp(struct uh_value *uv, const char *str) { - if (uv->len != strlen(str)) - return 0; + if (uv->len != strlen(str)) + return 0; - return (!strncasecmp(uv->at, str, uv->len)); + return (!strncasecmp(uv->at, str, uv->len)); } static int on_message_complete(http_parser *parser) { - struct uh_connection *con = container_of(parser, struct uh_connection, parser); - struct uh_route *r; + struct uh_connection *con = container_of(parser, struct uh_connection, parser); + struct uh_route *r; #if (UHTTP_DEBUG) - int i; - struct uh_header *header = con->req.header; - - uh_log_debug("Url:[%.*s]\n", (int)con->req.url.len, con->req.url.at); - - for (i = 0; i < con->req.header_num; i++) { - uh_log_debug("[%.*s:%.*s]\n", (int)header[i].field.len, header[i].field.at, - (int)header[i].value.len, header[i].value.at); - } + int i; + struct uh_header *header = con->req.header; + + uh_log_debug("Url:[%.*s]\n", (int)con->req.url.len, con->req.url.at); + + for (i = 0; i < con->req.header_num; i++) { + uh_log_debug("[%.*s:%.*s]\n", (int)header[i].field.len, header[i].field.at, + (int)header[i].value.len, header[i].value.at); + } - uh_log_debug("Body:[%.*s]\n", (int)con->req.body.len, con->req.body.at); + uh_log_debug("Body:[%.*s]\n", (int)con->req.body.len, con->req.body.at); #endif - list_for_each_entry(r, &con->srv->routes, list) { - if (uh_value_cmp(&con->req.url, r->path)) { - r->cb(con); - return 0; - } - } + list_for_each_entry(r, &con->srv->routes, list) { + if (uh_value_cmp(&con->req.url, r->path)) { + r->cb(con); + return 0; + } + } - uh_send_error(con, UH_STATUS_NOT_FOUND, NULL); - - return 0; + uh_send_error(con, UH_STATUS_NOT_FOUND, NULL); + + return 0; } static http_parser_settings parser_settings = { - .on_message_begin = on_message_begin, - .on_url = on_url, - .on_header_field = on_header_field, - .on_header_value = on_header_value, - .on_headers_complete = on_headers_complete, - .on_body = on_body, - .on_message_complete = on_message_complete + .on_message_begin = on_message_begin, + .on_url = on_url, + .on_header_field = on_header_field, + .on_header_value = on_header_value, + .on_headers_complete = on_headers_complete, + .on_body = on_body, + .on_message_complete = on_message_complete }; static void connection_read_cb(struct ev_loop *loop, ev_io *w, int revents) { - struct uh_connection *con = container_of(w, struct uh_connection, read_watcher); - struct uh_buf *buf = &con->read_buf; - char *base; - int len, parsered; - + struct uh_connection *con = container_of(w, struct uh_connection, read_watcher); + struct uh_buf *buf = &con->read_buf; + char *base; + int len, parsered; + #if (UHTTP_SSL_ENABLED) - if (con->flags & UH_CON_SSL_HANDSHAKE_DONE) - goto handshake_done; + if (con->flags & UH_CON_SSL_HANDSHAKE_DONE) + goto handshake_done; - uh_ssl_handshake(con); - if (con->flags & UH_CON_CLOSE) - uh_connection_destroy(con); - return; - + uh_ssl_handshake(con); + if (con->flags & UH_CON_CLOSE) + uh_connection_destroy(con); + return; + handshake_done: #endif - if (uh_buf_available(buf) < UH_BUFFER_SIZE) - uh_buf_grow(buf, UH_BUFFER_SIZE); + if (uh_buf_available(buf) < UH_BUFFER_SIZE) + uh_buf_grow(buf, UH_BUFFER_SIZE); - base = buf->base + buf->len; - - len = uh_ssl_read(con, base, UH_BUFFER_SIZE); - if (unlikely(len <= 0)) { - if (con->flags & UH_CON_CLOSE) - uh_connection_destroy(con); - return; - } + base = buf->base + buf->len; + + len = uh_ssl_read(con, base, UH_BUFFER_SIZE); + if (unlikely(len <= 0)) { + if (con->flags & UH_CON_CLOSE) + uh_connection_destroy(con); + return; + } - buf->len += len; + buf->len += len; #if (UHTTP_DEBUG) - uh_log_debug("read:[%.*s]\n", len, base); + uh_log_debug("read:[%.*s]\n", len, base); #endif - if (!(con->flags & UH_CON_PARSERING)) { - 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; - } - - base = buf->base; - len = buf->len; - con->flags |= UH_CON_PARSERING; - } + if (!(con->flags & UH_CON_PARSERING)) { + 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; + } + + 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 && !(con->flags & UH_CON_CLOSE))) { - uh_log_err("http parser failed:%s", http_errno_description(HTTP_PARSER_ERRNO(&con->parser))); - uh_send_error(con, UH_STATUS_BAD_REQUEST, NULL); - } else { - ev_timer_mode(loop, &con->timer_watcher, UH_CONNECTION_TIMEOUT, 0); - } + parsered = http_parser_execute(&con->parser, &parser_settings, base, len); + if (unlikely(parsered != len && !(con->flags & UH_CON_CLOSE))) { + uh_log_err("http parser failed:%s", http_errno_description(HTTP_PARSER_ERRNO(&con->parser))); + uh_send_error(con, UH_STATUS_BAD_REQUEST, NULL); + } else { + ev_timer_mode(loop, &con->timer_watcher, UH_CONNECTION_TIMEOUT, 0); + } } static void connection_write_cb(struct ev_loop *loop, ev_io *w, int revents) { - struct uh_connection *con = container_of(w, struct uh_connection, write_watcher); - struct uh_buf *buf = &con->write_buf; - - if (buf->len > 0) { - int len = uh_ssl_write(con, buf->base, buf->len); - if (len > 0) - uh_buf_remove(buf, len); - } + struct uh_connection *con = container_of(w, struct uh_connection, write_watcher); + struct uh_buf *buf = &con->write_buf; + + if (buf->len > 0) { + int len = uh_ssl_write(con, buf->base, buf->len); + if (len > 0) + uh_buf_remove(buf, len); + } - if (buf->len == 0) { - ev_io_stop(loop, w); + if (buf->len == 0) { + ev_io_stop(loop, w); - if (!http_should_keep_alive(&con->parser)) - con->flags |= UH_CON_CLOSE; - } + if (!http_should_keep_alive(&con->parser)) + con->flags |= UH_CON_CLOSE; + } - if (con->flags & UH_CON_CLOSE) - uh_connection_destroy(con); + if (con->flags & UH_CON_CLOSE) + uh_connection_destroy(con); } static void uh_accept_cb(struct ev_loop *loop, ev_io *w, int revents) { - int sock = -1; - struct uh_server *srv = container_of(w, struct uh_server, read_watcher); - struct uh_connection *con = NULL; - ev_io *read_watcher, *write_watcher; - ev_timer *timer_watcher; - - con = calloc(1, sizeof(struct uh_connection)); - if (unlikely(!con)) { - uh_log_err("calloc"); - return; - } + int sock = -1; + struct uh_server *srv = container_of(w, struct uh_server, read_watcher); + struct uh_connection *con = NULL; + ev_io *read_watcher, *write_watcher; + ev_timer *timer_watcher; + + con = calloc(1, sizeof(struct uh_connection)); + if (unlikely(!con)) { + uh_log_err("calloc"); + return; + } - con->srv = srv; - list_add(&con->list, &srv->connections); - - sock = uh_ssl_accept(con); - if (unlikely(sock < 0)) - goto err; + con->srv = srv; + list_add(&con->list, &srv->connections); + + sock = uh_ssl_accept(con); + if (unlikely(sock < 0)) + goto err; - read_watcher = &con->read_watcher; - ev_io_init(read_watcher, connection_read_cb, sock, EV_READ); - ev_io_start(loop,read_watcher); + read_watcher = &con->read_watcher; + ev_io_init(read_watcher, connection_read_cb, sock, EV_READ); + ev_io_start(loop,read_watcher); - write_watcher = &con->write_watcher; - ev_io_init(write_watcher, connection_write_cb, sock, EV_WRITE); + write_watcher = &con->write_watcher; + ev_io_init(write_watcher, connection_write_cb, sock, EV_WRITE); - timer_watcher = &con->timer_watcher; - ev_timer_init(timer_watcher, connection_timeout_cb, UH_CONNECTION_TIMEOUT, 0); - ev_timer_start(loop, timer_watcher); - - http_parser_init(&con->parser, HTTP_REQUEST); - - uh_log_info("new connection:%p", con); - return; + timer_watcher = &con->timer_watcher; + ev_timer_init(timer_watcher, connection_timeout_cb, UH_CONNECTION_TIMEOUT, 0); + ev_timer_start(loop, timer_watcher); + + http_parser_init(&con->parser, HTTP_REQUEST); + + uh_log_info("new connection:%p", con); + return; err: - uh_connection_destroy(con); + uh_connection_destroy(con); } struct uh_server *uh_server_new(struct ev_loop *loop, const char *ipaddr, int port) { - struct uh_server *srv = NULL; - struct sockaddr_in addr; - int sock = -1, on = 1; - ev_io *read_watcher; - - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - - if (inet_pton(AF_INET, ipaddr, &addr.sin_addr) <= 0) { - uh_log_err("invalid ipaddr"); - return NULL; - } - - srv = calloc(1, sizeof(struct uh_server)); - if (!srv) { - uh_log_err("calloc"); - return NULL; - } + struct uh_server *srv = NULL; + struct sockaddr_in addr; + int sock = -1, on = 1; + ev_io *read_watcher; + + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + + if (inet_pton(AF_INET, ipaddr, &addr.sin_addr) <= 0) { + uh_log_err("invalid ipaddr"); + return NULL; + } + + srv = calloc(1, sizeof(struct uh_server)); + if (!srv) { + uh_log_err("calloc"); + return NULL; + } - INIT_LIST_HEAD(&srv->routes); - INIT_LIST_HEAD(&srv->connections); - - sock = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0); - if (sock < 0) { - uh_log_err("socket"); - goto err; - } + INIT_LIST_HEAD(&srv->routes); + INIT_LIST_HEAD(&srv->connections); + + sock = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0); + if (sock < 0) { + uh_log_err("socket"); + goto err; + } - srv->sock = sock; - srv->loop = loop; - - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + srv->sock = sock; + srv->loop = loop; + + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); - if (bind(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) { - uh_log_err("bind"); - goto err; - } + if (bind(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) { + uh_log_err("bind"); + goto err; + } - if (listen(sock, SOMAXCONN) < 0) { - uh_log_err("listen"); - goto err; - } + if (listen(sock, SOMAXCONN) < 0) { + uh_log_err("listen"); + goto err; + } - read_watcher = &srv->read_watcher; - ev_io_init(read_watcher, uh_accept_cb, sock, EV_READ); - ev_io_start(loop, read_watcher); - - return srv; + read_watcher = &srv->read_watcher; + ev_io_init(read_watcher, uh_accept_cb, sock, EV_READ); + ev_io_start(loop, read_watcher); + + return srv; err: - uh_server_free(srv); - return NULL; + uh_server_free(srv); + return NULL; } void uh_server_free(struct uh_server *srv) { - if (srv) { - struct uh_connection *con, *tmp_c; - struct uh_route *r, *tmp_r; - - if (srv->sock > 0) - close(srv->sock); - - ev_io_stop(srv->loop, &srv->read_watcher); - - list_for_each_entry_safe(con, tmp_c, &srv->connections, list) { - uh_connection_destroy(con); - } + if (srv) { + struct uh_connection *con, *tmp_c; + struct uh_route *r, *tmp_r; + + if (srv->sock > 0) + close(srv->sock); + + ev_io_stop(srv->loop, &srv->read_watcher); + + list_for_each_entry_safe(con, tmp_c, &srv->connections, list) { + uh_connection_destroy(con); + } - list_for_each_entry_safe(r, tmp_r, &srv->routes, list) { - list_del(&r->list); - free(r->path); - free(r); - } + list_for_each_entry_safe(r, tmp_r, &srv->routes, list) { + list_del(&r->list); + free(r->path); + free(r); + } - uh_ssl_ctx_free(srv); - - free(srv); - } + uh_ssl_ctx_free(srv); + + free(srv); + } } int uh_send(struct uh_connection *con, const void *buf, int len) { - len = uh_buf_append(&con->write_buf, buf, len); - if (len > 0) - ev_io_start(con->srv->loop, &con->write_watcher); - return len; + len = uh_buf_append(&con->write_buf, buf, len); + if (len > 0) + ev_io_start(con->srv->loop, &con->write_watcher); + return len; } int uh_printf(struct uh_connection *con, const char *fmt, ...) { - int len = 0; - va_list ap; - char *str = NULL; + int len = 0; + va_list ap; + char *str = NULL; - assert(fmt); + assert(fmt); - if (*fmt) { - va_start(ap, fmt); - len = vasprintf(&str, fmt, ap); - va_end(ap); - } - - if (len >= 0) { - len = uh_send(con, str, len); - free(str); - } - return len; + if (*fmt) { + va_start(ap, fmt); + len = vasprintf(&str, fmt, ap); + va_end(ap); + } + + if (len >= 0) { + len = uh_send(con, str, len); + free(str); + } + return len; } static void send_status_line(struct uh_connection *con, int code) { - const char *reason = get_http_status_message(code); - uh_printf(con, "HTTP/1.1 %d %s\r\nServer: Libuhttp %s\r\n", - code, reason, UHTTP_VERSION_STRING); + const char *reason = get_http_status_message(code); + uh_printf(con, "HTTP/1.1 %d %s\r\nServer: Libuhttp %s\r\n", + code, reason, UHTTP_VERSION_STRING); } void uh_send_head(struct uh_connection *con, int status, int length, const char *extra_headers) { - send_status_line(con, status); - - if (length < 0) - uh_printf(con, "%s", "Transfer-Encoding: chunked\r\n"); - else - uh_printf(con, "Content-Length: %d\r\n", length); + send_status_line(con, status); + + if (length < 0) + uh_printf(con, "%s", "Transfer-Encoding: chunked\r\n"); + else + uh_printf(con, "Content-Length: %d\r\n", length); - if (extra_headers) - uh_send(con, extra_headers, strlen(extra_headers)); + if (extra_headers) + uh_send(con, extra_headers, strlen(extra_headers)); - uh_send(con, "\r\n", 2); + uh_send(con, "\r\n", 2); } void uh_send_error(struct uh_connection *con, int code, const char *reason) { - http_parser *parser = &con->parser; - - if (!reason) - reason = get_http_status_message(code); + http_parser *parser = &con->parser; + + if (!reason) + reason = get_http_status_message(code); - 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"); - con->flags |= UH_CON_CLOSE; - } + 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"); + con->flags |= UH_CON_CLOSE; + } } void uh_redirect(struct uh_connection *con, int code, const char *location) { - char body[128] = ""; - http_parser *parser = &con->parser; - - snprintf(body, sizeof(body), "

Moved here

", location); + char body[128] = ""; + http_parser *parser = &con->parser; + + snprintf(body, sizeof(body), "

Moved here

", location); - send_status_line(con, code); + send_status_line(con, code); - uh_printf(con, - "Location: %s\r\n" - "Content-Type: text/html\r\n" - "Content-Length: %zu\r\n" - "Cache-Control: no-cache\r\n", location, strlen(body)); - - uh_send(con, "\r\n", 2); + uh_printf(con, + "Location: %s\r\n" + "Content-Type: text/html\r\n" + "Content-Length: %zu\r\n" + "Cache-Control: no-cache\r\n", location, strlen(body)); + + uh_send(con, "\r\n", 2); - if (parser->method != HTTP_HEAD) - uh_send(con, body, strlen(body)); + if (parser->method != HTTP_HEAD) + uh_send(con, body, strlen(body)); } int uh_send_chunk(struct uh_connection *con, const char *buf, int len) { - int slen = 0; - slen += uh_printf(con, "%X\r\n", len); - slen += uh_send(con, buf, len); - slen += uh_send(con, "\r\n", 2); - return slen; + int slen = 0; + slen += uh_printf(con, "%X\r\n", len); + slen += uh_send(con, buf, len); + slen += uh_send(con, "\r\n", 2); + return slen; } int uh_printf_chunk(struct uh_connection *con, const char *fmt, ...) { - int len = 0; - va_list ap; - char *str = NULL; + int len = 0; + va_list ap; + char *str = NULL; - assert(fmt); + assert(fmt); - if (*fmt) { - va_start(ap, fmt); - len = vasprintf(&str, fmt, ap); - va_end(ap); - } + if (*fmt) { + va_start(ap, fmt); + len = vasprintf(&str, fmt, ap); + va_end(ap); + } - if (len >= 0) { - len = uh_send_chunk(con, str, len); - free(str); - } + if (len >= 0) { + len = uh_send_chunk(con, str, len); + free(str); + } - return len; + return len; } int uh_register_route(struct uh_server *srv, const char *path, uh_route_handler_t cb) { - struct uh_route *r; + struct uh_route *r; - assert(path); + assert(path); - r = calloc(1, sizeof(struct uh_route)); - if (!r) { - uh_log_err("calloc"); - return -1; - } + r = calloc(1, sizeof(struct uh_route)); + if (!r) { + uh_log_err("calloc"); + return -1; + } - r->path = strdup(path); - if (!r->path) { - uh_log_err("strdup"); - free(r); - return -1; - } - - r->cb = cb; - list_add(&r->list, &srv->routes); - - return 0; + r->path = strdup(path); + if (!r->path) { + uh_log_err("strdup"); + free(r); + return -1; + } + + r->cb = cb; + list_add(&r->list, &srv->routes); + + return 0; } inline struct uh_value *uh_get_url(struct uh_connection *con) { - return &con->req.url; + return &con->req.url; } struct uh_value *uh_get_header(struct uh_connection *con, const char *name) { - int i; - struct uh_header *header = con->req.header; - - for (i = 0; i < con->req.header_num; i++) { - if (uh_value_cmp(&header[i].field, name)) - return &header[i].value; - } - return NULL; + int i; + struct uh_header *header = con->req.header; + + for (i = 0; i < con->req.header_num; i++) { + if (uh_value_cmp(&header[i].field, name)) + return &header[i].value; + } + return NULL; } diff --git a/src/uhttp.h b/src/uhttp.h index 33f7136..888c605 100755 --- a/src/uhttp.h +++ b/src/uhttp.h @@ -8,73 +8,73 @@ /* 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 + 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; struct uh_value { - const char *at; - size_t len; + const char *at; + size_t len; }; typedef void (*uh_route_handler_t)(struct uh_connection *con); @@ -131,9 +131,9 @@ void uh_redirect(struct uh_connection *con, int code, const char *location); * to tell the client that everything was sent. * * Example: - * char data[] = "Hello World"; - * uh_send_chunk(con, data, strlen(data)); - * uh_send_chunk(con, NULL, 0); // Tell the client we're finished + * char data[] = "Hello World"; + * uh_send_chunk(con, data, strlen(data)); + * uh_send_chunk(con, NULL, 0); // Tell the client we're finished */ int uh_send_chunk(struct uh_connection *con, const char *buf, int len); diff --git a/src/uhttp_buf.c b/src/uhttp_buf.c index b4ab1e2..e549019 100755 --- a/src/uhttp_buf.c +++ b/src/uhttp_buf.c @@ -5,64 +5,64 @@ int uh_buf_init(struct uh_buf *buf, size_t initial_size) { - buf->len = buf->size = 0; + buf->len = buf->size = 0; - if (buf->base) { - free(buf->base); - buf->base = NULL; - } + if (buf->base) { + free(buf->base); + buf->base = NULL; + } - if (initial_size > 0) { - buf->base = malloc(initial_size); - if (!buf->base) - return -1; - buf->size = initial_size; - } + if (initial_size > 0) { + buf->base = malloc(initial_size); + if (!buf->base) + return -1; + buf->size = initial_size; + } - return 0; + return 0; } int uh_buf_grow(struct uh_buf *buf, size_t size) { - void *base = realloc(buf->base, buf->size + size); - if (!base) - return -1; - - buf->base = base; - buf->size += size; + void *base = realloc(buf->base, buf->size + size); + if (!base) + return -1; + + buf->base = base; + buf->size += size; - uh_log_debug("uh_buf_grow:%p +%d", buf, size); - - return 0; + uh_log_debug("uh_buf_grow:%p +%d", buf, size); + + return 0; } void uh_buf_free(struct uh_buf *buf) { - uh_buf_init(buf, 0); + uh_buf_init(buf, 0); } size_t uh_buf_append(struct uh_buf *buf, const void *data, size_t len) { - assert(buf); + assert(buf); - if (!data) - return 0; + if (!data) + return 0; - if (buf->len + len > buf->size) { - if (uh_buf_grow(buf, len * UH_BUF_SIZE_MULTIPLIER) == -1) - len = buf->size - buf->len; - } + if (buf->len + len > buf->size) { + if (uh_buf_grow(buf, len * UH_BUF_SIZE_MULTIPLIER) == -1) + len = buf->size - buf->len; + } - memcpy(buf->base + buf->len, data, len); - buf->len += len; + memcpy(buf->base + buf->len, data, len); + buf->len += len; - return len; + return len; } void uh_buf_remove(struct uh_buf *buf, size_t n) { - if (n > 0 && n <= buf->len) { - memmove(buf->base, buf->base + n, buf->len - n); - buf->len -= n; - } + if (n > 0 && n <= buf->len) { + memmove(buf->base, buf->base + n, buf->len - n); + buf->len -= n; + } } \ No newline at end of file diff --git a/src/uhttp_buf.h b/src/uhttp_buf.h index 8458f5f..0b528d9 100755 --- a/src/uhttp_buf.h +++ b/src/uhttp_buf.h @@ -8,9 +8,9 @@ #define UH_BUF_SIZE_MULTIPLIER 1.5 struct uh_buf { - char *base; /* Buffer pointer */ - size_t len; /* Data length */ - size_t size; /* Buffer size */ + char *base; /* Buffer pointer */ + size_t len; /* Data length */ + size_t size; /* Buffer size */ }; #define uh_buf_available(b) ((b)->size - (b)->len) diff --git a/src/uhttp_config.h.in b/src/uhttp_config.h.in index 8ebd119..1e2e9a8 100755 --- a/src/uhttp_config.h.in +++ b/src/uhttp_config.h.in @@ -1,9 +1,9 @@ #ifndef _UHTTP_CONFIG_H #define _UHTTP_CONFIG_H -#define UHTTP_VERSION_MAJOR @UHTTP_VERSION_MAJOR@ -#define UHTTP_VERSION_MINOR @UHTTP_VERSION_MINOR@ -#define UHTTP_VERSION_STRING "@UHTTP_VERSION_MAJOR@.@UHTTP_VERSION_MINOR@" +#define UHTTP_VERSION_MAJOR @UHTTP_VERSION_MAJOR@ +#define UHTTP_VERSION_MINOR @UHTTP_VERSION_MINOR@ +#define UHTTP_VERSION_STRING "@UHTTP_VERSION_MAJOR@.@UHTTP_VERSION_MINOR@" #define UHTTP_DEBUG @UHTTP_DEBUG_CONFIG@ diff --git a/src/uhttp_internal.h b/src/uhttp_internal.h index 90bdc14..748b042 100755 --- a/src/uhttp_internal.h +++ b/src/uhttp_internal.h @@ -10,65 +10,65 @@ #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_MAX_HTTP_HEADERS 20 -#define UH_CON_CLOSE (1 << 0) -#define UH_CON_SSL_HANDSHAKE_DONE (1 << 1) /* SSL hanshake has completed */ -#define UH_CON_PARSERING (1 << 2) /* Whether executed http_parser_execute() */ +#define UH_CON_CLOSE (1 << 0) +#define UH_CON_SSL_HANDSHAKE_DONE (1 << 1) /* SSL hanshake has completed */ +#define UH_CON_PARSERING (1 << 2) /* Whether executed http_parser_execute() */ -#define likely(x) (__builtin_expect(!!(x), 1)) -#define unlikely(x) (__builtin_expect(!!(x), 0)) +#define likely(x) (__builtin_expect(!!(x), 1)) +#define unlikely(x) (__builtin_expect(!!(x), 0)) #define ev_timer_mode(l,w,after,repeat) do { \ - ev_timer_stop(l, w); \ - ev_timer_init(w, ev_cb(w), after, repeat); \ - ev_timer_start(l, w); \ - } while (0) + ev_timer_stop(l, w); \ + ev_timer_init(w, ev_cb(w), after, repeat); \ + ev_timer_start(l, w); \ + } while (0) struct uh_route { - char *path; - uh_route_handler_t cb; - struct list_head list; + char *path; + uh_route_handler_t cb; + struct list_head list; }; struct uh_server { - int sock; -#if (UHTTP_SSL_ENABLED) - void *ssl_ctx; + int sock; +#if (UHTTP_SSL_ENABLED) + void *ssl_ctx; #endif - ev_io read_watcher; - struct ev_loop *loop; - struct list_head routes; - struct list_head connections; + ev_io read_watcher; + struct ev_loop *loop; + struct list_head routes; + struct list_head connections; }; struct uh_header { - struct uh_value field; - struct uh_value value; + struct uh_value field; + struct uh_value value; }; struct uh_request { - struct uh_value url; - struct uh_value body; - int header_num; - struct uh_header header[UH_MAX_HTTP_HEADERS]; + struct uh_value url; + struct uh_value body; + int header_num; + struct uh_header header[UH_MAX_HTTP_HEADERS]; }; -struct uh_connection { - int sock; -#if (UHTTP_SSL_ENABLED) - void *ssl; +struct uh_connection { + int sock; +#if (UHTTP_SSL_ENABLED) + void *ssl; #endif - unsigned char flags; - struct uh_buf read_buf; - struct uh_buf write_buf; - ev_io read_watcher; - ev_io write_watcher; - ev_timer timer_watcher; - struct uh_request req; - http_parser parser; - struct list_head list; - struct uh_server *srv; + unsigned char flags; + struct uh_buf read_buf; + struct uh_buf write_buf; + ev_io read_watcher; + ev_io write_watcher; + ev_timer timer_watcher; + struct uh_request req; + http_parser parser; + struct list_head list; + struct uh_server *srv; }; #endif diff --git a/src/uhttp_log.c b/src/uhttp_log.c index 652c3f3..9dd69e1 100755 --- a/src/uhttp_log.c +++ b/src/uhttp_log.c @@ -2,29 +2,29 @@ void __uh_log(const char *filename, int line, int priority, const char *format, ...) { - va_list ap; - static char buf[128]; + va_list ap; + static char buf[128]; - snprintf(buf, sizeof(buf), "(%s:%d) ", filename, line); - - va_start(ap, format); - vsnprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), format, ap); - va_end(ap); + snprintf(buf, sizeof(buf), "(%s:%d) ", filename, line); + + va_start(ap, format); + vsnprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), format, ap); + va_end(ap); - if (priority == LOG_ERR && errno > 0) { - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ":%s", strerror(errno)); - errno = 0; - } - - syslog(priority, "%s", buf); + if (priority == LOG_ERR && errno > 0) { + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ":%s", strerror(errno)); + errno = 0; + } + + syslog(priority, "%s", buf); #if (UHTTP_DEBUG) - fprintf(stderr, "%s\n", buf); + fprintf(stderr, "%s\n", buf); #else - if (priority == LOG_ERR) - fprintf(stderr, "%s\n", buf); + if (priority == LOG_ERR) + fprintf(stderr, "%s\n", buf); #endif } diff --git a/src/uhttp_log.h b/src/uhttp_log.h index 8d8a49a..d17bfd9 100755 --- a/src/uhttp_log.h +++ b/src/uhttp_log.h @@ -16,13 +16,13 @@ #define uh_log(priority, format...) __uh_log(__FILENAME__, __LINE__, priority, format) #if (UHTTP_DEBUG) -#define uh_log_debug(format...) uh_log(LOG_DEBUG, format) +#define uh_log_debug(format...) uh_log(LOG_DEBUG, format) #else #define uh_log_debug(format...) #endif -#define uh_log_info(format...) uh_log(LOG_INFO, format) -#define uh_log_err(format...) uh_log(LOG_ERR, format) +#define uh_log_info(format...) uh_log(LOG_INFO, format) +#define uh_log_err(format...) uh_log(LOG_ERR, format) void __uh_log(const char *filename, int line, int priority, const char *format, ...); diff --git a/src/uhttp_ssl.c b/src/uhttp_ssl.c index f2bb9d0..8928084 100755 --- a/src/uhttp_ssl.c +++ b/src/uhttp_ssl.c @@ -5,196 +5,196 @@ #if (UHTTP_SSL_ENABLED) int uh_ssl_init(struct uh_server *srv, const char *cert, const char *key) { - SSL_CTX *ctx = NULL; + SSL_CTX *ctx = NULL; - SSL_library_init(); + SSL_library_init(); - /* registers the error strings for all libssl functions */ - SSL_load_error_strings(); - - /* creates a new SSL_CTX object */ - ctx = SSL_CTX_new(SSLv23_server_method()); - if (!ctx) { - uh_log_err("Failed to create SSL context"); - return -1; - } + /* registers the error strings for all libssl functions */ + SSL_load_error_strings(); + + /* creates a new SSL_CTX object */ + ctx = SSL_CTX_new(SSLv23_server_method()); + if (!ctx) { + uh_log_err("Failed to create SSL context"); + return -1; + } - /* loads the first certificate stored in file into ctx */ - if (SSL_CTX_use_certificate_file(ctx, cert, SSL_FILETYPE_PEM) != SSL_SUCCESS) { - uh_log_err("OpenSSL Error: loading certificate file failed"); - goto err; - } - - /* - * adds the first private RSA key found in file to ctx. - * - * checks the consistency of a private key with the corresponding - * certificate loaded into ctx. If more than one key/certificate - * pair (RSA/DSA) is installed, the last item installed will be checked. - */ - if (SSL_CTX_use_RSAPrivateKey_file(ctx, key, SSL_FILETYPE_PEM) != SSL_SUCCESS) { - uh_log_err("OpenSSL Error: loading key failed"); - goto err; - } + /* loads the first certificate stored in file into ctx */ + if (SSL_CTX_use_certificate_file(ctx, cert, SSL_FILETYPE_PEM) != SSL_SUCCESS) { + uh_log_err("OpenSSL Error: loading certificate file failed"); + goto err; + } + + /* + * adds the first private RSA key found in file to ctx. + * + * checks the consistency of a private key with the corresponding + * certificate loaded into ctx. If more than one key/certificate + * pair (RSA/DSA) is installed, the last item installed will be checked. + */ + if (SSL_CTX_use_RSAPrivateKey_file(ctx, key, SSL_FILETYPE_PEM) != SSL_SUCCESS) { + uh_log_err("OpenSSL Error: loading key failed"); + goto err; + } - srv->ssl_ctx = ctx; - return 0; - + srv->ssl_ctx = ctx; + return 0; + err: - SSL_CTX_free(ctx); - return -1; + SSL_CTX_free(ctx); + return -1; } #endif void uh_ssl_ctx_free(struct uh_server *srv) { #if (UHTTP_SSL_ENABLED) - if (!srv->ssl_ctx) - return; - SSL_CTX_free(srv->ssl_ctx); + if (!srv->ssl_ctx) + return; + SSL_CTX_free(srv->ssl_ctx); #endif } void uh_ssl_free(struct uh_connection *con) { #if (UHTTP_SSL_ENABLED) - if (!con->ssl) - return; - SSL_shutdown(con->ssl); - SSL_free(con->ssl); + if (!con->ssl) + return; + SSL_shutdown(con->ssl); + SSL_free(con->ssl); #endif } #if (UHTTP_SSL_ENABLED) static int uh_ssl_err(struct uh_connection *con, int ret, const char *fun) { - int err; - err = SSL_get_error(con->ssl, ret); - if (err == SSL_ERROR_ZERO_RETURN || ERR_peek_error()) { - con->flags |= UH_CON_CLOSE; - return 0; - } - + int err; + err = SSL_get_error(con->ssl, ret); + if (err == SSL_ERROR_ZERO_RETURN || ERR_peek_error()) { + con->flags |= UH_CON_CLOSE; + return 0; + } + #if (UHTTP_USE_OPENSSL) - if (ret == 0) { - con->flags |= UH_CON_CLOSE; - return 0; - } + if (ret == 0) { + con->flags |= UH_CON_CLOSE; + return 0; + } #endif - if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) - return -1; + if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) + return -1; - if (err == SSL_ERROR_SYSCALL) { - if (errno > 0) - uh_log_err("%s", fun); - con->flags |= UH_CON_CLOSE; - return -1; - } + if (err == SSL_ERROR_SYSCALL) { + if (errno > 0) + uh_log_err("%s", fun); + con->flags |= UH_CON_CLOSE; + return -1; + } - con->flags |= UH_CON_CLOSE; - uh_log_err("%s() Error: %s", fun, ERR_reason_error_string(err)); - - return -1; + con->flags |= UH_CON_CLOSE; + uh_log_err("%s() Error: %s", fun, ERR_reason_error_string(err)); + + return -1; } #endif int uh_ssl_read(struct uh_connection *con, void *buf, int count) { - int ret = -1; + int ret = -1; #if (UHTTP_SSL_ENABLED) - if (!con->ssl) - goto no_ssl; + if (!con->ssl) + goto no_ssl; - ret = SSL_read(con->ssl, buf, count); - if (ret > 0) - return ret; + ret = SSL_read(con->ssl, buf, count); + if (ret > 0) + return ret; - return uh_ssl_err(con, ret, "SSL_read"); + return uh_ssl_err(con, ret, "SSL_read"); no_ssl: #endif - ret = read(con->sock, buf, count); - if (ret <= 0) { - if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) - return ret; - - if (ret != 0) { - con->flags |= UH_CON_CLOSE; - uh_log_err("read"); - } - } - return ret; + ret = read(con->sock, buf, count); + if (ret <= 0) { + if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) + return ret; + + if (ret != 0) { + con->flags |= UH_CON_CLOSE; + uh_log_err("read"); + } + } + return ret; } int uh_ssl_write(struct uh_connection *con, void *buf, int count) { - int ret = -1; + int ret = -1; #if (UHTTP_SSL_ENABLED) - if (!con->ssl) - goto no_ssl; + if (!con->ssl) + goto no_ssl; - ret = SSL_write(con->ssl, buf, count); - if (ret > 0) - return ret; + ret = SSL_write(con->ssl, buf, count); + if (ret > 0) + return ret; - return uh_ssl_err(con, ret, "SSL_write"); + return uh_ssl_err(con, ret, "SSL_write"); no_ssl: #endif - ret = write(con->sock, buf, count); - if (ret <= 0) { - if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) - return ret; - if (ret != 0) { - con->flags |= UH_CON_CLOSE; - uh_log_err("write"); - } - } - return ret; + ret = write(con->sock, buf, count); + if (ret <= 0) { + if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) + return ret; + if (ret != 0) { + con->flags |= UH_CON_CLOSE; + uh_log_err("write"); + } + } + return ret; } int uh_ssl_accept(struct uh_connection *con) { - int sock = -1; - struct uh_server *srv = con->srv; + int sock = -1; + struct uh_server *srv = con->srv; - sock = accept4(srv->sock, NULL, NULL, SOCK_NONBLOCK | SOCK_CLOEXEC); - if (unlikely(sock < 0)) { - if (errno != EINTR && errno != EAGAIN && errno != EWOULDBLOCK) - uh_log_err("accept4"); - return -1; - } - - con->sock = sock; + sock = accept4(srv->sock, NULL, NULL, SOCK_NONBLOCK | SOCK_CLOEXEC); + if (unlikely(sock < 0)) { + if (errno != EINTR && errno != EAGAIN && errno != EWOULDBLOCK) + uh_log_err("accept4"); + return -1; + } + + con->sock = sock; #if (UHTTP_SSL_ENABLED) - if (!srv->ssl_ctx) - return sock; + if (!srv->ssl_ctx) + return sock; - con->ssl = SSL_new(srv->ssl_ctx); - if (!con->ssl) - return -1; - - if (!SSL_set_fd(con->ssl, sock)) { - uh_log_err("SSL_set_fd() failed"); - return -1; - } - - SSL_set_accept_state(con->ssl); + con->ssl = SSL_new(srv->ssl_ctx); + if (!con->ssl) + return -1; + + if (!SSL_set_fd(con->ssl, sock)) { + uh_log_err("SSL_set_fd() failed"); + return -1; + } + + SSL_set_accept_state(con->ssl); #endif - - return sock; + + return sock; } void uh_ssl_handshake(struct uh_connection *con) { #if (UHTTP_SSL_ENABLED) - int ret = SSL_accept(con->ssl); - if (ret == 1) { - con->flags |= UH_CON_SSL_HANDSHAKE_DONE; - return; - } + int ret = SSL_accept(con->ssl); + if (ret == 1) { + con->flags |= UH_CON_SSL_HANDSHAKE_DONE; + return; + } - uh_ssl_err(con, ret, "SSL_accept"); + uh_ssl_err(con, ret, "SSL_accept"); #endif } diff --git a/src/uhttp_ssl.h b/src/uhttp_ssl.h index acadf14..5ca2711 100755 --- a/src/uhttp_ssl.h +++ b/src/uhttp_ssl.h @@ -8,7 +8,7 @@ #include #ifndef SSL_SUCCESS -#define SSL_SUCCESS 1 +#define SSL_SUCCESS 1 #endif #elif (UHTTP_USE_CYASSL)