mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
h2: post: handle no content length better
http content-length is not mandatory on POST, making a whole bunch of difficulties. On h2, the client will set the stream half-closed by DATA with END_STREAM flag when it is done. Improve the post data tracking to understand that situation properly.
This commit is contained in:
parent
677b6e370c
commit
c6cb821165
1 changed files with 37 additions and 11 deletions
|
@ -125,18 +125,22 @@ lws_read_h1(struct lws *wsi, unsigned char *buf, lws_filepos_t len)
|
|||
case LRS_DISCARD_BODY:
|
||||
case LRS_BODY:
|
||||
http_postbody:
|
||||
lwsl_debug("%s: http post body: remain %d\n", __func__,
|
||||
(int)wsi->http.rx_content_remain);
|
||||
lwsl_info("%s: http post body: cl set %d, remain %d, len %d\n", __func__,
|
||||
(int)wsi->http.content_length_given,
|
||||
(int)wsi->http.rx_content_remain, (int)len);
|
||||
|
||||
if (!wsi->http.rx_content_remain)
|
||||
if (wsi->http.content_length_given && !wsi->http.rx_content_remain)
|
||||
goto postbody_completion;
|
||||
|
||||
while (len && wsi->http.rx_content_remain) {
|
||||
while (len && (!wsi->http.content_length_given || wsi->http.rx_content_remain)) {
|
||||
/* Copy as much as possible, up to the limit of:
|
||||
* what we have in the read buffer (len)
|
||||
* remaining portion of the POST body (content_remain)
|
||||
*/
|
||||
body_chunk_len = min(wsi->http.rx_content_remain, len);
|
||||
if (wsi->http.content_length_given)
|
||||
body_chunk_len = min(wsi->http.rx_content_remain, len);
|
||||
else
|
||||
body_chunk_len = len;
|
||||
wsi->http.rx_content_remain -= body_chunk_len;
|
||||
// len -= body_chunk_len;
|
||||
#ifdef LWS_WITH_CGI
|
||||
|
@ -159,18 +163,38 @@ http_postbody:
|
|||
} else {
|
||||
#endif
|
||||
if (lwsi_state(wsi) != LRS_DISCARD_BODY) {
|
||||
n = wsi->a.protocol->callback(wsi,
|
||||
LWS_CALLBACK_HTTP_BODY, wsi->user_space,
|
||||
buf, (size_t)body_chunk_len);
|
||||
if (n)
|
||||
goto bail;
|
||||
lwsl_info("%s: HTTP_BODY %d\n", __func__, (int)body_chunk_len);
|
||||
n = (unsigned int)wsi->a.protocol->callback(wsi,
|
||||
LWS_CALLBACK_HTTP_BODY, wsi->user_space,
|
||||
buf, (size_t)body_chunk_len);
|
||||
if (n)
|
||||
goto bail;
|
||||
}
|
||||
n = (size_t)body_chunk_len;
|
||||
#ifdef LWS_WITH_CGI
|
||||
}
|
||||
#endif
|
||||
lwsl_info("%s: advancing buf by %d\n", __func__, (int)n);
|
||||
buf += n;
|
||||
|
||||
#if defined(LWS_ROLE_H2)
|
||||
if (lwsi_role_h2(wsi) && !wsi->http.content_length_given) {
|
||||
struct lws *w = lws_get_network_wsi(wsi);
|
||||
|
||||
lwsl_info("%s: h2: nwsi h2 flags %d\n", __func__,
|
||||
w->h2.h2n ? w->h2.h2n->flags: -1);
|
||||
|
||||
if (w && w->h2.h2n && !(w->h2.h2n->flags & 1)) {
|
||||
lwsl_info("%s: h2, no cl, not END_STREAM, continuing\n", __func__);
|
||||
lws_set_timeout(wsi,
|
||||
PENDING_TIMEOUT_HTTP_CONTENT,
|
||||
(int)wsi->a.context->timeout_secs);
|
||||
break;
|
||||
}
|
||||
goto postbody_completion;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (wsi->http.rx_content_remain) {
|
||||
lws_set_timeout(wsi,
|
||||
PENDING_TIMEOUT_HTTP_CONTENT,
|
||||
|
@ -213,8 +237,10 @@ postbody_completion:
|
|||
n = wsi->a.protocol->callback(wsi,
|
||||
LWS_CALLBACK_HTTP_BODY_COMPLETION,
|
||||
wsi->user_space, NULL, 0);
|
||||
if (n)
|
||||
if (n) {
|
||||
lwsl_info("%s: bailing after BODY_COMPLETION\n", __func__);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if (wsi->mux_substream)
|
||||
lwsi_set_state(wsi, LRS_ESTABLISHED);
|
||||
|
|
Loading…
Add table
Reference in a new issue