In order to be compatible with different editor, convert all Tab to spaces

Signed-off-by: Jianhui Zhao <jianhuizhao329@gmail.com>
main
Jianhui Zhao 2017-11-13 20:51:42 +08:00
parent 8eb57bef1e
commit ee31e3f1fa
11 changed files with 747 additions and 747 deletions

View File

@ -4,67 +4,67 @@
static void signal_cb(struct ev_loop *loop, ev_signal *w, int revents) static void signal_cb(struct ev_loop *loop, ev_signal *w, int revents)
{ {
printf("Got signal: %d\n", w->signum); printf("Got signal: %d\n", w->signum);
ev_break(loop, EVBREAK_ALL); ev_break(loop, EVBREAK_ALL);
} }
void route_test(struct uh_connection *con) void route_test(struct uh_connection *con)
{ {
struct uh_value *url = uh_get_url(con); struct uh_value *url = uh_get_url(con);
struct uh_value *header_host = uh_get_header(con, "Host"); struct uh_value *header_host = uh_get_header(con, "Host");
struct uh_value *header_ua = uh_get_header(con, "User-Agent"); struct uh_value *header_ua = uh_get_header(con, "User-Agent");
uh_send_head(con, UH_STATUS_OK, -1, NULL);
uh_printf_chunk(con, "<h1>Hello World</h1>");
uh_printf_chunk(con, "<h1>Libuhttp v%s</h1>", uh_version());
uh_printf_chunk(con, "<h1>Url: %.*s</h1>", (int)url->len, url->at);
if (header_host) uh_send_head(con, UH_STATUS_OK, -1, NULL);
uh_printf_chunk(con, "<h1>Host: %.*s</h1>", (int)header_host->len, header_host->at); uh_printf_chunk(con, "<h1>Hello World</h1>");
uh_printf_chunk(con, "<h1>Libuhttp v%s</h1>", uh_version());
uh_printf_chunk(con, "<h1>Url: %.*s</h1>", (int)url->len, url->at);
if (header_ua) if (header_host)
uh_printf_chunk(con, "<h1>User-Agent: %.*s</h1>", (int)header_ua->len, header_ua->at); uh_printf_chunk(con, "<h1>Host: %.*s</h1>", (int)header_host->len, header_host->at);
uh_send_chunk(con, NULL, 0); if (header_ua)
uh_printf_chunk(con, "<h1>User-Agent: %.*s</h1>", (int)header_ua->len, header_ua->at);
uh_send_chunk(con, NULL, 0);
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
struct ev_loop *loop = EV_DEFAULT; struct ev_loop *loop = EV_DEFAULT;
ev_signal *sig_watcher = NULL; ev_signal *sig_watcher = NULL;
struct uh_server *srv = 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)); sig_watcher = calloc(1, sizeof(ev_signal));
if (!sig_watcher) if (!sig_watcher)
return -1; return -1;
ev_signal_init(sig_watcher, signal_cb, SIGINT); ev_signal_init(sig_watcher, signal_cb, SIGINT);
ev_signal_start(loop, sig_watcher); ev_signal_start(loop, sig_watcher);
srv = uh_server_new(loop, "0.0.0.0", 8000); srv = uh_server_new(loop, "0.0.0.0", 8000);
if (!srv) { if (!srv) {
uh_log_err("uh_server_new failed\n"); uh_log_err("uh_server_new failed\n");
goto err; goto err;
} }
#if (UHTTP_SSL_ENABLED) #if (UHTTP_SSL_ENABLED)
if (uh_ssl_init(srv, "server-cert.pem", "server-key.pem") < 0) if (uh_ssl_init(srv, "server-cert.pem", "server-key.pem") < 0)
goto err; goto err;
#endif #endif
uh_register_route(srv, "/test", route_test); uh_register_route(srv, "/test", route_test);
uh_log_info("Listen on 8000...\n"); uh_log_info("Listen on 8000...\n");
ev_run(loop, 0); ev_run(loop, 0);
err: err:
free(sig_watcher); free(sig_watcher);
uh_server_free(srv); uh_server_free(srv);
return 0; return 0;
} }

File diff suppressed because it is too large Load Diff

View File

