kore

An easy to use, scalable and secure web application framework for writing web APIs in C.
Commits | Files | Refs | README | LICENSE | git clone https://git.kore.io/kore.git

commit b3a48f3c15ef4516b3dac641f413938bfa8146e7
parent ce9c5a135065a720450881f59fbde6a4ac38ad83
Author: Joris Vink <joris@coders.se>
Date:   Tue, 13 Feb 2018 11:56:51 +0100

Let http_request_limit matter.

Before http_request_limit just constrained the number of HTTP
requests we'd deal with in a single http_process_requests() call.

But it should really mean how many maximum HTTP requests are allowed
to be alive in the worker process before we start sending 503s back.

While here, drop the lock timeout for a worker to 100ms down from 500ms
and do not allow a worker to grab the accept lock if their HTTP request
queue is full.

This makes things much more pleasant memory wise as the http_request_pool
won't just grow over time.

Diffstat:
includes/http.h | 2+-
src/http.c | 9+++++++--
src/worker.c | 11++++++++---
3 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/includes/http.h b/includes/http.h @@ -234,12 +234,12 @@ struct http_state { int (*cb)(struct http_request *); }; -extern int http_request_count; extern u_int16_t http_header_max; extern size_t http_body_max; extern u_int64_t http_hsts_enable; extern u_int16_t http_keepalive_time; extern u_int32_t http_request_limit; +extern u_int32_t http_request_count; extern u_int64_t http_body_disk_offload; extern char *http_body_disk_path; diff --git a/src/http.c b/src/http.c @@ -70,7 +70,7 @@ static struct kore_pool http_host_pool; static struct kore_pool http_path_pool; static struct kore_pool http_body_path; -int http_request_count = 0; +u_int32_t http_request_count = 0; u_int32_t http_request_limit = HTTP_REQUEST_LIMIT; u_int64_t http_hsts_enable = HTTP_HSTS_ENABLE; u_int16_t http_header_max = HTTP_HEADER_MAX_LEN; @@ -100,7 +100,7 @@ http_init(void) prealloc = MIN((worker_max_connections / 10), 1000); kore_pool_init(&http_request_pool, "http_request_pool", - sizeof(struct http_request), prealloc); + sizeof(struct http_request), http_request_limit); kore_pool_init(&http_header_pool, "http_header_pool", sizeof(struct http_header), prealloc * HTTP_REQ_HEADER_MAX); kore_pool_init(&http_cookie_pool, "http_cookie_pool", @@ -161,6 +161,11 @@ http_request_new(struct connection *c, const char *host, kore_debug("http_request_new(%p, %s, %s, %s, %s)", c, host, method, path, version); + if (http_request_count >= http_request_limit) { + http_error_response(c, 503); + return (KORE_RESULT_ERROR); + } + if ((hostlen = strlen(host)) >= KORE_DOMAINNAME_LEN - 1) { http_error_response(c, 400); return (KORE_RESULT_ERROR); diff --git a/src/worker.c b/src/worker.c @@ -58,7 +58,7 @@ #define WAIT_ANY (-1) #endif -#define WORKER_LOCK_TIMEOUT 500 +#define WORKER_LOCK_TIMEOUT 100 #define WORKER(id) \ (struct kore_worker *)((u_int8_t *)kore_workers + \ @@ -383,8 +383,8 @@ kore_worker_entry(struct kore_worker *kw) now = kore_time_ms(); netwait = kore_timer_run(now); - if (netwait > 100) - netwait = 100; + if (netwait > 10) + netwait = 10; #if !defined(KORE_NO_TLS) if ((now - last_seed) > KORE_RESEED_TIME) { @@ -559,6 +559,11 @@ kore_worker_acceptlock_obtain(void) if (worker_active_connections >= worker_max_connections) return (0); +#if !defined(KORE_NO_HTTP) + if (http_request_count >= http_request_limit) + return (0); +#endif + r = 0; if (worker_trylock()) { r = 1;