| Index: content/browser/renderer_host/websocket_host.cc
|
| diff --git a/content/browser/renderer_host/websocket_host.cc b/content/browser/renderer_host/websocket_host.cc
|
| index ed398f8d1e4457fa4c5776d5494d6f2df39fe8e7..7f6391803724443ca9814127df14f59ba346edcf 100644
|
| --- a/content/browser/renderer_host/websocket_host.cc
|
| +++ b/content/browser/renderer_host/websocket_host.cc
|
| @@ -5,13 +5,17 @@
|
| #include "content/browser/renderer_host/websocket_host.h"
|
|
|
| #include "base/basictypes.h"
|
| +#include "base/memory/weak_ptr.h"
|
| #include "base/strings/string_util.h"
|
| #include "content/browser/renderer_host/websocket_dispatcher_host.h"
|
| +#include "content/browser/ssl/ssl_error_handler.h"
|
| +#include "content/browser/ssl/ssl_manager.h"
|
| #include "content/common/websocket_messages.h"
|
| #include "ipc/ipc_message_macros.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/websockets/websocket_channel.h"
|
| #include "net/websockets/websocket_event_interface.h"
|
| #include "net/websockets/websocket_frame.h" // for WebSocketFrameHeader::OpCode
|
| @@ -80,7 +84,9 @@ ChannelState StateCast(WebSocketDispatcherHost::WebSocketHostState host_state) {
|
| // renderer or child process via WebSocketDispatcherHost.
|
| class WebSocketEventHandler : public net::WebSocketEventInterface {
|
| public:
|
| - WebSocketEventHandler(WebSocketDispatcherHost* dispatcher, int routing_id);
|
| + WebSocketEventHandler(WebSocketDispatcherHost* dispatcher,
|
| + int routing_id,
|
| + int render_frame_id);
|
| virtual ~WebSocketEventHandler();
|
|
|
| // net::WebSocketEventInterface implementation
|
| @@ -102,18 +108,50 @@ class WebSocketEventHandler : public net::WebSocketEventInterface {
|
| scoped_ptr<net::WebSocketHandshakeRequestInfo> request) OVERRIDE;
|
| virtual ChannelState OnFinishOpeningHandshake(
|
| scoped_ptr<net::WebSocketHandshakeResponseInfo> response) OVERRIDE;
|
| + virtual ChannelState OnSSLCertificateError(
|
| + scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks,
|
| + const GURL& url,
|
| + const net::SSLInfo& ssl_info,
|
| + bool fatal) OVERRIDE;
|
|
|
| private:
|
| + class SSLErrorHandlerDelegate : public SSLErrorHandler::Delegate {
|
| + public:
|
| + SSLErrorHandlerDelegate(
|
| + scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks);
|
| + virtual ~SSLErrorHandlerDelegate();
|
| +
|
| + base::WeakPtr<SSLErrorHandler::Delegate> GetWeakPtr();
|
| +
|
| + // SSLErrorHandler::Delegate methods
|
| + virtual void CancelSSLRequest(const GlobalRequestID& id,
|
| + int error,
|
| + const net::SSLInfo* ssl_info) OVERRIDE;
|
| + virtual void ContinueSSLRequest(const GlobalRequestID& id) OVERRIDE;
|
| +
|
| + private:
|
| + scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks_;
|
| + base::WeakPtrFactory<SSLErrorHandlerDelegate> weak_ptr_factory_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(SSLErrorHandlerDelegate);
|
| + };
|
| +
|
| WebSocketDispatcherHost* const dispatcher_;
|
| const int routing_id_;
|
| + const int render_frame_id_;
|
| + scoped_ptr<SSLErrorHandlerDelegate> ssl_error_handler_delegate_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(WebSocketEventHandler);
|
| };
|
|
|
| WebSocketEventHandler::WebSocketEventHandler(
|
| WebSocketDispatcherHost* dispatcher,
|
| - int routing_id)
|
| - : dispatcher_(dispatcher), routing_id_(routing_id) {}
|
| + int routing_id,
|
| + int render_frame_id)
|
| + : dispatcher_(dispatcher),
|
| + routing_id_(routing_id),
|
| + render_frame_id_(render_frame_id) {
|
| +}
|
|
|
| WebSocketEventHandler::~WebSocketEventHandler() {
|
| DVLOG(1) << "WebSocketEventHandler destroyed routing_id=" << routing_id_;
|
| @@ -227,18 +265,67 @@ ChannelState WebSocketEventHandler::OnFinishOpeningHandshake(
|
| response_to_pass));
|
| }
|
|
|
| +ChannelState WebSocketEventHandler::OnSSLCertificateError(
|
| + scoped_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()
|
| + << " cert_status=" << ssl_info.cert_status << " fatal=" << fatal;
|
| + ssl_error_handler_delegate_.reset(
|
| + new SSLErrorHandlerDelegate(callbacks.Pass()));
|
| + // We don't need request_id to be unique so just make a fake one.
|
| + GlobalRequestID request_id(-1, -1);
|
| + SSLManager::OnSSLCertificateError(ssl_error_handler_delegate_->GetWeakPtr(),
|
| + request_id,
|
| + ResourceType::SUB_RESOURCE,
|
| + url,
|
| + dispatcher_->render_process_id(),
|
| + render_frame_id_,
|
| + ssl_info,
|
| + fatal);
|
| + // The above method is always asynchronous.
|
| + return WebSocketEventInterface::CHANNEL_ALIVE;
|
| +}
|
| +
|
| +WebSocketEventHandler::SSLErrorHandlerDelegate::SSLErrorHandlerDelegate(
|
| + scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks)
|
| + : callbacks_(callbacks.Pass()), weak_ptr_factory_(this) {}
|
| +
|
| +WebSocketEventHandler::SSLErrorHandlerDelegate::~SSLErrorHandlerDelegate() {}
|
| +
|
| +base::WeakPtr<SSLErrorHandler::Delegate>
|
| +WebSocketEventHandler::SSLErrorHandlerDelegate::GetWeakPtr() {
|
| + return weak_ptr_factory_.GetWeakPtr();
|
| +}
|
| +
|
| +void WebSocketEventHandler::SSLErrorHandlerDelegate::CancelSSLRequest(
|
| + const GlobalRequestID& id,
|
| + int error,
|
| + const net::SSLInfo* ssl_info) {
|
| + DVLOG(3) << "SSLErrorHandlerDelegate::CancelSSLRequest"
|
| + << " error=" << error
|
| + << " cert_status=" << (ssl_info ? ssl_info->cert_status
|
| + : static_cast<net::CertStatus>(-1));
|
| + callbacks_->CancelSSLRequest(error, ssl_info);
|
| +}
|
| +
|
| +void WebSocketEventHandler::SSLErrorHandlerDelegate::ContinueSSLRequest(
|
| + const GlobalRequestID& id) {
|
| + DVLOG(3) << "SSLErrorHandlerDelegate::ContinueSSLRequest";
|
| + callbacks_->ContinueSSLRequest();
|
| +}
|
| +
|
| } // namespace
|
|
|
| WebSocketHost::WebSocketHost(int routing_id,
|
| WebSocketDispatcherHost* dispatcher,
|
| net::URLRequestContext* url_request_context)
|
| - : routing_id_(routing_id) {
|
| + : dispatcher_(dispatcher),
|
| + url_request_context_(url_request_context),
|
| + routing_id_(routing_id) {
|
| DVLOG(1) << "WebSocketHost: created routing_id=" << routing_id;
|
| -
|
| - scoped_ptr<net::WebSocketEventInterface> event_interface(
|
| - new WebSocketEventHandler(dispatcher, routing_id));
|
| - channel_.reset(
|
| - new net::WebSocketChannel(event_interface.Pass(), url_request_context));
|
| }
|
|
|
| WebSocketHost::~WebSocketHost() {}
|
| @@ -258,15 +345,20 @@ bool WebSocketHost::OnMessageReceived(const IPC::Message& message) {
|
| void WebSocketHost::OnAddChannelRequest(
|
| const GURL& socket_url,
|
| const std::vector<std::string>& requested_protocols,
|
| - const url::Origin& origin) {
|
| + const url::Origin& origin,
|
| + int render_frame_id) {
|
| DVLOG(3) << "WebSocketHost::OnAddChannelRequest"
|
| << " routing_id=" << routing_id_ << " socket_url=\"" << socket_url
|
| << "\" requested_protocols=\""
|
| << JoinString(requested_protocols, ", ") << "\" origin=\""
|
| << origin.string() << "\"";
|
|
|
| - channel_->SendAddChannelRequest(
|
| - socket_url, requested_protocols, origin);
|
| + DCHECK(!channel_);
|
| + scoped_ptr<net::WebSocketEventInterface> event_interface(
|
| + new WebSocketEventHandler(dispatcher_, routing_id_, render_frame_id));
|
| + channel_.reset(
|
| + new net::WebSocketChannel(event_interface.Pass(), url_request_context_));
|
| + channel_->SendAddChannelRequest(socket_url, requested_protocols, origin);
|
| }
|
|
|
| void WebSocketHost::OnSendFrame(bool fin,
|
| @@ -276,6 +368,7 @@ void WebSocketHost::OnSendFrame(bool fin,
|
| << " routing_id=" << routing_id_ << " fin=" << fin
|
| << " type=" << type << " data is " << data.size() << " bytes";
|
|
|
| + DCHECK(channel_);
|
| channel_->SendFrame(fin, MessageTypeToOpCode(type), data);
|
| }
|
|
|
| @@ -283,6 +376,7 @@ void WebSocketHost::OnFlowControl(int64 quota) {
|
| DVLOG(3) << "WebSocketHost::OnFlowControl"
|
| << " routing_id=" << routing_id_ << " quota=" << quota;
|
|
|
| + DCHECK(channel_);
|
| channel_->SendFlowControl(quota);
|
| }
|
|
|
| @@ -293,6 +387,7 @@ void WebSocketHost::OnDropChannel(bool was_clean,
|
| << " routing_id=" << routing_id_ << " was_clean=" << was_clean
|
| << " code=" << code << " reason=\"" << reason << "\"";
|
|
|
| + DCHECK(channel_);
|
| // TODO(yhirano): Handle |was_clean| appropriately.
|
| channel_->StartClosingHandshake(code, reason);
|
| }
|
|
|