diff --git a/lib/core/context.c b/lib/core/context.c index 8b0759455..8ea35dc6d 100644 --- a/lib/core/context.c +++ b/lib/core/context.c @@ -522,11 +522,13 @@ lws_create_context(const struct lws_context_creation_info *info) else context->max_http_header_pool = context->max_fds; + if (info->fd_limit_per_thread) context->fd_limit_per_thread = lpf; 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 7e79eb009..1bbf77a63 100644 --- a/lib/roles/http/server/lws-spa.c +++ b/lib/roles/http/server/lws-spa.c @@ -42,10 +42,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; @@ -69,10 +72,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; @@ -150,7 +155,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; while (len--) { @@ -281,29 +286,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';