@ -8,73 +8,73 @@
/* HTTP Status Codes */ /* HTTP Status Codes */
enum uh_status { enum uh_status {
UH_STATUS_CONTINUE = 100, UH_STATUS_CONTINUE = 100,
UH_STATUS_SWITCHING_PROTOCOLS = 101, UH_STATUS_SWITCHING_PROTOCOLS = 101,
UH_STATUS_PROCESSING = 102, UH_STATUS_PROCESSING = 102,
UH_STATUS_OK = 200, UH_STATUS_OK = 200,
UH_STATUS_CREATED = 201, UH_STATUS_CREATED = 201,
UH_STATUS_ACCEPTED = 202, UH_STATUS_ACCEPTED = 202,
UH_STATUS_NON_AUTHORITATIVE_INFORMATION = 203, UH_STATUS_NON_AUTHORITATIVE_INFORMATION = 203,
UH_STATUS_NO_CONTENT = 204, UH_STATUS_NO_CONTENT = 204,
UH_STATUS_RESET_CONTENT = 205, UH_STATUS_RESET_CONTENT = 205,
UH_STATUS_PARTIAL_CONTENT = 206, UH_STATUS_PARTIAL_CONTENT = 206,
UH_STATUS_MULTI_STATUS = 207, UH_STATUS_MULTI_STATUS = 207,
UH_STATUS_ALREADY_REPORTED = 208, UH_STATUS_ALREADY_REPORTED = 208,
UH_STATUS_IM_USED = 226, UH_STATUS_IM_USED = 226,
UH_STATUS_MULTIPLE_CHOICES = 300, UH_STATUS_MULTIPLE_CHOICES = 300,
UH_STATUS_MOVED_PERMANENTLY = 301, UH_STATUS_MOVED_PERMANENTLY = 301,
UH_STATUS_FOUND = 302, UH_STATUS_FOUND = 302,
UH_STATUS_SEE_OTHER = 303, UH_STATUS_SEE_OTHER = 303,
UH_STATUS_NOT_MODIFIED = 304, UH_STATUS_NOT_MODIFIED = 304,
UH_STATUS_USE_PROXY = 305, UH_STATUS_USE_PROXY = 305,
UH_STATUS_TEMPORARY_REDIRECT = 307, UH_STATUS_TEMPORARY_REDIRECT = 307,
UH_STATUS_PERMANENT_REDIRECT = 308, UH_STATUS_PERMANENT_REDIRECT = 308,
UH_STATUS_BAD_REQUEST = 400, UH_STATUS_BAD_REQUEST = 400,
UH_STATUS_UNAUTHORIZED = 401, UH_STATUS_UNAUTHORIZED = 401,
UH_STATUS_PAYMENT_REQUIRED = 402, UH_STATUS_PAYMENT_REQUIRED = 402,
UH_STATUS_FORBIDDEN = 403, UH_STATUS_FORBIDDEN = 403,
UH_STATUS_NOT_FOUND = 404, UH_STATUS_NOT_FOUND = 404,
UH_STATUS_METHOD_NOT_ALLOWED = 405, UH_STATUS_METHOD_NOT_ALLOWED = 405,
UH_STATUS_NOT_ACCEPTABLE = 406, UH_STATUS_NOT_ACCEPTABLE = 406,
UH_STATUS_PROXY_AUTHENTICATION_REQUIRED = 407, UH_STATUS_PROXY_AUTHENTICATION_REQUIRED = 407,
UH_STATUS_REQUEST_TIMEOUT = 408, UH_STATUS_REQUEST_TIMEOUT = 408,
UH_STATUS_CONFLICT = 409, UH_STATUS_CONFLICT = 409,
UH_STATUS_GONE = 410, UH_STATUS_GONE = 410,
UH_STATUS_LENGTH_REQUIRED = 411, UH_STATUS_LENGTH_REQUIRED = 411,
UH_STATUS_PRECONDITION_FAILED = 412, UH_STATUS_PRECONDITION_FAILED = 412,
UH_STATUS_PAYLOAD_TOO_LARGE = 413, UH_STATUS_PAYLOAD_TOO_LARGE = 413,
UH_STATUS_URI_TOO_LONG = 414, UH_STATUS_URI_TOO_LONG = 414,
UH_STATUS_UNSUPPORTED_MEDIA_TYPE = 415, UH_STATUS_UNSUPPORTED_MEDIA_TYPE = 415,
UH_STATUS_RANGE_NOT_SATISFIABLE = 416, UH_STATUS_RANGE_NOT_SATISFIABLE = 416,
UH_STATUS_EXPECTATION_FAILED = 417, UH_STATUS_EXPECTATION_FAILED = 417,
UH_STATUS_MISDIRECTED_REQUEST = 421, UH_STATUS_MISDIRECTED_REQUEST = 421,
UH_STATUS_UNPROCESSABLE_ENTITY = 422, UH_STATUS_UNPROCESSABLE_ENTITY = 422,
UH_STATUS_LOCKED = 423, UH_STATUS_LOCKED = 423,
UH_STATUS_FAILED_DEPENDENCY = 424, UH_STATUS_FAILED_DEPENDENCY = 424,
UH_STATUS_UPGRADE_REQUIRED = 426, UH_STATUS_UPGRADE_REQUIRED = 426,
UH_STATUS_PRECONDITION_REQUIRED = 428, UH_STATUS_PRECONDITION_REQUIRED = 428,
UH_STATUS_TOO_MANY_REQUESTS = 429, UH_STATUS_TOO_MANY_REQUESTS = 429,
UH_STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE = 431, UH_STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
UH_STATUS_UNAVAILABLE_FOR_LEGAL_REASONS = 451, UH_STATUS_UNAVAILABLE_FOR_LEGAL_REASONS = 451,
UH_STATUS_INTERNAL_SERVER_ERROR = 500, UH_STATUS_INTERNAL_SERVER_ERROR = 500,
UH_STATUS_NOT_IMPLEMENTED = 501, UH_STATUS_NOT_IMPLEMENTED = 501,
UH_STATUS_BAD_GATEWAY = 502, UH_STATUS_BAD_GATEWAY = 502,
UH_STATUS_SERVICE_UNAVAILABLE = 503, UH_STATUS_SERVICE_UNAVAILABLE = 503,
UH_STATUS_GATEWAY_TIMEOUT = 504, UH_STATUS_GATEWAY_TIMEOUT = 504,
UH_STATUS_HTTP_VERSION_NOT_SUPPORTED = 505, UH_STATUS_HTTP_VERSION_NOT_SUPPORTED = 505,
UH_STATUS_VARIANT_ALSO_NEGOTIATES = 506, UH_STATUS_VARIANT_ALSO_NEGOTIATES = 506,
UH_STATUS_INSUFFICIENT_STORAGE = 507, UH_STATUS_INSUFFICIENT_STORAGE = 507,
UH_STATUS_LOOP_DETECTED = 508, UH_STATUS_LOOP_DETECTED = 508,
UH_STATUS_NOT_EXTENDED = 510, UH_STATUS_NOT_EXTENDED = 510,
UH_STATUS_NETWORK_AUTHENTICATION_REQUIRED = 511 UH_STATUS_NETWORK_AUTHENTICATION_REQUIRED = 511
}; };
struct uh_server; struct uh_server;
struct uh_connection; struct uh_connection;
struct uh_value { struct uh_value {
const char *at; const char *at;
size_t len; size_t len;
}; };
typedef void (*uh_route_handler_t)(struct uh_connection *con); 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. * to tell the client that everything was sent.
* *
* Example: * Example:
* char data[] = "Hello World"; * char data[] = "Hello World";
* uh_send_chunk(con, data, strlen(data)); * uh_send_chunk(con, data, strlen(data));
* uh_send_chunk(con, NULL, 0); // Tell the client we're finished * 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); int uh_send_chunk(struct uh_connection *con, const char *buf, int len);

