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

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

Issue 1568523002: Implement content::WebSocketBlobSender (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@websocket_blob_send_ipcs
Patch Set: Use the real net::TestCompletionCallback. Created 4 years, 11 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
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 <inttypes.h>
7 #include <utility> 8 #include <utility>
8 9
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
9 #include "base/location.h" 12 #include "base/location.h"
13 #include "base/logging.h"
10 #include "base/macros.h" 14 #include "base/macros.h"
yhirano 2016/01/25 10:52:23 Can you tell me why you stopped including weak_ptr
Adam Rice 2016/01/25 23:04:01 It is included in websocket_host.h.
11 #include "base/memory/weak_ptr.h"
12 #include "base/single_thread_task_runner.h" 15 #include "base/single_thread_task_runner.h"
13 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
17 #include "base/strings/stringprintf.h"
14 #include "base/thread_task_runner_handle.h" 18 #include "base/thread_task_runner_handle.h"
19 #include "content/browser/bad_message.h"
20 #include "content/browser/renderer_host/websocket_blob_sender.h"
15 #include "content/browser/renderer_host/websocket_dispatcher_host.h" 21 #include "content/browser/renderer_host/websocket_dispatcher_host.h"
16 #include "content/browser/ssl/ssl_error_handler.h" 22 #include "content/browser/ssl/ssl_error_handler.h"
17 #include "content/browser/ssl/ssl_manager.h" 23 #include "content/browser/ssl/ssl_manager.h"
18 #include "content/common/websocket_messages.h" 24 #include "content/common/websocket_messages.h"
25 #include "content/public/browser/browser_thread.h"
19 #include "content/public/browser/render_frame_host.h" 26 #include "content/public/browser/render_frame_host.h"
27 #include "content/public/browser/storage_partition.h"
20 #include "ipc/ipc_message_macros.h" 28 #include "ipc/ipc_message_macros.h"
29 #include "net/base/net_errors.h"
21 #include "net/http/http_request_headers.h" 30 #include "net/http/http_request_headers.h"
22 #include "net/http/http_response_headers.h" 31 #include "net/http/http_response_headers.h"
23 #include "net/http/http_util.h" 32 #include "net/http/http_util.h"
24 #include "net/ssl/ssl_info.h" 33 #include "net/ssl/ssl_info.h"
25 #include "net/websockets/websocket_channel.h" 34 #include "net/websockets/websocket_channel.h"
26 #include "net/websockets/websocket_errors.h" 35 #include "net/websockets/websocket_errors.h"
27 #include "net/websockets/websocket_event_interface.h" 36 #include "net/websockets/websocket_event_interface.h"
28 #include "net/websockets/websocket_frame.h" // for WebSocketFrameHeader::OpCode 37 #include "net/websockets/websocket_frame.h" // for WebSocketFrameHeader::OpCode
29 #include "net/websockets/websocket_handshake_request_info.h" 38 #include "net/websockets/websocket_handshake_request_info.h"
30 #include "net/websockets/websocket_handshake_response_info.h" 39 #include "net/websockets/websocket_handshake_response_info.h"
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 // for the conversion. 88 // for the conversion.
80 static_assert(static_cast<ChannelState>(WEBSOCKET_HOST_ALIVE) == 89 static_assert(static_cast<ChannelState>(WEBSOCKET_HOST_ALIVE) ==
81 net::WebSocketEventInterface::CHANNEL_ALIVE, 90 net::WebSocketEventInterface::CHANNEL_ALIVE,
82 "enum values must match for state_alive"); 91 "enum values must match for state_alive");
83 static_assert(static_cast<ChannelState>(WEBSOCKET_HOST_DELETED) == 92 static_assert(static_cast<ChannelState>(WEBSOCKET_HOST_DELETED) ==
84 net::WebSocketEventInterface::CHANNEL_DELETED, 93 net::WebSocketEventInterface::CHANNEL_DELETED,
85 "enum values must match for state_deleted"); 94 "enum values must match for state_deleted");
86 return static_cast<ChannelState>(host_state); 95 return static_cast<ChannelState>(host_state);
87 } 96 }
88 97
98 // Implementation of WebSocketBlobSender::Channel
99 class SendChannelImpl : public WebSocketBlobSender::Channel {
100 public:
101 explicit SendChannelImpl(net::WebSocketChannel* channel)
102 : channel_(channel) {}
103
104 // Implementation of WebSocketBlobSender::Channel
105 int GetSendQuota() const override { return channel_->current_send_quota(); }
106
107 ChannelState SendFrame(bool fin, const std::vector<char>& data) override {
108 int opcode = first_frame_ ? net::WebSocketFrameHeader::kOpCodeBinary
109 : net::WebSocketFrameHeader::kOpCodeContinuation;
110 first_frame_ = false;
111 return channel_->SendFrame(fin, opcode, data);
112 }
113
114 private:
115 net::WebSocketChannel* channel_;
116 bool first_frame_ = true;
117
118 DISALLOW_COPY_AND_ASSIGN(SendChannelImpl);
119 };
120
121 } // namespace
122
89 // Implementation of net::WebSocketEventInterface. Receives events from our 123 // Implementation of net::WebSocketEventInterface. Receives events from our
90 // WebSocketChannel object. Each event is translated to an IPC and sent to the 124 // WebSocketChannel object. Each event is translated to an IPC and sent to the
91 // renderer or child process via WebSocketDispatcherHost. 125 // renderer or child process via WebSocketDispatcherHost.
92 class WebSocketEventHandler : public net::WebSocketEventInterface { 126 class WebSocketHost::WebSocketEventHandler
127 : public net::WebSocketEventInterface {
93 public: 128 public:
94 WebSocketEventHandler(WebSocketDispatcherHost* dispatcher, 129 WebSocketEventHandler(WebSocketDispatcherHost* dispatcher,
130 WebSocketHost* host,
95 int routing_id, 131 int routing_id,
96 int render_frame_id); 132 int render_frame_id);
97 ~WebSocketEventHandler() override; 133 ~WebSocketEventHandler() override;
98 134
99 // net::WebSocketEventInterface implementation 135 // net::WebSocketEventInterface implementation
100 136
101 ChannelState OnAddChannelResponse(const std::string& selected_subprotocol, 137 ChannelState OnAddChannelResponse(const std::string& selected_subprotocol,
102 const std::string& extensions) override; 138 const std::string& extensions) override;
103 ChannelState OnDataFrame(bool fin, 139 ChannelState OnDataFrame(bool fin,
104 WebSocketMessageType type, 140 WebSocketMessageType type,
(...skipping 28 matching lines...) Expand all
133 void ContinueSSLRequest() override; 169 void ContinueSSLRequest() override;
134 170
135 private: 171 private:
136 scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks_; 172 scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks_;
137 base::WeakPtrFactory<SSLErrorHandlerDelegate> weak_ptr_factory_; 173 base::WeakPtrFactory<SSLErrorHandlerDelegate> weak_ptr_factory_;
138 174
139 DISALLOW_COPY_AND_ASSIGN(SSLErrorHandlerDelegate); 175 DISALLOW_COPY_AND_ASSIGN(SSLErrorHandlerDelegate);
140 }; 176 };
141 177
142 WebSocketDispatcherHost* const dispatcher_; 178 WebSocketDispatcherHost* const dispatcher_;
179 WebSocketHost* const host_;
143 const int routing_id_; 180 const int routing_id_;
144 const int render_frame_id_; 181 const int render_frame_id_;
145 scoped_ptr<SSLErrorHandlerDelegate> ssl_error_handler_delegate_; 182 scoped_ptr<SSLErrorHandlerDelegate> ssl_error_handler_delegate_;
146 183
147 DISALLOW_COPY_AND_ASSIGN(WebSocketEventHandler); 184 DISALLOW_COPY_AND_ASSIGN(WebSocketEventHandler);
148 }; 185 };
149 186
150 WebSocketEventHandler::WebSocketEventHandler( 187 WebSocketHost::WebSocketEventHandler::WebSocketEventHandler(
151 WebSocketDispatcherHost* dispatcher, 188 WebSocketDispatcherHost* dispatcher,
189 WebSocketHost* host,
152 int routing_id, 190 int routing_id,
153 int render_frame_id) 191 int render_frame_id)
154 : dispatcher_(dispatcher), 192 : dispatcher_(dispatcher),
193 host_(host),
155 routing_id_(routing_id), 194 routing_id_(routing_id),
156 render_frame_id_(render_frame_id) { 195 render_frame_id_(render_frame_id) {}
157 }
158 196
159 WebSocketEventHandler::~WebSocketEventHandler() { 197 WebSocketHost::WebSocketEventHandler::~WebSocketEventHandler() {
160 DVLOG(1) << "WebSocketEventHandler destroyed routing_id=" << routing_id_; 198 DVLOG(1) << "WebSocketEventHandler destroyed routing_id=" << routing_id_;
161 } 199 }
162 200
163 ChannelState WebSocketEventHandler::OnAddChannelResponse( 201 ChannelState WebSocketHost::WebSocketEventHandler::OnAddChannelResponse(
164 const std::string& selected_protocol, 202 const std::string& selected_protocol,
165 const std::string& extensions) { 203 const std::string& extensions) {
166 DVLOG(3) << "WebSocketEventHandler::OnAddChannelResponse" 204 DVLOG(3) << "WebSocketEventHandler::OnAddChannelResponse"
167 << " routing_id=" << routing_id_ 205 << " routing_id=" << routing_id_
168 << " selected_protocol=\"" << selected_protocol << "\"" 206 << " selected_protocol=\"" << selected_protocol << "\""
169 << " extensions=\"" << extensions << "\""; 207 << " extensions=\"" << extensions << "\"";
170 208
171 return StateCast(dispatcher_->SendAddChannelResponse( 209 return StateCast(dispatcher_->SendAddChannelResponse(
172 routing_id_, selected_protocol, extensions)); 210 routing_id_, selected_protocol, extensions));
173 } 211 }
174 212
175 ChannelState WebSocketEventHandler::OnDataFrame( 213 ChannelState WebSocketHost::WebSocketEventHandler::OnDataFrame(
176 bool fin, 214 bool fin,
177 net::WebSocketFrameHeader::OpCode type, 215 net::WebSocketFrameHeader::OpCode type,
178 const std::vector<char>& data) { 216 const std::vector<char>& data) {
179 DVLOG(3) << "WebSocketEventHandler::OnDataFrame" 217 DVLOG(3) << "WebSocketEventHandler::OnDataFrame"
180 << " routing_id=" << routing_id_ << " fin=" << fin 218 << " routing_id=" << routing_id_ << " fin=" << fin
181 << " type=" << type << " data is " << data.size() << " bytes"; 219 << " type=" << type << " data is " << data.size() << " bytes";
182 220
183 return StateCast(dispatcher_->SendFrame( 221 return StateCast(dispatcher_->SendFrame(routing_id_, fin,
184 routing_id_, fin, OpCodeToMessageType(type), data)); 222 OpCodeToMessageType(type), data));
185 } 223 }
186 224
187 ChannelState WebSocketEventHandler::OnClosingHandshake() { 225 ChannelState WebSocketHost::WebSocketEventHandler::OnClosingHandshake() {
188 DVLOG(3) << "WebSocketEventHandler::OnClosingHandshake" 226 DVLOG(3) << "WebSocketEventHandler::OnClosingHandshake"
189 << " routing_id=" << routing_id_; 227 << " routing_id=" << routing_id_;
190 228
191 return StateCast(dispatcher_->NotifyClosingHandshake(routing_id_)); 229 return StateCast(dispatcher_->NotifyClosingHandshake(routing_id_));
192 } 230 }
193 231
194 ChannelState WebSocketEventHandler::OnFlowControl(int64_t quota) { 232 ChannelState WebSocketHost::WebSocketEventHandler::OnFlowControl(
233 int64_t quota) {
195 DVLOG(3) << "WebSocketEventHandler::OnFlowControl" 234 DVLOG(3) << "WebSocketEventHandler::OnFlowControl"
196 << " routing_id=" << routing_id_ << " quota=" << quota; 235 << " routing_id=" << routing_id_ << " quota=" << quota;
197 236
237 if (host_->blob_sender_)
238 host_->blob_sender_->OnNewSendQuota();
198 return StateCast(dispatcher_->SendFlowControl(routing_id_, quota)); 239 return StateCast(dispatcher_->SendFlowControl(routing_id_, quota));
199 } 240 }
200 241
201 ChannelState WebSocketEventHandler::OnDropChannel(bool was_clean, 242 ChannelState WebSocketHost::WebSocketEventHandler::OnDropChannel(
202 uint16_t code, 243 bool was_clean,
203 const std::string& reason) { 244 uint16_t code,
245 const std::string& reason) {
204 DVLOG(3) << "WebSocketEventHandler::OnDropChannel" 246 DVLOG(3) << "WebSocketEventHandler::OnDropChannel"
205 << " routing_id=" << routing_id_ << " was_clean=" << was_clean 247 << " routing_id=" << routing_id_ << " was_clean=" << was_clean
206 << " code=" << code << " reason=\"" << reason << "\""; 248 << " code=" << code << " reason=\"" << reason << "\"";
207 249
208 return StateCast( 250 return StateCast(
209 dispatcher_->DoDropChannel(routing_id_, was_clean, code, reason)); 251 dispatcher_->DoDropChannel(routing_id_, was_clean, code, reason));
210 } 252 }
211 253
212 ChannelState WebSocketEventHandler::OnFailChannel(const std::string& message) { 254 ChannelState WebSocketHost::WebSocketEventHandler::OnFailChannel(
255 const std::string& message) {
213 DVLOG(3) << "WebSocketEventHandler::OnFailChannel" 256 DVLOG(3) << "WebSocketEventHandler::OnFailChannel"
214 << " routing_id=" << routing_id_ 257 << " routing_id=" << routing_id_ << " message=\"" << message << "\"";
215 << " message=\"" << message << "\"";
216 258
217 return StateCast(dispatcher_->NotifyFailure(routing_id_, message)); 259 return StateCast(dispatcher_->NotifyFailure(routing_id_, message));
218 } 260 }
219 261
220 ChannelState WebSocketEventHandler::OnStartOpeningHandshake( 262 ChannelState WebSocketHost::WebSocketEventHandler::OnStartOpeningHandshake(
221 scoped_ptr<net::WebSocketHandshakeRequestInfo> request) { 263 scoped_ptr<net::WebSocketHandshakeRequestInfo> request) {
222 bool should_send = dispatcher_->CanReadRawCookies(); 264 bool should_send = dispatcher_->CanReadRawCookies();
223 DVLOG(3) << "WebSocketEventHandler::OnStartOpeningHandshake " 265 DVLOG(3) << "WebSocketEventHandler::OnStartOpeningHandshake "
224 << "should_send=" << should_send; 266 << "should_send=" << should_send;
225 267
226 if (!should_send) 268 if (!should_send)
227 return WebSocketEventInterface::CHANNEL_ALIVE; 269 return WebSocketEventInterface::CHANNEL_ALIVE;
228 270
229 WebSocketHandshakeRequest request_to_pass; 271 WebSocketHandshakeRequest request_to_pass;
230 request_to_pass.url.Swap(&request->url); 272 request_to_pass.url.Swap(&request->url);
231 net::HttpRequestHeaders::Iterator it(request->headers); 273 net::HttpRequestHeaders::Iterator it(request->headers);
232 while (it.GetNext()) 274 while (it.GetNext())
233 request_to_pass.headers.push_back(std::make_pair(it.name(), it.value())); 275 request_to_pass.headers.push_back(std::make_pair(it.name(), it.value()));
234 request_to_pass.headers_text = 276 request_to_pass.headers_text =
235 base::StringPrintf("GET %s HTTP/1.1\r\n", 277 base::StringPrintf("GET %s HTTP/1.1\r\n",
236 request_to_pass.url.spec().c_str()) + 278 request_to_pass.url.spec().c_str()) +
237 request->headers.ToString(); 279 request->headers.ToString();
238 request_to_pass.request_time = request->request_time; 280 request_to_pass.request_time = request->request_time;
239 281
240 return StateCast(dispatcher_->NotifyStartOpeningHandshake(routing_id_, 282 return StateCast(
241 request_to_pass)); 283 dispatcher_->NotifyStartOpeningHandshake(routing_id_, request_to_pass));
242 } 284 }
243 285
244 ChannelState WebSocketEventHandler::OnFinishOpeningHandshake( 286 ChannelState WebSocketHost::WebSocketEventHandler::OnFinishOpeningHandshake(
245 scoped_ptr<net::WebSocketHandshakeResponseInfo> response) { 287 scoped_ptr<net::WebSocketHandshakeResponseInfo> response) {
246 bool should_send = dispatcher_->CanReadRawCookies(); 288 bool should_send = dispatcher_->CanReadRawCookies();
247 DVLOG(3) << "WebSocketEventHandler::OnFinishOpeningHandshake " 289 DVLOG(3) << "WebSocketEventHandler::OnFinishOpeningHandshake "
248 << "should_send=" << should_send; 290 << "should_send=" << should_send;
249 291
250 if (!should_send) 292 if (!should_send)
251 return WebSocketEventInterface::CHANNEL_ALIVE; 293 return WebSocketEventInterface::CHANNEL_ALIVE;
252 294
253 WebSocketHandshakeResponse response_to_pass; 295 WebSocketHandshakeResponse response_to_pass;
254 response_to_pass.url.Swap(&response->url); 296 response_to_pass.url.Swap(&response->url);
255 response_to_pass.status_code = response->status_code; 297 response_to_pass.status_code = response->status_code;
256 response_to_pass.status_text.swap(response->status_text); 298 response_to_pass.status_text.swap(response->status_text);
257 void* iter = NULL; 299 void* iter = NULL;
258 std::string name, value; 300 std::string name, value;
259 while (response->headers->EnumerateHeaderLines(&iter, &name, &value)) 301 while (response->headers->EnumerateHeaderLines(&iter, &name, &value))
260 response_to_pass.headers.push_back(std::make_pair(name, value)); 302 response_to_pass.headers.push_back(std::make_pair(name, value));
261 response_to_pass.headers_text = 303 response_to_pass.headers_text =
262 net::HttpUtil::ConvertHeadersBackToHTTPResponse( 304 net::HttpUtil::ConvertHeadersBackToHTTPResponse(
263 response->headers->raw_headers()); 305 response->headers->raw_headers());
264 response_to_pass.response_time = response->response_time; 306 response_to_pass.response_time = response->response_time;
265 307
266 return StateCast(dispatcher_->NotifyFinishOpeningHandshake(routing_id_, 308 return StateCast(
267 response_to_pass)); 309 dispatcher_->NotifyFinishOpeningHandshake(routing_id_, response_to_pass));
268 } 310 }
269 311
270 ChannelState WebSocketEventHandler::OnSSLCertificateError( 312 ChannelState WebSocketHost::WebSocketEventHandler::OnSSLCertificateError(
271 scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks, 313 scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks,
272 const GURL& url, 314 const GURL& url,
273 const net::SSLInfo& ssl_info, 315 const net::SSLInfo& ssl_info,
274 bool fatal) { 316 bool fatal) {
275 DVLOG(3) << "WebSocketEventHandler::OnSSLCertificateError" 317 DVLOG(3) << "WebSocketEventHandler::OnSSLCertificateError"
276 << " routing_id=" << routing_id_ << " url=" << url.spec() 318 << " routing_id=" << routing_id_ << " url=" << url.spec()
277 << " cert_status=" << ssl_info.cert_status << " fatal=" << fatal; 319 << " cert_status=" << ssl_info.cert_status << " fatal=" << fatal;
278 ssl_error_handler_delegate_.reset( 320 ssl_error_handler_delegate_.reset(
279 new SSLErrorHandlerDelegate(std::move(callbacks))); 321 new SSLErrorHandlerDelegate(std::move(callbacks)));
280 SSLManager::OnSSLCertificateSubresourceError( 322 SSLManager::OnSSLCertificateSubresourceError(
281 ssl_error_handler_delegate_->GetWeakPtr(), url, 323 ssl_error_handler_delegate_->GetWeakPtr(), url,
282 dispatcher_->render_process_id(), render_frame_id_, ssl_info, fatal); 324 dispatcher_->render_process_id(), render_frame_id_, ssl_info, fatal);
283 // The above method is always asynchronous. 325 // The above method is always asynchronous.
284 return WebSocketEventInterface::CHANNEL_ALIVE; 326 return WebSocketEventInterface::CHANNEL_ALIVE;
285 } 327 }
286 328
287 WebSocketEventHandler::SSLErrorHandlerDelegate::SSLErrorHandlerDelegate( 329 WebSocketHost::WebSocketEventHandler::SSLErrorHandlerDelegate::
288 scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks) 330 SSLErrorHandlerDelegate(
331 scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks)
289 : callbacks_(std::move(callbacks)), weak_ptr_factory_(this) {} 332 : callbacks_(std::move(callbacks)), weak_ptr_factory_(this) {}
290 333
291 WebSocketEventHandler::SSLErrorHandlerDelegate::~SSLErrorHandlerDelegate() {} 334 WebSocketHost::WebSocketEventHandler::SSLErrorHandlerDelegate::
335 ~SSLErrorHandlerDelegate() {}
292 336
293 base::WeakPtr<SSLErrorHandler::Delegate> 337 base::WeakPtr<SSLErrorHandler::Delegate>
294 WebSocketEventHandler::SSLErrorHandlerDelegate::GetWeakPtr() { 338 WebSocketHost::WebSocketEventHandler::SSLErrorHandlerDelegate::GetWeakPtr() {
295 return weak_ptr_factory_.GetWeakPtr(); 339 return weak_ptr_factory_.GetWeakPtr();
296 } 340 }
297 341
298 void WebSocketEventHandler::SSLErrorHandlerDelegate::CancelSSLRequest( 342 void WebSocketHost::WebSocketEventHandler::SSLErrorHandlerDelegate::
299 int error, 343 CancelSSLRequest(int error, const net::SSLInfo* ssl_info) {
300 const net::SSLInfo* ssl_info) {
301 DVLOG(3) << "SSLErrorHandlerDelegate::CancelSSLRequest" 344 DVLOG(3) << "SSLErrorHandlerDelegate::CancelSSLRequest"
302 << " error=" << error 345 << " error=" << error
303 << " cert_status=" << (ssl_info ? ssl_info->cert_status 346 << " cert_status=" << (ssl_info ? ssl_info->cert_status
304 : static_cast<net::CertStatus>(-1)); 347 : static_cast<net::CertStatus>(-1));
305 callbacks_->CancelSSLRequest(error, ssl_info); 348 callbacks_->CancelSSLRequest(error, ssl_info);
306 } 349 }
307 350
308 void WebSocketEventHandler::SSLErrorHandlerDelegate::ContinueSSLRequest() { 351 void WebSocketHost::WebSocketEventHandler::SSLErrorHandlerDelegate::
352 ContinueSSLRequest() {
309 DVLOG(3) << "SSLErrorHandlerDelegate::ContinueSSLRequest"; 353 DVLOG(3) << "SSLErrorHandlerDelegate::ContinueSSLRequest";
310 callbacks_->ContinueSSLRequest(); 354 callbacks_->ContinueSSLRequest();
311 } 355 }
312 356
313 } // namespace
314
315 WebSocketHost::WebSocketHost(int routing_id, 357 WebSocketHost::WebSocketHost(int routing_id,
316 WebSocketDispatcherHost* dispatcher, 358 WebSocketDispatcherHost* dispatcher,
317 net::URLRequestContext* url_request_context, 359 net::URLRequestContext* url_request_context,
318 base::TimeDelta delay) 360 base::TimeDelta delay)
319 : dispatcher_(dispatcher), 361 : dispatcher_(dispatcher),
320 url_request_context_(url_request_context), 362 url_request_context_(url_request_context),
321 routing_id_(routing_id), 363 routing_id_(routing_id),
322 delay_(delay), 364 delay_(delay),
323 pending_flow_control_quota_(0), 365 pending_flow_control_quota_(0),
324 handshake_succeeded_(false), 366 handshake_succeeded_(false),
325 weak_ptr_factory_(this) { 367 weak_ptr_factory_(this) {
326 DVLOG(1) << "WebSocketHost: created routing_id=" << routing_id; 368 DVLOG(1) << "WebSocketHost: created routing_id=" << routing_id;
327 } 369 }
328 370
329 WebSocketHost::~WebSocketHost() {} 371 WebSocketHost::~WebSocketHost() {}
330 372
331 void WebSocketHost::GoAway() { 373 void WebSocketHost::GoAway() {
332 OnDropChannel(false, static_cast<uint16_t>(net::kWebSocketErrorGoingAway), 374 OnDropChannel(false, static_cast<uint16_t>(net::kWebSocketErrorGoingAway),
333 ""); 375 "");
334 } 376 }
335 377
336 bool WebSocketHost::OnMessageReceived(const IPC::Message& message) { 378 bool WebSocketHost::OnMessageReceived(const IPC::Message& message) {
337 bool handled = true; 379 bool handled = true;
338 IPC_BEGIN_MESSAGE_MAP(WebSocketHost, message) 380 IPC_BEGIN_MESSAGE_MAP(WebSocketHost, message)
339 IPC_MESSAGE_HANDLER(WebSocketHostMsg_AddChannelRequest, OnAddChannelRequest) 381 IPC_MESSAGE_HANDLER(WebSocketHostMsg_AddChannelRequest, OnAddChannelRequest)
382 IPC_MESSAGE_HANDLER(WebSocketHostMsg_SendBlob, OnSendBlob)
340 IPC_MESSAGE_HANDLER(WebSocketMsg_SendFrame, OnSendFrame) 383 IPC_MESSAGE_HANDLER(WebSocketMsg_SendFrame, OnSendFrame)
341 IPC_MESSAGE_HANDLER(WebSocketMsg_FlowControl, OnFlowControl) 384 IPC_MESSAGE_HANDLER(WebSocketMsg_FlowControl, OnFlowControl)
342 IPC_MESSAGE_HANDLER(WebSocketMsg_DropChannel, OnDropChannel) 385 IPC_MESSAGE_HANDLER(WebSocketMsg_DropChannel, OnDropChannel)
343 IPC_MESSAGE_UNHANDLED(handled = false) 386 IPC_MESSAGE_UNHANDLED(handled = false)
344 IPC_END_MESSAGE_MAP() 387 IPC_END_MESSAGE_MAP()
345 return handled; 388 return handled;
346 } 389 }
347 390
348 void WebSocketHost::OnAddChannelRequest( 391 void WebSocketHost::OnAddChannelRequest(
349 const GURL& socket_url, 392 const GURL& socket_url,
(...skipping 26 matching lines...) Expand all
376 int render_frame_id) { 419 int render_frame_id) {
377 DVLOG(3) << "WebSocketHost::AddChannel" 420 DVLOG(3) << "WebSocketHost::AddChannel"
378 << " routing_id=" << routing_id_ << " socket_url=\"" << socket_url 421 << " routing_id=" << routing_id_ << " socket_url=\"" << socket_url
379 << "\" requested_protocols=\"" 422 << "\" requested_protocols=\""
380 << base::JoinString(requested_protocols, ", ") << "\" origin=\"" 423 << base::JoinString(requested_protocols, ", ") << "\" origin=\""
381 << origin << "\""; 424 << origin << "\"";
382 425
383 DCHECK(!channel_); 426 DCHECK(!channel_);
384 427
385 scoped_ptr<net::WebSocketEventInterface> event_interface( 428 scoped_ptr<net::WebSocketEventInterface> event_interface(
386 new WebSocketEventHandler(dispatcher_, routing_id_, render_frame_id)); 429 new WebSocketEventHandler(dispatcher_, this, routing_id_,
430 render_frame_id));
387 channel_.reset(new net::WebSocketChannel(std::move(event_interface), 431 channel_.reset(new net::WebSocketChannel(std::move(event_interface),
388 url_request_context_)); 432 url_request_context_));
389 433
390 if (pending_flow_control_quota_ > 0) { 434 if (pending_flow_control_quota_ > 0) {
391 // channel_->SendFlowControl(pending_flow_control_quota_) must be called 435 // channel_->SendFlowControl(pending_flow_control_quota_) must be called
392 // after channel_->SendAddChannelRequest() below. 436 // after channel_->SendAddChannelRequest() below.
393 // We post OnFlowControl() here using |weak_ptr_factory_| instead of 437 // We post OnFlowControl() here using |weak_ptr_factory_| instead of
394 // calling SendFlowControl directly, because |this| may have been deleted 438 // calling SendFlowControl directly, because |this| may have been deleted
395 // after channel_->SendAddChannelRequest(). 439 // after channel_->SendAddChannelRequest().
396 base::ThreadTaskRunnerHandle::Get()->PostTask( 440 base::ThreadTaskRunnerHandle::Get()->PostTask(
397 FROM_HERE, base::Bind(&WebSocketHost::OnFlowControl, 441 FROM_HERE, base::Bind(&WebSocketHost::OnFlowControl,
398 weak_ptr_factory_.GetWeakPtr(), 442 weak_ptr_factory_.GetWeakPtr(),
399 pending_flow_control_quota_)); 443 pending_flow_control_quota_));
400 pending_flow_control_quota_ = 0; 444 pending_flow_control_quota_ = 0;
401 } 445 }
402 446
403 channel_->SendAddChannelRequest(socket_url, requested_protocols, origin); 447 channel_->SendAddChannelRequest(socket_url, requested_protocols, origin);
404 // |this| may have been deleted here. 448 // |this| may have been deleted here.
405 } 449 }
406 450
451 void WebSocketHost::OnSendBlob(const std::string& uuid,
452 uint64_t expected_size) {
453 DVLOG(3) << "WebSocketHost::OnSendBlob"
454 << " routing_id=" << routing_id_ << " uuid=" << uuid
455 << " expected_size=" << expected_size;
456
457 DCHECK(channel_);
458 if (blob_sender_) {
459 bad_message::ReceivedBadMessage(
460 dispatcher_, bad_message::WSH_SEND_BLOB_DURING_BLOB_SEND);
461 return;
462 }
463 blob_sender_.reset(new WebSocketBlobSender(
464 make_scoped_ptr(new SendChannelImpl(channel_.get()))));
465 StoragePartition* partition = dispatcher_->storage_partition();
466 storage::FileSystemContext* file_system_context =
467 partition->GetFileSystemContext();
468
469 net::WebSocketEventInterface::ChannelState channel_state =
470 net::WebSocketEventInterface::CHANNEL_ALIVE;
471
472 // This use of base::Unretained is safe because the WebSocketBlobSender object
473 // is owned by this object and will not call it back after destruction.
474 int rv = blob_sender_->Start(
475 uuid, expected_size, dispatcher_->blob_storage_context(),
476 file_system_context,
477 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE).get(),
478 &channel_state,
479 base::Bind(&WebSocketHost::BlobSendComplete, base::Unretained(this)));
480 if (channel_state == net::WebSocketEventInterface::CHANNEL_ALIVE &&
481 rv != net::ERR_IO_PENDING)
482 BlobSendComplete(rv);
483 // |this| may be destroyed here.
484 }
485
407 void WebSocketHost::OnSendFrame(bool fin, 486 void WebSocketHost::OnSendFrame(bool fin,
408 WebSocketMessageType type, 487 WebSocketMessageType type,
409 const std::vector<char>& data) { 488 const std::vector<char>& data) {
410 DVLOG(3) << "WebSocketHost::OnSendFrame" 489 DVLOG(3) << "WebSocketHost::OnSendFrame"
411 << " routing_id=" << routing_id_ << " fin=" << fin 490 << " routing_id=" << routing_id_ << " fin=" << fin
412 << " type=" << type << " data is " << data.size() << " bytes"; 491 << " type=" << type << " data is " << data.size() << " bytes";
413 492
414 DCHECK(channel_); 493 DCHECK(channel_);
494 if (blob_sender_) {
495 bad_message::ReceivedBadMessage(
496 dispatcher_, bad_message::WSH_SEND_FRAME_DURING_BLOB_SEND);
497 return;
498 }
415 channel_->SendFrame(fin, MessageTypeToOpCode(type), data); 499 channel_->SendFrame(fin, MessageTypeToOpCode(type), data);
416 } 500 }
417 501
418 void WebSocketHost::OnFlowControl(int64_t quota) { 502 void WebSocketHost::OnFlowControl(int64_t quota) {
419 DVLOG(3) << "WebSocketHost::OnFlowControl" 503 DVLOG(3) << "WebSocketHost::OnFlowControl"
420 << " routing_id=" << routing_id_ << " quota=" << quota; 504 << " routing_id=" << routing_id_ << " quota=" << quota;
421 505
422 if (!channel_) { 506 if (!channel_) {
423 // WebSocketChannel is not yet created due to the delay introduced by 507 // WebSocketChannel is not yet created due to the delay introduced by
424 // per-renderer WebSocket throttling. 508 // per-renderer WebSocket throttling.
425 // SendFlowControl() is called after WebSocketChannel is created. 509 // SendFlowControl() is called after WebSocketChannel is created.
426 pending_flow_control_quota_ += quota; 510 pending_flow_control_quota_ += quota;
427 return; 511 return;
428 } 512 }
429 513
430 channel_->SendFlowControl(quota); 514 channel_->SendFlowControl(quota);
431 } 515 }
432 516
433 void WebSocketHost::OnDropChannel(bool was_clean, 517 void WebSocketHost::OnDropChannel(bool was_clean,
434 uint16_t code, 518 uint16_t code,
435 const std::string& reason) { 519 const std::string& reason) {
436 DVLOG(3) << "WebSocketHost::OnDropChannel" 520 DVLOG(3) << "WebSocketHost::OnDropChannel"
437 << " routing_id=" << routing_id_ << " was_clean=" << was_clean 521 << " routing_id=" << routing_id_ << " was_clean=" << was_clean
438 << " code=" << code << " reason=\"" << reason << "\""; 522 << " code=" << code << " reason=\"" << reason << "\"";
439 523
440 if (!channel_) { 524 if (!channel_) {
441 // WebSocketChannel is not yet created due to the delay introduced by 525 // WebSocketChannel is not yet created due to the delay introduced by
442 // per-renderer WebSocket throttling. 526 // per-renderer WebSocket throttling.
443 WebSocketDispatcherHost::WebSocketHostState result = 527 WebSocketDispatcherHost::WebSocketHostState result =
444 dispatcher_->DoDropChannel(routing_id_, 528 dispatcher_->DoDropChannel(routing_id_, false,
445 false, 529 net::kWebSocketErrorAbnormalClosure, "");
446 net::kWebSocketErrorAbnormalClosure,
447 "");
448 DCHECK_EQ(WebSocketDispatcherHost::WEBSOCKET_HOST_DELETED, result); 530 DCHECK_EQ(WebSocketDispatcherHost::WEBSOCKET_HOST_DELETED, result);
449 return; 531 return;
450 } 532 }
451 533
534 blob_sender_.reset();
452 // TODO(yhirano): Handle |was_clean| appropriately. 535 // TODO(yhirano): Handle |was_clean| appropriately.
453 channel_->StartClosingHandshake(code, reason); 536 channel_->StartClosingHandshake(code, reason);
454 } 537 }
455 538
539 void WebSocketHost::BlobSendComplete(int result) {
540 DVLOG(3) << "WebSocketHost::BlobSendComplete"
541 << " routing_id=" << routing_id_
542 << " result=" << net::ErrorToString(result);
543
544 // All paths through this method must reset blob_sender_, so take ownership
545 // at the beginning.
546 scoped_ptr<WebSocketBlobSender> blob_sender(std::move(blob_sender_));
547 switch (result) {
548 case net::OK:
549 ignore_result(dispatcher_->BlobSendComplete(routing_id_));
550 // |this| may be destroyed here.
551 return;
552
553 case net::ERR_UPLOAD_FILE_CHANGED: {
554 uint64_t expected_size = blob_sender->expected_size();
555 uint64_t actual_size = blob_sender->ActualSize();
556 if (expected_size != actual_size) {
557 ignore_result(dispatcher_->NotifyFailure(
558 routing_id_,
559 base::StringPrintf("Blob size mismatch; renderer size = %" PRIu64
560 ", browser size = %" PRIu64,
561 expected_size, actual_size)));
562 // |this| is destroyed here.
563 return;
564 } // else fallthrough
565 }
566
567 default:
568 ignore_result(dispatcher_->NotifyFailure(
569 routing_id_,
570 "Failed to load Blob: error code = " + net::ErrorToString(result)));
571 // |this| is destroyed here.
572 return;
573 }
574 }
575
456 } // namespace content 576 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698