Commit c570adab authored by Yoichi Osato's avatar Yoichi Osato Committed by Commit Bot

[websocket] Reland: "Split interface mojom::WebSocketClient"

This CL splits the interface to two parts so that WebRequestProxyingWebSocket or
extensions proxy only handshake of WebSocket:

interface WebSocketHandshakeClient {
  OnStartOpeningHandshake(WebSocketHandshakeRequest request);
  OnFinishOpeningHandshake(WebSocketHandshakeResponse response);
  OnAddChannelResponse(string selected_protocol, string extensions);
};

interface WebSocketClient {
  OnDataFrame(bool fin, WebSocketMessageType type, array<uint8> data);
  OnFlowControl(int64 quota);
  OnDropChannel(bool was_clean, uint16 code, string reason);
  OnClosingHandshake();
  OnFailChannel(string reason);
};

Performance gain of receive-arraybuffer-1MBx100.html:
Mine: 1050 ms
ToT : 1221 ms

Relanding:
 The previous patch was reverted because of a browser test
of "--disable-features=NetworkService". This patch fixes it to adapt
a WebRequestAPI test to both expectations.
 Reverted-change: https://chromium-review.googlesource.com/c/chromium/src/+/1628497

Bug: 865001, 942989
Test: browser_tests --gtest_filter=*ExtensionWebRequestApiTest* (--disable-features=NetworkService)
Change-Id: I24d573c0a977d4557cc8c211900a110e73fb996e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1630084Reviewed-by: default avatarKaran Bhatia <karandeepb@chromium.org>
Reviewed-by: default avatarYutaka Hirano <yhirano@chromium.org>
Reviewed-by: default avatarAdam Rice <ricea@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Commit-Queue: Yoichi Osato <yoichio@chromium.org>
Cr-Commit-Position: refs/heads/master@{#665824}
parent 83fe3883
...@@ -1519,7 +1519,14 @@ IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, ...@@ -1519,7 +1519,14 @@ IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest,
WebSocketRequestAuthRequired) { WebSocketRequestAuthRequired) {
ASSERT_TRUE(StartEmbeddedTestServer()); ASSERT_TRUE(StartEmbeddedTestServer());
ASSERT_TRUE(StartWebSocketServer(net::GetWebSocketTestDataDirectory(), true)); ASSERT_TRUE(StartWebSocketServer(net::GetWebSocketTestDataDirectory(), true));
ASSERT_TRUE(RunExtensionSubtest("webrequest", "test_websocket_auth.html")) // Test expectations differ with the Network Service because of the way
// mojo onError is handled.
const char* network_service_arg =
base::FeatureList::IsEnabled(network::features::kNetworkService)
? "NetworkServiceEnabled"
: "NetworkServiceDisabled";
ASSERT_TRUE(RunExtensionSubtestWithArg(
"webrequest", "test_websocket_auth.html", network_service_arg))
<< message_; << message_;
} }
......
...@@ -2,363 +2,420 @@ ...@@ -2,363 +2,420 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
chrome.tabs.getCurrent(function(tab) { chrome.test.getConfig(function(config) {
runTestsForTab([ // TODO(yoichio): Remove this if network service is enabled w/o flag.
// onAuthRequired is not a blocking function. let networkServiceEnabled = (config.customArg === 'NetworkServiceEnabled');
function webSocketAuthRequiredNonBlocking() {
var url = getWSTestURL(testWebSocketPort);
expect(
[ //events
{ label: 'onBeforeRequest',
event: 'onBeforeRequest',
details: {
url: url,
type: 'websocket',
frameUrl: 'unknown frame URL',
initiator: getDomain(initiators.WEB_INITIATED)
},
},
{ label: 'onBeforeSendHeaders',
event: 'onBeforeSendHeaders',
details: {
url: url,
type: 'websocket',
initiator: getDomain(initiators.WEB_INITIATED)
},
},
{ label: 'onSendHeaders',
event: 'onSendHeaders',
details: {
url: url,
type: 'websocket',
initiator: getDomain(initiators.WEB_INITIATED)
},
},
{ label: 'onHeadersReceived',
event: 'onHeadersReceived',
details: {
url: url,
type: 'websocket',
statusCode: 401,
statusLine: 'HTTP/1.0 401 Unauthorized',
responseHeadersExist: true,
initiator: getDomain(initiators.WEB_INITIATED)
}
},
{ label: 'onAuthRequired',
event: 'onAuthRequired',
details: {
url: url,
type: 'websocket',
isProxy: false,
scheme: 'basic',
realm: 'Pywebsocket',
challenger: {host: 'localhost', port: testWebSocketPort},
statusCode: 401,
statusLine: 'HTTP/1.0 401 Unauthorized',
responseHeadersExist: true,
initiator: getDomain(initiators.WEB_INITIATED)
}
},
{ label: 'onResponseStarted',
event: 'onResponseStarted',
details: {
url: url,
type: 'websocket',
ip: '127.0.0.1',
fromCache: false,
statusCode: 401,
statusLine: 'HTTP/1.0 401 Unauthorized',
responseHeadersExist: true,
initiator: getDomain(initiators.WEB_INITIATED)
}
},
{ label: 'onErrorOccurred',
event: 'onErrorOccurred',
details: {
url: url,
type: 'websocket',
ip: '127.0.0.1',
fromCache: false,
error: 'net::ERR_ABORTED',
initiator: getDomain(initiators.WEB_INITIATED)
}
},
],
[ // event order
['onBeforeRequest', 'onBeforeSendHeaders', 'onSendHeaders',
'onHeadersReceived', 'onAuthRequired', 'onResponseStarted',
'onErrorOccurred']
],
{urls: ['<all_urls>']}, // filter
['responseHeaders'] // extraInfoSpec
);
testWebSocketConnection(url, false /* expectedToConnect*/);
},
// onAuthRequired is a blocking function but takes no action. chrome.tabs.getCurrent(function(tab) {
function webSocketAuthRequiredSyncNoAction() { runTestsForTab(
var url = getWSTestURL(testWebSocketPort); [
expect( // onAuthRequired is not a blocking function.
[ // events function webSocketAuthRequiredNonBlocking() {
{ label: 'onBeforeRequest', var url = getWSTestURL(testWebSocketPort);
event: 'onBeforeRequest', expect(
details: { [
url: url, // events
type: 'websocket', {
frameUrl: 'unknown frame URL', label: 'onBeforeRequest',
initiator: getDomain(initiators.WEB_INITIATED) event: 'onBeforeRequest',
} details: {
}, url: url,
{ label: 'onBeforeSendHeaders', type: 'websocket',
event: 'onBeforeSendHeaders', frameUrl: 'unknown frame URL',
details: { initiator: getDomain(initiators.WEB_INITIATED)
url: url, },
type: 'websocket', },
initiator: getDomain(initiators.WEB_INITIATED) {
}, label: 'onBeforeSendHeaders',
}, event: 'onBeforeSendHeaders',
{ label: 'onSendHeaders', details: {
event: 'onSendHeaders', url: url,
details: { type: 'websocket',
url: url, initiator: getDomain(initiators.WEB_INITIATED)
type: 'websocket', },
initiator: getDomain(initiators.WEB_INITIATED) },
} {
}, label: 'onSendHeaders',
{ label: 'onHeadersReceived', event: 'onSendHeaders',
event: 'onHeadersReceived', details: {
details: { url: url,
url: url, type: 'websocket',
type: 'websocket', initiator: getDomain(initiators.WEB_INITIATED)
statusCode: 401, },
statusLine: 'HTTP/1.0 401 Unauthorized', },
initiator: getDomain(initiators.WEB_INITIATED) {
} label: 'onHeadersReceived',
event: 'onHeadersReceived',
details: {
url: url,
type: 'websocket',
statusCode: 401,
statusLine: 'HTTP/1.0 401 Unauthorized',
responseHeadersExist: true,
initiator: getDomain(initiators.WEB_INITIATED)
}
},
{
label: 'onAuthRequired',
event: 'onAuthRequired',
details: {
url: url,
type: 'websocket',
isProxy: false,
scheme: 'basic',
realm: 'Pywebsocket',
challenger: {host: 'localhost', port: testWebSocketPort},
statusCode: 401,
statusLine: 'HTTP/1.0 401 Unauthorized',
responseHeadersExist: true,
initiator: getDomain(initiators.WEB_INITIATED)
}
},
{
label: 'onResponseStarted',
event: 'onResponseStarted',
details: {
url: url,
type: 'websocket',
ip: '127.0.0.1',
fromCache: false,
statusCode: 401,
statusLine: 'HTTP/1.0 401 Unauthorized',
responseHeadersExist: true,
initiator: getDomain(initiators.WEB_INITIATED)
}
},
{
label: 'onErrorOccurred',
event: 'onErrorOccurred',
details: {
url: url,
type: 'websocket',
ip: '127.0.0.1',
fromCache: false,
error:
(networkServiceEnabled ? 'net::ERR_FAILED' :
'net::ERR_ABORTED'),
initiator: getDomain(initiators.WEB_INITIATED)
}
},
],
[ // event order
[
'onBeforeRequest', 'onBeforeSendHeaders', 'onSendHeaders',
'onHeadersReceived', 'onAuthRequired', 'onResponseStarted',
'onErrorOccurred'
]
],
{urls: ['<all_urls>']}, // filter
['responseHeaders'] // extraInfoSpec
);
testWebSocketConnection(url, false /* expectedToConnect*/);
}, },
{ label: 'onAuthRequired',
event: 'onAuthRequired',
details: {
url: url,
type: 'websocket',
isProxy: false,
scheme: 'basic',
realm: 'Pywebsocket',
challenger: {host: 'localhost', port: testWebSocketPort},
statusCode: 401,
statusLine: 'HTTP/1.0 401 Unauthorized',
initiator: getDomain(initiators.WEB_INITIATED)
}
},
{ label: 'onResponseStarted',
event: 'onResponseStarted',
details: {
url: url,
type: 'websocket',
fromCache: false,
ip: '127.0.0.1',
statusCode: 401,
statusLine: 'HTTP/1.0 401 Unauthorized',
initiator: getDomain(initiators.WEB_INITIATED)
}
},
{ label: 'onErrorOccurred',
event: 'onErrorOccurred',
details: {
url: url,
type: 'websocket',
ip: '127.0.0.1',
fromCache: false,
error: 'net::ERR_ABORTED',
initiator: getDomain(initiators.WEB_INITIATED)
}
},
],
[ // event order
['onBeforeRequest', 'onBeforeSendHeaders', 'onSendHeaders',
'onHeadersReceived', 'onAuthRequired', 'onResponseStarted',
'onErrorOccurred']
],
{urls: ['<all_urls>']}, ['blocking']);
testWebSocketConnection(url, false /* expectedToConnect*/);
},
// onAuthRequired is a blocking function that cancels the auth attempt. // onAuthRequired is a blocking function but takes no action.
function webSocketAuthRequiredSyncCancelAuth() { function webSocketAuthRequiredSyncNoAction() {
var url = getWSTestURL(testWebSocketPort); var url = getWSTestURL(testWebSocketPort);
expect( expect(
[ // events [
{ label: 'onBeforeRequest', // events
event: 'onBeforeRequest', {
details: { label: 'onBeforeRequest',
url: url, event: 'onBeforeRequest',
type: 'websocket', details: {
frameUrl: 'unknown frame URL', url: url,
initiator: getDomain(initiators.WEB_INITIATED) type: 'websocket',
} frameUrl: 'unknown frame URL',
}, initiator: getDomain(initiators.WEB_INITIATED)
{ label: 'onBeforeSendHeaders', }
event: 'onBeforeSendHeaders', },
details: { {
url: url, label: 'onBeforeSendHeaders',
type: 'websocket', event: 'onBeforeSendHeaders',
initiator: getDomain(initiators.WEB_INITIATED) details: {
}, url: url,
}, type: 'websocket',
{ label: 'onSendHeaders', initiator: getDomain(initiators.WEB_INITIATED)
event: 'onSendHeaders', },
details: { },
url: url, {
type: 'websocket', label: 'onSendHeaders',
initiator: getDomain(initiators.WEB_INITIATED) event: 'onSendHeaders',
} details: {
}, url: url,
{ label: 'onHeadersReceived', type: 'websocket',
event: 'onHeadersReceived', initiator: getDomain(initiators.WEB_INITIATED)
details: { }
url: url, },
type: 'websocket', {
statusCode: 401, label: 'onHeadersReceived',
statusLine: 'HTTP/1.0 401 Unauthorized', event: 'onHeadersReceived',
initiator: getDomain(initiators.WEB_INITIATED) details: {
} url: url,
type: 'websocket',
statusCode: 401,
statusLine: 'HTTP/1.0 401 Unauthorized',
initiator: getDomain(initiators.WEB_INITIATED)
}
},
{
label: 'onAuthRequired',
event: 'onAuthRequired',
details: {
url: url,
type: 'websocket',
isProxy: false,
scheme: 'basic',
realm: 'Pywebsocket',
challenger: {host: 'localhost', port: testWebSocketPort},
statusCode: 401,
statusLine: 'HTTP/1.0 401 Unauthorized',
initiator: getDomain(initiators.WEB_INITIATED)
}
},
{
label: 'onResponseStarted',
event: 'onResponseStarted',
details: {
url: url,
type: 'websocket',
fromCache: false,
ip: '127.0.0.1',
statusCode: 401,
statusLine: 'HTTP/1.0 401 Unauthorized',
initiator: getDomain(initiators.WEB_INITIATED)
}
},
{
label: 'onErrorOccurred',
event: 'onErrorOccurred',
details: {
url: url,
type: 'websocket',
ip: '127.0.0.1',
fromCache: false,
error:
(networkServiceEnabled ? 'net::ERR_FAILED' :
'net::ERR_ABORTED'),
initiator: getDomain(initiators.WEB_INITIATED)
}
},
],
[ // event order
[
'onBeforeRequest', 'onBeforeSendHeaders', 'onSendHeaders',
'onHeadersReceived', 'onAuthRequired', 'onResponseStarted',
'onErrorOccurred'
]
],
{urls: ['<all_urls>']}, ['blocking']);
testWebSocketConnection(url, false /* expectedToConnect*/);
}, },
{ label: 'onAuthRequired',
event: 'onAuthRequired',
details: {
url: url,
type: 'websocket',
isProxy: false,
scheme: 'basic',
realm: 'Pywebsocket',
challenger: {host: 'localhost', port: testWebSocketPort},
statusCode: 401,
statusLine: 'HTTP/1.0 401 Unauthorized',
initiator: getDomain(initiators.WEB_INITIATED)
},
retval: {cancel: true}
},
{ label: 'onResponseStarted',
event: 'onResponseStarted',
details: {
url: url,
type: 'websocket',
fromCache: false,
ip: '127.0.0.1',
statusCode: 401,
statusLine: 'HTTP/1.0 401 Unauthorized',
initiator: getDomain(initiators.WEB_INITIATED)
}
},
{ label: 'onErrorOccurred',
event: 'onErrorOccurred',
details: {
url: url,
type: 'websocket',
ip: '127.0.0.1',
fromCache: false,
error: 'net::ERR_ABORTED',
initiator: getDomain(initiators.WEB_INITIATED)
}
},
],
[ // event order
['onBeforeRequest', 'onBeforeSendHeaders', 'onSendHeaders',
'onHeadersReceived', 'onAuthRequired', 'onResponseStarted',
'onErrorOccurred']
],
{urls: ['<all_urls>']}, ['blocking']);
testWebSocketConnection(url, false /* expectedToConnect*/);
},
// onAuthRequired is a blocking function setting authentication credentials. // onAuthRequired is a blocking function that cancels the auth
function webSocketAuthRequiredSyncSetAuth() { // attempt.
var url = getWSTestURL(testWebSocketPort); function webSocketAuthRequiredSyncCancelAuth() {
expect( var url = getWSTestURL(testWebSocketPort);
[ // events expect(
{ label: 'onBeforeRequest', [
event: 'onBeforeRequest', // events
details: { {
url: url, label: 'onBeforeRequest',
type: 'websocket', event: 'onBeforeRequest',
frameUrl: 'unknown frame URL', details: {
initiator: getDomain(initiators.WEB_INITIATED) url: url,
} type: 'websocket',
}, frameUrl: 'unknown frame URL',
{ label: 'onBeforeSendHeaders', initiator: getDomain(initiators.WEB_INITIATED)
event: 'onBeforeSendHeaders', }
details: { },
url: url, {
type: 'websocket', label: 'onBeforeSendHeaders',
initiator: getDomain(initiators.WEB_INITIATED) event: 'onBeforeSendHeaders',
}, details: {
}, url: url,
{ label: 'onSendHeaders', type: 'websocket',
event: 'onSendHeaders', initiator: getDomain(initiators.WEB_INITIATED)
details: { },
url: url, },
type: 'websocket', {
initiator: getDomain(initiators.WEB_INITIATED) label: 'onSendHeaders',
} event: 'onSendHeaders',
}, details: {
{ label: 'onHeadersReceived', url: url,
event: 'onHeadersReceived', type: 'websocket',
details: { initiator: getDomain(initiators.WEB_INITIATED)
url: url, }
type: 'websocket', },
statusCode: 401, {
statusLine: 'HTTP/1.0 401 Unauthorized', label: 'onHeadersReceived',
initiator: getDomain(initiators.WEB_INITIATED) event: 'onHeadersReceived',
} details: {
url: url,
type: 'websocket',
statusCode: 401,
statusLine: 'HTTP/1.0 401 Unauthorized',
initiator: getDomain(initiators.WEB_INITIATED)
}
},
{
label: 'onAuthRequired',
event: 'onAuthRequired',
details: {
url: url,
type: 'websocket',
isProxy: false,
scheme: 'basic',
realm: 'Pywebsocket',
challenger: {host: 'localhost', port: testWebSocketPort},
statusCode: 401,
statusLine: 'HTTP/1.0 401 Unauthorized',
initiator: getDomain(initiators.WEB_INITIATED)
},
retval: {cancel: true}
},
{
label: 'onResponseStarted',
event: 'onResponseStarted',
details: {
url: url,
type: 'websocket',
fromCache: false,
ip: '127.0.0.1',
statusCode: 401,
statusLine: 'HTTP/1.0 401 Unauthorized',
initiator: getDomain(initiators.WEB_INITIATED)
}
},
{
label: 'onErrorOccurred',
event: 'onErrorOccurred',
details: {
url: url,
type: 'websocket',
ip: '127.0.0.1',
fromCache: false,
error:
(networkServiceEnabled ? 'net::ERR_FAILED' :
'net::ERR_ABORTED'),
initiator: getDomain(initiators.WEB_INITIATED)
}
},
],
[ // event order
[
'onBeforeRequest', 'onBeforeSendHeaders', 'onSendHeaders',
'onHeadersReceived', 'onAuthRequired', 'onResponseStarted',
'onErrorOccurred'
]
],
{urls: ['<all_urls>']}, ['blocking']);
testWebSocketConnection(url, false /* expectedToConnect*/);
}, },
{ label: 'onAuthRequired',
event: 'onAuthRequired', // onAuthRequired is a blocking function setting authentication
details: { // credentials.
url: url, function webSocketAuthRequiredSyncSetAuth() {
type: 'websocket', var url = getWSTestURL(testWebSocketPort);
isProxy: false, expect(
scheme: 'basic', [
realm: 'Pywebsocket', // events
challenger: {host: 'localhost', port: testWebSocketPort}, {
statusCode: 401, label: 'onBeforeRequest',
statusLine: 'HTTP/1.0 401 Unauthorized', event: 'onBeforeRequest',
initiator: getDomain(initiators.WEB_INITIATED) details: {
}, url: url,
// Note: The test WebSocket server accepts only these credentials. type: 'websocket',
retval: {authCredentials: {username: 'test', password: 'test'}} frameUrl: 'unknown frame URL',
}, initiator: getDomain(initiators.WEB_INITIATED)
{ label: 'onResponseStarted', }
event: 'onResponseStarted', },
details: { {
url: url, label: 'onBeforeSendHeaders',
type: 'websocket', event: 'onBeforeSendHeaders',
ip: '127.0.0.1', details: {
fromCache: false, url: url,
statusCode: 101, type: 'websocket',
statusLine: 'HTTP/1.1 101 Switching Protocols', initiator: getDomain(initiators.WEB_INITIATED)
initiator: getDomain(initiators.WEB_INITIATED) },
}, },
}, {
{ label: 'onCompleted', label: 'onSendHeaders',
event: 'onCompleted', event: 'onSendHeaders',
details: { details: {
url: url, url: url,
type: 'websocket', type: 'websocket',
ip: '127.0.0.1', initiator: getDomain(initiators.WEB_INITIATED)
fromCache: false, }
statusCode: 101, },
statusLine: 'HTTP/1.1 101 Switching Protocols', {
initiator: getDomain(initiators.WEB_INITIATED) label: 'onHeadersReceived',
} event: 'onHeadersReceived',
details: {
url: url,
type: 'websocket',
statusCode: 401,
statusLine: 'HTTP/1.0 401 Unauthorized',
initiator: getDomain(initiators.WEB_INITIATED)
}
},
{
label: 'onAuthRequired',
event: 'onAuthRequired',
details: {
url: url,
type: 'websocket',
isProxy: false,
scheme: 'basic',
realm: 'Pywebsocket',
challenger: {host: 'localhost', port: testWebSocketPort},
statusCode: 401,
statusLine: 'HTTP/1.0 401 Unauthorized',
initiator: getDomain(initiators.WEB_INITIATED)
},
// Note: The test WebSocket server accepts only these
// credentials.
retval:
{authCredentials: {username: 'test', password: 'test'}}
},
{
label: 'onResponseStarted',
event: 'onResponseStarted',
details: {
url: url,
type: 'websocket',
ip: '127.0.0.1',
fromCache: false,
statusCode: 101,
statusLine: 'HTTP/1.1 101 Switching Protocols',
initiator: getDomain(initiators.WEB_INITIATED)
},
},
{
label: 'onCompleted',
event: 'onCompleted',
details: {
url: url,
type: 'websocket',
ip: '127.0.0.1',
fromCache: false,
statusCode: 101,
statusLine: 'HTTP/1.1 101 Switching Protocols',
initiator: getDomain(initiators.WEB_INITIATED)
}
},
],
[ // event order
[
'onBeforeRequest', 'onBeforeSendHeaders', 'onSendHeaders',
'onHeadersReceived', 'onAuthRequired', 'onResponseStarted',
'onCompleted'
]
],
{urls: ['<all_urls>']}, ['blocking']);
testWebSocketConnection(url, true /* expectedToConnect*/);
}, },
], ],
[ // event order tab);
['onBeforeRequest', 'onBeforeSendHeaders', 'onSendHeaders', });
'onHeadersReceived', 'onAuthRequired', 'onResponseStarted', });
'onCompleted'] \ No newline at end of file
],
{urls: ['<all_urls>']}, ['blocking']);
testWebSocketConnection(url, true /* expectedToConnect*/);
},
], tab);
});
...@@ -78,8 +78,10 @@ void WebRequestProxyingWebSocket::AddChannelRequest( ...@@ -78,8 +78,10 @@ void WebRequestProxyingWebSocket::AddChannelRequest(
const std::vector<std::string>& requested_protocols, const std::vector<std::string>& requested_protocols,
const GURL& site_for_cookies, const GURL& site_for_cookies,
std::vector<network::mojom::HttpHeaderPtr> additional_headers, std::vector<network::mojom::HttpHeaderPtr> additional_headers,
network::mojom::WebSocketHandshakeClientPtr handshake_client,
network::mojom::WebSocketClientPtr client) { network::mojom::WebSocketClientPtr client) {
if (binding_as_client_.is_bound() || !client || forwarding_client_) { if (binding_as_client_.is_bound() || !handshake_client ||
forwarding_handshake_client_ || !client || forwarding_client_) {
// Illegal request. // Illegal request.
proxied_socket_ = nullptr; proxied_socket_ = nullptr;
return; return;
...@@ -96,6 +98,7 @@ void WebRequestProxyingWebSocket::AddChannelRequest( ...@@ -96,6 +98,7 @@ void WebRequestProxyingWebSocket::AddChannelRequest(
nullptr, routing_id, resource_context_, request_, nullptr, routing_id, resource_context_, request_,
false /* is_download */, true /* is_async */)); false /* is_download */, true /* is_async */));
forwarding_handshake_client_ = std::move(handshake_client);
forwarding_client_ = std::move(client); forwarding_client_ = std::move(client);
additional_headers_ = std::move(additional_headers); additional_headers_ = std::move(additional_headers);
...@@ -154,31 +157,15 @@ void WebRequestProxyingWebSocket::StartClosingHandshake( ...@@ -154,31 +157,15 @@ void WebRequestProxyingWebSocket::StartClosingHandshake(
proxied_socket_->StartClosingHandshake(code, reason); proxied_socket_->StartClosingHandshake(code, reason);
} }
void WebRequestProxyingWebSocket::OnFailChannel(const std::string& reason) {
DCHECK(forwarding_client_);
forwarding_client_->OnFailChannel(reason);
forwarding_client_ = nullptr;
int rv = net::ERR_FAILED;
if (reason == "HTTP Authentication failed; no valid credentials available" ||
reason == "Proxy authentication failed") {
// This is needed to make some tests pass.
// TODO(yhirano): Remove this hack.
rv = net::ERR_ABORTED;
}
OnError(rv);
}
void WebRequestProxyingWebSocket::OnStartOpeningHandshake( void WebRequestProxyingWebSocket::OnStartOpeningHandshake(
network::mojom::WebSocketHandshakeRequestPtr request) { network::mojom::WebSocketHandshakeRequestPtr request) {
DCHECK(forwarding_client_); DCHECK(forwarding_handshake_client_);
forwarding_client_->OnStartOpeningHandshake(std::move(request)); forwarding_handshake_client_->OnStartOpeningHandshake(std::move(request));
} }
void WebRequestProxyingWebSocket::OnFinishOpeningHandshake( void WebRequestProxyingWebSocket::OnFinishOpeningHandshake(
network::mojom::WebSocketHandshakeResponsePtr response) { network::mojom::WebSocketHandshakeResponsePtr response) {
DCHECK(forwarding_client_); DCHECK(forwarding_handshake_client_);
// response_.headers will be set in OnBeforeSendHeaders if // response_.headers will be set in OnBeforeSendHeaders if
// binding_as_header_client_ is set. // binding_as_header_client_ is set.
...@@ -198,7 +185,7 @@ void WebRequestProxyingWebSocket::OnFinishOpeningHandshake( ...@@ -198,7 +185,7 @@ void WebRequestProxyingWebSocket::OnFinishOpeningHandshake(
// OnFinishOpeningHandshake is called with the original response headers. // OnFinishOpeningHandshake is called with the original response headers.
// That means if OnHeadersReceived modified them the renderer won't see that // That means if OnHeadersReceived modified them the renderer won't see that
// modification. This is the opposite of http(s) requests. // modification. This is the opposite of http(s) requests.
forwarding_client_->OnFinishOpeningHandshake(std::move(response)); forwarding_handshake_client_->OnFinishOpeningHandshake(std::move(response));
if (!binding_as_header_client_ || response_.headers) { if (!binding_as_header_client_ || response_.headers) {
ContinueToHeadersReceived(); ContinueToHeadersReceived();
...@@ -231,41 +218,14 @@ void WebRequestProxyingWebSocket::ContinueToHeadersReceived() { ...@@ -231,41 +218,14 @@ void WebRequestProxyingWebSocket::ContinueToHeadersReceived() {
void WebRequestProxyingWebSocket::OnAddChannelResponse( void WebRequestProxyingWebSocket::OnAddChannelResponse(
const std::string& selected_protocol, const std::string& selected_protocol,
const std::string& extensions) { const std::string& extensions) {
DCHECK(forwarding_client_); DCHECK(forwarding_handshake_client_);
DCHECK(!is_done_); DCHECK(!is_done_);
is_done_ = true; is_done_ = true;
ExtensionWebRequestEventRouter::GetInstance()->OnCompleted( ExtensionWebRequestEventRouter::GetInstance()->OnCompleted(
browser_context_, info_map_, &info_.value(), net::ERR_WS_UPGRADE); browser_context_, info_map_, &info_.value(), net::ERR_WS_UPGRADE);
forwarding_client_->OnAddChannelResponse(selected_protocol, extensions); forwarding_handshake_client_->OnAddChannelResponse(selected_protocol,
} extensions);
void WebRequestProxyingWebSocket::OnDataFrame(
bool fin,
network::mojom::WebSocketMessageType type,
const std::vector<uint8_t>& data) {
DCHECK(forwarding_client_);
forwarding_client_->OnDataFrame(fin, type, data);
}
void WebRequestProxyingWebSocket::OnFlowControl(int64_t quota) {
DCHECK(forwarding_client_);
forwarding_client_->OnFlowControl(quota);
}
void WebRequestProxyingWebSocket::OnDropChannel(bool was_clean,
uint16_t code,
const std::string& reason) {
DCHECK(forwarding_client_);
forwarding_client_->OnDropChannel(was_clean, code, reason);
forwarding_client_ = nullptr;
OnError(net::ERR_FAILED);
}
void WebRequestProxyingWebSocket::OnClosingHandshake() {
DCHECK(forwarding_client_);
forwarding_client_->OnClosingHandshake();
} }
void WebRequestProxyingWebSocket::OnAuthRequired( void WebRequestProxyingWebSocket::OnAuthRequired(
...@@ -410,7 +370,7 @@ void WebRequestProxyingWebSocket::OnBeforeSendHeadersComplete( ...@@ -410,7 +370,7 @@ void WebRequestProxyingWebSocket::OnBeforeSendHeadersComplete(
} }
void WebRequestProxyingWebSocket::ContinueToStartRequest(int error_code) { void WebRequestProxyingWebSocket::ContinueToStartRequest(int error_code) {
network::mojom::WebSocketClientPtr proxy; network::mojom::WebSocketHandshakeClientPtr proxy;
base::flat_set<std::string> used_header_names; base::flat_set<std::string> used_header_names;
std::vector<network::mojom::HttpHeaderPtr> additional_headers; std::vector<network::mojom::HttpHeaderPtr> additional_headers;
...@@ -432,7 +392,8 @@ void WebRequestProxyingWebSocket::ContinueToStartRequest(int error_code) { ...@@ -432,7 +392,8 @@ void WebRequestProxyingWebSocket::ContinueToStartRequest(int error_code) {
base::Unretained(this), net::ERR_FAILED)); base::Unretained(this), net::ERR_FAILED));
proxied_socket_->AddChannelRequest( proxied_socket_->AddChannelRequest(
request_.url, websocket_protocols_, request_.site_for_cookies, request_.url, websocket_protocols_, request_.site_for_cookies,
std::move(additional_headers), std::move(proxy)); std::move(additional_headers), std::move(proxy),
std::move(forwarding_client_));
} }
void WebRequestProxyingWebSocket::OnHeadersReceivedComplete(int error_code) { void WebRequestProxyingWebSocket::OnHeadersReceivedComplete(int error_code) {
...@@ -522,8 +483,6 @@ void WebRequestProxyingWebSocket::OnError(int error_code) { ...@@ -522,8 +483,6 @@ void WebRequestProxyingWebSocket::OnError(int error_code) {
browser_context_, info_map_, &info_.value(), true /* started */, browser_context_, info_map_, &info_.value(), true /* started */,
error_code); error_code);
} }
if (forwarding_client_)
forwarding_client_->OnFailChannel(net::ErrorToString(error_code));
// Deletes |this|. // Deletes |this|.
proxies_->RemoveProxy(this); proxies_->RemoveProxy(this);
......
...@@ -36,7 +36,7 @@ namespace extensions { ...@@ -36,7 +36,7 @@ namespace extensions {
class WebRequestProxyingWebSocket class WebRequestProxyingWebSocket
: public WebRequestAPI::Proxy, : public WebRequestAPI::Proxy,
public network::mojom::WebSocket, public network::mojom::WebSocket,
public network::mojom::WebSocketClient, public network::mojom::WebSocketHandshakeClient,
public network::mojom::AuthenticationHandler, public network::mojom::AuthenticationHandler,
public network::mojom::TrustedHeaderClient { public network::mojom::TrustedHeaderClient {
public: public:
...@@ -61,6 +61,7 @@ class WebRequestProxyingWebSocket ...@@ -61,6 +61,7 @@ class WebRequestProxyingWebSocket
const std::vector<std::string>& requested_protocols, const std::vector<std::string>& requested_protocols,
const GURL& site_for_cookies, const GURL& site_for_cookies,
std::vector<network::mojom::HttpHeaderPtr> additional_headers, std::vector<network::mojom::HttpHeaderPtr> additional_headers,
network::mojom::WebSocketHandshakeClientPtr handshake_client,
network::mojom::WebSocketClientPtr client) override; network::mojom::WebSocketClientPtr client) override;
void SendFrame(bool fin, void SendFrame(bool fin,
network::mojom::WebSocketMessageType type, network::mojom::WebSocketMessageType type,
...@@ -68,22 +69,13 @@ class WebRequestProxyingWebSocket ...@@ -68,22 +69,13 @@ class WebRequestProxyingWebSocket
void AddReceiveFlowControlQuota(int64_t quota) override; void AddReceiveFlowControlQuota(int64_t quota) override;
void StartClosingHandshake(uint16_t code, const std::string& reason) override; void StartClosingHandshake(uint16_t code, const std::string& reason) override;
// mojom::WebSocketClient methods: // mojom::WebSocketHandShakeClient methods:
void OnFailChannel(const std::string& reason) override;
void OnStartOpeningHandshake( void OnStartOpeningHandshake(
network::mojom::WebSocketHandshakeRequestPtr request) override; network::mojom::WebSocketHandshakeRequestPtr request) override;
void OnFinishOpeningHandshake( void OnFinishOpeningHandshake(
network::mojom::WebSocketHandshakeResponsePtr response) override; network::mojom::WebSocketHandshakeResponsePtr response) override;
void OnAddChannelResponse(const std::string& selected_protocol, void OnAddChannelResponse(const std::string& selected_protocol,
const std::string& extensions) override; const std::string& extensions) override;
void OnDataFrame(bool fin,
network::mojom::WebSocketMessageType type,
const std::vector<uint8_t>& data) override;
void OnFlowControl(int64_t quota) override;
void OnDropChannel(bool was_clean,
uint16_t code,
const std::string& reason) override;
void OnClosingHandshake() override;
// mojom::AuthenticationHandler method: // mojom::AuthenticationHandler method:
void OnAuthRequired(const net::AuthChallengeInfo& auth_info, void OnAuthRequired(const net::AuthChallengeInfo& auth_info,
...@@ -134,9 +126,10 @@ class WebRequestProxyingWebSocket ...@@ -134,9 +126,10 @@ class WebRequestProxyingWebSocket
InfoMap* const info_map_; InfoMap* const info_map_;
scoped_refptr<WebRequestAPI::RequestIDGenerator> request_id_generator_; scoped_refptr<WebRequestAPI::RequestIDGenerator> request_id_generator_;
network::mojom::WebSocketPtr proxied_socket_; network::mojom::WebSocketPtr proxied_socket_;
network::mojom::WebSocketHandshakeClientPtr forwarding_handshake_client_;
network::mojom::WebSocketClientPtr forwarding_client_; network::mojom::WebSocketClientPtr forwarding_client_;
mojo::Binding<network::mojom::WebSocket> binding_as_websocket_; mojo::Binding<network::mojom::WebSocket> binding_as_websocket_;
mojo::Binding<network::mojom::WebSocketClient> binding_as_client_; mojo::Binding<network::mojom::WebSocketHandshakeClient> binding_as_client_;
mojo::Binding<network::mojom::AuthenticationHandler> binding_as_auth_handler_; mojo::Binding<network::mojom::AuthenticationHandler> binding_as_auth_handler_;
mojo::Binding<network::mojom::TrustedHeaderClient> binding_as_header_client_; mojo::Binding<network::mojom::TrustedHeaderClient> binding_as_header_client_;
......
...@@ -49,9 +49,7 @@ interface AuthenticationHandler { ...@@ -49,9 +49,7 @@ interface AuthenticationHandler {
IPEndPoint remote_endpoint) => (AuthCredentials? credentials); IPEndPoint remote_endpoint) => (AuthCredentials? credentials);
}; };
interface WebSocketClient { interface WebSocketHandshakeClient {
OnFailChannel(string reason);
// Notify the renderer that the browser has started an opening handshake. // Notify the renderer that the browser has started an opening handshake.
OnStartOpeningHandshake(WebSocketHandshakeRequest request); OnStartOpeningHandshake(WebSocketHandshakeRequest request);
...@@ -65,7 +63,9 @@ interface WebSocketClient { ...@@ -65,7 +63,9 @@ interface WebSocketClient {
// the server selected, or empty if no sub-protocol was selected. // the server selected, or empty if no sub-protocol was selected.
// |extensions| is the list of extensions negotiated for the connection. // |extensions| is the list of extensions negotiated for the connection.
OnAddChannelResponse(string selected_protocol, string extensions); OnAddChannelResponse(string selected_protocol, string extensions);
};
interface WebSocketClient {
// Receive a non-control frame from the remote server. // Receive a non-control frame from the remote server.
// - |fin| indicates that this frame is the last in the current message. // - |fin| indicates that this frame is the last in the current message.
// - |type| is the type of the message. On the first frame of a message, it // - |type| is the type of the message. On the first frame of a message, it
...@@ -104,6 +104,8 @@ interface WebSocketClient { ...@@ -104,6 +104,8 @@ interface WebSocketClient {
// Notify the renderer that a closing handshake has been initiated by the // Notify the renderer that a closing handshake has been initiated by the
// server, so that it can set the Javascript readyState to CLOSING. // server, so that it can set the Javascript readyState to CLOSING.
OnClosingHandshake(); OnClosingHandshake();
OnFailChannel(string reason);
}; };
interface WebSocket { interface WebSocket {
...@@ -123,6 +125,7 @@ interface WebSocket { ...@@ -123,6 +125,7 @@ interface WebSocket {
array<string> requested_protocols, array<string> requested_protocols,
url.mojom.Url first_party_for_cookies, url.mojom.Url first_party_for_cookies,
array<HttpHeader> additional_headers, array<HttpHeader> additional_headers,
WebSocketHandshakeClient handshake_client,
WebSocketClient client); WebSocketClient client);
// Send a non-control frame to the remote server. // Send a non-control frame to the remote server.
......
...@@ -147,7 +147,7 @@ void WebSocket::WebSocketEventHandler::OnAddChannelResponse( ...@@ -147,7 +147,7 @@ void WebSocket::WebSocketEventHandler::OnAddChannelResponse(
impl_->handshake_succeeded_ = true; impl_->handshake_succeeded_ = true;
impl_->pending_connection_tracker_.OnCompleteHandshake(); impl_->pending_connection_tracker_.OnCompleteHandshake();
impl_->client_->OnAddChannelResponse(selected_protocol, extensions); impl_->handshake_client_->OnAddChannelResponse(selected_protocol, extensions);
} }
void WebSocket::WebSocketEventHandler::OnDataFrame( void WebSocket::WebSocketEventHandler::OnDataFrame(
...@@ -238,7 +238,7 @@ void WebSocket::WebSocketEventHandler::OnStartOpeningHandshake( ...@@ -238,7 +238,7 @@ void WebSocket::WebSocketEventHandler::OnStartOpeningHandshake(
headers_text.append("\r\n"); headers_text.append("\r\n");
request_to_pass->headers_text = std::move(headers_text); request_to_pass->headers_text = std::move(headers_text);
impl_->client_->OnStartOpeningHandshake(std::move(request_to_pass)); impl_->handshake_client_->OnStartOpeningHandshake(std::move(request_to_pass));
} }
void WebSocket::WebSocketEventHandler::OnFinishOpeningHandshake( void WebSocket::WebSocketEventHandler::OnFinishOpeningHandshake(
...@@ -272,7 +272,8 @@ void WebSocket::WebSocketEventHandler::OnFinishOpeningHandshake( ...@@ -272,7 +272,8 @@ void WebSocket::WebSocketEventHandler::OnFinishOpeningHandshake(
headers_text.append("\r\n"); headers_text.append("\r\n");
response_to_pass->headers_text = headers_text; response_to_pass->headers_text = headers_text;
impl_->client_->OnFinishOpeningHandshake(std::move(response_to_pass)); impl_->handshake_client_->OnFinishOpeningHandshake(
std::move(response_to_pass));
} }
void WebSocket::WebSocketEventHandler::OnSSLCertificateError( void WebSocket::WebSocketEventHandler::OnSSLCertificateError(
...@@ -360,6 +361,7 @@ void WebSocket::AddChannelRequest( ...@@ -360,6 +361,7 @@ void WebSocket::AddChannelRequest(
const std::vector<std::string>& requested_protocols, const std::vector<std::string>& requested_protocols,
const GURL& site_for_cookies, const GURL& site_for_cookies,
std::vector<mojom::HttpHeaderPtr> additional_headers, std::vector<mojom::HttpHeaderPtr> additional_headers,
mojom::WebSocketHandshakeClientPtr handshake_client,
mojom::WebSocketClientPtr client) { mojom::WebSocketClientPtr client) {
DVLOG(3) << "WebSocket::AddChannelRequest @" << reinterpret_cast<void*>(this) DVLOG(3) << "WebSocket::AddChannelRequest @" << reinterpret_cast<void*>(this)
<< " socket_url=\"" << socket_url << "\" requested_protocols=\"" << " socket_url=\"" << socket_url << "\" requested_protocols=\""
...@@ -372,6 +374,7 @@ void WebSocket::AddChannelRequest( ...@@ -372,6 +374,7 @@ void WebSocket::AddChannelRequest(
return; return;
} }
handshake_client_ = std::move(handshake_client);
client_ = std::move(client); client_ = std::move(client);
DCHECK(!channel_); DCHECK(!channel_);
...@@ -446,8 +449,9 @@ void WebSocket::StartClosingHandshake(uint16_t code, ...@@ -446,8 +449,9 @@ void WebSocket::StartClosingHandshake(uint16_t code,
if (!channel_) { if (!channel_) {
// WebSocketChannel is not yet created due to the delay introduced by // WebSocketChannel is not yet created due to the delay introduced by
// per-renderer WebSocket throttling. // per-renderer WebSocket throttling.
if (client_) if (client_) {
client_->OnDropChannel(false, net::kWebSocketErrorAbnormalClosure, ""); client_->OnDropChannel(false, net::kWebSocketErrorAbnormalClosure, "");
}
return; return;
} }
......
...@@ -84,6 +84,7 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) WebSocket : public mojom::WebSocket { ...@@ -84,6 +84,7 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) WebSocket : public mojom::WebSocket {
const std::vector<std::string>& requested_protocols, const std::vector<std::string>& requested_protocols,
const GURL& site_for_cookies, const GURL& site_for_cookies,
std::vector<mojom::HttpHeaderPtr> additional_headers, std::vector<mojom::HttpHeaderPtr> additional_headers,
mojom::WebSocketHandshakeClientPtr handshake_client,
mojom::WebSocketClientPtr client) override; mojom::WebSocketClientPtr client) override;
void SendFrame(bool fin, void SendFrame(bool fin,
mojom::WebSocketMessageType type, mojom::WebSocketMessageType type,
...@@ -156,6 +157,7 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) WebSocket : public mojom::WebSocket { ...@@ -156,6 +157,7 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) WebSocket : public mojom::WebSocket {
std::unique_ptr<Delegate> delegate_; std::unique_ptr<Delegate> delegate_;
mojo::Binding<mojom::WebSocket> binding_; mojo::Binding<mojom::WebSocket> binding_;
mojom::WebSocketHandshakeClientPtr handshake_client_;
mojom::WebSocketClientPtr client_; mojom::WebSocketClientPtr client_;
mojom::AuthenticationHandlerPtr auth_handler_; mojom::AuthenticationHandlerPtr auth_handler_;
mojom::TrustedHeaderClientPtr header_client_; mojom::TrustedHeaderClientPtr header_client_;
......
...@@ -22,7 +22,7 @@ const uint16_t kAbnormalShutdownOpCode = 1006; ...@@ -22,7 +22,7 @@ const uint16_t kAbnormalShutdownOpCode = 1006;
} // namespace } // namespace
WebSocketHandleImpl::WebSocketHandleImpl() WebSocketHandleImpl::WebSocketHandleImpl()
: client_(nullptr), client_binding_(this) { : client_(nullptr), handshake_client_binding_(this), client_binding_(this) {
NETWORK_DVLOG(1) << this << " created"; NETWORK_DVLOG(1) << this << " created";
} }
...@@ -52,19 +52,23 @@ void WebSocketHandleImpl::Connect(network::mojom::blink::WebSocketPtr websocket, ...@@ -52,19 +52,23 @@ void WebSocketHandleImpl::Connect(network::mojom::blink::WebSocketPtr websocket,
DCHECK(client); DCHECK(client);
client_ = client; client_ = client;
network::mojom::blink::WebSocketClientPtr client_proxy; network::mojom::blink::WebSocketHandshakeClientPtr handshake_client_proxy;
Vector<network::mojom::blink::HttpHeaderPtr> additional_headers; Vector<network::mojom::blink::HttpHeaderPtr> additional_headers;
if (!user_agent_override.IsNull()) { if (!user_agent_override.IsNull()) {
additional_headers.push_back(network::mojom::blink::HttpHeader::New( additional_headers.push_back(network::mojom::blink::HttpHeader::New(
http_names::kUserAgent, user_agent_override)); http_names::kUserAgent, user_agent_override));
} }
handshake_client_binding_.Bind(
mojo::MakeRequest(&handshake_client_proxy, task_runner), task_runner);
network::mojom::blink::WebSocketClientPtr client_proxy;
client_binding_.Bind(mojo::MakeRequest(&client_proxy, task_runner), client_binding_.Bind(mojo::MakeRequest(&client_proxy, task_runner),
task_runner); task_runner);
client_binding_.set_connection_error_handler(WTF::Bind( client_binding_.set_connection_error_with_reason_handler(WTF::Bind(
&WebSocketHandleImpl::OnConnectionError, WTF::Unretained(this))); &WebSocketHandleImpl::OnConnectionError, WTF::Unretained(this)));
websocket_->AddChannelRequest(url, protocols, site_for_cookies,
std::move(additional_headers), websocket_->AddChannelRequest(
std::move(client_proxy)); url, protocols, site_for_cookies, std::move(additional_headers),
std::move(handshake_client_proxy), std::move(client_proxy));
} }
void WebSocketHandleImpl::Send(bool fin, void WebSocketHandleImpl::Send(bool fin,
...@@ -121,9 +125,16 @@ void WebSocketHandleImpl::Disconnect() { ...@@ -121,9 +125,16 @@ void WebSocketHandleImpl::Disconnect() {
client_ = nullptr; client_ = nullptr;
} }
void WebSocketHandleImpl::OnConnectionError() { void WebSocketHandleImpl::OnConnectionError(uint32_t custom_reason,
const std::string& description) {
// Our connection to the WebSocket was dropped. This could be due to // Our connection to the WebSocket was dropped. This could be due to
// exceeding the maximum number of concurrent websockets from this process. // exceeding the maximum number of concurrent websockets from this process.
// This handler is sufficient to detect all mojo connection errors, as
// any error will result in the data connection being dropped.
// By detecting the errors on this channel, we ensure that any FailChannel
// messages from the network service will be processed first.
NETWORK_DVLOG(1) << " OnConnectionError( reason: " << custom_reason
<< ", description:" << description;
OnFailChannel("Unknown reason"); OnFailChannel("Unknown reason");
} }
......
...@@ -38,8 +38,10 @@ ...@@ -38,8 +38,10 @@
namespace blink { namespace blink {
class WebSocketHandleImpl : public WebSocketHandle, class WebSocketHandleImpl
public network::mojom::blink::WebSocketClient { : public WebSocketHandle,
public network::mojom::blink::WebSocketHandshakeClient,
public network::mojom::blink::WebSocketClient {
public: public:
WebSocketHandleImpl(); WebSocketHandleImpl();
~WebSocketHandleImpl() override; ~WebSocketHandleImpl() override;
...@@ -57,16 +59,17 @@ class WebSocketHandleImpl : public WebSocketHandle, ...@@ -57,16 +59,17 @@ class WebSocketHandleImpl : public WebSocketHandle,
private: private:
void Disconnect(); void Disconnect();
void OnConnectionError(); void OnConnectionError(uint32_t custom_reason,
const std::string& description);
// network::mojom::blink::WebSocketClient methods: // network::mojom::blink::WebSocketHandshakeClient methods:
void OnFailChannel(const String& reason) override;
void OnStartOpeningHandshake( void OnStartOpeningHandshake(
network::mojom::blink::WebSocketHandshakeRequestPtr) override; network::mojom::blink::WebSocketHandshakeRequestPtr) override;
void OnFinishOpeningHandshake( void OnFinishOpeningHandshake(
network::mojom::blink::WebSocketHandshakeResponsePtr) override; network::mojom::blink::WebSocketHandshakeResponsePtr) override;
void OnAddChannelResponse(const String& selected_protocol, void OnAddChannelResponse(const String& selected_protocol,
const String& extensions) override; const String& extensions) override;
// network::mojom::blink::WebSocketClient methods:
void OnDataFrame(bool fin, void OnDataFrame(bool fin,
network::mojom::blink::WebSocketMessageType, network::mojom::blink::WebSocketMessageType,
const Vector<uint8_t>& data) override; const Vector<uint8_t>& data) override;
...@@ -75,10 +78,13 @@ class WebSocketHandleImpl : public WebSocketHandle, ...@@ -75,10 +78,13 @@ class WebSocketHandleImpl : public WebSocketHandle,
uint16_t code, uint16_t code,
const String& reason) override; const String& reason) override;
void OnClosingHandshake() override; void OnClosingHandshake() override;
void OnFailChannel(const String& reason) override;
WebSocketHandleClient* client_; WebSocketHandleClient* client_;
network::mojom::blink::WebSocketPtr websocket_; network::mojom::blink::WebSocketPtr websocket_;
mojo::Binding<network::mojom::blink::WebSocketHandshakeClient>
handshake_client_binding_;
mojo::Binding<network::mojom::blink::WebSocketClient> client_binding_; mojo::Binding<network::mojom::blink::WebSocketClient> client_binding_;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment