Skip to content

Commit

Permalink
Add WebSocketHttp2HandshakeStream.
Browse files Browse the repository at this point in the history
Add WebSocketHttp2HandshakeStream class to perform handshake according
to https://tools.ietf.org/html/draft-ietf-httpbis-h2-websockets-00.

Add WebSocketHandshakeStreamBase::CreateHttp2Stream() pure virtual
method and implement it in all derived classes.

Remove lowercase WebSocket-related headers that are not used after all
(they are leftover from early days of WebSockets over SPDY).

Bug: 801564
Change-Id: I02ca36c4ce3511de7f88b977083bc2b33c3bfcc1
Reviewed-on: https://chromium-review.googlesource.com/926769
Commit-Queue: Bence Béky <bnc@chromium.org>
Reviewed-by: Adam Rice <ricea@chromium.org>
Cr-Commit-Position: refs/heads/master@{#538522}
  • Loading branch information
Bence Béky authored and Commit Bot committed Feb 22, 2018
1 parent 127c4ef commit 46bfbc1
Show file tree
Hide file tree
Showing 16 changed files with 986 additions and 88 deletions.
2 changes: 2 additions & 0 deletions net/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -2188,6 +2188,8 @@ component("net") {
"websockets/websocket_handshake_stream_base.h",
"websockets/websocket_handshake_stream_create_helper.cc",
"websockets/websocket_handshake_stream_create_helper.h",
"websockets/websocket_http2_handshake_stream.cc",
"websockets/websocket_http2_handshake_stream.h",
"websockets/websocket_inflater.cc",
"websockets/websocket_inflater.h",
"websockets/websocket_stream.cc",
Expand Down
5 changes: 5 additions & 0 deletions net/http/http_cache_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,11 @@ class FakeWebSocketHandshakeStreamCreateHelper
bool using_proxy) override {
return nullptr;
}
std::unique_ptr<WebSocketHandshakeStreamBase> CreateHttp2Stream(
base::WeakPtr<SpdySession> session) override {
NOTREACHED();
return nullptr;
}
};

// Returns true if |entry| is not one of the log types paid attention to in this
Expand Down
5 changes: 5 additions & 0 deletions net/http/http_stream_factory_impl_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,11 @@ class WebSocketStreamCreateHelper
return std::make_unique<WebSocketBasicHandshakeStream>(
std::move(connection));
}
std::unique_ptr<WebSocketHandshakeStreamBase> CreateHttp2Stream(
base::WeakPtr<SpdySession> session) override {
NOTREACHED();
return nullptr;
}
};

struct TestCase {
Expand Down
22 changes: 22 additions & 0 deletions net/spdy/chromium/spdy_http_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,28 @@ void CreateSpdyHeadersFromHttpRequest(const HttpRequestInfo& info,
}
}

void CreateSpdyHeadersFromHttpRequestForWebSocket(
const GURL& url,
const HttpRequestHeaders& request_headers,
SpdyHeaderBlock* headers) {
(*headers)[kHttp2MethodHeader] = "CONNECT";
(*headers)[kHttp2AuthorityHeader] = GetHostAndPort(url);
(*headers)[kHttp2SchemeHeader] = "https";
(*headers)[kHttp2PathHeader] = url.PathForRequest();
(*headers)[kHttp2ProtocolHeader] = "websocket";

HttpRequestHeaders::Iterator it(request_headers);
while (it.GetNext()) {
SpdyString name = base::ToLowerASCII(it.name());
if (name.empty() || name[0] == ':' || name == "upgrade" ||
name == "connection" || name == "proxy-connection" ||
name == "transfer-encoding" || name == "host") {
continue;
}
AddSpdyHeader(name, it.value(), headers);
}
}

static_assert(HIGHEST - LOWEST < 4 && HIGHEST - MINIMUM_PRIORITY < 6,
"request priority incompatible with spdy");

Expand Down
7 changes: 7 additions & 0 deletions net/spdy/chromium/spdy_http_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ NET_EXPORT void CreateSpdyHeadersFromHttpRequest(
const HttpRequestHeaders& request_headers,
SpdyHeaderBlock* headers);

// Create a SpdyHeaderBlock from HttpRequestInfo and HttpRequestHeaders for a
// WebSockets over HTTP/2 request.
NET_EXPORT void CreateSpdyHeadersFromHttpRequestForWebSocket(
const GURL& url,
const HttpRequestHeaders& request_headers,
SpdyHeaderBlock* headers);

