Commit 307321d4 authored by Keita Suzuki's avatar Keita Suzuki Committed by Commit Bot

[WebSocket] Add support to consume Datapipe in network service

This commit adds support to network service to consume websocket frame
data from mojo datapipe produced from blink. To achieve this, this
commit adds a new message SendMessage() in mojo WebSocket interface.
It also adds SimpleWatcher to watch the consumer and be notified when
needed, and add callback function OnReadable() to support this.

This commit also adds ReadAndSendFrameFromDataPipe() to actually
consume data from the datapipe.

The producer side of the datapipe and the caller of SendMessage() are
not implemented yet for security review. WIP CLs are uploaded here:
https://chromium-review.googlesource.com/c/chromium/src/+/2082869
https://chromium-review.googlesource.com/c/chromium/src/+/2083777

Design Doc:
https://docs.google.com/document/d/1YWj1z9r8wxemGdod6S2tkchudhp6PvNaH3qSO0oucfY/

Bug: 1056030
Change-Id: I580e3776bf0f1a27e8d83e5c92087f5542b19cb6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2071189
Commit-Queue: Keita Suzuki <suzukikeita@google.com>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-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 avatarYoichi Osato <yoichio@chromium.org>
Cr-Commit-Position: refs/heads/master@{#751557}
parent 629f0149
......@@ -166,7 +166,8 @@ void WebRequestProxyingWebSocket::OnConnectionEstablished(
mojo::PendingRemote<network::mojom::WebSocket> websocket,
mojo::PendingReceiver<network::mojom::WebSocketClient> client_receiver,
network::mojom::WebSocketHandshakeResponsePtr response,
mojo::ScopedDataPipeConsumerHandle readable) {
mojo::ScopedDataPipeConsumerHandle readable,
mojo::ScopedDataPipeProducerHandle writable) {
DCHECK(forwarding_handshake_client_);
DCHECK(!is_done_);
is_done_ = true;
......@@ -174,6 +175,7 @@ void WebRequestProxyingWebSocket::OnConnectionEstablished(
client_receiver_ = std::move(client_receiver);
handshake_response_ = std::move(response);
readable_ = std::move(readable);
writable_ = std::move(writable);
response_->remote_endpoint = handshake_response_->remote_endpoint;
......@@ -203,7 +205,8 @@ void WebRequestProxyingWebSocket::ContinueToCompleted() {
browser_context_, &info_, net::ERR_WS_UPGRADE);
forwarding_handshake_client_->OnConnectionEstablished(
std::move(websocket_), std::move(client_receiver_),
std::move(handshake_response_), std::move(readable_));
std::move(handshake_response_), std::move(readable_),
std::move(writable_));
// Deletes |this|.
proxies_->RemoveProxy(this);
......
......@@ -64,7 +64,8 @@ class WebRequestProxyingWebSocket
mojo::PendingRemote<network::mojom::WebSocket> websocket,
mojo::PendingReceiver<network::mojom::WebSocketClient> client_receiver,
network::mojom::WebSocketHandshakeResponsePtr response,
mojo::ScopedDataPipeConsumerHandle readable) override;
mojo::ScopedDataPipeConsumerHandle readable,
mojo::ScopedDataPipeProducerHandle writable) override;
// network::mojom::AuthenticationHandler method:
void OnAuthRequired(const net::AuthChallengeInfo& auth_info,
......@@ -147,6 +148,7 @@ class WebRequestProxyingWebSocket
mojo::PendingReceiver<network::mojom::WebSocketClient> client_receiver_;
network::mojom::WebSocketHandshakeResponsePtr handshake_response_ = nullptr;
mojo::ScopedDataPipeConsumerHandle readable_;
mojo::ScopedDataPipeProducerHandle writable_;
WebRequestInfo info_;
......
......@@ -54,6 +54,8 @@ interface AuthenticationHandler {
IPEndPoint remote_endpoint) => (AuthCredentials? credentials);
};
// This interface is for client-side WebSocket handshake. Used to initialize
// the WebSocket Connection.
interface WebSocketHandshakeClient {
// Notify the renderer that the browser has started an opening handshake.
OnOpeningHandshakeStarted(WebSocketHandshakeRequest request);
......@@ -61,13 +63,20 @@ interface WebSocketHandshakeClient {
// Called when the connection is established.
// |response| may contain cookie-related headers when the client has
// an access to raw cookie information.
// |readable| is readable datapipe to receive data from browser.
// |readable| is readable datapipe to receive data from network service.
// |writable| is writable datapipe used to transfer the actual content of the
// message(data) to the network service. The network services later sends out
// the actual message by framing each message from the meta-info given from
// the renderer side with |SendMessage()|.
OnConnectionEstablished(pending_remote<WebSocket> socket,
pending_receiver<WebSocketClient> client_receiver,
WebSocketHandshakeResponse response,
handle<data_pipe_consumer> readable);
handle<data_pipe_consumer> readable,
handle<data_pipe_producer> writable);
};
// The interface for the client side of WebSocket. Implemented by renderer
// processes to receive messages from the network service.
interface WebSocketClient {
// Receive a non-control frame from the remote server.
// - |fin| indicates that this frame is the last in the current message.
......@@ -112,6 +121,8 @@ interface WebSocketClient {
OnClosingHandshake();
};
// The interface for the server side of WebSocket. Implemented by the network
// service. Used to send out data to the network service.
interface WebSocket {
// The client side may observe the following disconnection reason from the
// service side:
......@@ -131,6 +142,17 @@ interface WebSocket {
WebSocketMessageType type,
mojo_base.mojom.ReadOnlyBuffer data);
// Sends a message via mojo datapipe to the remote server.
// - |type| is the type of the message. It must be set to either
// WebSocketMessageType.TEXT or WebSocketMessageType.BINARY.
// - |data_length| is the actual length of message. The message is written to
// the datapipe named |writable| in the
// WebSocketHandshakeClient.OnConnectionEstablished message.
//
// If |type| is WebSocketMessageType.TEXT, then the message must be
// valid UTF-8.
SendMessage(WebSocketMessageType type, uint64 data_length);
// Let browser to start receiving WebSocket data frames from network stream.
// TODO(yoichio): Remove this by move Connect() after checking throttle at
// WebSocketChannelImpl::Connect so that OnAddChannelResponse is
......
......@@ -211,6 +211,20 @@ void WebSocket::WebSocketEventHandler::OnAddChannelResponse(
base::BindRepeating(&WebSocket::OnWritable, base::Unretained(impl_)));
DCHECK_EQ(mojo_result, MOJO_RESULT_OK);
mojo::ScopedDataPipeProducerHandle writable;
const MojoResult write_pipe_result =
mojo::CreateDataPipe(&data_pipe_options, &writable, &impl_->readable_);
if (write_pipe_result != MOJO_RESULT_OK) {
DVLOG(1) << "mojo::CreateDataPipe error:" << result;
impl_->Reset();
return;
}
const MojoResult mojo_readable_result = impl_->readable_watcher_.Watch(
impl_->readable_.get(), MOJO_HANDLE_SIGNAL_READABLE,
MOJO_WATCH_CONDITION_SATISFIED,
base::BindRepeating(&WebSocket::OnReadable, base::Unretained(impl_)));
DCHECK_EQ(mojo_readable_result, MOJO_RESULT_OK);
mojom::WebSocketHandshakeResponsePtr mojo_response =
ToMojo(std::move(response), !!impl_->has_raw_headers_access_);
mojo_response->selected_protocol = selected_protocol;
......@@ -218,7 +232,7 @@ void WebSocket::WebSocketEventHandler::OnAddChannelResponse(
impl_->handshake_client_->OnConnectionEstablished(
impl_->receiver_.BindNewPipeAndPassRemote(),
impl_->client_.BindNewPipeAndPassReceiver(), std::move(mojo_response),
std::move(readable));
std::move(readable), std::move(writable));
impl_->receiver_.set_disconnect_handler(base::BindOnce(
&WebSocket::OnConnectionError, base::Unretained(impl_), FROM_HERE));
impl_->handshake_client_.reset();
......@@ -385,6 +399,9 @@ WebSocket::WebSocket(
site_for_cookies_(site_for_cookies),
has_raw_headers_access_(has_raw_headers_access),
writable_watcher_(FROM_HERE,
mojo::SimpleWatcher::ArmingPolicy::MANUAL,
base::ThreadTaskRunnerHandle::Get()),
readable_watcher_(FROM_HERE,
mojo::SimpleWatcher::ArmingPolicy::MANUAL,
base::ThreadTaskRunnerHandle::Get()) {
DCHECK(handshake_client_);
......@@ -449,6 +466,26 @@ void WebSocket::SendFrame(bool fin,
data.size());
}
void WebSocket::SendMessage(mojom::WebSocketMessageType type,
uint64_t data_length) {
DVLOG(3) << "WebSocket::SendMessage @" << reinterpret_cast<void*>(this)
<< " type=" << type << " data is " << data_length << " bytes";
DCHECK(channel_) << "WebSocket::SendMessage is called but there is "
"no active channel.";
DCHECK(handshake_succeeded_);
// This is guaranteed by mojo.
if (type == mojom::WebSocketMessageType::CONTINUATION) {
Reset();
return;
}
DCHECK(IsKnownEnumValue(type));
pending_send_data_frames_.push(DataFrame(type, data_length));
ReadAndSendFromDataPipe();
}
void WebSocket::StartReceiving() {
DCHECK(pending_data_frames_.empty());
ignore_result(channel_->ReadFrames());
......@@ -627,6 +664,70 @@ void WebSocket::SendDataFrame(base::span<const char>* payload) {
return;
}
void WebSocket::OnReadable(MojoResult result,
const mojo::HandleSignalsState& state) {
if (result != MOJO_RESULT_OK) {
DVLOG(1) << "WebSocket::OnWritable mojo error=" << result;
Reset();
return;
}
wait_for_readable_ = false;
ReadAndSendFromDataPipe();
}
void WebSocket::ReadAndSendFromDataPipe() {
if (wait_for_readable_) {
return;
}
while (!pending_send_data_frames_.empty()) {
DataFrame& data_frame = pending_send_data_frames_.front();
DVLOG(2) << " ConsumePendingDataFrame frame=(" << data_frame.type
<< ", (data_length = " << data_frame.data_length << "))";
if (data_frame.data_length == 0) {
auto data_to_pass = base::MakeRefCounted<net::IOBuffer>(0);
channel_->SendFrame(true, MessageTypeToOpCode(data_frame.type),
std::move(data_to_pass), 0);
pending_send_data_frames_.pop();
continue;
}
const void* buffer;
uint32_t readable_size;
const MojoResult begin_result = readable_->BeginReadData(
&buffer, &readable_size, MOJO_READ_DATA_FLAG_NONE);
if (begin_result == MOJO_RESULT_SHOULD_WAIT) {
wait_for_readable_ = true;
readable_watcher_.ArmOrNotify();
return;
}
if (begin_result == MOJO_RESULT_FAILED_PRECONDITION) {
return;
}
DCHECK_EQ(begin_result, MOJO_RESULT_OK);
const size_t size_to_send =
std::min(static_cast<uint64_t>(readable_size), data_frame.data_length);
auto data_to_pass = base::MakeRefCounted<net::IOBuffer>(size_to_send);
const bool is_final = (size_to_send == data_frame.data_length);
memcpy(data_to_pass->data(), buffer, size_to_send);
channel_->SendFrame(is_final, MessageTypeToOpCode(data_frame.type),
std::move(data_to_pass), size_to_send);
const MojoResult end_result = readable_->EndReadData(size_to_send);
DCHECK_EQ(end_result, MOJO_RESULT_OK);
if (size_to_send == data_frame.data_length) {
pending_send_data_frames_.pop();
continue;
}
DCHECK_GT(data_frame.data_length, size_to_send);
data_frame.type = mojom::WebSocketMessageType::CONTINUATION;
data_frame.data_length -= size_to_send;
}
return;
}
void WebSocket::OnSSLCertificateErrorResponse(
std::unique_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks,
const net::SSLInfo& ssl_info,
......
......@@ -72,6 +72,8 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) WebSocket : public mojom::WebSocket {
void SendFrame(bool fin,
mojom::WebSocketMessageType type,
base::span<const uint8_t> data) override;
void SendMessage(mojom::WebSocketMessageType type,
uint64_t data_length) override;
void StartReceiving() override;
void StartClosingHandshake(uint16_t code, const std::string& reason) override;
......@@ -116,6 +118,13 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) WebSocket : public mojom::WebSocket {
DISALLOW_COPY_AND_ASSIGN(UnownedPointer);
};
struct DataFrame final {
DataFrame(mojom::WebSocketMessageType type, uint64_t data_length)
: type(type), data_length(data_length) {}
mojom::WebSocketMessageType type;
uint64_t data_length;
};
void OnConnectionError(const base::Location& set_from);
void AddChannel(const GURL& socket_url,
const std::vector<std::string>& requested_protocols,
......@@ -150,6 +159,10 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) WebSocket : public mojom::WebSocket {
void SendPendingDataFrames();
void SendDataFrame(base::span<const char>* data_span);
// Datapipe functions to send.
void OnReadable(MojoResult result, const mojo::HandleSignalsState& state);
void ReadAndSendFromDataPipe();
// |factory_| owns |this|.
WebSocketFactory* const factory_;
mojo::Receiver<mojom::WebSocket> receiver_{this};
......@@ -189,6 +202,12 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) WebSocket : public mojom::WebSocket {
base::queue<base::span<const char>> pending_data_frames_;
bool wait_for_writable_ = false;
// Datapipe fields to send.
mojo::ScopedDataPipeConsumerHandle readable_;
mojo::SimpleWatcher readable_watcher_;
base::queue<DataFrame> pending_send_data_frames_;
bool wait_for_readable_ = false;
base::WeakPtrFactory<WebSocket> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(WebSocket);
......
......@@ -456,7 +456,8 @@ void WebSocketChannelImpl::OnConnectionEstablished(
mojo::PendingReceiver<network::mojom::blink::WebSocketClient>
client_receiver,
network::mojom::blink::WebSocketHandshakeResponsePtr response,
mojo::ScopedDataPipeConsumerHandle readable) {
mojo::ScopedDataPipeConsumerHandle readable,
mojo::ScopedDataPipeProducerHandle writable) {
DCHECK_EQ(GetState(), State::kConnecting);
const String& protocol = response->selected_protocol;
const String& extensions = response->extensions;
......@@ -484,6 +485,8 @@ void WebSocketChannelImpl::OnConnectionEstablished(
websocket_.Bind(std::move(websocket),
execution_context_->GetTaskRunner(TaskType::kNetworking));
readable_ = std::move(readable);
// TODO(suzukikeita): Implement upload via |writable_| instead of SendFrame.
writable_ = std::move(writable);
const MojoResult mojo_result = readable_watcher_.Watch(
readable_.get(), MOJO_HANDLE_SIGNAL_READABLE,
MOJO_WATCH_CONDITION_SATISFIED,
......
......@@ -119,7 +119,8 @@ class MODULES_EXPORT WebSocketChannelImpl final
mojo::PendingReceiver<network::mojom::blink::WebSocketClient>
client_receiver,
network::mojom::blink::WebSocketHandshakeResponsePtr,
mojo::ScopedDataPipeConsumerHandle readable) override;
mojo::ScopedDataPipeConsumerHandle readable,
mojo::ScopedDataPipeProducerHandle writable) override;
// network::mojom::blink::WebSocketClient methods:
void OnDataFrame(bool fin,
......@@ -265,6 +266,8 @@ class MODULES_EXPORT WebSocketChannelImpl final
mojo::SimpleWatcher readable_watcher_;
WTF::Deque<DataFrame> pending_data_frames_;
mojo::ScopedDataPipeProducerHandle writable_;
const scoped_refptr<base::SingleThreadTaskRunner> file_reading_task_runner_;
};
......
......@@ -107,6 +107,18 @@ class WebSocketChannelImplTest : public PageTestBase {
}
};
struct DataFrame final {
DataFrame(WebSocketMessageType type, uint64_t data_length)
: type(type), data_length(data_length) {}
WebSocketMessageType type;
uint64_t data_length;
bool operator==(const DataFrame& that) const {
return std::tie(type, data_length) ==
std::tie(that.type, that.data_length);
}
};
explicit TestWebSocket(
mojo::PendingReceiver<network::mojom::blink::WebSocket>
pending_receiver)
......@@ -119,6 +131,10 @@ class WebSocketChannelImplTest : public PageTestBase {
data_to_pass.AppendRange(data.begin(), data.end());
frames_.push_back(Frame{fin, type, std::move(data_to_pass)});
}
void SendMessage(WebSocketMessageType type, uint64_t data_length) override {
pending_send_data_frames_.push_back(DataFrame(type, data_length));
return;
}
void StartReceiving() override {
DCHECK(!is_start_receiving_called_);
is_start_receiving_called_ = true;
......@@ -132,6 +148,10 @@ class WebSocketChannelImplTest : public PageTestBase {
const Vector<Frame>& GetFrames() const { return frames_; }
void ClearFrames() { frames_.clear(); }
const Vector<DataFrame>& GetDataFrames() const {
return pending_send_data_frames_;
}
void ClearDataFrames() { pending_send_data_frames_.clear(); }
bool IsStartReceivingCalled() const { return is_start_receiving_called_; }
bool IsStartClosingHandshakeCalled() const {
return is_start_closing_handshake_called_;
......@@ -141,6 +161,7 @@ class WebSocketChannelImplTest : public PageTestBase {
private:
Vector<Frame> frames_;
Vector<DataFrame> pending_send_data_frames_;
bool is_start_receiving_called_ = false;
bool is_start_closing_handshake_called_ = false;
uint16_t closing_code_ = 0;
......@@ -149,6 +170,7 @@ class WebSocketChannelImplTest : public PageTestBase {
mojo::Receiver<network::mojom::blink::WebSocket> receiver_;
};
using Frames = Vector<TestWebSocket::Frame>;
using DataFrames = Vector<TestWebSocket::DataFrame>;
class WebSocketConnector final : public mojom::blink::WebSocketConnector {
public:
......@@ -233,6 +255,7 @@ class WebSocketChannelImplTest : public PageTestBase {
const String& selected_protocol,
const String& extensions,
mojo::ScopedDataPipeConsumerHandle readable,
mojo::ScopedDataPipeProducerHandle writable,
mojo::Remote<network::mojom::blink::WebSocketClient>* client) {
mojo::PendingRemote<network::mojom::blink::WebSocketClient> client_remote;
mojo::PendingRemote<network::mojom::blink::WebSocket> websocket_to_pass;
......@@ -248,7 +271,7 @@ class WebSocketChannelImplTest : public PageTestBase {
handshake_client->OnConnectionEstablished(
std::move(websocket_to_pass),
client_remote.InitWithNewPipeAndPassReceiver(), std::move(response),
std::move(readable));
std::move(readable), std::move(writable));
client->Bind(std::move(client_remote));
return websocket;
}
......@@ -295,6 +318,7 @@ class WebSocketChannelImplTest : public PageTestBase {
std::unique_ptr<TestWebSocket> Connect(
uint32_t capacity,
mojo::ScopedDataPipeProducerHandle* writable,
mojo::ScopedDataPipeConsumerHandle* readable,
mojo::Remote<network::mojom::blink::WebSocketClient>* client) {
if (!Channel()->Connect(KURL("ws://localhost/"), "")) {
ADD_FAILURE() << "WebSocketChannelImpl::Connect returns false.";
......@@ -310,13 +334,22 @@ class WebSocketChannelImplTest : public PageTestBase {
mojo::Remote<network::mojom::blink::WebSocketHandshakeClient>
handshake_client(std::move(connect_args[0].handshake_client));
mojo::ScopedDataPipeConsumerHandle readable;
if (CreateDataPipe(capacity, writable, &readable) != MOJO_RESULT_OK) {
mojo::ScopedDataPipeConsumerHandle remote_readable;
if (CreateDataPipe(capacity, writable, &remote_readable) !=
MOJO_RESULT_OK) {
ADD_FAILURE() << "Failed to create a datapipe.";
return nullptr;
}
mojo::ScopedDataPipeProducerHandle remote_writable;
if (CreateDataPipe(capacity, &remote_writable, readable) !=
MOJO_RESULT_OK) {
ADD_FAILURE() << "Failed to create a datapipe.";
return nullptr;
}
auto websocket = EstablishConnection(handshake_client.get(), "", "",
std::move(readable), client);
std::move(remote_readable),
std::move(remote_writable), client);
test::RunPendingTasks();
return websocket;
}
......@@ -387,13 +420,20 @@ TEST_F(WebSocketChannelImplTest, ConnectSuccess) {
mojo::Remote<network::mojom::blink::WebSocketHandshakeClient>
handshake_client(std::move(connect_args[0].handshake_client));
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
ASSERT_EQ(CreateDataPipe(32, &writable, &readable), MOJO_RESULT_OK);
mojo::ScopedDataPipeProducerHandle incoming_writable;
mojo::ScopedDataPipeConsumerHandle incoming_readable;
ASSERT_EQ(CreateDataPipe(32, &incoming_writable, &incoming_readable),
MOJO_RESULT_OK);
mojo::ScopedDataPipeProducerHandle outgoing_writable;
mojo::ScopedDataPipeConsumerHandle outgoing_readable;
ASSERT_EQ(CreateDataPipe(32, &outgoing_writable, &outgoing_readable),
MOJO_RESULT_OK);
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = EstablishConnection(handshake_client.get(), "a", "b",
std::move(readable), &client);
std::move(incoming_readable),
std::move(outgoing_writable), &client);
checkpoint.Call(1);
test::RunPendingTasks();
......@@ -434,8 +474,9 @@ TEST_F(WebSocketChannelImplTest, SendText) {
EXPECT_CALL(*ChannelClient(), DidConsumeBufferedAmount(_)).Times(AnyNumber());
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
Channel()->Send("foo", base::OnceClosure());
......@@ -464,8 +505,9 @@ TEST_F(WebSocketChannelImplTest, SendTextContinuation) {
EXPECT_CALL(*ChannelClient(), DidConsumeBufferedAmount(_)).Times(AnyNumber());
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
client->AddSendFlowControlQuota(16);
......@@ -513,8 +555,9 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInVector) {
EXPECT_CALL(*ChannelClient(), DidConsumeBufferedAmount(_)).Times(AnyNumber());
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
client->AddSendFlowControlQuota(16);
......@@ -534,8 +577,9 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferPartial) {
EXPECT_CALL(*ChannelClient(), DidConsumeBufferedAmount(_)).Times(AnyNumber());
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
client->AddSendFlowControlQuota(16);
......@@ -565,8 +609,9 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferWithNullBytes) {
EXPECT_CALL(*ChannelClient(), DidConsumeBufferedAmount(_)).Times(AnyNumber());
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
{
......@@ -605,8 +650,9 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferNonLatin1UTF8) {
EXPECT_CALL(*ChannelClient(), DidConsumeBufferedAmount(_)).Times(AnyNumber());
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
DOMArrayBuffer* b = DOMArrayBuffer::Create("\xe7\x8b\x90", 3);
......@@ -627,8 +673,9 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferNonUTF8) {
EXPECT_CALL(*ChannelClient(), DidConsumeBufferedAmount(_)).Times(AnyNumber());
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
DOMArrayBuffer* b = DOMArrayBuffer::Create("\x80\xff\xe7", 3);
......@@ -650,8 +697,9 @@ TEST_F(WebSocketChannelImplTest,
EXPECT_CALL(*ChannelClient(), DidConsumeBufferedAmount(_)).Times(AnyNumber());
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
DOMArrayBuffer* b = DOMArrayBuffer::Create(
......@@ -684,8 +732,9 @@ TEST_F(WebSocketChannelImplTest, SendTextSync) {
EXPECT_CALL(*ChannelClient(), DidConsumeBufferedAmount(_)).Times(AnyNumber());
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
client->AddSendFlowControlQuota(5);
......@@ -701,8 +750,9 @@ TEST_F(WebSocketChannelImplTest, SendTextAsyncDueToQuota) {
EXPECT_CALL(*ChannelClient(), DidConsumeBufferedAmount(_)).Times(AnyNumber());
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
client->AddSendFlowControlQuota(4);
......@@ -724,8 +774,9 @@ TEST_F(WebSocketChannelImplTest, SendTextAsyncDueToQueueing) {
EXPECT_CALL(*ChannelClient(), DidConsumeBufferedAmount(_)).Times(AnyNumber());
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
client->AddSendFlowControlQuota(8);
......@@ -751,8 +802,9 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferSync) {
EXPECT_CALL(*ChannelClient(), DidConsumeBufferedAmount(_)).Times(AnyNumber());
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
client->AddSendFlowControlQuota(5);
......@@ -770,8 +822,9 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferAsyncDueToQuota) {
EXPECT_CALL(*ChannelClient(), DidConsumeBufferedAmount(_)).Times(AnyNumber());
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
client->AddSendFlowControlQuota(4);
......@@ -794,8 +847,9 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferAsyncDueToQueueing) {
EXPECT_CALL(*ChannelClient(), DidConsumeBufferedAmount(_)).Times(AnyNumber());
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
client->AddSendFlowControlQuota(8);
......@@ -826,8 +880,9 @@ TEST_F(WebSocketChannelImplTest, ReceiveText) {
}
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
uint32_t num_bytes = 6;
......@@ -848,8 +903,9 @@ TEST_F(WebSocketChannelImplTest, ReceiveTextContinuation) {
}
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
uint32_t num_bytes = 3;
......@@ -873,8 +929,9 @@ TEST_F(WebSocketChannelImplTest, ReceiveTextNonLatin1) {
}
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
uint32_t num_bytes = 6;
......@@ -897,8 +954,9 @@ TEST_F(WebSocketChannelImplTest, ReceiveTextNonLatin1Continuation) {
}
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
uint32_t num_bytes = 6;
......@@ -923,8 +981,9 @@ TEST_F(WebSocketChannelImplTest, ReceiveBinary) {
}
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
uint32_t num_bytes = 3;
......@@ -945,8 +1004,9 @@ TEST_F(WebSocketChannelImplTest, ReceiveBinaryContinuation) {
}
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
uint32_t num_bytes = 3;
......@@ -975,8 +1035,9 @@ TEST_F(WebSocketChannelImplTest, ReceiveBinaryWithNullBytes) {
}
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
uint32_t num_bytes = 12;
......@@ -1001,8 +1062,9 @@ TEST_F(WebSocketChannelImplTest, ReceiveBinaryNonLatin1UTF8) {
'\xe7', '\x8b', '\x90', '\xe0', '\xa4', '\x94'})));
}
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
uint32_t num_bytes = 6;
......@@ -1025,8 +1087,9 @@ TEST_F(WebSocketChannelImplTest, ReceiveBinaryNonLatin1UTF8Continuation) {
}
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
uint32_t num_bytes = 6;
......@@ -1051,8 +1114,9 @@ TEST_F(WebSocketChannelImplTest, ReceiveBinaryNonUTF8) {
}
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
uint32_t num_bytes = 2;
......@@ -1074,8 +1138,9 @@ TEST_F(WebSocketChannelImplTest, ReceiveWithExplicitBackpressure) {
}
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
uint32_t num_bytes = 3;
......@@ -1113,8 +1178,9 @@ TEST_F(WebSocketChannelImplTest,
}
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
client->OnDataFrame(true, WebSocketMessageType::TEXT, 3);
......@@ -1179,8 +1245,9 @@ TEST_F(WebSocketChannelImplTest, ConnectionCloseInitiatedByServer) {
}
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
client->OnClosingHandshake();
......@@ -1219,8 +1286,9 @@ TEST_F(WebSocketChannelImplTest, ConnectionCloseInitiatedByClient) {
}
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
EXPECT_FALSE(websocket->IsStartClosingHandshakeCalled());
......@@ -1254,8 +1322,9 @@ TEST_F(WebSocketChannelImplTest, MojoConnectionError) {
}
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
// Send a frame so that the WebSocketChannelImpl try to read the data pipe.
......@@ -1285,8 +1354,9 @@ TEST_F(WebSocketChannelImplTest, FailFromClient) {
}
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
Channel()->Fail("fail message from WebSocket",
......@@ -1329,6 +1399,11 @@ TEST_F(WebSocketChannelImplHandshakeThrottleTest, ThrottleSucceedsFirst) {
mojo::ScopedDataPipeConsumerHandle readable;
ASSERT_EQ(CreateDataPipe(32, &writable, &readable), MOJO_RESULT_OK);
mojo::ScopedDataPipeProducerHandle outgoing_writable;
mojo::ScopedDataPipeConsumerHandle outgoing_readable;
ASSERT_EQ(CreateDataPipe(32, &outgoing_writable, &outgoing_readable),
MOJO_RESULT_OK);
mojo::Remote<network::mojom::blink::WebSocketClient> client;
checkpoint.Call(1);
......@@ -1337,8 +1412,9 @@ TEST_F(WebSocketChannelImplHandshakeThrottleTest, ThrottleSucceedsFirst) {
Channel()->OnCompletion(base::nullopt);
checkpoint.Call(2);
auto websocket = EstablishConnection(handshake_client.get(), "", "",
std::move(readable), &client);
auto websocket =
EstablishConnection(handshake_client.get(), "", "", std::move(readable),
std::move(outgoing_writable), &client);
test::RunPendingTasks();
}
......@@ -1354,10 +1430,11 @@ TEST_F(WebSocketChannelImplHandshakeThrottleTest, HandshakeSucceedsFirst) {
}
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
checkpoint.Call(1);
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
checkpoint.Call(2);
......@@ -1398,8 +1475,9 @@ TEST_F(WebSocketChannelImplHandshakeThrottleTest,
}
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
Channel()->Fail("close during handshake",
......@@ -1449,8 +1527,9 @@ TEST_F(WebSocketChannelImplHandshakeThrottleTest,
}
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
Channel()->Disconnect();
......@@ -1490,8 +1569,9 @@ TEST_F(WebSocketChannelImplHandshakeThrottleTest,
}
mojo::ScopedDataPipeProducerHandle writable;
mojo::ScopedDataPipeConsumerHandle readable;
mojo::Remote<network::mojom::blink::WebSocketClient> client;
auto websocket = Connect(4 * 1024, &writable, &client);
auto websocket = Connect(4 * 1024, &writable, &readable, &client);
ASSERT_TRUE(websocket);
Channel()->OnCompletion("Connection blocked by throttle");
......
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