View File

@ -5,64 +5,64 @@
int uh_buf_init(struct uh_buf *buf, size_t initial_size) 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) { if (buf->base) {
free(buf->base); free(buf->base);
buf->base = NULL; buf->base = NULL;
} }
if (initial_size > 0) { if (initial_size > 0) {
buf->base = malloc(initial_size); buf->base = malloc(initial_size);
if (!buf->base) if (!buf->base)
return -1; return -1;
buf->size = initial_size; buf->size = initial_size;
} }
return 0; return 0;
} }
int uh_buf_grow(struct uh_buf *buf, size_t size) int uh_buf_grow(struct uh_buf *buf, size_t size)
{ {
void *base = realloc(buf->base, buf->size + size); void *base = realloc(buf->base, buf->size + size);
if (!base) if (!base)
return -1; return -1;
buf->base = base; buf->base = base;
buf->size += size; buf->size += size;
uh_log_debug("uh_buf_grow:%p +%d", buf, size); uh_log_debug("uh_buf_grow:%p +%d", buf, size);
return 0; return 0;
} }
void uh_buf_free(struct uh_buf *buf) 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) size_t uh_buf_append(struct uh_buf *buf, const void *data, size_t len)
{ {
assert(buf); assert(buf);
if (!data) if (!data)
return 0; return 0;
if (buf->len + len > buf->size) { if (buf->len + len > buf->size) {
if (uh_buf_grow(buf, len * UH_BUF_SIZE_MULTIPLIER) == -1) if (uh_buf_grow(buf, len * UH_BUF_SIZE_MULTIPLIER) == -1)
len = buf->size - buf->len; len = buf->size - buf->len;
} }
memcpy(buf->base + buf->len, data, len); memcpy(buf->base + buf->len, data, len);
buf->len += len; buf->len += len;
return len; return len;
} }
void uh_buf_remove(struct uh_buf *buf, size_t n) void uh_buf_remove(struct uh_buf *buf, size_t n)
{ {
if (n > 0 && n <= buf->len) { if (n > 0 && n <= buf->len) {
memmove(buf->base, buf->base + n, buf->len - n); memmove(buf->base, buf->base + n, buf->len - n);
buf->len -= n; buf->len -= n;
} }
} }

