}
struct lws *
-lws_create_server_child_wsi(struct lws_context *context, struct lws *parent_wsi,
+lws_create_server_child_wsi(struct lws_vhost *vhost, struct lws *parent_wsi,
unsigned int sid)
{
- struct lws *wsi = lws_create_new_server_wsi(context);
+ struct lws *wsi = lws_create_new_server_wsi(vhost);
if (!wsi)
return NULL;
if (parent_wsi->u.http2.child_count + 1 ==
parent_wsi->u.http2.peer_settings.setting[
LWS_HTTP2_SETTINGS__MAX_CONCURRENT_STREAMS])
- return NULL;
-
+ goto bail;
lws_http2_init(&wsi->u.http2.peer_settings);
lws_http2_init(&wsi->u.http2.my_settings);
wsi->u.http2.stream_id = sid;
wsi->state = LWSS_HTTP2_ESTABLISHED;
wsi->mode = parent_wsi->mode;
- wsi->protocol = &context->protocols[0];
- lws_ensure_user_space(wsi);
+ wsi->protocol = &vhost->protocols[0];
+ if (lws_ensure_user_space(wsi))
+ goto bail;
lwsl_info("%s: %p new child %p, sid %d, user_space=%p\n", __func__,
parent_wsi, wsi, sid, wsi->user_space);
return wsi;
+
+bail:
+ vhost->protocols[0].callback(wsi, LWS_CALLBACK_WSI_DESTROY,
+ NULL, NULL, 0);
+ lws_free(wsi);
+
+ return NULL;
}
int lws_remove_server_child_wsi(struct lws_context *context, struct lws *wsi)
*p++ = sid >> 8;
*p++ = sid;
- lwsl_info("%s: %p (eff %p). type %d, flags 0x%x, sid=%d, len=%d\n",
+ lwsl_info("%s: %p (eff %p). type %d, flags 0x%x, sid=%d, len=%d, tx_credit=%d\n",
__func__, wsi, wsi_eff, type, flags, sid, len,
wsi->u.http2.tx_credit);
if (type == LWS_HTTP2_FRAME_TYPE_DATA) {
if (wsi->u.http2.tx_credit < len)
lwsl_err("%s: %p: sending payload len %d"
- " but tx_credit only %d!\n", len,
+ " but tx_credit only %d!\n", __func__, wsi, len,
wsi->u.http2.tx_credit);
wsi->u.http2.tx_credit -= len;
}
int
lws_http2_parser(struct lws *wsi, unsigned char c)
{
- struct lws_context *context = wsi->context;
struct lws *swsi;
int n;
case LWS_HTTP2_FRAME_TYPE_CONTINUATION:
case LWS_HTTP2_FRAME_TYPE_HEADERS:
lwsl_info(" %02X\n", c);
- if (lws_hpack_interpret(wsi->u.http2.stream_wsi, c))
+ if (!wsi->u.http2.stream_wsi->u.hdr.ah)
+ if (lws_header_table_attach(wsi->u.http2.stream_wsi, 0)) {
+ lwsl_err("%s: Failed to get ah\n", __func__);
+ return 1;
+ }
+ if (lws_hpack_interpret(wsi->u.http2.stream_wsi, c)) {
+ lwsl_notice("%s: lws_hpack_interpret failed\n", __func__);
return 1;
+ }
break;
case LWS_HTTP2_FRAME_TYPE_GOAWAY:
if (wsi->u.http2.count >= 5 && wsi->u.http2.count <= 8) {
break;
case LWS_HTTP2_FRAME_TYPE_WINDOW_UPDATE:
wsi->u.http2.hpack_e_dep &= ~(1 << 31);
- if ((long long)swsi->u.http2.tx_credit + (unsigned long long)wsi->u.http2.hpack_e_dep > (~(1 << 31)))
+ if ((lws_intptr_t)swsi->u.http2.tx_credit + (lws_intptr_t)wsi->u.http2.hpack_e_dep > (~(1 << 31)))
return 1; /* actually need to close swsi not the whole show */
swsi->u.http2.tx_credit += wsi->u.http2.hpack_e_dep;
if (swsi->u.http2.waiting_tx_credit && swsi->u.http2.tx_credit > 0) {
lwsl_info("LWS_HTTP2_FRAME_TYPE_HEADERS: stream_id = %d\n", wsi->u.http2.stream_id);
if (!wsi->u.http2.stream_id)
return 1;
- if (!wsi->u.http2.stream_wsi)
- wsi->u.http2.stream_wsi = lws_create_server_child_wsi(context, wsi, wsi->u.http2.stream_id);
+ if (!wsi->u.http2.stream_wsi) {
+ wsi->u.http2.stream_wsi =
+ lws_create_server_child_wsi(wsi->vhost, wsi, wsi->u.http2.stream_id);
+ wsi->u.http2.stream_wsi->http2_substream = 1;
+ }
/* END_STREAM means after servicing this, close the stream */
wsi->u.http2.END_STREAM = !!(wsi->u.http2.flags & LWS_HTTP2_FLAG_END_STREAM);
if (wsi->state == LWSS_HTTP2_ESTABLISHED_PRE_SETTINGS) {
wsi->state = LWSS_HTTP2_ESTABLISHED;
- wsi->u.http.fd = LWS_INVALID_FILE;
+ wsi->u.http.fop_fd = NULL;
if (lws_is_ssl(lws_http2_get_network_wsi(wsi))) {
- lwsl_info("skipping nonexistant ssl upgrade headers\n");
+ lwsl_info("skipping nonexistent ssl upgrade headers\n");
break;
}
*/
lwsl_info("%s: setting up sid 1\n", __func__);
- swsi = wsi->u.http2.stream_wsi = lws_create_server_child_wsi(context, wsi, 1);
+ swsi = wsi->u.http2.stream_wsi =
+ lws_create_server_child_wsi(wsi->vhost, wsi, 1);
/* pass on the initial headers to SID 1 */
swsi->u.http.ah = wsi->u.http.ah;
wsi->u.http.ah = NULL;