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

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

Powered by Google App Engine
This is Rietveld 408576698