View File

@ -8,9 +8,9 @@
#define UH_BUF_SIZE_MULTIPLIER 1.5 #define UH_BUF_SIZE_MULTIPLIER 1.5
struct uh_buf { struct uh_buf {
char *base; /* Buffer pointer */ char *base; /* Buffer pointer */
size_t len; /* Data length */ size_t len; /* Data length */
size_t size; /* Buffer size */ size_t size; /* Buffer size */
}; };
#define uh_buf_available(b) ((b)->size - (b)->len) #define uh_buf_available(b) ((b)->size - (b)->len)

View File

@ -1,9 +1,9 @@
#ifndef _UHTTP_CONFIG_H #ifndef _UHTTP_CONFIG_H
#define _UHTTP_CONFIG_H #define _UHTTP_CONFIG_H
#define UHTTP_VERSION_MAJOR @UHTTP_VERSION_MAJOR@ #define UHTTP_VERSION_MAJOR @UHTTP_VERSION_MAJOR@
#define UHTTP_VERSION_MINOR @UHTTP_VERSION_MINOR@ #define UHTTP_VERSION_MINOR @UHTTP_VERSION_MINOR@
#define UHTTP_VERSION_STRING "@UHTTP_VERSION_MAJOR@.@UHTTP_VERSION_MINOR@" #define UHTTP_VERSION_STRING "@UHTTP_VERSION_MAJOR@.@UHTTP_VERSION_MINOR@"
#define UHTTP_DEBUG @UHTTP_DEBUG_CONFIG@ #define UHTTP_DEBUG @UHTTP_DEBUG_CONFIG@

View File

@ -10,65 +10,65 @@
#define UH_CONNECTION_TIMEOUT 30 #define UH_CONNECTION_TIMEOUT 30
#define UH_MAX_HTTP_HEAD_SIZE 1024 #define UH_MAX_HTTP_HEAD_SIZE 1024
#define UH_MAX_HTTP_BODY_SIZE (2 * 1024 * 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_CLOSE (1 << 0)
#define UH_CON_SSL_HANDSHAKE_DONE (1 << 1) /* SSL hanshake has completed */ #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_PARSERING (1 << 2) /* Whether executed http_parser_execute() */
#define likely(x) (__builtin_expect(!!(x), 1)) #define likely(x) (__builtin_expect(!!(x), 1))
#define unlikely(x) (__builtin_expect(!!(x), 0)) #define unlikely(x) (__builtin_expect(!!(x), 0))
#define ev_timer_mode(l,w,after,repeat) do { \ #define ev_timer_mode(l,w,after,repeat) do { \
ev_timer_stop(l, w); \ ev_timer_stop(l, w); \
ev_timer_init(w, ev_cb(w), after, repeat); \ ev_timer_init(w, ev_cb(w), after, repeat); \
ev_timer_start(l, w); \ ev_timer_start(l, w); \
} while (0) } while (0)
struct uh_route { struct uh_route {
char *path; char *path;
uh_route_handler_t cb; uh_route_handler_t cb;
struct list_head list; struct list_head list;
}; };
struct uh_server { struct uh_server {
int sock; int sock;
#if (UHTTP_SSL_ENABLED) #if (UHTTP_SSL_ENABLED)
void *ssl_ctx; void *ssl_ctx;
#endif #endif
ev_io read_watcher; ev_io read_watcher;
struct ev_loop *loop; struct ev_loop *loop;
struct list_head routes; struct list_head routes;
struct list_head connections; struct list_head connections;
}; };
struct uh_header { struct uh_header {
struct uh_value field; struct uh_value field;
struct uh_value value; struct uh_value value;
}; };
struct uh_request { struct uh_request {
struct uh_value url; struct uh_value url;
struct uh_value body; struct uh_value body;
int header_num; int header_num;
struct uh_header header[UH_MAX_HTTP_HEADERS]; struct uh_header header[UH_MAX_HTTP_HEADERS];
}; };
struct uh_connection { struct uh_connection {
int sock; int sock;
#if (UHTTP_SSL_ENABLED) #if (UHTTP_SSL_ENABLED)
void *ssl; void *ssl;
#endif #endif
unsigned char flags; unsigned char flags;
struct uh_buf read_buf; struct uh_buf read_buf;
struct uh_buf write_buf; struct uh_buf write_buf;
ev_io read_watcher; ev_io read_watcher;
ev_io write_watcher; ev_io write_watcher;
ev_timer timer_watcher; ev_timer timer_watcher;
struct uh_request req; struct uh_request req;
http_parser parser; http_parser parser;
struct list_head list; struct list_head list;
struct uh_server *srv; struct uh_server *srv;
}; };
#endif #endif

