Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(720)

Unified Diff: content/browser/websocket/websocket_impl.cc

Issue 2119973002: Port WebSockets to Mojo IPC (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/websocket/websocket_impl.cc
diff --git a/content/browser/renderer_host/websocket_host.cc b/content/browser/websocket/websocket_impl.cc
similarity index 52%
rename from content/browser/renderer_host/websocket_host.cc
rename to content/browser/websocket/websocket_impl.cc
index cce4485b3d4d67801e5037ee042d88fd5aaaaa41..6b8dd77753aa3e6bf6fcb1228f9a48721c7e47b5 100644
--- a/content/browser/renderer_host/websocket_host.cc
+++ b/content/browser/websocket/websocket_impl.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/browser/renderer_host/websocket_host.h"
+#include "content/browser/websocket/websocket_impl.h"
#include <inttypes.h>
@@ -19,20 +19,19 @@
#include "base/strings/stringprintf.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/browser/bad_message.h"
-#include "content/browser/renderer_host/websocket_blob_sender.h"
-#include "content/browser/renderer_host/websocket_dispatcher_host.h"
+#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/ssl/ssl_error_handler.h"
#include "content/browser/ssl/ssl_manager.h"
-#include "content/common/websocket_messages.h"
+#include "content/browser/websocket/websocket_blob_sender.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/storage_partition.h"
-#include "ipc/ipc_message_macros.h"
#include "net/base/net_errors.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_util.h"
#include "net/ssl/ssl_info.h"
+#include "net/url_request/url_request_context_getter.h"
#include "net/websockets/websocket_channel.h"
#include "net/websockets/websocket_errors.h"
#include "net/websockets/websocket_event_interface.h"
@@ -42,7 +41,6 @@
#include "url/origin.h"
namespace content {
-
namespace {
typedef net::WebSocketEventInterface::ChannelState ChannelState;
@@ -50,54 +48,37 @@ typedef net::WebSocketEventInterface::ChannelState ChannelState;
// Convert a content::WebSocketMessageType to a
// net::WebSocketFrameHeader::OpCode
net::WebSocketFrameHeader::OpCode MessageTypeToOpCode(
- WebSocketMessageType type) {
- DCHECK(type == WEB_SOCKET_MESSAGE_TYPE_CONTINUATION ||
- type == WEB_SOCKET_MESSAGE_TYPE_TEXT ||
- type == WEB_SOCKET_MESSAGE_TYPE_BINARY);
+ mojom::WebSocketMessageType type) {
+ DCHECK(type == mojom::WebSocketMessageType::CONTINUATION ||
+ type == mojom::WebSocketMessageType::TEXT ||
+ type == mojom::WebSocketMessageType::BINARY);
typedef net::WebSocketFrameHeader::OpCode OpCode;
// These compile asserts verify that the same underlying values are used for
// both types, so we can simply cast between them.
- static_assert(static_cast<OpCode>(WEB_SOCKET_MESSAGE_TYPE_CONTINUATION) ==
- net::WebSocketFrameHeader::kOpCodeContinuation,
- "enum values must match for opcode continuation");
- static_assert(static_cast<OpCode>(WEB_SOCKET_MESSAGE_TYPE_TEXT) ==
- net::WebSocketFrameHeader::kOpCodeText,
- "enum values must match for opcode text");
- static_assert(static_cast<OpCode>(WEB_SOCKET_MESSAGE_TYPE_BINARY) ==
- net::WebSocketFrameHeader::kOpCodeBinary,
- "enum values must match for opcode binary");
+ static_assert(
+ static_cast<OpCode>(mojom::WebSocketMessageType::CONTINUATION) ==
+ net::WebSocketFrameHeader::kOpCodeContinuation,
+ "enum values must match for opcode continuation");
+ static_assert(
+ static_cast<OpCode>(mojom::WebSocketMessageType::TEXT) ==
+ net::WebSocketFrameHeader::kOpCodeText,
+ "enum values must match for opcode text");
+ static_assert(
+ static_cast<OpCode>(mojom::WebSocketMessageType::BINARY) ==
+ net::WebSocketFrameHeader::kOpCodeBinary,
+ "enum values must match for opcode binary");
return static_cast<OpCode>(type);
}
-WebSocketMessageType OpCodeToMessageType(
+mojom::WebSocketMessageType OpCodeToMessageType(
net::WebSocketFrameHeader::OpCode opCode) {
DCHECK(opCode == net::WebSocketFrameHeader::kOpCodeContinuation ||
opCode == net::WebSocketFrameHeader::kOpCodeText ||
opCode == net::WebSocketFrameHeader::kOpCodeBinary);
// This cast is guaranteed valid by the static_assert() statements above.
- return static_cast<WebSocketMessageType>(opCode);
-}
-
-ChannelState StateCast(WebSocketDispatcherHost::WebSocketHostState host_state) {
- const WebSocketDispatcherHost::WebSocketHostState WEBSOCKET_HOST_ALIVE =
- WebSocketDispatcherHost::WEBSOCKET_HOST_ALIVE;
- const WebSocketDispatcherHost::WebSocketHostState WEBSOCKET_HOST_DELETED =
- WebSocketDispatcherHost::WEBSOCKET_HOST_DELETED;
-
- DCHECK(host_state == WEBSOCKET_HOST_ALIVE ||
- host_state == WEBSOCKET_HOST_DELETED);
- // These compile asserts verify that we can get away with using static_cast<>
- // for the conversion.
- static_assert(static_cast<ChannelState>(WEBSOCKET_HOST_ALIVE) ==
- net::WebSocketEventInterface::CHANNEL_ALIVE,
- "enum values must match for state_alive");
- static_assert(static_cast<ChannelState>(WEBSOCKET_HOST_DELETED) ==
- net::WebSocketEventInterface::CHANNEL_DELETED,
- "enum values must match for state_deleted");
- return static_cast<ChannelState>(host_state);
+ return static_cast<mojom::WebSocketMessageType>(opCode);
}
-// Implementation of WebSocketBlobSender::Channel
class SendChannelImpl final : public WebSocketBlobSender::Channel {
public:
explicit SendChannelImpl(net::WebSocketChannel* channel)
@@ -127,13 +108,10 @@ class SendChannelImpl final : public WebSocketBlobSender::Channel {
// Implementation of net::WebSocketEventInterface. Receives events from our
// WebSocketChannel object. Each event is translated to an IPC and sent to the
// renderer or child process via WebSocketDispatcherHost.
-class WebSocketHost::WebSocketEventHandler final
+class WebSocketImpl::WebSocketEventHandler final
: public net::WebSocketEventInterface {
public:
- WebSocketEventHandler(WebSocketDispatcherHost* dispatcher,
- WebSocketHost* host,
- int routing_id,
- int render_frame_id);
+ explicit WebSocketEventHandler(WebSocketImpl* impl);
~WebSocketEventHandler() override;
// net::WebSocketEventInterface implementation
@@ -181,172 +159,206 @@ class WebSocketHost::WebSocketEventHandler final
DISALLOW_COPY_AND_ASSIGN(SSLErrorHandlerDelegate);
};
- WebSocketDispatcherHost* const dispatcher_;
- WebSocketHost* const host_;
- const int routing_id_;
- const int render_frame_id_;
+ WebSocketImpl* const impl_;
std::unique_ptr<SSLErrorHandlerDelegate> ssl_error_handler_delegate_;
DISALLOW_COPY_AND_ASSIGN(WebSocketEventHandler);
};
-WebSocketHost::WebSocketEventHandler::WebSocketEventHandler(
- WebSocketDispatcherHost* dispatcher,
- WebSocketHost* host,
- int routing_id,
- int render_frame_id)
- : dispatcher_(dispatcher),
- host_(host),
- routing_id_(routing_id),
- render_frame_id_(render_frame_id) {}
-
-WebSocketHost::WebSocketEventHandler::~WebSocketEventHandler() {
- DVLOG(1) << "WebSocketEventHandler destroyed routing_id=" << routing_id_;
+WebSocketImpl::WebSocketEventHandler::WebSocketEventHandler(WebSocketImpl* impl)
+ : impl_(impl) {
+ DVLOG(1) << "WebSocketEventHandler created @"
+ << reinterpret_cast<void*>(this);
+}
+
+WebSocketImpl::WebSocketEventHandler::~WebSocketEventHandler() {
+ DVLOG(1) << "WebSocketEventHandler destroyed @"
+ << reinterpret_cast<void*>(this);
}
-ChannelState WebSocketHost::WebSocketEventHandler::OnAddChannelResponse(
+ChannelState WebSocketImpl::WebSocketEventHandler::OnAddChannelResponse(
const std::string& selected_protocol,
const std::string& extensions) {
- DVLOG(3) << "WebSocketEventHandler::OnAddChannelResponse"
- << " routing_id=" << routing_id_
+ DVLOG(3) << "WebSocketEventHandler::OnAddChannelResponse @"
+ << reinterpret_cast<void*>(this)
<< " selected_protocol=\"" << selected_protocol << "\""
<< " extensions=\"" << extensions << "\"";
- return StateCast(dispatcher_->SendAddChannelResponse(
- routing_id_, selected_protocol, extensions));
+ impl_->delegate_->OnReceivedResponseFromServer(impl_);
+
+ impl_->client_->OnAddChannelResponse(selected_protocol, extensions);
+
+ return net::WebSocketEventInterface::CHANNEL_ALIVE;
}
-ChannelState WebSocketHost::WebSocketEventHandler::OnDataFrame(
+ChannelState WebSocketImpl::WebSocketEventHandler::OnDataFrame(
bool fin,
net::WebSocketFrameHeader::OpCode type,
const std::vector<char>& data) {
- DVLOG(3) << "WebSocketEventHandler::OnDataFrame"
- << " routing_id=" << routing_id_ << " fin=" << fin
+ DVLOG(3) << "WebSocketEventHandler::OnDataFrame @"
+ << reinterpret_cast<void*>(this)
+ << " fin=" << fin
<< " type=" << type << " data is " << data.size() << " bytes";
- return StateCast(dispatcher_->SendFrame(routing_id_, fin,
- OpCodeToMessageType(type), data));
+ // TODO(darin): Avoid this copy.
+ mojo::Array<uint8_t> data_to_pass(data.size());
+ memcpy(&data_to_pass[0], &data[0], data.size());
+
+ impl_->client_->OnDataFrame(fin, OpCodeToMessageType(type),
+ std::move(data_to_pass));
+
+ return net::WebSocketEventInterface::CHANNEL_ALIVE;
}
-ChannelState WebSocketHost::WebSocketEventHandler::OnClosingHandshake() {
- DVLOG(3) << "WebSocketEventHandler::OnClosingHandshake"
- << " routing_id=" << routing_id_;
+ChannelState WebSocketImpl::WebSocketEventHandler::OnClosingHandshake() {
+ DVLOG(3) << "WebSocketEventHandler::OnClosingHandshake @"
+ << reinterpret_cast<void*>(this);
+
+ impl_->client_->OnClosingHandshake();
- return StateCast(dispatcher_->NotifyClosingHandshake(routing_id_));
+ return net::WebSocketEventInterface::CHANNEL_ALIVE;
}
-ChannelState WebSocketHost::WebSocketEventHandler::OnFlowControl(
+ChannelState WebSocketImpl::WebSocketEventHandler::OnFlowControl(
int64_t quota) {
- DVLOG(3) << "WebSocketEventHandler::OnFlowControl"
- << " routing_id=" << routing_id_ << " quota=" << quota;
+ DVLOG(3) << "WebSocketEventHandler::OnFlowControl @"
+ << reinterpret_cast<void*>(this)
+ << " quota=" << quota;
- if (host_->blob_sender_)
- host_->blob_sender_->OnNewSendQuota();
- return StateCast(dispatcher_->SendFlowControl(routing_id_, quota));
+ if (impl_->blob_sender_)
+ impl_->blob_sender_->OnNewSendQuota();
+
+ impl_->client_->OnFlowControl(quota);
+
+ return net::WebSocketEventInterface::CHANNEL_ALIVE;
}
-ChannelState WebSocketHost::WebSocketEventHandler::OnDropChannel(
+ChannelState WebSocketImpl::WebSocketEventHandler::OnDropChannel(
bool was_clean,
uint16_t code,
const std::string& reason) {
- DVLOG(3) << "WebSocketEventHandler::OnDropChannel"
- << " routing_id=" << routing_id_ << " was_clean=" << was_clean
- << " code=" << code << " reason=\"" << reason << "\"";
+ DVLOG(3) << "WebSocketEventHandler::OnDropChannel @"
+ << reinterpret_cast<void*>(this)
+ << " was_clean=" << was_clean << " code=" << code
+ << " reason=\"" << reason << "\"";
- return StateCast(
- dispatcher_->DoDropChannel(routing_id_, was_clean, code, reason));
+ impl_->client_->OnDropChannel(was_clean, code, reason);
+
+ return net::WebSocketEventInterface::CHANNEL_ALIVE;
}
-ChannelState WebSocketHost::WebSocketEventHandler::OnFailChannel(
+ChannelState WebSocketImpl::WebSocketEventHandler::OnFailChannel(
const std::string& message) {
- DVLOG(3) << "WebSocketEventHandler::OnFailChannel"
- << " routing_id=" << routing_id_ << " message=\"" << message << "\"";
+ DVLOG(3) << "WebSocketEventHandler::OnFailChannel @"
+ << reinterpret_cast<void*>(this) << " message=\"" << message << "\"";
+
+ impl_->client_->OnFailChannel(message);
- return StateCast(dispatcher_->NotifyFailure(routing_id_, message));
+ return net::WebSocketEventInterface::CHANNEL_ALIVE;
}
-ChannelState WebSocketHost::WebSocketEventHandler::OnStartOpeningHandshake(
+ChannelState WebSocketImpl::WebSocketEventHandler::OnStartOpeningHandshake(
std::unique_ptr<net::WebSocketHandshakeRequestInfo> request) {
- bool should_send = dispatcher_->CanReadRawCookies();
- DVLOG(3) << "WebSocketEventHandler::OnStartOpeningHandshake "
- << "should_send=" << should_send;
+ bool should_send =
+ ChildProcessSecurityPolicyImpl::GetInstance()->CanReadRawCookies(
+ impl_->delegate_->GetClientProcessId());
+
+ DVLOG(3) << "WebSocketEventHandler::OnStartOpeningHandshake @"
+ << reinterpret_cast<void*>(this) << " should_send=" << should_send;
if (!should_send)
return WebSocketEventInterface::CHANNEL_ALIVE;
- WebSocketHandshakeRequest request_to_pass;
- request_to_pass.url.Swap(&request->url);
+ mojom::WebSocketHandshakeRequestPtr request_to_pass(
+ mojom::WebSocketHandshakeRequest::New());
+ request_to_pass->url.Swap(&request->url);
net::HttpRequestHeaders::Iterator it(request->headers);
- while (it.GetNext())
- request_to_pass.headers.push_back(std::make_pair(it.name(), it.value()));
- request_to_pass.headers_text =
+ while (it.GetNext()) {
+ mojom::HttpHeaderPtr header(mojom::HttpHeader::New());
+ header->name = it.name();
+ header->value = it.value();
+ request_to_pass->headers.push_back(std::move(header));
+ }
+ request_to_pass->headers_text =
base::StringPrintf("GET %s HTTP/1.1\r\n",
- request_to_pass.url.spec().c_str()) +
+ request_to_pass->url.spec().c_str()) +
request->headers.ToString();
- request_to_pass.request_time = request->request_time;
- return StateCast(
- dispatcher_->NotifyStartOpeningHandshake(routing_id_, request_to_pass));
+ impl_->client_->OnStartOpeningHandshake(std::move(request_to_pass));
+
+ return WebSocketEventInterface::CHANNEL_ALIVE;
}
-ChannelState WebSocketHost::WebSocketEventHandler::OnFinishOpeningHandshake(
+ChannelState WebSocketImpl::WebSocketEventHandler::OnFinishOpeningHandshake(
std::unique_ptr<net::WebSocketHandshakeResponseInfo> response) {
- bool should_send = dispatcher_->CanReadRawCookies();
+ bool should_send =
+ ChildProcessSecurityPolicyImpl::GetInstance()->CanReadRawCookies(
+ impl_->delegate_->GetClientProcessId());
+
DVLOG(3) << "WebSocketEventHandler::OnFinishOpeningHandshake "
- << "should_send=" << should_send;
+ << reinterpret_cast<void*>(this) << " should_send=" << should_send;
if (!should_send)
return WebSocketEventInterface::CHANNEL_ALIVE;
- WebSocketHandshakeResponse response_to_pass;
- response_to_pass.url.Swap(&response->url);
- response_to_pass.status_code = response->status_code;
- response_to_pass.status_text.swap(response->status_text);
+ mojom::WebSocketHandshakeResponsePtr response_to_pass(
+ mojom::WebSocketHandshakeResponse::New());
+ response_to_pass->url.Swap(&response->url);
+ response_to_pass->status_code = response->status_code;
+ response_to_pass->status_text = response->status_text;
size_t iter = 0;
std::string name, value;
- while (response->headers->EnumerateHeaderLines(&iter, &name, &value))
- response_to_pass.headers.push_back(std::make_pair(name, value));
- response_to_pass.headers_text =
+ while (response->headers->EnumerateHeaderLines(&iter, &name, &value)) {
+ mojom::HttpHeaderPtr header(mojom::HttpHeader::New());
+ header->name = name;
+ header->value = value;
+ response_to_pass->headers.push_back(std::move(header));
+ }
+ response_to_pass->headers_text =
net::HttpUtil::ConvertHeadersBackToHTTPResponse(
response->headers->raw_headers());
- response_to_pass.response_time = response->response_time;
- return StateCast(
- dispatcher_->NotifyFinishOpeningHandshake(routing_id_, response_to_pass));
+ impl_->client_->OnFinishOpeningHandshake(std::move(response_to_pass));
+
+ return WebSocketEventInterface::CHANNEL_ALIVE;
}
-ChannelState WebSocketHost::WebSocketEventHandler::OnSSLCertificateError(
+ChannelState WebSocketImpl::WebSocketEventHandler::OnSSLCertificateError(
std::unique_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks,
const GURL& url,
const net::SSLInfo& ssl_info,
bool fatal) {
DVLOG(3) << "WebSocketEventHandler::OnSSLCertificateError"
- << " routing_id=" << routing_id_ << " url=" << url.spec()
+ << reinterpret_cast<void*>(this) << " url=" << url.spec()
<< " cert_status=" << ssl_info.cert_status << " fatal=" << fatal;
ssl_error_handler_delegate_.reset(
new SSLErrorHandlerDelegate(std::move(callbacks)));
SSLManager::OnSSLCertificateSubresourceError(
- ssl_error_handler_delegate_->GetWeakPtr(), url,
- dispatcher_->render_process_id(), render_frame_id_, ssl_info, fatal);
+ ssl_error_handler_delegate_->GetWeakPtr(),
+ url,
+ impl_->delegate_->GetClientProcessId(),
+ impl_->render_frame_id_,
+ ssl_info,
+ fatal);
// The above method is always asynchronous.
return WebSocketEventInterface::CHANNEL_ALIVE;
}
-WebSocketHost::WebSocketEventHandler::SSLErrorHandlerDelegate::
+WebSocketImpl::WebSocketEventHandler::SSLErrorHandlerDelegate::
SSLErrorHandlerDelegate(
std::unique_ptr<net::WebSocketEventInterface::SSLErrorCallbacks>
callbacks)
: callbacks_(std::move(callbacks)), weak_ptr_factory_(this) {}
-WebSocketHost::WebSocketEventHandler::SSLErrorHandlerDelegate::
+WebSocketImpl::WebSocketEventHandler::SSLErrorHandlerDelegate::
~SSLErrorHandlerDelegate() {}
base::WeakPtr<SSLErrorHandler::Delegate>
-WebSocketHost::WebSocketEventHandler::SSLErrorHandlerDelegate::GetWeakPtr() {
+WebSocketImpl::WebSocketEventHandler::SSLErrorHandlerDelegate::GetWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
-void WebSocketHost::WebSocketEventHandler::SSLErrorHandlerDelegate::
+void WebSocketImpl::WebSocketEventHandler::SSLErrorHandlerDelegate::
CancelSSLRequest(int error, const net::SSLInfo* ssl_info) {
DVLOG(3) << "SSLErrorHandlerDelegate::CancelSSLRequest"
<< " error=" << error
@@ -355,54 +367,51 @@ void WebSocketHost::WebSocketEventHandler::SSLErrorHandlerDelegate::
callbacks_->CancelSSLRequest(error, ssl_info);
}
-void WebSocketHost::WebSocketEventHandler::SSLErrorHandlerDelegate::
+void WebSocketImpl::WebSocketEventHandler::SSLErrorHandlerDelegate::
ContinueSSLRequest() {
DVLOG(3) << "SSLErrorHandlerDelegate::ContinueSSLRequest";
callbacks_->ContinueSSLRequest();
}
-WebSocketHost::WebSocketHost(int routing_id,
- WebSocketDispatcherHost* dispatcher,
- net::URLRequestContext* url_request_context,
- base::TimeDelta delay)
- : dispatcher_(dispatcher),
- url_request_context_(url_request_context),
- routing_id_(routing_id),
+WebSocketImpl::WebSocketImpl(
+ Delegate* delegate,
+ mojom::WebSocketRequest request,
+ int render_frame_id,
+ base::TimeDelta delay)
+ : delegate_(delegate),
+ binding_(this, std::move(request)),
+ render_frame_id_(render_frame_id),
delay_(delay),
pending_flow_control_quota_(0),
handshake_succeeded_(false),
weak_ptr_factory_(this) {
- DVLOG(1) << "WebSocketHost: created routing_id=" << routing_id;
+ binding_.set_connection_error_handler(
+ base::Bind(&WebSocketImpl::OnConnectionError, base::Unretained(this)));
}
-WebSocketHost::~WebSocketHost() {}
+WebSocketImpl::~WebSocketImpl() {}
-void WebSocketHost::GoAway() {
- OnDropChannel(false, static_cast<uint16_t>(net::kWebSocketErrorGoingAway),
- "");
+void WebSocketImpl::GoAway() {
+ StartClosingHandshake(static_cast<uint16_t>(net::kWebSocketErrorGoingAway),
+ "");
}
-bool WebSocketHost::OnMessageReceived(const IPC::Message& message) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(WebSocketHost, message)
- IPC_MESSAGE_HANDLER(WebSocketHostMsg_AddChannelRequest, OnAddChannelRequest)
- IPC_MESSAGE_HANDLER(WebSocketHostMsg_SendBlob, OnSendBlob)
- IPC_MESSAGE_HANDLER(WebSocketMsg_SendFrame, OnSendFrame)
- IPC_MESSAGE_HANDLER(WebSocketMsg_FlowControl, OnFlowControl)
- IPC_MESSAGE_HANDLER(WebSocketMsg_DropChannel, OnDropChannel)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
+void WebSocketImpl::Initialize(mojom::WebSocketClientPtr client) {
+ client_ = std::move(client);
}
-void WebSocketHost::OnAddChannelRequest(
+void WebSocketImpl::AddChannelRequest(
const GURL& socket_url,
- const std::vector<std::string>& requested_protocols,
- const url::Origin& origin,
- int render_frame_id) {
- DVLOG(3) << "WebSocketHost::OnAddChannelRequest"
- << " routing_id=" << routing_id_ << " socket_url=\"" << socket_url
- << "\" requested_protocols=\""
+ mojo::Array<mojo::String> requested_protocols_mojo,
+ const url::Origin& origin) {
+ // Convert to STL types.
+ std::vector<std::string> requested_protocols(
+ requested_protocols_mojo.begin(),
+ requested_protocols_mojo.end());
+
+ DVLOG(3) << "WebSocketImpl::AddChannelRequest @"
+ << reinterpret_cast<void*>(this)
+ << " socket_url=\"" << socket_url << "\" requested_protocols=\""
<< base::JoinString(requested_protocols, ", ") << "\" origin=\""
<< origin << "\"";
@@ -410,68 +419,33 @@ void WebSocketHost::OnAddChannelRequest(
if (delay_ > base::TimeDelta()) {
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
- base::Bind(&WebSocketHost::AddChannel, weak_ptr_factory_.GetWeakPtr(),
- socket_url, requested_protocols, origin, render_frame_id),
+ base::Bind(&WebSocketImpl::AddChannel,
+ weak_ptr_factory_.GetWeakPtr(),
+ socket_url,
+ requested_protocols,
+ origin),
delay_);
} else {
- AddChannel(socket_url, requested_protocols, origin, render_frame_id);
- }
- // |this| may have been deleted here.
-}
-
-void WebSocketHost::AddChannel(
- const GURL& socket_url,
- const std::vector<std::string>& requested_protocols,
- const url::Origin& origin,
- int render_frame_id) {
- DVLOG(3) << "WebSocketHost::AddChannel"
- << " routing_id=" << routing_id_ << " socket_url=\"" << socket_url
- << "\" requested_protocols=\""
- << base::JoinString(requested_protocols, ", ") << "\" origin=\""
- << origin << "\"";
-
- DCHECK(!channel_);
-
- std::unique_ptr<net::WebSocketEventInterface> event_interface(
- new WebSocketEventHandler(dispatcher_, this, routing_id_,
- render_frame_id));
- channel_.reset(new net::WebSocketChannel(std::move(event_interface),
- url_request_context_));
-
- if (pending_flow_control_quota_ > 0) {
- // channel_->SendFlowControl(pending_flow_control_quota_) must be called
- // after channel_->SendAddChannelRequest() below.
- // We post OnFlowControl() here using |weak_ptr_factory_| instead of
- // calling SendFlowControl directly, because |this| may have been deleted
- // after channel_->SendAddChannelRequest().
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(&WebSocketHost::OnFlowControl,
- weak_ptr_factory_.GetWeakPtr(),
- pending_flow_control_quota_));
- pending_flow_control_quota_ = 0;
+ AddChannel(socket_url, requested_protocols, origin);
}
-
- channel_->SendAddChannelRequest(socket_url, requested_protocols, origin);
- // |this| may have been deleted here.
}
-void WebSocketHost::OnSendBlob(const std::string& uuid,
- uint64_t expected_size) {
- DVLOG(3) << "WebSocketHost::OnSendBlob"
- << " routing_id=" << routing_id_ << " uuid=" << uuid
+void WebSocketImpl::SendBlob(const mojo::String& uuid, uint64_t expected_size) {
+ DVLOG(3) << "WebSocketImpl::OnSendBlob @"
+ << reinterpret_cast<void*>(this) << " uuid=" << uuid
<< " expected_size=" << expected_size;
DCHECK(channel_);
if (blob_sender_) {
bad_message::ReceivedBadMessage(
- dispatcher_, bad_message::WSH_SEND_BLOB_DURING_BLOB_SEND);
+ delegate_->GetClientProcessId(),
+ bad_message::WSI_SEND_BLOB_DURING_BLOB_SEND);
return;
}
blob_sender_.reset(new WebSocketBlobSender(
base::WrapUnique(new SendChannelImpl(channel_.get()))));
- StoragePartition* partition = dispatcher_->storage_partition();
storage::FileSystemContext* file_system_context =
- partition->GetFileSystemContext();
+ delegate_->GetStoragePartition()->GetFileSystemContext();
net::WebSocketEventInterface::ChannelState channel_state =
net::WebSocketEventInterface::CHANNEL_ALIVE;
@@ -479,36 +453,42 @@ void WebSocketHost::OnSendBlob(const std::string& uuid,
// This use of base::Unretained is safe because the WebSocketBlobSender object
// is owned by this object and will not call it back after destruction.
int rv = blob_sender_->Start(
- uuid, expected_size, dispatcher_->blob_storage_context(),
+ uuid,
+ expected_size,
+ delegate_->GetBlobStorageContext(),
file_system_context,
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE).get(),
&channel_state,
- base::Bind(&WebSocketHost::BlobSendComplete, base::Unretained(this)));
+ base::Bind(&WebSocketImpl::BlobSendComplete, base::Unretained(this)));
if (channel_state == net::WebSocketEventInterface::CHANNEL_ALIVE &&
rv != net::ERR_IO_PENDING)
BlobSendComplete(rv);
- // |this| may be destroyed here.
}
-void WebSocketHost::OnSendFrame(bool fin,
- WebSocketMessageType type,
- const std::vector<char>& data) {
- DVLOG(3) << "WebSocketHost::OnSendFrame"
- << " routing_id=" << routing_id_ << " fin=" << fin
+void WebSocketImpl::SendFrame(bool fin, mojom::WebSocketMessageType type,
+ mojo::Array<uint8_t> data) {
+ DVLOG(3) << "WebSocketImpl::OnSendFrame @"
+ << reinterpret_cast<void*>(this) << " fin=" << fin
<< " type=" << type << " data is " << data.size() << " bytes";
DCHECK(channel_);
if (blob_sender_) {
bad_message::ReceivedBadMessage(
- dispatcher_, bad_message::WSH_SEND_FRAME_DURING_BLOB_SEND);
+ delegate_->GetClientProcessId(),
+ bad_message::WSI_SEND_FRAME_DURING_BLOB_SEND);
return;
}
- channel_->SendFrame(fin, MessageTypeToOpCode(type), data);
+
+ // TODO(darin): Avoid this copy.
+ std::vector<char> data_to_pass(data.size());
+ memcpy(&data_to_pass[0], &data[0], data.size());
+
+ channel_->SendFrame(fin, MessageTypeToOpCode(type), data_to_pass);
}
-void WebSocketHost::OnFlowControl(int64_t quota) {
- DVLOG(3) << "WebSocketHost::OnFlowControl"
- << " routing_id=" << routing_id_ << " quota=" << quota;
+void WebSocketImpl::SendFlowControl(int64_t quota) {
+ DVLOG(3) << "WebSocketImpl::OnFlowControl @"
+ << reinterpret_cast<void*>(this) << " quota=" << quota;
if (!channel_) {
// WebSocketChannel is not yet created due to the delay introduced by
@@ -521,20 +501,26 @@ void WebSocketHost::OnFlowControl(int64_t quota) {
ignore_result(channel_->SendFlowControl(quota));
}
-void WebSocketHost::OnDropChannel(bool was_clean,
- uint16_t code,
- const std::string& reason) {
- DVLOG(3) << "WebSocketHost::OnDropChannel"
- << " routing_id=" << routing_id_ << " was_clean=" << was_clean
+void WebSocketImpl::StartClosingHandshake(uint16_t code,
+ const mojo::String& reason) {
+ DVLOG(3) << "WebSocketImpl::StartClosingHandshake @"
+ << reinterpret_cast<void*>(this)
<< " code=" << code << " reason=\"" << reason << "\"";
if (!channel_) {
// WebSocketChannel is not yet created due to the delay introduced by
// per-renderer WebSocket throttling.
+#if 0
WebSocketDispatcherHost::WebSocketHostState result =
dispatcher_->DoDropChannel(routing_id_, false,
net::kWebSocketErrorAbnormalClosure, "");
DCHECK_EQ(WebSocketDispatcherHost::WEBSOCKET_HOST_DELETED, result);
+#endif
+ client_->OnDropChannel(false, net::kWebSocketErrorAbnormalClosure, "");
+
+ // XXX need to break connection
+ // XXX -- No, we will observe the client dropping the connection
+
return;
}
@@ -543,9 +529,53 @@ void WebSocketHost::OnDropChannel(bool was_clean,
ignore_result(channel_->StartClosingHandshake(code, reason));
}
-void WebSocketHost::BlobSendComplete(int result) {
- DVLOG(3) << "WebSocketHost::BlobSendComplete"
- << " routing_id=" << routing_id_
+void WebSocketImpl::OnConnectionError() {
+ delegate_->OnLostConnectionToClient(this);
+}
+
+void WebSocketImpl::AddChannel(
+ const GURL& socket_url,
+ const std::vector<std::string>& requested_protocols,
+ const url::Origin& origin) {
+ DVLOG(3) << "WebSocketImpl::AddChannel @"
+ << reinterpret_cast<void*>(this)
+ << " socket_url=\"" << socket_url
+ << "\" requested_protocols=\""
+ << base::JoinString(requested_protocols, ", ") << "\" origin=\""
+ << origin << "\"";
+
+ DCHECK(!channel_);
+
+ StoragePartition* partition = delegate_->GetStoragePartition();
+
+ std::unique_ptr<net::WebSocketEventInterface> event_interface(
+ new WebSocketEventHandler(this));
+ channel_.reset(
+ new net::WebSocketChannel(
+ std::move(event_interface),
+ partition->GetURLRequestContext()->GetURLRequestContext()));
+
+ if (pending_flow_control_quota_ > 0) {
+ // channel_->SendFlowControl(pending_flow_control_quota_) must be called
+ // after channel_->SendAddChannelRequest() below.
+ // We post SendFlowControl() here using |weak_ptr_factory_| instead of
+ // calling SendFlowControl directly, because |this| may have been deleted
+ // after channel_->SendAddChannelRequest().
+ // XXX we should be able to call this after SendAddChannelRequest now
+ // as connection errors are observed asynchronously.
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(&WebSocketImpl::SendFlowControl,
+ weak_ptr_factory_.GetWeakPtr(),
+ pending_flow_control_quota_));
+ pending_flow_control_quota_ = 0;
+ }
+
+ channel_->SendAddChannelRequest(socket_url, requested_protocols, origin);
+}
+
+void WebSocketImpl::BlobSendComplete(int result) {
+ DVLOG(3) << "WebSocketImpl::BlobSendComplete @"
+ << reinterpret_cast<void*>(this)
<< " result=" << net::ErrorToString(result);
// All paths through this method must reset blob_sender_, so take ownership
@@ -553,29 +583,30 @@ void WebSocketHost::BlobSendComplete(int result) {
std::unique_ptr<WebSocketBlobSender> blob_sender(std::move(blob_sender_));
switch (result) {
case net::OK:
- ignore_result(dispatcher_->BlobSendComplete(routing_id_));
- // |this| may be destroyed here.
+ client_->OnBlobSent();
return;
case net::ERR_UPLOAD_FILE_CHANGED: {
uint64_t expected_size = blob_sender->expected_size();
uint64_t actual_size = blob_sender->ActualSize();
if (expected_size != actual_size) {
- ignore_result(dispatcher_->NotifyFailure(
- routing_id_,
+ // XXX ignore_result(dispatcher_->NotifyFailure(
+ // XXX routing_id_,
+ client_->OnFailChannel(
base::StringPrintf("Blob size mismatch; renderer size = %" PRIu64
", browser size = %" PRIu64,
- expected_size, actual_size)));
- // |this| is destroyed here.
+ expected_size, actual_size));
+ // XXX |this| is destroyed here.
return;
} // else fallthrough
}
default:
- ignore_result(dispatcher_->NotifyFailure(
- routing_id_,
- "Failed to load Blob: error code = " + net::ErrorToString(result)));
- // |this| is destroyed here.
+ // XXX ignore_result(dispatcher_->NotifyFailure(
+ // XXX routing_id_,
+ client_->OnFailChannel(
+ "Failed to load Blob: error code = " + net::ErrorToString(result));
+ // XXX |this| is destroyed here.
return;
}
}

Powered by Google App Engine
This is Rietveld 408576698