diff --git a/lib/core-net/close.c b/lib/core-net/close.c index 77545b48b..7803ccc00 100644 --- a/lib/core-net/close.c +++ b/lib/core-net/close.c @@ -239,6 +239,10 @@ __lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason, lws_access_log(wsi); + if (!lws_dll2_is_detached(&wsi->dll_buflist)) { + lwsl_info("%s: wsi %p: going down with stuff in buflist\n", + __func__, wsi); } + context = wsi->context; pt = &context->pt[(int)wsi->tsi]; lws_stats_bump(pt, LWSSTATS_C_API_CLOSE, 1); diff --git a/lib/core-net/dummy-callback.c b/lib/core-net/dummy-callback.c index f677719bd..44346c3fc 100644 --- a/lib/core-net/dummy-callback.c +++ b/lib/core-net/dummy-callback.c @@ -261,7 +261,7 @@ lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason, struct lws_cgi_args *args; #endif #if defined(LWS_WITH_CGI) || defined(LWS_WITH_HTTP_PROXY) - char buf[8192]; + char buf[LWS_PRE + 32 + 8192]; int n; #endif #if defined(LWS_WITH_HTTP_PROXY) diff --git a/lib/core-net/server.c b/lib/core-net/server.c index d92fdd6a5..ef35e6c23 100644 --- a/lib/core-net/server.c +++ b/lib/core-net/server.c @@ -224,7 +224,8 @@ lws_json_dump_context(const struct lws_context *context, char *buf, int len, "\"ah_pool_max\":\"%d\",\n" "\"deprecated\":\"%d\",\n" "\"wsi_alive\":\"%d\",\n", - (unsigned long long)(lws_now_usecs() - context->time_up), + (unsigned long long)(lws_now_usecs() - context->time_up) / + LWS_US_PER_SEC, context->count_cgi_spawned, context->fd_limit_per_thread, context->max_http_header_pool, diff --git a/lib/core-net/service.c b/lib/core-net/service.c index a2eeeefb5..1bfc604fc 100644 --- a/lib/core-net/service.c +++ b/lib/core-net/service.c @@ -269,13 +269,15 @@ lws_rxflow_cache(struct lws *wsi, unsigned char *buf, int n, int len) /* a new rxflow, buffer it and warn caller */ + lwsl_debug("%s: rxflow append %d\n", __func__, len - n); m = lws_buflist_append_segment(&wsi->buflist, buf + n, len - n); if (m < 0) return LWSRXFC_ERROR; if (m) { lwsl_debug("%s: added %p to rxflow list\n", __func__, wsi); - lws_dll2_add_head(&wsi->dll_buflist, &pt->dll_buflist_owner); + if (lws_dll2_is_detached(&wsi->dll_buflist)) + lws_dll2_add_head(&wsi->dll_buflist, &pt->dll_buflist_owner); } return ret; @@ -366,12 +368,14 @@ lws_buflist_aware_read(struct lws_context_per_thread *pt, struct lws *wsi, /* stash what we read */ + // lwsl_debug("%s: appending %d\n", __func__, ebuf->len); n = lws_buflist_append_segment(&wsi->buflist, ebuf->token, ebuf->len); if (n < 0) return -1; if (n) { - lwsl_debug("%s: added %p to rxflow list\n", __func__, wsi); - lws_dll2_add_head(&wsi->dll_buflist, &pt->dll_buflist_owner); + // lwsl_debug("%s: added %p to rxflow list\n", __func__, wsi); + if (lws_dll2_is_detached(&wsi->dll_buflist)) + lws_dll2_add_head(&wsi->dll_buflist, &pt->dll_buflist_owner); } /* get the first buflist guy in line */ @@ -420,9 +424,11 @@ lws_buflist_aware_consume(struct lws *wsi, struct lws_tokens *ebuf, int used, if (m) { lwsl_debug("%s: added %p to rxflow list\n", __func__, wsi); - lws_dll2_add_head(&wsi->dll_buflist, + if (lws_dll2_is_detached(&wsi->dll_buflist)) + lws_dll2_add_head(&wsi->dll_buflist, &pt->dll_buflist_owner); } + // lws_buflist_describe(&wsi->buflist, wsi); } return 0; diff --git a/lib/core/buflist.c b/lib/core/buflist.c index 723bb5bb1..c220ae4ff 100644 --- a/lib/core/buflist.c +++ b/lib/core/buflist.c @@ -59,7 +59,8 @@ lws_buflist_append_segment(struct lws_buflist **head, const uint8_t *buf, lwsl_info("%s: len %u first %d %p\n", __func__, (unsigned int)len, first, p); - nbuf = (struct lws_buflist *)lws_malloc(sizeof(**head) + len, __func__); + nbuf = (struct lws_buflist *)lws_malloc( + sizeof(struct lws_buflist) + len + LWS_PRE, __func__); if (!nbuf) { lwsl_err("%s: OOM\n", __func__); return -1; @@ -69,7 +70,8 @@ lws_buflist_append_segment(struct lws_buflist **head, const uint8_t *buf, nbuf->pos = 0; nbuf->next = NULL; - p = (void *)nbuf->buf; + /* whoever consumes this might need LWS_PRE from the start... */ + p = (uint8_t *)nbuf + sizeof(*nbuf) + LWS_PRE; memcpy(p, buf, len); *head = nbuf; @@ -85,6 +87,7 @@ lws_buflist_destroy_segment(struct lws_buflist **head) assert(*head); *head = old->next; old->next = NULL; + old->pos = old->len = 0; lws_free(old); return !*head; /* returns 1 if last segment just destroyed */ @@ -108,48 +111,60 @@ lws_buflist_destroy_all_segments(struct lws_buflist **head) size_t lws_buflist_next_segment_len(struct lws_buflist **head, uint8_t **buf) { - if (!*head) { + struct lws_buflist *b = (*head); + + if (!b) { if (buf) *buf = NULL; return 0; } - if (!(*head)->len && (*head)->next) + if (!b->len && b->next) lws_buflist_destroy_segment(head); - if (!*head) { + if (!b) { if (buf) *buf = NULL; return 0; } - assert((*head)->pos < (*head)->len); + assert(b->pos < b->len); if (buf) - *buf = (*head)->buf + (*head)->pos; + *buf = ((uint8_t *)b) + sizeof(*b) + b->pos + LWS_PRE; - return (*head)->len - (*head)->pos; + return b->len - b->pos; } int lws_buflist_use_segment(struct lws_buflist **head, size_t len) { - assert(*head); + struct lws_buflist *b = (*head); + + assert(b); assert(len); - assert((*head)->pos + len <= (*head)->len); + assert(b->pos + len <= b->len); - (*head)->pos += len; - if ((*head)->pos == (*head)->len) - lws_buflist_destroy_segment(head); + b->pos = b->pos + (size_t)len; - if (!*head) - return 0; + assert(b->pos <= b->len); - return (int)((*head)->len - (*head)->pos); + if (b->pos < b->len) + return (int)(b->len - b->pos); + + if (b->pos == b->len) { + if (lws_buflist_destroy_segment(head)) + return 0; + + return lws_buflist_next_segment_len(head, NULL); + } + + return 0; } +#if defined(_DEBUG) void lws_buflist_describe(struct lws_buflist **head, void *id) { @@ -173,3 +188,4 @@ lws_buflist_describe(struct lws_buflist **head, void *id) n++; } } +#endif diff --git a/lib/core/private-lib-core.h b/lib/core/private-lib-core.h index cf72f27eb..12576d734 100644 --- a/lib/core/private-lib-core.h +++ b/lib/core/private-lib-core.h @@ -464,14 +464,10 @@ signed char char_to_hex(const char c); struct lws_buflist { struct lws_buflist *next; - size_t len; size_t pos; - - uint8_t buf[1]; /* true length of this is set by the oversize malloc */ }; - LWS_EXTERN char * lws_strdup(const char *s); diff --git a/lib/roles/h2/hpack.c b/lib/roles/h2/hpack.c index 01dd47595..66021791d 100644 --- a/lib/roles/h2/hpack.c +++ b/lib/roles/h2/hpack.c @@ -1349,7 +1349,8 @@ int lws_add_http2_header_by_name(struct lws *wsi, const unsigned char *name, { int len; - lwsl_header("%s: %p %s:%s\n", __func__, *p, name, value); + lwsl_header("%s: %p %s:%s (len %d)\n", __func__, *p, name, value, + length); len = (int)strlen((char *)name); if (len) diff --git a/lib/roles/h2/ops-h2.c b/lib/roles/h2/ops-h2.c index 99d10829d..765aebe34 100644 --- a/lib/roles/h2/ops-h2.c +++ b/lib/roles/h2/ops-h2.c @@ -291,7 +291,8 @@ drain: if (m) { lwsl_debug("%s: added %p to rxflow list\n", __func__, wsi); - lws_dll2_add_head(&wsi->dll_buflist, + if (lws_dll2_is_detached(&wsi->dll_buflist)) + lws_dll2_add_head(&wsi->dll_buflist, &pt->dll_buflist_owner); } } diff --git a/lib/roles/http/client/client-http.c b/lib/roles/http/client/client-http.c index 8947cc24c..5c0fe0296 100644 --- a/lib/roles/http/client/client-http.c +++ b/lib/roles/http/client/client-http.c @@ -141,7 +141,6 @@ lws_client_socket_service(struct lws *wsi, struct lws_pollfd *pollfd, switch (lwsi_state(wsi)) { case LRS_WAITING_DNS: - /* * we are under PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE * timeout protection set in client-handshake.c diff --git a/lib/roles/ws/server-ws.c b/lib/roles/ws/server-ws.c index 18b26e692..91d8e9fbf 100644 --- a/lib/roles/ws/server-ws.c +++ b/lib/roles/ws/server-ws.c @@ -368,8 +368,8 @@ lws_process_ws_upgrade2(struct lws *wsi) #if defined(LWS_WITH_ACCESS_LOG) { - char *uptr = NULL, combo[128]; - int l, meth = lws_http_get_uri_and_method(wsi, &uptr, &l); + char *uptr = "unknown method", combo[128]; + int l = 14, meth = lws_http_get_uri_and_method(wsi, &uptr, &l); if (wsi->h2_stream_carries_ws) wsi->http.request_version = HTTP_VERSION_2;