View File

@ -2,29 +2,29 @@
void __uh_log(const char *filename, int line, int priority, const char *format, ...) void __uh_log(const char *filename, int line, int priority, const char *format, ...)
{ {
va_list ap; va_list ap;
static char buf[128]; static char buf[128];
snprintf(buf, sizeof(buf), "(%s:%d) ", filename, line); snprintf(buf, sizeof(buf), "(%s:%d) ", filename, line);
va_start(ap, format); va_start(ap, format);
vsnprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), format, ap); vsnprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), format, ap);
va_end(ap); va_end(ap);
if (priority == LOG_ERR && errno > 0) { if (priority == LOG_ERR && errno > 0) {
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ":%s", strerror(errno)); snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ":%s", strerror(errno));
errno = 0; errno = 0;
} }
syslog(priority, "%s", buf); syslog(priority, "%s", buf);
#if (UHTTP_DEBUG) #if (UHTTP_DEBUG)
fprintf(stderr, "%s\n", buf); fprintf(stderr, "%s\n", buf);
#else #else
if (priority == LOG_ERR) if (priority == LOG_ERR)
fprintf(stderr, "%s\n", buf); fprintf(stderr, "%s\n", buf);
#endif #endif
} }

View File

@ -16,13 +16,13 @@
#define uh_log(priority, format...) __uh_log(__FILENAME__, __LINE__, priority, format) #define uh_log(priority, format...) __uh_log(__FILENAME__, __LINE__, priority, format)
#if (UHTTP_DEBUG) #if (UHTTP_DEBUG)
#define uh_log_debug(format...) uh_log(LOG_DEBUG, format) #define uh_log_debug(format...) uh_log(LOG_DEBUG, format)
#else #else
#define uh_log_debug(format...) #define uh_log_debug(format...)
#endif #endif
#define uh_log_info(format...) uh_log(LOG_INFO, format) #define uh_log_info(format...) uh_log(LOG_INFO, format)
#define uh_log_err(format...) uh_log(LOG_ERR, format) #define uh_log_err(format...) uh_log(LOG_ERR, format)
void __uh_log(const char *filename, int line, int priority, const char *format, ...); void __uh_log(const char *filename, int line, int priority, const char *format, ...);

View File

