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

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

Powered by Google App Engine
This is Rietveld 408576698