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

Side by Side Diff: content/browser/renderer_host/websocket_host.cc

Issue 304093003: Support recovery from SSL errors for new WebSocket implementation (Closed) Base URL: http://git.chromium.org/chromium/src.git@master-for-pool-throttling
Patch Set: clang compile fix. Also lint & format cleanups. Created 6 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 unified diff | Download patch
« no previous file with comments | « content/browser/renderer_host/websocket_host.h ('k') | content/child/websocket_bridge.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/renderer_host/websocket_host.h" 5 #include "content/browser/renderer_host/websocket_host.h"
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/memory/weak_ptr.h"
8 #include "base/strings/string_util.h" 9 #include "base/strings/string_util.h"
9 #include "content/browser/renderer_host/websocket_dispatcher_host.h" 10 #include "content/browser/renderer_host/websocket_dispatcher_host.h"
11 #include "content/browser/ssl/ssl_error_handler.h"
12 #include "content/browser/ssl/ssl_manager.h"
10 #include "content/common/websocket_messages.h" 13 #include "content/common/websocket_messages.h"
11 #include "ipc/ipc_message_macros.h" 14 #include "ipc/ipc_message_macros.h"
12 #include "net/http/http_request_headers.h" 15 #include "net/http/http_request_headers.h"
13 #include "net/http/http_response_headers.h" 16 #include "net/http/http_response_headers.h"
14 #include "net/http/http_util.h" 17 #include "net/http/http_util.h"
18 #include "net/ssl/ssl_info.h"
15 #include "net/websockets/websocket_channel.h" 19 #include "net/websockets/websocket_channel.h"
16 #include "net/websockets/websocket_event_interface.h" 20 #include "net/websockets/websocket_event_interface.h"
17 #include "net/websockets/websocket_frame.h" // for WebSocketFrameHeader::OpCode 21 #include "net/websockets/websocket_frame.h" // for WebSocketFrameHeader::OpCode
18 #include "net/websockets/websocket_handshake_request_info.h" 22 #include "net/websockets/websocket_handshake_request_info.h"
19 #include "net/websockets/websocket_handshake_response_info.h" 23 #include "net/websockets/websocket_handshake_response_info.h"
20 #include "url/origin.h" 24 #include "url/origin.h"
21 25
22 namespace content { 26 namespace content {
23 27
24 namespace { 28 namespace {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 net::WebSocketEventInterface::CHANNEL_DELETED, 77 net::WebSocketEventInterface::CHANNEL_DELETED,
74 enum_values_must_match_for_state_deleted); 78 enum_values_must_match_for_state_deleted);
75 return static_cast<ChannelState>(host_state); 79 return static_cast<ChannelState>(host_state);
76 } 80 }
77 81
78 // Implementation of net::WebSocketEventInterface. Receives events from our 82 // Implementation of net::WebSocketEventInterface. Receives events from our
79 // WebSocketChannel object. Each event is translated to an IPC and sent to the 83 // WebSocketChannel object. Each event is translated to an IPC and sent to the
80 // renderer or child process via WebSocketDispatcherHost. 84 // renderer or child process via WebSocketDispatcherHost.
81 class WebSocketEventHandler : public net::WebSocketEventInterface { 85 class WebSocketEventHandler : public net::WebSocketEventInterface {
82 public: 86 public:
83 WebSocketEventHandler(WebSocketDispatcherHost* dispatcher, int routing_id); 87 WebSocketEventHandler(WebSocketDispatcherHost* dispatcher,
88 int routing_id,
89 int render_frame_id);
84 virtual ~WebSocketEventHandler(); 90 virtual ~WebSocketEventHandler();
85 91
86 // net::WebSocketEventInterface implementation 92 // net::WebSocketEventInterface implementation
87 93
88 virtual ChannelState OnAddChannelResponse( 94 virtual ChannelState OnAddChannelResponse(
89 bool fail, 95 bool fail,
90 const std::string& selected_subprotocol, 96 const std::string& selected_subprotocol,
91 const std::string& extensions) OVERRIDE; 97 const std::string& extensions) OVERRIDE;
92 virtual ChannelState OnDataFrame(bool fin, 98 virtual ChannelState OnDataFrame(bool fin,
93 WebSocketMessageType type, 99 WebSocketMessageType type,
94 const std::vector<char>& data) OVERRIDE; 100 const std::vector<char>& data) OVERRIDE;
95 virtual ChannelState OnClosingHandshake() OVERRIDE; 101 virtual ChannelState OnClosingHandshake() OVERRIDE;
96 virtual ChannelState OnFlowControl(int64 quota) OVERRIDE; 102 virtual ChannelState OnFlowControl(int64 quota) OVERRIDE;
97 virtual ChannelState OnDropChannel(bool was_clean, 103 virtual ChannelState OnDropChannel(bool was_clean,
98 uint16 code, 104 uint16 code,
99 const std::string& reason) OVERRIDE; 105 const std::string& reason) OVERRIDE;
100 virtual ChannelState OnFailChannel(const std::string& message) OVERRIDE; 106 virtual ChannelState OnFailChannel(const std::string& message) OVERRIDE;
101 virtual ChannelState OnStartOpeningHandshake( 107 virtual ChannelState OnStartOpeningHandshake(
102 scoped_ptr<net::WebSocketHandshakeRequestInfo> request) OVERRIDE; 108 scoped_ptr<net::WebSocketHandshakeRequestInfo> request) OVERRIDE;
103 virtual ChannelState OnFinishOpeningHandshake( 109 virtual ChannelState OnFinishOpeningHandshake(
104 scoped_ptr<net::WebSocketHandshakeResponseInfo> response) OVERRIDE; 110 scoped_ptr<net::WebSocketHandshakeResponseInfo> response) OVERRIDE;
111 virtual ChannelState OnSSLCertificateError(
112 scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks,
113 const GURL& url,
114 const net::SSLInfo& ssl_info,
115 bool fatal) OVERRIDE;
105 116
106 private: 117 private:
118 class SSLErrorHandlerDelegate : public SSLErrorHandler::Delegate {
119 public:
120 SSLErrorHandlerDelegate(
121 scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks);
122 virtual ~SSLErrorHandlerDelegate();
123
124 base::WeakPtr<SSLErrorHandler::Delegate> GetWeakPtr();
125
126 // SSLErrorHandler::Delegate methods
127 virtual void CancelSSLRequest(const GlobalRequestID& id,
128 int error,
129 const net::SSLInfo* ssl_info) OVERRIDE;
130 virtual void ContinueSSLRequest(const GlobalRequestID& id) OVERRIDE;
131
132 private:
133 scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks_;
134 base::WeakPtrFactory<SSLErrorHandlerDelegate> weak_ptr_factory_;
135
136 DISALLOW_COPY_AND_ASSIGN(SSLErrorHandlerDelegate);
137 };
138
107 WebSocketDispatcherHost* const dispatcher_; 139 WebSocketDispatcherHost* const dispatcher_;
108 const int routing_id_; 140 const int routing_id_;
141 const int render_frame_id_;
142 scoped_ptr<SSLErrorHandlerDelegate> ssl_error_handler_delegate_;
109 143
110 DISALLOW_COPY_AND_ASSIGN(WebSocketEventHandler); 144 DISALLOW_COPY_AND_ASSIGN(WebSocketEventHandler);
111 }; 145 };
112 146
113 WebSocketEventHandler::WebSocketEventHandler( 147 WebSocketEventHandler::WebSocketEventHandler(
114 WebSocketDispatcherHost* dispatcher, 148 WebSocketDispatcherHost* dispatcher,
115 int routing_id) 149 int routing_id,
116 : dispatcher_(dispatcher), routing_id_(routing_id) {} 150 int render_frame_id)
151 : dispatcher_(dispatcher),
152 routing_id_(routing_id),
153 render_frame_id_(render_frame_id) {
154 }
117 155
118 WebSocketEventHandler::~WebSocketEventHandler() { 156 WebSocketEventHandler::~WebSocketEventHandler() {
119 DVLOG(1) << "WebSocketEventHandler destroyed routing_id=" << routing_id_; 157 DVLOG(1) << "WebSocketEventHandler destroyed routing_id=" << routing_id_;
120 } 158 }
121 159
122 ChannelState WebSocketEventHandler::OnAddChannelResponse( 160 ChannelState WebSocketEventHandler::OnAddChannelResponse(
123 bool fail, 161 bool fail,
124 const std::string& selected_protocol, 162 const std::string& selected_protocol,
125 const std::string& extensions) { 163 const std::string& extensions) {
126 DVLOG(3) << "WebSocketEventHandler::OnAddChannelResponse" 164 DVLOG(3) << "WebSocketEventHandler::OnAddChannelResponse"
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 response_to_pass.headers.push_back(std::make_pair(name, value)); 258 response_to_pass.headers.push_back(std::make_pair(name, value));
221 response_to_pass.headers_text = 259 response_to_pass.headers_text =
222 net::HttpUtil::ConvertHeadersBackToHTTPResponse( 260 net::HttpUtil::ConvertHeadersBackToHTTPResponse(
223 response->headers->raw_headers()); 261 response->headers->raw_headers());
224 response_to_pass.response_time = response->response_time; 262 response_to_pass.response_time = response->response_time;
225 263
226 return StateCast(dispatcher_->NotifyFinishOpeningHandshake(routing_id_, 264 return StateCast(dispatcher_->NotifyFinishOpeningHandshake(routing_id_,
227 response_to_pass)); 265 response_to_pass));
228 } 266 }
229 267
268 ChannelState WebSocketEventHandler::OnSSLCertificateError(
269 scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks,
270 const GURL& url,
271 const net::SSLInfo& ssl_info,
272 bool fatal) {
273 DVLOG(3) << "WebSocketEventHandler::OnSSLCertificateError"
274 << " routing_id=" << routing_id_ << " url=" << url.spec()
275 << " cert_status=" << ssl_info.cert_status << " fatal=" << fatal;
276 ssl_error_handler_delegate_.reset(
277 new SSLErrorHandlerDelegate(callbacks.Pass()));
278 // We don't need request_id to be unique so just make a fake one.
279 GlobalRequestID request_id(-1, -1);
280 SSLManager::OnSSLCertificateError(ssl_error_handler_delegate_->GetWeakPtr(),
281 request_id,
282 ResourceType::SUB_RESOURCE,
283 url,
284 dispatcher_->render_process_id(),
285 render_frame_id_,
286 ssl_info,
287 fatal);
288 // The above method is always asynchronous.
289 return WebSocketEventInterface::CHANNEL_ALIVE;
290 }
291
292 WebSocketEventHandler::SSLErrorHandlerDelegate::SSLErrorHandlerDelegate(
293 scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks)
294 : callbacks_(callbacks.Pass()), weak_ptr_factory_(this) {}
295
296 WebSocketEventHandler::SSLErrorHandlerDelegate::~SSLErrorHandlerDelegate() {}
297
298 base::WeakPtr<SSLErrorHandler::Delegate>
299 WebSocketEventHandler::SSLErrorHandlerDelegate::GetWeakPtr() {
300 return weak_ptr_factory_.GetWeakPtr();
301 }
302
303 void WebSocketEventHandler::SSLErrorHandlerDelegate::CancelSSLRequest(
304 const GlobalRequestID& id,
305 int error,
306 const net::SSLInfo* ssl_info) {
307 DVLOG(3) << "SSLErrorHandlerDelegate::CancelSSLRequest"
308 << " error=" << error
309 << " cert_status=" << (ssl_info ? ssl_info->cert_status
310 : static_cast<net::CertStatus>(-1));
311 callbacks_->CancelSSLRequest(error, ssl_info);
312 }
313
314 void WebSocketEventHandler::SSLErrorHandlerDelegate::ContinueSSLRequest(
315 const GlobalRequestID& id) {
316 DVLOG(3) << "SSLErrorHandlerDelegate::ContinueSSLRequest";
317 callbacks_->ContinueSSLRequest();
318 }
319
230 } // namespace 320 } // namespace
231 321
232 WebSocketHost::WebSocketHost(int routing_id, 322 WebSocketHost::WebSocketHost(int routing_id,
233 WebSocketDispatcherHost* dispatcher, 323 WebSocketDispatcherHost* dispatcher,
234 net::URLRequestContext* url_request_context) 324 net::URLRequestContext* url_request_context)
235 : routing_id_(routing_id) { 325 : dispatcher_(dispatcher),
326 url_request_context_(url_request_context),
327 routing_id_(routing_id) {
236 DVLOG(1) << "WebSocketHost: created routing_id=" << routing_id; 328 DVLOG(1) << "WebSocketHost: created routing_id=" << routing_id;
237
238 scoped_ptr<net::WebSocketEventInterface> event_interface(
239 new WebSocketEventHandler(dispatcher, routing_id));
240 channel_.reset(
241 new net::WebSocketChannel(event_interface.Pass(), url_request_context));
242 } 329 }
243 330
244 WebSocketHost::~WebSocketHost() {} 331 WebSocketHost::~WebSocketHost() {}
245 332
246 bool WebSocketHost::OnMessageReceived(const IPC::Message& message) { 333 bool WebSocketHost::OnMessageReceived(const IPC::Message& message) {
247 bool handled = true; 334 bool handled = true;
248 IPC_BEGIN_MESSAGE_MAP(WebSocketHost, message) 335 IPC_BEGIN_MESSAGE_MAP(WebSocketHost, message)
249 IPC_MESSAGE_HANDLER(WebSocketHostMsg_AddChannelRequest, OnAddChannelRequest) 336 IPC_MESSAGE_HANDLER(WebSocketHostMsg_AddChannelRequest, OnAddChannelRequest)
250 IPC_MESSAGE_HANDLER(WebSocketMsg_SendFrame, OnSendFrame) 337 IPC_MESSAGE_HANDLER(WebSocketMsg_SendFrame, OnSendFrame)
251 IPC_MESSAGE_HANDLER(WebSocketMsg_FlowControl, OnFlowControl) 338 IPC_MESSAGE_HANDLER(WebSocketMsg_FlowControl, OnFlowControl)
252 IPC_MESSAGE_HANDLER(WebSocketMsg_DropChannel, OnDropChannel) 339 IPC_MESSAGE_HANDLER(WebSocketMsg_DropChannel, OnDropChannel)
253 IPC_MESSAGE_UNHANDLED(handled = false) 340 IPC_MESSAGE_UNHANDLED(handled = false)
254 IPC_END_MESSAGE_MAP() 341 IPC_END_MESSAGE_MAP()
255 return handled; 342 return handled;
256 } 343 }
257 344
258 void WebSocketHost::OnAddChannelRequest( 345 void WebSocketHost::OnAddChannelRequest(
259 const GURL& socket_url, 346 const GURL& socket_url,
260 const std::vector<std::string>& requested_protocols, 347 const std::vector<std::string>& requested_protocols,
261 const url::Origin& origin) { 348 const url::Origin& origin,
349 int render_frame_id) {
262 DVLOG(3) << "WebSocketHost::OnAddChannelRequest" 350 DVLOG(3) << "WebSocketHost::OnAddChannelRequest"
263 << " routing_id=" << routing_id_ << " socket_url=\"" << socket_url 351 << " routing_id=" << routing_id_ << " socket_url=\"" << socket_url
264 << "\" requested_protocols=\"" 352 << "\" requested_protocols=\""
265 << JoinString(requested_protocols, ", ") << "\" origin=\"" 353 << JoinString(requested_protocols, ", ") << "\" origin=\""
266 << origin.string() << "\""; 354 << origin.string() << "\"";
267 355
yhirano 2014/06/03 05:44:51 DCHECK(!channel_)
Adam Rice 2014/06/03 06:36:50 Done. I also changed the if() conditions in the ot
268 channel_->SendAddChannelRequest( 356 scoped_ptr<net::WebSocketEventInterface> event_interface(
269 socket_url, requested_protocols, origin); 357 new WebSocketEventHandler(dispatcher_, routing_id_, render_frame_id));
358 channel_.reset(
359 new net::WebSocketChannel(event_interface.Pass(), url_request_context_));
360 channel_->SendAddChannelRequest(socket_url, requested_protocols, origin);
270 } 361 }
271 362
272 void WebSocketHost::OnSendFrame(bool fin, 363 void WebSocketHost::OnSendFrame(bool fin,
273 WebSocketMessageType type, 364 WebSocketMessageType type,
274 const std::vector<char>& data) { 365 const std::vector<char>& data) {
275 DVLOG(3) << "WebSocketHost::OnSendFrame" 366 DVLOG(3) << "WebSocketHost::OnSendFrame"
276 << " routing_id=" << routing_id_ << " fin=" << fin 367 << " routing_id=" << routing_id_ << " fin=" << fin
277 << " type=" << type << " data is " << data.size() << " bytes"; 368 << " type=" << type << " data is " << data.size() << " bytes";
278 369
279 channel_->SendFrame(fin, MessageTypeToOpCode(type), data); 370 if (channel_)
371 channel_->SendFrame(fin, MessageTypeToOpCode(type), data);
280 } 372 }
281 373
282 void WebSocketHost::OnFlowControl(int64 quota) { 374 void WebSocketHost::OnFlowControl(int64 quota) {
283 DVLOG(3) << "WebSocketHost::OnFlowControl" 375 DVLOG(3) << "WebSocketHost::OnFlowControl"
284 << " routing_id=" << routing_id_ << " quota=" << quota; 376 << " routing_id=" << routing_id_ << " quota=" << quota;
285 377
286 channel_->SendFlowControl(quota); 378 if (channel_)
379 channel_->SendFlowControl(quota);
287 } 380 }
288 381
289 void WebSocketHost::OnDropChannel(bool was_clean, 382 void WebSocketHost::OnDropChannel(bool was_clean,
290 uint16 code, 383 uint16 code,
291 const std::string& reason) { 384 const std::string& reason) {
292 DVLOG(3) << "WebSocketHost::OnDropChannel" 385 DVLOG(3) << "WebSocketHost::OnDropChannel"
293 << " routing_id=" << routing_id_ << " was_clean=" << was_clean 386 << " routing_id=" << routing_id_ << " was_clean=" << was_clean
294 << " code=" << code << " reason=\"" << reason << "\""; 387 << " code=" << code << " reason=\"" << reason << "\"";
295 388
296 // TODO(yhirano): Handle |was_clean| appropriately. 389 if (channel_) {
297 channel_->StartClosingHandshake(code, reason); 390 // TODO(yhirano): Handle |was_clean| appropriately.
391 channel_->StartClosingHandshake(code, reason);
392 }
298 } 393 }
299 394
300 } // namespace content 395 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/websocket_host.h ('k') | content/child/websocket_bridge.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698