http2 padding and ping to autopong

Signed-off-by: Andy Green <andy.green@linaro.org>
This commit is contained in:
Andy Green 2014-10-27 16:46:44 +08:00
parent 040465d082
commit bbbf07a834
4 changed files with 84 additions and 30 deletions

View file

@ -377,6 +377,12 @@ int lws_hpack_interpret(struct libwebsocket_context *context,
break;
case HPKS_TYPE:
if (wsi->u.http2.count > (wsi->u.http2.length - wsi->u.http2.padding)) {
lwsl_info("padding eat\n");
break;
}
if (c & 0x80) { /* indexed header field only */
/* just a possibly-extended integer */
wsi->u.http2.hpack_type = HPKT_INDEXED_HDR_7;

View file

@ -222,6 +222,7 @@ lws_http2_parser(struct libwebsocket_context *context,
LWS_HTTP2_SETTINGS_LENGTH))
return 1;
break;
case LWS_HTTP2_FRAME_TYPE_CONTINUATION:
case LWS_HTTP2_FRAME_TYPE_HEADERS:
lwsl_info(" %02X\n", c);
if (lws_hpack_interpret(context, wsi->u.http2.stream_wsi, c))
@ -237,6 +238,24 @@ lws_http2_parser(struct libwebsocket_context *context,
}
wsi->u.http2.GOING_AWAY = 1;
break;
case LWS_HTTP2_FRAME_TYPE_DATA:
break;
case LWS_HTTP2_FRAME_TYPE_PRIORITY:
break;
case LWS_HTTP2_FRAME_TYPE_RST_STREAM:
break;
case LWS_HTTP2_FRAME_TYPE_PUSH_PROMISE:
break;
case LWS_HTTP2_FRAME_TYPE_PING:
if (wsi->u.http2.flags & LWS_HTTP2_FLAG_SETTINGS_ACK) { // ack
} else { /* they're sending us a ping request */
if (wsi->u.http2.count > 8)
return 1;
wsi->u.http2.ping_payload[wsi->u.http2.count - 1] = c;
}
break;
case LWS_HTTP2_FRAME_TYPE_WINDOW_UPDATE:
break;
}
if (wsi->u.http2.count != wsi->u.http2.length)
break;
@ -258,6 +277,12 @@ lws_http2_parser(struct libwebsocket_context *context,
n = lws_http_action(context, wsi->u.http2.stream_wsi);
lwsl_info(" action result %d\n", n);
break;
case LWS_HTTP2_FRAME_TYPE_PING:
if (wsi->u.http2.flags & LWS_HTTP2_FLAG_SETTINGS_ACK) { // ack
} else { /* they're sending us a ping request */
lws_set_protocol_write_pending(context, wsi, LWS_PPS_HTTP2_PONG);
}
break;
}
break;
}
@ -302,6 +327,12 @@ lws_http2_parser(struct libwebsocket_context *context,
/* non-ACK coming in means we must ACK it */
lws_set_protocol_write_pending(context, wsi, LWS_PPS_HTTP2_ACK_SETTINGS);
break;
case LWS_HTTP2_FRAME_TYPE_PING:
if (wsi->u.http2.stream_id)
return 1;
if (wsi->u.http2.length != 8)
return 1;
break;
case LWS_HTTP2_FRAME_TYPE_CONTINUATION:
if (wsi->u.http2.END_HEADERS)
return 1;
@ -418,6 +449,17 @@ int lws_http2_do_pps_send(struct libwebsocket_context *context, struct libwebsoc
return lws_http_action(context, swsi);
}
break;
case LWS_PPS_HTTP2_PONG:
memcpy(&settings[LWS_SEND_BUFFER_PRE_PADDING], wsi->u.http2.ping_payload, 8);
n = lws_http2_frame_write(wsi, LWS_HTTP2_FRAME_TYPE_PING,
LWS_HTTP2_FLAG_SETTINGS_ACK,
LWS_HTTP2_STREAM_ID_MASTER, 8,
&settings[LWS_SEND_BUFFER_PRE_PADDING]);
if (n != 8) {
lwsl_info("send %d %d\n", n, m);
return 1;
}
break;
default:
break;
}

View file

@ -325,6 +325,7 @@ enum lws_pending_protocol_send {
LWS_PPS_NONE,
LWS_PPS_HTTP2_MY_SETTINGS,
LWS_PPS_HTTP2_ACK_SETTINGS,
LWS_PPS_HTTP2_PONG,
};
enum lws_rx_parse_state {
@ -696,6 +697,8 @@ struct _lws_http2_related {
unsigned char flags;
unsigned char frame_state;
unsigned char padding;
unsigned char ping_payload[8];
unsigned short round_robin_POLLOUT;
unsigned short count_POLLOUT_children;

View file

@ -100,7 +100,9 @@ lws_context_init_http2_ssl(struct libwebsocket_context *context)
SSL_CTX_set_alpn_select_cb(context->ssl_ctx, alpn_cb, &protos);
lwsl_notice(" HTTP2 / ALPN enabled\n");
#else
lwsl_notice(" HTTP2 / ALPN configured but not supported by OpenSSL version 0x%x\n", OPENSSL_VERSION_NUMBER);
lwsl_notice(
" HTTP2 / ALPN configured but not supported by OpenSSL 0x%x\n",
OPENSSL_VERSION_NUMBER);
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
}
@ -119,36 +121,37 @@ void lws_http2_configure_if_upgraded(struct libwebsocket *wsi)
method = "npn";
}
if (len) {
lwsl_info("negotiated %s using %s\n", name, method);
wsi->use_ssl = 1;
if (strncmp((char *)name, "http/1.1", 8) == 0)
return;
/* http2 */
wsi->mode = LWS_CONNMODE_HTTP2_SERVING;
wsi->state = WSI_STATE_HTTP2_AWAIT_CLIENT_PREFACE;
/* adopt the header info */
ah = wsi->u.hdr.ah;
wsi->mode = LWS_CONNMODE_HTTP2_SERVING;
/* union transition */
memset(&wsi->u, 0, sizeof(wsi->u));
/* http2 union member has http union struct at start */
wsi->u.http.ah = ah;
lws_http2_init(&wsi->u.http2.peer_settings);
lws_http2_init(&wsi->u.http2.my_settings);
/* HTTP2 union */
} else
if (!len) {
lwsl_info("no npn/alpn upgrade\n");
return;
}
lwsl_info("negotiated %s using %s\n", name, method);
wsi->use_ssl = 1;
if (strncmp((char *)name, "http/1.1", 8) == 0)
return;
/* http2 */
wsi->mode = LWS_CONNMODE_HTTP2_SERVING;
wsi->state = WSI_STATE_HTTP2_AWAIT_CLIENT_PREFACE;
/* adopt the header info */
ah = wsi->u.hdr.ah;
wsi->mode = LWS_CONNMODE_HTTP2_SERVING;
/* union transition */
memset(&wsi->u, 0, sizeof(wsi->u));
/* http2 union member has http union struct at start */
wsi->u.http.ah = ah;
lws_http2_init(&wsi->u.http2.peer_settings);
lws_http2_init(&wsi->u.http2.my_settings);
/* HTTP2 union */
#endif
}