@ -5,196 +5,196 @@
#if (UHTTP_SSL_ENABLED) #if (UHTTP_SSL_ENABLED)
int uh_ssl_init(struct uh_server *srv, const char *cert, const char *key) 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 */ /* registers the error strings for all libssl functions */
SSL_load_error_strings(); SSL_load_error_strings();
/* creates a new SSL_CTX object */ /* creates a new SSL_CTX object */
ctx = SSL_CTX_new(SSLv23_server_method()); ctx = SSL_CTX_new(SSLv23_server_method());
if (!ctx) { if (!ctx) {
uh_log_err("Failed to create SSL context"); uh_log_err("Failed to create SSL context");
return -1; return -1;
} }
/* loads the first certificate stored in file into ctx */ /* loads the first certificate stored in file into ctx */
if (SSL_CTX_use_certificate_file(ctx, cert, SSL_FILETYPE_PEM) != SSL_SUCCESS) { if (SSL_CTX_use_certificate_file(ctx, cert, SSL_FILETYPE_PEM) != SSL_SUCCESS) {
uh_log_err("OpenSSL Error: loading certificate file failed"); uh_log_err("OpenSSL Error: loading certificate file failed");
goto err; goto err;
} }
/* /*
* adds the first private RSA key found in file to ctx. * adds the first private RSA key found in file to ctx.
* *
* checks the consistency of a private key with the corresponding * checks the consistency of a private key with the corresponding
* certificate loaded into ctx. If more than one key/certificate * certificate loaded into ctx. If more than one key/certificate
* pair (RSA/DSA) is installed, the last item installed will be checked. * 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) { if (SSL_CTX_use_RSAPrivateKey_file(ctx, key, SSL_FILETYPE_PEM) != SSL_SUCCESS) {
uh_log_err("OpenSSL Error: loading key failed"); uh_log_err("OpenSSL Error: loading key failed");
goto err; goto err;
} }
srv->ssl_ctx = ctx; srv->ssl_ctx = ctx;
return 0; return 0;
err: err:
SSL_CTX_free(ctx); SSL_CTX_free(ctx);
return -1; return -1;
} }
#endif #endif
void uh_ssl_ctx_free(struct uh_server *srv) void uh_ssl_ctx_free(struct uh_server *srv)
{ {
#if (UHTTP_SSL_ENABLED) #if (UHTTP_SSL_ENABLED)
if (!srv->ssl_ctx) if (!srv->ssl_ctx)
return; return;
SSL_CTX_free(srv->ssl_ctx); SSL_CTX_free(srv->ssl_ctx);
#endif #endif
} }
void uh_ssl_free(struct uh_connection *con) void uh_ssl_free(struct uh_connection *con)
{ {
#if (UHTTP_SSL_ENABLED) #if (UHTTP_SSL_ENABLED)
if (!con->ssl) if (!con->ssl)
return; return;
SSL_shutdown(con->ssl); SSL_shutdown(con->ssl);
SSL_free(con->ssl); SSL_free(con->ssl);
#endif #endif
} }
#if (UHTTP_SSL_ENABLED) #if (UHTTP_SSL_ENABLED)
static int uh_ssl_err(struct uh_connection *con, int ret, const char *fun) static int uh_ssl_err(struct uh_connection *con, int ret, const char *fun)
{ {
int err; int err;
err = SSL_get_error(con->ssl, ret); err = SSL_get_error(con->ssl, ret);
if (err == SSL_ERROR_ZERO_RETURN || ERR_peek_error()) { if (err == SSL_ERROR_ZERO_RETURN || ERR_peek_error()) {
con->flags |= UH_CON_CLOSE; con->flags |= UH_CON_CLOSE;
return 0; return 0;
} }
#if (UHTTP_USE_OPENSSL) #if (UHTTP_USE_OPENSSL)
if (ret == 0) { if (ret == 0) {
con->flags |= UH_CON_CLOSE; con->flags |= UH_CON_CLOSE;
return 0; return 0;
} }
#endif #endif
if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE)
return -1; return -1;
if (err == SSL_ERROR_SYSCALL) { if (err == SSL_ERROR_SYSCALL) {
if (errno > 0) if (errno > 0)
uh_log_err("%s", fun); uh_log_err("%s", fun);
con->flags |= UH_CON_CLOSE; con->flags |= UH_CON_CLOSE;
return -1; return -1;
} }
con->flags |= UH_CON_CLOSE; con->flags |= UH_CON_CLOSE;
uh_log_err("%s() Error: %s", fun, ERR_reason_error_string(err)); uh_log_err("%s() Error: %s", fun, ERR_reason_error_string(err));
return -1; return -1;
} }
#endif #endif
int uh_ssl_read(struct uh_connection *con, void *buf, int count) int uh_ssl_read(struct uh_connection *con, void *buf, int count)
{ {
int ret = -1; int ret = -1;
#if (UHTTP_SSL_ENABLED) #if (UHTTP_SSL_ENABLED)
if (!con->ssl) if (!con->ssl)
goto no_ssl; goto no_ssl;
ret = SSL_read(con->ssl, buf, count); ret = SSL_read(con->ssl, buf, count);
if (ret > 0) if (ret > 0)
return ret; return ret;
return uh_ssl_err(con, ret, "SSL_read"); return uh_ssl_err(con, ret, "SSL_read");
no_ssl: no_ssl:
#endif #endif
ret = read(con->sock, buf, count); ret = read(con->sock, buf, count);
if (ret <= 0) { if (ret <= 0) {
if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
return ret; return ret;
if (ret != 0) { if (ret != 0) {
con->flags |= UH_CON_CLOSE; con->flags |= UH_CON_CLOSE;
uh_log_err("read"); uh_log_err("read");
} }
} }
return ret; return ret;
} }
int uh_ssl_write(struct uh_connection *con, void *buf, int count) int uh_ssl_write(struct uh_connection *con, void *buf, int count)
{ {
int ret = -1; int ret = -1;
#if (UHTTP_SSL_ENABLED) #if (UHTTP_SSL_ENABLED)
if (!con->ssl) if (!con->ssl)
goto no_ssl; goto no_ssl;
ret = SSL_write(con->ssl, buf, count); ret = SSL_write(con->ssl, buf, count);
if (ret > 0) if (ret > 0)
return ret; return ret;
return uh_ssl_err(con, ret, "SSL_write"); return uh_ssl_err(con, ret, "SSL_write");
no_ssl: no_ssl:
#endif #endif
ret = write(con->sock, buf, count); ret = write(con->sock, buf, count);
if (ret <= 0) { if (ret <= 0) {
if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
return ret; return ret;
if (ret != 0) { if (ret != 0) {
con->flags |= UH_CON_CLOSE; con->flags |= UH_CON_CLOSE;
uh_log_err("write"); uh_log_err("write");
} }
} }
return ret; return ret;
} }
int uh_ssl_accept(struct uh_connection *con) int uh_ssl_accept(struct uh_connection *con)
{ {
int sock = -1; int sock = -1;
struct uh_server *srv = con->srv; struct uh_server *srv = con->srv;
sock = accept4(srv->sock, NULL, NULL, SOCK_NONBLOCK | SOCK_CLOEXEC); sock = accept4(srv->sock, NULL, NULL, SOCK_NONBLOCK | SOCK_CLOEXEC);
if (unlikely(sock < 0)) { if (unlikely(sock < 0)) {
if (errno != EINTR && errno != EAGAIN && errno != EWOULDBLOCK) if (errno != EINTR && errno != EAGAIN && errno != EWOULDBLOCK)
uh_log_err("accept4"); uh_log_err("accept4");
return -1; return -1;
} }
con->sock = sock; con->sock = sock;
#if (UHTTP_SSL_ENABLED) #if (UHTTP_SSL_ENABLED)
if (!srv->ssl_ctx) if (!srv->ssl_ctx)
return sock; return sock;
con->ssl = SSL_new(srv->ssl_ctx); con->ssl = SSL_new(srv->ssl_ctx);
if (!con->ssl) if (!con->ssl)
return -1; return -1;
if (!SSL_set_fd(con->ssl, sock)) { if (!SSL_set_fd(con->ssl, sock)) {
uh_log_err("SSL_set_fd() failed"); uh_log_err("SSL_set_fd() failed");
return -1; return -1;
} }
SSL_set_accept_state(con->ssl); SSL_set_accept_state(con->ssl);
#endif #endif
return sock; return sock;
} }
void uh_ssl_handshake(struct uh_connection *con) void uh_ssl_handshake(struct uh_connection *con)
{ {
#if (UHTTP_SSL_ENABLED) #if (UHTTP_SSL_ENABLED)
int ret = SSL_accept(con->ssl); int ret = SSL_accept(con->ssl);
if (ret == 1) { if (ret == 1) {
con->flags |= UH_CON_SSL_HANDSHAKE_DONE; con->flags |= UH_CON_SSL_HANDSHAKE_DONE;
return; return;
} }
uh_ssl_err(con, ret, "SSL_accept"); uh_ssl_err(con, ret, "SSL_accept");
#endif #endif
} }

View File

@ -8,7 +8,7 @@
#include <openssl/err.h> #include <openssl/err.h>
#ifndef SSL_SUCCESS #ifndef SSL_SUCCESS
#define SSL_SUCCESS 1 #define SSL_SUCCESS 1
#endif #endif
#elif (UHTTP_USE_CYASSL) #elif (UHTTP_USE_CYASSL)