diff --git a/lib/core/context.c b/lib/core/context.c index 38aaf3b53..5d2aa33dd 100644 --- a/lib/core/context.c +++ b/lib/core/context.c @@ -341,11 +341,13 @@ lwsl_info("context created\n"); else context->max_http_header_pool = context->max_fds; + if (info->fd_limit_per_thread) context->fd_limit_per_thread = info->fd_limit_per_thread; else - context->fd_limit_per_thread = context->max_fds / - context->count_threads; + if (context->count_threads) + context->fd_limit_per_thread = context->max_fds / + context->count_threads; #if defined(LWS_WITH_NETWORK) /* diff --git a/lib/roles/http/server/lws-spa.c b/lib/roles/http/server/lws-spa.c index 4e2569544..0414016b2 100644 --- a/lib/roles/http/server/lws-spa.c +++ b/lib/roles/http/server/lws-spa.c @@ -39,10 +39,13 @@ enum urldecode_stateful { MT_COMPLETED, }; -static const char * const mp_hdr[] = { - "content-disposition: ", - "content-type: ", - "\x0d\x0a" +static struct mp_hdr { + const char * const hdr; + uint8_t hdr_len; +} mp_hdrs[] = { + { "content-disposition: ", 21 }, + { "content-type: ", 14 }, + { "\x0d\x0a", 2 } }; struct lws_spa; @@ -66,10 +69,12 @@ struct lws_urldecode_stateful { int mp; int sum; - unsigned int multipart_form_data:1; - unsigned int inside_quote:1; - unsigned int subname:1; - unsigned int boundary_real_crlf:1; + uint8_t matchable; + + uint8_t multipart_form_data:1; + uint8_t inside_quote:1; + uint8_t subname:1; + uint8_t boundary_real_crlf:1; enum urldecode_stateful state; @@ -147,7 +152,7 @@ static int lws_urldecode_s_process(struct lws_urldecode_stateful *s, const char *in, int len) { - int n, m, hit = 0; + int n, hit; char c, was_end = 0; while (len--) { @@ -159,6 +164,7 @@ lws_urldecode_s_process(struct lws_urldecode_stateful *s, const char *in, was_end = s->pos; s->pos = 0; } + switch (s->state) { /* states for url arg style */ @@ -278,29 +284,52 @@ retry_as_first: break; case MT_HNAME: - m = 0; c =*in; if (c >= 'A' && c <= 'Z') c += 'a' - 'A'; - for (n = 0; n < (int)LWS_ARRAY_SIZE(mp_hdr); n++) - if (c == mp_hdr[n][s->mp]) { - m++; - hit = n; + if (!s->mp) + /* initially, any of them might match */ + s->matchable = (1 << LWS_ARRAY_SIZE(mp_hdrs)) - 1; + + hit = -1; + for (n = 0; n < (int)LWS_ARRAY_SIZE(mp_hdrs); n++) { + + if (!(s->matchable & (1 << n))) + continue; + /* this guy is still in contention... */ + + if (s->mp >= mp_hdrs[n].hdr_len) { + /* he went past the end of it */ + s->matchable &= ~(1 << n); + continue; } + + if (c != mp_hdrs[n].hdr[s->mp]) { + /* mismatched a char */ + s->matchable &= ~(1 << n); + continue; + } + + if (s->mp + 1 == mp_hdrs[n].hdr_len) { + /* we have a winner... */ + hit = n; + break; + } + } + in++; - if (!m) { - /* Unknown header - ignore it */ + if (hit == -1 && !s->matchable) { + /* We ruled them all out */ s->state = MT_IGNORE1; s->mp = 0; continue; } s->mp++; - if (m != 1) + if (hit < 0) continue; - if (mp_hdr[hit][s->mp]) - continue; + /* we matched the one in hit */ s->mp = 0; s->temp[0] = '\0';