1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

h2: post: add states to wait for body

This commit is contained in:
Andy Green 2020-12-19 09:13:24 +00:00
parent c6cb821165
commit eb5f437578
7 changed files with 70 additions and 11 deletions

View file

@ -181,7 +181,8 @@ http_postbody:
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__,
if (w)
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)) {

View file

@ -370,11 +370,14 @@ bail1:
}
int lws_h2_issue_preface(struct lws *wsi)
int
lws_h2_issue_preface(struct lws *wsi)
{
struct lws_h2_netconn *h2n = wsi->h2.h2n;
struct lws_h2_protocol_send *pps;
lwsl_notice("%s: wsi %p: fd %d\n", __func__, wsi, (int)wsi->desc.sockfd);
if (lws_issue_raw(wsi, (uint8_t *)preface, strlen(preface)) !=
(int)strlen(preface))
return 1;
@ -997,9 +1000,14 @@ lws_h2_parse_frame_header(struct lws *wsi)
/* ie, IGNORE */
h2n->type = LWS_H2_FRAME_TYPE_COUNT;
} else {
lwsl_info("%s: received %d bytes data for unknown sid %d, highest known %d\n",
__func__, (int)h2n->length, (int)h2n->sid, (int)h2n->highest_sid_opened);
// if (h2n->sid > h2n->highest_sid_opened) {
lws_h2_goaway(wsi, H2_ERR_STREAM_CLOSED,
"Data for nonexistent sid");
return 0;
// }
}
}
/* if the sid is credible, treat as wsi for it closed */

View file

@ -963,6 +963,18 @@ rops_perform_user_POLLOUT_h2(struct lws *wsi)
lws_h2_bind_for_post_before_action(w);
/*
* Well, we could be getting a POST from the client, it
* may not have any content-length. In that case, we
* will be in LRS_BODY state, we can't actually start
* the action until we had the body and the stream is
* half-closed, indicating that we can reply
*/
if (lwsi_state(w) == LRS_BODY &&
w->h2.h2_state != LWS_H2_STATE_HALF_CLOSED_REMOTE)
goto next_child;
lwsl_info(" h2 action start...\n");
n = lws_http_action(w);
if (n < 0)

View file

@ -137,6 +137,8 @@ lws_http_client_socket_service(struct lws *wsi, struct lws_pollfd *pollfd)
case LRS_H1C_ISSUE_HANDSHAKE:
lwsl_notice("%s: LRS_H1C_ISSUE_HANDSHAKE\n", __func__);
/*
* we are under PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE
* timeout protection set in client-handshake.c
@ -150,13 +152,37 @@ start_ws_handshake:
if (lws_change_pollfd(wsi, LWS_POLLOUT, 0))
return -1;
#if defined(LWS_ROLE_H2) || defined(LWS_WITH_TLS)
if (
#if defined(LWS_WITH_TLS)
!(wsi->tls.use_ssl & LCCSCF_USE_SSL)
#endif
#if defined(LWS_ROLE_H2) && defined(LWS_WITH_TLS)
&&
#endif
#if defined(LWS_ROLE_H2)
!(wsi->flags & LCCSCF_H2_PRIOR_KNOWLEDGE)
#endif
)
goto hs2;
#endif
#if defined(LWS_WITH_TLS)
n = lws_client_create_tls(wsi, &cce, 1);
if (n < 0)
if (n == CCTLS_RETURN_ERROR)
goto bail3;
if (n == 1)
if (n == CCTLS_RETURN_RETRY)
return 0;
/*
* lws_client_create_tls() can already have done the
* whole tls setup and preface send... if so he set our state
* to LRS_H1C_ISSUE_HANDSHAKE2... let's proceed but be prepared
* to notice our state and not resend the preface...
*/
lwsl_notice("%s: LRS_H1C_ISSUE_HANDSHAKE fallthru\n", __func__);
/* fallthru */
case LRS_WAITING_SSL:
@ -171,7 +197,7 @@ start_ws_handshake:
}
} else {
wsi->tls.ssl = NULL;
if(wsi->flags & LCCSCF_H2_PRIOR_KNOWLEDGE) {
if (wsi->flags & LCCSCF_H2_PRIOR_KNOWLEDGE) {
lwsl_info("h2 prior knowledge\n");
lws_role_call_alpn_negotiated(wsi, "h2");
}
@ -187,8 +213,9 @@ start_ws_handshake:
lws_det_lat_cb(wsi->a.context, &wsi->detlat);
}
#endif
#if defined (LWS_WITH_HTTP2)
if (wsi->client_h2_alpn) {
if (wsi->client_h2_alpn && lwsi_state(wsi) != LRS_H1C_ISSUE_HANDSHAKE2) {
/*
* We connected to the server and set up tls and
* negotiated "h2" or connected as clear text
@ -199,9 +226,8 @@ start_ws_handshake:
*/
#if defined(LWS_WITH_TLS)
if (wsi->tls.use_ssl & LCCSCF_USE_SSL) {
if (wsi->tls.use_ssl & LCCSCF_USE_SSL)
lws_tls_server_conn_alpn(wsi);
}
#endif
/* send the H2 preface to legitimize the connection */
@ -221,6 +247,9 @@ start_ws_handshake:
/* fallthru */
case LRS_H1C_ISSUE_HANDSHAKE2:
hs2:
p = lws_generate_client_handshake(wsi, p);
if (p == NULL) {
if (wsi->role_ops == &role_ops_raw_skt
@ -336,6 +365,10 @@ client_http_body_sent:
goto bail3;
}
if (pollfd->revents & LWS_POLLOUT)
if (lws_change_pollfd(wsi, LWS_POLLOUT, 0))
return -1;
if (!(pollfd->revents & LWS_POLLIN))
break;

View file

@ -1192,7 +1192,8 @@ drain:
}
//lws_buflist_describe(&wsi->buflist, wsi, __func__);
//lwsl_notice("%s: consuming %d / %d\n", __func__, n, ebuf.len);
if (lws_buflist_aware_finished_consuming(wsi, &ebuf, n,
if (ebuf.len < 0 ||
lws_buflist_aware_finished_consuming(wsi, &ebuf, n,
buffered, __func__))
return LWS_HPI_RET_PLEASE_CLOSE_ME;
}

View file

@ -199,6 +199,7 @@ lws_client_create_tls(struct lws *wsi, const char **pcce, int do_c1)
} else
wsi->tls.ssl = NULL;
#if 0
#if defined (LWS_WITH_HTTP2)
if (wsi->client_h2_alpn) {
/*
@ -217,7 +218,10 @@ lws_client_create_tls(struct lws *wsi, const char **pcce, int do_c1)
*pcce = "error sending h2 preface";
return CCTLS_RETURN_ERROR;
}
lwsi_set_state(wsi, LRS_H1C_ISSUE_HANDSHAKE2);
}
#endif
#endif
return CCTLS_RETURN_DONE; /* OK */

View file

@ -88,11 +88,11 @@ callback_http(struct lws *wsi, enum lws_callback_reasons reason,
* Tell lws we are going to send the body next...
*/
if (posting && !lws_http_is_redirected_to_get(wsi)) {
lwsl_user("%s: doing POST flow\n", __func__);
lwsl_user("%s: conn %d, doing POST flow\n", __func__, idx);
lws_client_http_body_pending(wsi, 1);
lws_callback_on_writable(wsi);
} else
lwsl_user("%s: doing GET flow\n", __func__);
lwsl_user("%s: conn %d, doing GET flow\n", __func__, idx);
break;
/* uninterpreted http content */