// Create HttpRequestHeaders from SpdyHeaderBlock.
NET_EXPORT void ConvertHeaderBlockToHttpRequestHeaders(
const SpdyHeaderBlock& spdy_headers,
Expand Down
20 changes: 5 additions & 15 deletions net/websockets/websocket_basic_stream_adapters_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "net/test/gtest_util.h"
#include "net/test/test_data_directory.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/websockets/websocket_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

Expand Down Expand Up @@ -303,23 +304,12 @@ class WebSocketSpdyStreamAdapterTest : public Test {
~WebSocketSpdyStreamAdapterTest() override = default;

static SpdyHeaderBlock RequestHeaders() {
SpdyHeaderBlock request_headers;
request_headers[kHttp2MethodHeader] = "CONNECT";
request_headers[kHttp2AuthorityHeader] = "www.example.org:443";
request_headers[kHttp2SchemeHeader] = "https";
request_headers[kHttp2PathHeader] = "/";
request_headers[":protocol"] = "websocket";
request_headers["origin"] = "http://www.example.org";
request_headers["sec-websocket-version"] = "13";
request_headers["sec-websocket-extensions"] =
"permessage-deflate; client_max_window_bits";
return request_headers;
return WebSocketHttp2Request("/", "www.example.org:443",
"http://www.example.org", {});
}

static SpdyHeaderBlock ResponseHeaders() {
SpdyHeaderBlock response_headers;
response_headers[kHttp2StatusHeader] = "200";
return response_headers;
return WebSocketHttp2Response({});
}

void AddSocketData(SocketDataProvider* data) {
Expand Down Expand Up @@ -349,7 +339,7 @@ class WebSocketSpdyStreamAdapterTest : public Test {

private:
const GURL url_;
SpdySessionKey key_;
const SpdySessionKey key_;
SpdySessionDependencies session_deps_;
std::unique_ptr<HttpNetworkSession> session_;
SSLSocketDataProvider ssl_;
Expand Down
3 changes: 0 additions & 3 deletions net/websockets/websocket_handshake_constants.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@ const char kWebSocketGuid[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";

const char kSecWebSocketProtocolLowercase[] = "sec-websocket-protocol";
const char kSecWebSocketExtensionsLowercase[] = "sec-websocket-extensions";
const char kSecWebSocketKeyLowercase[] = "sec-websocket-key";
const char kSecWebSocketVersionLowercase[] = "sec-websocket-version";
const char kUpgradeLowercase[] = "upgrade";
const char kWebSocketLowercase[] = "websocket";

} // namespace websockets
Expand Down
9 changes: 0 additions & 9 deletions net/websockets/websocket_handshake_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,6 @@ extern const char kSecWebSocketProtocolLowercase[];
// "sec-websocket-extensions"
extern const char kSecWebSocketExtensionsLowercase[];

// "sec-webSocket-key"
extern const char kSecWebSocketKeyLowercase[];

// "sec-websocket-version"
extern const char kSecWebSocketVersionLowercase[];

// "upgrade"
extern const char kUpgradeLowercase[];

// "websocket", as used in the "Upgrade:" header. This is always lowercase
// (except in obsolete versions of the protocol).
extern const char kWebSocketLowercase[];
Expand Down
7 changes: 7 additions & 0 deletions net/websockets/websocket_handshake_stream_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
namespace net {

class ClientSocketHandle;
class SpdySession;

// WebSocketHandshakeStreamBase is the base class of
// WebSocketBasicHandshakeStream. net/http code uses this interface to handle
Expand All @@ -49,6 +50,12 @@ class NET_EXPORT WebSocketHandshakeStreamBase : public HttpStream {
virtual std::unique_ptr<WebSocketHandshakeStreamBase> CreateBasicStream(
std::unique_ptr<ClientSocketHandle> connection,
bool using_proxy) = 0;

// Create a WebSocketHttp2HandshakeStream. This is called after the
// underlying HTTP/2 connection has been established but before the stream
// has been opened. This cannot be called more than once.
virtual std::unique_ptr<WebSocketHandshakeStreamBase> CreateHttp2Stream(
base::WeakPtr<SpdySession> session) = 0;
};

// This has to have an inline implementation so that the net/url_request/
Expand Down
16 changes: 16 additions & 0 deletions net/websockets/websocket_handshake_stream_create_helper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "base/memory/weak_ptr.h"
#include "net/socket/client_socket_handle.h"
#include "net/websockets/websocket_basic_handshake_stream.h"
#include "net/websockets/websocket_http2_handshake_stream.h"

namespace net {

Expand Down Expand Up @@ -45,6 +46,21 @@ WebSocketHandshakeStreamCreateHelper::CreateBasicStream(
return std::move(stream);
}

std::unique_ptr<WebSocketHandshakeStreamBase>
WebSocketHandshakeStreamCreateHelper::CreateHttp2Stream(
base::WeakPtr<SpdySession> session) {
DCHECK(request_) << "set_request() must be called";

std::vector<std::string> extensions(
1, "permessage-deflate; client_max_window_bits");
std::unique_ptr<WebSocketHandshakeStreamBase> stream =
std::make_unique<WebSocketHttp2HandshakeStream>(
session, connect_delegate_, requested_subprotocols_, extensions,
request_);
request_->OnHandshakeStreamCreated(stream.get());
return stream;
}

void WebSocketHandshakeStreamCreateHelper::OnBasicStreamCreated(
WebSocketBasicHandshakeStream* stream) {}

Expand Down
7 changes: 6 additions & 1 deletion net/websockets/websocket_handshake_stream_create_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
namespace net {

class WebSocketStreamRequest;
class SpdySession;
class WebSocketBasicHandshakeStream;

// Implementation of WebSocketHandshakeStreamBase::CreateHelper. This class is
Expand All @@ -37,11 +38,15 @@ class NET_EXPORT_PRIVATE WebSocketHandshakeStreamCreateHelper

// WebSocketHandshakeStreamBase::CreateHelper methods

// Creates a WebSocketBasicHandshakeStream.
// Creates a WebSocketBasicHandshakeStream over a TCP/IP or TLS socket.
std::unique_ptr<WebSocketHandshakeStreamBase> CreateBasicStream(
std::unique_ptr<ClientSocketHandle> connection,
bool using_proxy) override;

// Creates a WebSocketHttp2HandshakeStream over an HTTP/2 connection.
std::unique_ptr<WebSocketHandshakeStreamBase> CreateHttp2Stream(
base::WeakPtr<SpdySession> session) override;

// WebSocketHandshakeStreamCreateHelper methods

// This method must be called before CreateBasicStream().
Expand Down
Loading

0 comments on commit 46bfbc1

Please sign in to comment.