diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h index 7f06627f..3748acb5 100755 --- a/lib/private-libwebsockets.h +++ b/lib/private-libwebsockets.h @@ -353,6 +353,8 @@ enum connection_mode { LWS_CONNMODE_WS_SERVING, LWS_CONNMODE_WS_CLIENT, + + LWS_CONNMODE_HTTP2_SERVING, /* transient, ssl delay hiding */ LWS_CONNMODE_SSL_ACK_PENDING, @@ -552,6 +554,9 @@ struct _lws_http_mode_related { int content_remain; }; +struct _lws_http2_related { +}; + struct _lws_header_related { struct allocated_headers *ah; short lextable_pos; @@ -635,6 +640,7 @@ struct libwebsocket { union u { struct _lws_http_mode_related http; + struct _lws_http2_related http2; struct _lws_header_related hdr; struct _lws_websocket_related ws; } u; diff --git a/lib/server.c b/lib/server.c index f0ebb1fa..35a82e95 100644 --- a/lib/server.c +++ b/lib/server.c @@ -358,11 +358,37 @@ int lws_handshake_server(struct libwebsocket_context *context, "websocket")) goto upgrade_ws; + if (!strcasecmp(lws_hdr_simple_ptr(wsi, WSI_TOKEN_UPGRADE), + "h2c")) + goto upgrade_h2c; /* dunno what he wanted to upgrade to */ goto bail_nuke_ah; +upgrade_h2c: + + strcpy(protocol_list, "HTTP/1.1 101 Switching Protocols\x0d\x0a" + "Connection: Upgrade\x0d\x0a" + "Upgrade: h2c\x0d\x0a\x0d\x0a"); + n = libwebsocket_write(wsi, (unsigned char *)protocol_list, + strlen(protocol_list), LWS_WRITE_HTTP); + if (n != strlen(protocol_list)) { + lwsl_debug("http2 switch: ERROR writing to socket\n"); + goto bail_nuke_ah; + } + + /* drop the header info -- no bail_nuke_ah after this */ + + if (wsi->u.hdr.ah) + free(wsi->u.hdr.ah); + + wsi->mode = LWS_CONNMODE_HTTP2_SERVING; + + /* union transition */ + memset(&wsi->u, 0, sizeof(wsi->u)); + return 0; + upgrade_ws: if (!wsi->protocol) lwsl_err("NULL protocol at libwebsocket_read\n"); diff --git a/lib/service.c b/lib/service.c index e1b322ca..9238967c 100644 --- a/lib/service.c +++ b/lib/service.c @@ -471,6 +471,9 @@ drain: goto read_pending; break; + case LWS_CONNMODE_HTTP2_SERVING: + break; + default: #ifdef LWS_NO_CLIENT break; diff --git a/test-server/test-server.c b/test-server/test-server.c index 1a820994..984c43ab 100644 --- a/test-server/test-server.c +++ b/test-server/test-server.c @@ -857,7 +857,7 @@ int main(int argc, char **argv) lws_set_log_level(debug_level, lwsl_emit_syslog); lwsl_notice("libwebsockets test server - " - "(C) Copyright 2010-2013 Andy Green - " + "(C) Copyright 2010-2014 Andy Green - " "licensed under LGPL2.1\n"); #ifdef EXTERNAL_POLL max_poll_elements = getdtablesize();