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

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

Issue 1664743002: [OBSOLETE][DO NOT SUBMIT][DO NOT COMMIT]] Browser-side implementation of WebSocket Blob receive. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@websocket_blob_send_sender
Patch Set: Now actually works. 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
« no previous file with comments | « content/browser/renderer_host/websocket_host.h ('k') | content/common/websocket.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/renderer_host/websocket_host.h" 5 #include "content/browser/renderer_host/websocket_host.h"
6 6
7 #include <inttypes.h> 7 #include <inttypes.h>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/bind_helpers.h" 11 #include "base/bind_helpers.h"
12 #include "base/location.h" 12 #include "base/location.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/macros.h" 14 #include "base/macros.h"
15 #include "base/single_thread_task_runner.h" 15 #include "base/single_thread_task_runner.h"
16 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
17 #include "base/strings/stringprintf.h" 17 #include "base/strings/stringprintf.h"
18 #include "base/thread_task_runner_handle.h" 18 #include "base/thread_task_runner_handle.h"
19 #include "content/browser/bad_message.h" 19 #include "content/browser/bad_message.h"
20 #include "content/browser/renderer_host/websocket_blob_receiver.h"
20 #include "content/browser/renderer_host/websocket_blob_sender.h" 21 #include "content/browser/renderer_host/websocket_blob_sender.h"
21 #include "content/browser/renderer_host/websocket_dispatcher_host.h" 22 #include "content/browser/renderer_host/websocket_dispatcher_host.h"
22 #include "content/browser/ssl/ssl_error_handler.h" 23 #include "content/browser/ssl/ssl_error_handler.h"
23 #include "content/browser/ssl/ssl_manager.h" 24 #include "content/browser/ssl/ssl_manager.h"
24 #include "content/common/websocket_messages.h" 25 #include "content/common/websocket_messages.h"
25 #include "content/public/browser/browser_thread.h" 26 #include "content/public/browser/browser_thread.h"
26 #include "content/public/browser/render_frame_host.h" 27 #include "content/public/browser/render_frame_host.h"
27 #include "content/public/browser/storage_partition.h" 28 #include "content/public/browser/storage_partition.h"
28 #include "ipc/ipc_message_macros.h" 29 #include "ipc/ipc_message_macros.h"
29 #include "net/base/net_errors.h" 30 #include "net/base/net_errors.h"
30 #include "net/http/http_request_headers.h" 31 #include "net/http/http_request_headers.h"
31 #include "net/http/http_response_headers.h" 32 #include "net/http/http_response_headers.h"
32 #include "net/http/http_util.h" 33 #include "net/http/http_util.h"
33 #include "net/ssl/ssl_info.h" 34 #include "net/ssl/ssl_info.h"
34 #include "net/websockets/websocket_channel.h" 35 #include "net/websockets/websocket_channel.h"
35 #include "net/websockets/websocket_errors.h" 36 #include "net/websockets/websocket_errors.h"
36 #include "net/websockets/websocket_event_interface.h"
37 #include "net/websockets/websocket_frame.h" // for WebSocketFrameHeader::OpCode 37 #include "net/websockets/websocket_frame.h" // for WebSocketFrameHeader::OpCode
38 #include "net/websockets/websocket_handshake_request_info.h" 38 #include "net/websockets/websocket_handshake_request_info.h"
39 #include "net/websockets/websocket_handshake_response_info.h" 39 #include "net/websockets/websocket_handshake_response_info.h"
40 #include "url/origin.h" 40 #include "url/origin.h"
41 41
42 namespace content { 42 namespace content {
43 43
44 namespace { 44 namespace {
45 45
46 typedef net::WebSocketEventInterface::ChannelState ChannelState; 46 using net::WebSocketEventInterface;
47 using net::WebSocketFrameHeader;
48 using ChannelState = WebSocketEventInterface::ChannelState;
49 using OpCode = WebSocketFrameHeader::OpCode;
50
51 const auto CHANNEL_ALIVE = WebSocketEventInterface::CHANNEL_ALIVE;
52 const auto CHANNEL_DELETED = WebSocketEventInterface::CHANNEL_DELETED;
53 const auto WEBSOCKET_HOST_ALIVE = WebSocketDispatcherHost::WEBSOCKET_HOST_ALIVE;
54 const auto WEBSOCKET_HOST_DELETED =
55 WebSocketDispatcherHost::WEBSOCKET_HOST_DELETED;
47 56
48 // Convert a content::WebSocketMessageType to a 57 // Convert a content::WebSocketMessageType to a
49 // net::WebSocketFrameHeader::OpCode 58 // WebSocketFrameHeader::OpCode
50 net::WebSocketFrameHeader::OpCode MessageTypeToOpCode( 59 OpCode MessageTypeToOpCode(WebSocketMessageType type) {
51 WebSocketMessageType type) {
52 DCHECK(type == WEB_SOCKET_MESSAGE_TYPE_CONTINUATION || 60 DCHECK(type == WEB_SOCKET_MESSAGE_TYPE_CONTINUATION ||
53 type == WEB_SOCKET_MESSAGE_TYPE_TEXT || 61 type == WEB_SOCKET_MESSAGE_TYPE_TEXT ||
54 type == WEB_SOCKET_MESSAGE_TYPE_BINARY); 62 type == WEB_SOCKET_MESSAGE_TYPE_BINARY);
55 typedef net::WebSocketFrameHeader::OpCode OpCode;
56 // These compile asserts verify that the same underlying values are used for 63 // These compile asserts verify that the same underlying values are used for
57 // both types, so we can simply cast between them. 64 // both types, so we can simply cast between them.
58 static_assert(static_cast<OpCode>(WEB_SOCKET_MESSAGE_TYPE_CONTINUATION) == 65 static_assert(static_cast<OpCode>(WEB_SOCKET_MESSAGE_TYPE_CONTINUATION) ==
59 net::WebSocketFrameHeader::kOpCodeContinuation, 66 WebSocketFrameHeader::kOpCodeContinuation,
60 "enum values must match for opcode continuation"); 67 "enum values must match for opcode continuation");
61 static_assert(static_cast<OpCode>(WEB_SOCKET_MESSAGE_TYPE_TEXT) == 68 static_assert(static_cast<OpCode>(WEB_SOCKET_MESSAGE_TYPE_TEXT) ==
62 net::WebSocketFrameHeader::kOpCodeText, 69 WebSocketFrameHeader::kOpCodeText,
63 "enum values must match for opcode text"); 70 "enum values must match for opcode text");
64 static_assert(static_cast<OpCode>(WEB_SOCKET_MESSAGE_TYPE_BINARY) == 71 static_assert(static_cast<OpCode>(WEB_SOCKET_MESSAGE_TYPE_BINARY) ==
65 net::WebSocketFrameHeader::kOpCodeBinary, 72 WebSocketFrameHeader::kOpCodeBinary,
66 "enum values must match for opcode binary"); 73 "enum values must match for opcode binary");
67 return static_cast<OpCode>(type); 74 return static_cast<OpCode>(type);
68 } 75 }
69 76
70 WebSocketMessageType OpCodeToMessageType( 77 WebSocketMessageType OpCodeToMessageType(OpCode opCode) {
71 net::WebSocketFrameHeader::OpCode opCode) { 78 DCHECK(opCode == WebSocketFrameHeader::kOpCodeContinuation ||
72 DCHECK(opCode == net::WebSocketFrameHeader::kOpCodeContinuation || 79 opCode == WebSocketFrameHeader::kOpCodeText ||
73 opCode == net::WebSocketFrameHeader::kOpCodeText || 80 opCode == WebSocketFrameHeader::kOpCodeBinary);
74 opCode == net::WebSocketFrameHeader::kOpCodeBinary);
75 // This cast is guaranteed valid by the static_assert() statements above. 81 // This cast is guaranteed valid by the static_assert() statements above.
76 return static_cast<WebSocketMessageType>(opCode); 82 return static_cast<WebSocketMessageType>(opCode);
77 } 83 }
78 84
79 ChannelState StateCast(WebSocketDispatcherHost::WebSocketHostState host_state) { 85 ChannelState StateCast(WebSocketDispatcherHost::WebSocketHostState host_state) {
80 const WebSocketDispatcherHost::WebSocketHostState WEBSOCKET_HOST_ALIVE =
81 WebSocketDispatcherHost::WEBSOCKET_HOST_ALIVE;
82 const WebSocketDispatcherHost::WebSocketHostState WEBSOCKET_HOST_DELETED =
83 WebSocketDispatcherHost::WEBSOCKET_HOST_DELETED;
84
85 DCHECK(host_state == WEBSOCKET_HOST_ALIVE || 86 DCHECK(host_state == WEBSOCKET_HOST_ALIVE ||
86 host_state == WEBSOCKET_HOST_DELETED); 87 host_state == WEBSOCKET_HOST_DELETED);
87 // These compile asserts verify that we can get away with using static_cast<> 88 // These compile asserts verify that we can get away with using static_cast<>
88 // for the conversion. 89 // for the conversion.
89 static_assert(static_cast<ChannelState>(WEBSOCKET_HOST_ALIVE) == 90 static_assert(
90 net::WebSocketEventInterface::CHANNEL_ALIVE, 91 static_cast<ChannelState>(WEBSOCKET_HOST_ALIVE) == CHANNEL_ALIVE,
91 "enum values must match for state_alive"); 92 "enum values must match for state_alive");
92 static_assert(static_cast<ChannelState>(WEBSOCKET_HOST_DELETED) == 93 static_assert(
93 net::WebSocketEventInterface::CHANNEL_DELETED, 94 static_cast<ChannelState>(WEBSOCKET_HOST_DELETED) == CHANNEL_DELETED,
94 "enum values must match for state_deleted"); 95 "enum values must match for state_deleted");
95 return static_cast<ChannelState>(host_state); 96 return static_cast<ChannelState>(host_state);
96 } 97 }
97 98
98 // Implementation of WebSocketBlobSender::Channel 99 // Implementation of WebSocketBlobSender::Channel
99 class SendChannelImpl final : public WebSocketBlobSender::Channel { 100 class SendChannelImpl final : public WebSocketBlobSender::Channel {
100 public: 101 public:
101 explicit SendChannelImpl(net::WebSocketChannel* channel) 102 explicit SendChannelImpl(net::WebSocketChannel* channel)
102 : channel_(channel) {} 103 : channel_(channel) {}
103 104
104 // Implementation of WebSocketBlobSender::Channel 105 // Implementation of WebSocketBlobSender::Channel
105 size_t GetSendQuota() const override { 106 size_t GetSendQuota() const override {
106 return static_cast<size_t>(channel_->current_send_quota()); 107 return static_cast<size_t>(channel_->current_send_quota());
107 } 108 }
108 109
109 ChannelState SendFrame(bool fin, const std::vector<char>& data) override { 110 ChannelState SendFrame(bool fin, const std::vector<char>& data) override {
110 int opcode = first_frame_ ? net::WebSocketFrameHeader::kOpCodeBinary 111 int opcode = first_frame_ ? WebSocketFrameHeader::kOpCodeBinary
111 : net::WebSocketFrameHeader::kOpCodeContinuation; 112 : WebSocketFrameHeader::kOpCodeContinuation;
112 first_frame_ = false; 113 first_frame_ = false;
113 return channel_->SendFrame(fin, opcode, data); 114 return channel_->SendFrame(fin, opcode, data);
114 } 115 }
115 116
116 private: 117 private:
117 net::WebSocketChannel* channel_; 118 net::WebSocketChannel* channel_;
118 bool first_frame_ = true; 119 bool first_frame_ = true;
119 120
120 DISALLOW_COPY_AND_ASSIGN(SendChannelImpl); 121 DISALLOW_COPY_AND_ASSIGN(SendChannelImpl);
121 }; 122 };
(...skipping 23 matching lines...) Expand all
145 ChannelState OnFlowControl(int64_t quota) override; 146 ChannelState OnFlowControl(int64_t quota) override;
146 ChannelState OnDropChannel(bool was_clean, 147 ChannelState OnDropChannel(bool was_clean,
147 uint16_t code, 148 uint16_t code,
148 const std::string& reason) override; 149 const std::string& reason) override;
149 ChannelState OnFailChannel(const std::string& message) override; 150 ChannelState OnFailChannel(const std::string& message) override;
150 ChannelState OnStartOpeningHandshake( 151 ChannelState OnStartOpeningHandshake(
151 scoped_ptr<net::WebSocketHandshakeRequestInfo> request) override; 152 scoped_ptr<net::WebSocketHandshakeRequestInfo> request) override;
152 ChannelState OnFinishOpeningHandshake( 153 ChannelState OnFinishOpeningHandshake(
153 scoped_ptr<net::WebSocketHandshakeResponseInfo> response) override; 154 scoped_ptr<net::WebSocketHandshakeResponseInfo> response) override;
154 ChannelState OnSSLCertificateError( 155 ChannelState OnSSLCertificateError(
155 scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks, 156 scoped_ptr<WebSocketEventInterface::SSLErrorCallbacks> callbacks,
156 const GURL& url, 157 const GURL& url,
157 const net::SSLInfo& ssl_info, 158 const net::SSLInfo& ssl_info,
158 bool fatal) override; 159 bool fatal) override;
159 160
160 private: 161 private:
161 class SSLErrorHandlerDelegate final : public SSLErrorHandler::Delegate { 162 class SSLErrorHandlerDelegate final : public SSLErrorHandler::Delegate {
162 public: 163 public:
163 SSLErrorHandlerDelegate( 164 SSLErrorHandlerDelegate(
164 scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks); 165 scoped_ptr<WebSocketEventInterface::SSLErrorCallbacks> callbacks);
165 ~SSLErrorHandlerDelegate() override; 166 ~SSLErrorHandlerDelegate() override;
166 167
167 base::WeakPtr<SSLErrorHandler::Delegate> GetWeakPtr(); 168 base::WeakPtr<SSLErrorHandler::Delegate> GetWeakPtr();
168 169
169 // SSLErrorHandler::Delegate methods 170 // SSLErrorHandler::Delegate methods
170 void CancelSSLRequest(int error, const net::SSLInfo* ssl_info) override; 171 void CancelSSLRequest(int error, const net::SSLInfo* ssl_info) override;
171 void ContinueSSLRequest() override; 172 void ContinueSSLRequest() override;
172 173
173 private: 174 private:
174 scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks_; 175 scoped_ptr<WebSocketEventInterface::SSLErrorCallbacks> callbacks_;
175 base::WeakPtrFactory<SSLErrorHandlerDelegate> weak_ptr_factory_; 176 base::WeakPtrFactory<SSLErrorHandlerDelegate> weak_ptr_factory_;
176 177
177 DISALLOW_COPY_AND_ASSIGN(SSLErrorHandlerDelegate); 178 DISALLOW_COPY_AND_ASSIGN(SSLErrorHandlerDelegate);
178 }; 179 };
179 180
180 WebSocketDispatcherHost* const dispatcher_; 181 WebSocketDispatcherHost* const dispatcher_;
181 WebSocketHost* const host_; 182 WebSocketHost* const host_;
182 const int routing_id_; 183 const int routing_id_;
183 const int render_frame_id_; 184 const int render_frame_id_;
184 scoped_ptr<SSLErrorHandlerDelegate> ssl_error_handler_delegate_; 185 scoped_ptr<SSLErrorHandlerDelegate> ssl_error_handler_delegate_;
(...skipping 12 matching lines...) Expand all
197 render_frame_id_(render_frame_id) {} 198 render_frame_id_(render_frame_id) {}
198 199
199 WebSocketHost::WebSocketEventHandler::~WebSocketEventHandler() { 200 WebSocketHost::WebSocketEventHandler::~WebSocketEventHandler() {
200 DVLOG(1) << "WebSocketEventHandler destroyed routing_id=" << routing_id_; 201 DVLOG(1) << "WebSocketEventHandler destroyed routing_id=" << routing_id_;
201 } 202 }
202 203
203 ChannelState WebSocketHost::WebSocketEventHandler::OnAddChannelResponse( 204 ChannelState WebSocketHost::WebSocketEventHandler::OnAddChannelResponse(
204 const std::string& selected_protocol, 205 const std::string& selected_protocol,
205 const std::string& extensions) { 206 const std::string& extensions) {
206 DVLOG(3) << "WebSocketEventHandler::OnAddChannelResponse" 207 DVLOG(3) << "WebSocketEventHandler::OnAddChannelResponse"
207 << " routing_id=" << routing_id_ 208 << " routing_id=" << routing_id_ << " selected_protocol=\""
208 << " selected_protocol=\"" << selected_protocol << "\"" 209 << selected_protocol << "\""
209 << " extensions=\"" << extensions << "\""; 210 << " extensions=\"" << extensions << "\"";
210 211
211 return StateCast(dispatcher_->SendAddChannelResponse( 212 return StateCast(dispatcher_->SendAddChannelResponse(
212 routing_id_, selected_protocol, extensions)); 213 routing_id_, selected_protocol, extensions));
213 } 214 }
214 215
215 ChannelState WebSocketHost::WebSocketEventHandler::OnDataFrame( 216 ChannelState WebSocketHost::WebSocketEventHandler::OnDataFrame(
216 bool fin, 217 bool fin,
217 net::WebSocketFrameHeader::OpCode type, 218 OpCode type,
218 const std::vector<char>& data) { 219 const std::vector<char>& data) {
219 DVLOG(3) << "WebSocketEventHandler::OnDataFrame" 220 DVLOG(3) << "WebSocketEventHandler::OnDataFrame"
220 << " routing_id=" << routing_id_ << " fin=" << fin 221 << " routing_id=" << routing_id_ << " fin=" << fin
221 << " type=" << type << " data is " << data.size() << " bytes"; 222 << " type=" << type << " data is " << data.size() << " bytes";
222 223
223 return StateCast(dispatcher_->SendFrame(routing_id_, fin, 224 host_->receive_quota_multiplexer_.ReceivedFrame(data.size());
224 OpCodeToMessageType(type), data)); 225 if (host_->ShouldQueue(data.size())) {
226 host_->AppendToQueue(fin, type, data);
227 return CHANNEL_ALIVE;
228 }
229
230 bool started_blob_receive = false;
231 if (host_->SendFrameInternal(fin, type, data, &started_blob_receive) ==
232 CHANNEL_DELETED) {
233 // |this| has been destroyed here.
234 return CHANNEL_DELETED;
235 }
236 if (started_blob_receive)
237 host_->AppendToQueue(fin, type, data);
238 return CHANNEL_ALIVE;
225 } 239 }
226 240
227 ChannelState WebSocketHost::WebSocketEventHandler::OnClosingHandshake() { 241 ChannelState WebSocketHost::WebSocketEventHandler::OnClosingHandshake() {
228 DVLOG(3) << "WebSocketEventHandler::OnClosingHandshake" 242 DVLOG(3) << "WebSocketEventHandler::OnClosingHandshake"
229 << " routing_id=" << routing_id_; 243 << " routing_id=" << routing_id_;
230 244
231 return StateCast(dispatcher_->NotifyClosingHandshake(routing_id_)); 245 return StateCast(dispatcher_->NotifyClosingHandshake(routing_id_));
232 } 246 }
233 247
234 ChannelState WebSocketHost::WebSocketEventHandler::OnFlowControl( 248 ChannelState WebSocketHost::WebSocketEventHandler::OnFlowControl(
235 int64_t quota) { 249 int64_t quota) {
236 DVLOG(3) << "WebSocketEventHandler::OnFlowControl" 250 DVLOG(3) << "WebSocketEventHandler::OnFlowControl"
237 << " routing_id=" << routing_id_ << " quota=" << quota; 251 << " routing_id=" << routing_id_ << " quota=" << quota;
238 252
239 if (host_->blob_sender_) 253 if (host_->blob_sender_)
240 host_->blob_sender_->OnNewSendQuota(); 254 host_->blob_sender_->OnNewSendQuota();
241 return StateCast(dispatcher_->SendFlowControl(routing_id_, quota)); 255 return StateCast(dispatcher_->SendFlowControl(routing_id_, quota));
242 } 256 }
243 257
244 ChannelState WebSocketHost::WebSocketEventHandler::OnDropChannel( 258 ChannelState WebSocketHost::WebSocketEventHandler::OnDropChannel(
245 bool was_clean, 259 bool was_clean,
246 uint16_t code, 260 uint16_t code,
247 const std::string& reason) { 261 const std::string& reason) {
248 DVLOG(3) << "WebSocketEventHandler::OnDropChannel" 262 DVLOG(3) << "WebSocketEventHandler::OnDropChannel"
249 << " routing_id=" << routing_id_ << " was_clean=" << was_clean 263 << " routing_id=" << routing_id_ << " was_clean=" << was_clean
250 << " code=" << code << " reason=\"" << reason << "\""; 264 << " code=" << code << " reason=\"" << reason << "\"";
251 265
266 if (host_->ShouldDelayDropChannel()) {
267 DVLOG(3) << "WebSocketEventHandler::OnDropChannel delayed";
268 host_->SetPendingDropChannel(was_clean, code, reason);
269 return CHANNEL_ALIVE;
270 }
252 return StateCast( 271 return StateCast(
253 dispatcher_->DoDropChannel(routing_id_, was_clean, code, reason)); 272 dispatcher_->DoDropChannel(routing_id_, was_clean, code, reason));
254 } 273 }
255 274
256 ChannelState WebSocketHost::WebSocketEventHandler::OnFailChannel( 275 ChannelState WebSocketHost::WebSocketEventHandler::OnFailChannel(
257 const std::string& message) { 276 const std::string& message) {
258 DVLOG(3) << "WebSocketEventHandler::OnFailChannel" 277 DVLOG(3) << "WebSocketEventHandler::OnFailChannel"
259 << " routing_id=" << routing_id_ << " message=\"" << message << "\""; 278 << " routing_id=" << routing_id_ << " message=\"" << message << "\"";
260 279
261 return StateCast(dispatcher_->NotifyFailure(routing_id_, message)); 280 return StateCast(dispatcher_->NotifyFailure(routing_id_, message));
262 } 281 }
263 282
264 ChannelState WebSocketHost::WebSocketEventHandler::OnStartOpeningHandshake( 283 ChannelState WebSocketHost::WebSocketEventHandler::OnStartOpeningHandshake(
265 scoped_ptr<net::WebSocketHandshakeRequestInfo> request) { 284 scoped_ptr<net::WebSocketHandshakeRequestInfo> request) {
266 bool should_send = dispatcher_->CanReadRawCookies(); 285 bool should_send = dispatcher_->CanReadRawCookies();
267 DVLOG(3) << "WebSocketEventHandler::OnStartOpeningHandshake " 286 DVLOG(3) << "WebSocketEventHandler::OnStartOpeningHandshake "
268 << "should_send=" << should_send; 287 << "should_send=" << should_send;
269 288
270 if (!should_send) 289 if (!should_send)
271 return WebSocketEventInterface::CHANNEL_ALIVE; 290 return CHANNEL_ALIVE;
272 291
273 WebSocketHandshakeRequest request_to_pass; 292 WebSocketHandshakeRequest request_to_pass;
274 request_to_pass.url.Swap(&request->url); 293 request_to_pass.url.Swap(&request->url);
275 net::HttpRequestHeaders::Iterator it(request->headers); 294 net::HttpRequestHeaders::Iterator it(request->headers);
276 while (it.GetNext()) 295 while (it.GetNext())
277 request_to_pass.headers.push_back(std::make_pair(it.name(), it.value())); 296 request_to_pass.headers.push_back(std::make_pair(it.name(), it.value()));
278 request_to_pass.headers_text = 297 request_to_pass.headers_text =
279 base::StringPrintf("GET %s HTTP/1.1\r\n", 298 base::StringPrintf("GET %s HTTP/1.1\r\n",
280 request_to_pass.url.spec().c_str()) + 299 request_to_pass.url.spec().c_str()) +
281 request->headers.ToString(); 300 request->headers.ToString();
282 request_to_pass.request_time = request->request_time; 301 request_to_pass.request_time = request->request_time;
283 302
284 return StateCast( 303 return StateCast(
285 dispatcher_->NotifyStartOpeningHandshake(routing_id_, request_to_pass)); 304 dispatcher_->NotifyStartOpeningHandshake(routing_id_, request_to_pass));
286 } 305 }
287 306
288 ChannelState WebSocketHost::WebSocketEventHandler::OnFinishOpeningHandshake( 307 ChannelState WebSocketHost::WebSocketEventHandler::OnFinishOpeningHandshake(
289 scoped_ptr<net::WebSocketHandshakeResponseInfo> response) { 308 scoped_ptr<net::WebSocketHandshakeResponseInfo> response) {
290 bool should_send = dispatcher_->CanReadRawCookies(); 309 bool should_send = dispatcher_->CanReadRawCookies();
291 DVLOG(3) << "WebSocketEventHandler::OnFinishOpeningHandshake " 310 DVLOG(3) << "WebSocketEventHandler::OnFinishOpeningHandshake "
292 << "should_send=" << should_send; 311 << "should_send=" << should_send;
293 312
294 if (!should_send) 313 if (!should_send)
295 return WebSocketEventInterface::CHANNEL_ALIVE; 314 return CHANNEL_ALIVE;
296 315
297 WebSocketHandshakeResponse response_to_pass; 316 WebSocketHandshakeResponse response_to_pass;
298 response_to_pass.url.Swap(&response->url); 317 response_to_pass.url.Swap(&response->url);
299 response_to_pass.status_code = response->status_code; 318 response_to_pass.status_code = response->status_code;
300 response_to_pass.status_text.swap(response->status_text); 319 response_to_pass.status_text.swap(response->status_text);
301 void* iter = NULL; 320 void* iter = NULL;
302 std::string name, value; 321 std::string name, value;
303 while (response->headers->EnumerateHeaderLines(&iter, &name, &value)) 322 while (response->headers->EnumerateHeaderLines(&iter, &name, &value))
304 response_to_pass.headers.push_back(std::make_pair(name, value)); 323 response_to_pass.headers.push_back(std::make_pair(name, value));
305 response_to_pass.headers_text = 324 response_to_pass.headers_text =
306 net::HttpUtil::ConvertHeadersBackToHTTPResponse( 325 net::HttpUtil::ConvertHeadersBackToHTTPResponse(
307 response->headers->raw_headers()); 326 response->headers->raw_headers());
308 response_to_pass.response_time = response->response_time; 327 response_to_pass.response_time = response->response_time;
309 328
310 return StateCast( 329 return StateCast(
311 dispatcher_->NotifyFinishOpeningHandshake(routing_id_, response_to_pass)); 330 dispatcher_->NotifyFinishOpeningHandshake(routing_id_, response_to_pass));
312 } 331 }
313 332
314 ChannelState WebSocketHost::WebSocketEventHandler::OnSSLCertificateError( 333 ChannelState WebSocketHost::WebSocketEventHandler::OnSSLCertificateError(
315 scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks, 334 scoped_ptr<WebSocketEventInterface::SSLErrorCallbacks> callbacks,
316 const GURL& url, 335 const GURL& url,
317 const net::SSLInfo& ssl_info, 336 const net::SSLInfo& ssl_info,
318 bool fatal) { 337 bool fatal) {
319 DVLOG(3) << "WebSocketEventHandler::OnSSLCertificateError" 338 DVLOG(3) << "WebSocketEventHandler::OnSSLCertificateError"
320 << " routing_id=" << routing_id_ << " url=" << url.spec() 339 << " routing_id=" << routing_id_ << " url=" << url.spec()
321 << " cert_status=" << ssl_info.cert_status << " fatal=" << fatal; 340 << " cert_status=" << ssl_info.cert_status << " fatal=" << fatal;
322 ssl_error_handler_delegate_.reset( 341 ssl_error_handler_delegate_.reset(
323 new SSLErrorHandlerDelegate(std::move(callbacks))); 342 new SSLErrorHandlerDelegate(std::move(callbacks)));
324 SSLManager::OnSSLCertificateSubresourceError( 343 SSLManager::OnSSLCertificateSubresourceError(
325 ssl_error_handler_delegate_->GetWeakPtr(), url, 344 ssl_error_handler_delegate_->GetWeakPtr(), url,
326 dispatcher_->render_process_id(), render_frame_id_, ssl_info, fatal); 345 dispatcher_->render_process_id(), render_frame_id_, ssl_info, fatal);
327 // The above method is always asynchronous. 346 // The above method is always asynchronous.
328 return WebSocketEventInterface::CHANNEL_ALIVE; 347 return CHANNEL_ALIVE;
329 } 348 }
330 349
331 WebSocketHost::WebSocketEventHandler::SSLErrorHandlerDelegate:: 350 WebSocketHost::WebSocketEventHandler::SSLErrorHandlerDelegate::
332 SSLErrorHandlerDelegate( 351 SSLErrorHandlerDelegate(
333 scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks) 352 scoped_ptr<WebSocketEventInterface::SSLErrorCallbacks> callbacks)
334 : callbacks_(std::move(callbacks)), weak_ptr_factory_(this) {} 353 : callbacks_(std::move(callbacks)), weak_ptr_factory_(this) {}
335 354
336 WebSocketHost::WebSocketEventHandler::SSLErrorHandlerDelegate:: 355 WebSocketHost::WebSocketEventHandler::SSLErrorHandlerDelegate::
337 ~SSLErrorHandlerDelegate() {} 356 ~SSLErrorHandlerDelegate() {}
338 357
339 base::WeakPtr<SSLErrorHandler::Delegate> 358 base::WeakPtr<SSLErrorHandler::Delegate>
340 WebSocketHost::WebSocketEventHandler::SSLErrorHandlerDelegate::GetWeakPtr() { 359 WebSocketHost::WebSocketEventHandler::SSLErrorHandlerDelegate::GetWeakPtr() {
341 return weak_ptr_factory_.GetWeakPtr(); 360 return weak_ptr_factory_.GetWeakPtr();
342 } 361 }
343 362
344 void WebSocketHost::WebSocketEventHandler::SSLErrorHandlerDelegate:: 363 void WebSocketHost::WebSocketEventHandler::SSLErrorHandlerDelegate::
345 CancelSSLRequest(int error, const net::SSLInfo* ssl_info) { 364 CancelSSLRequest(int error, const net::SSLInfo* ssl_info) {
346 DVLOG(3) << "SSLErrorHandlerDelegate::CancelSSLRequest" 365 DVLOG(3) << "SSLErrorHandlerDelegate::CancelSSLRequest"
347 << " error=" << error 366 << " error=" << error
348 << " cert_status=" << (ssl_info ? ssl_info->cert_status 367 << " cert_status=" << (ssl_info ? ssl_info->cert_status
349 : static_cast<net::CertStatus>(-1)); 368 : static_cast<net::CertStatus>(-1));
350 callbacks_->CancelSSLRequest(error, ssl_info); 369 callbacks_->CancelSSLRequest(error, ssl_info);
351 } 370 }
352 371
353 void WebSocketHost::WebSocketEventHandler::SSLErrorHandlerDelegate:: 372 void WebSocketHost::WebSocketEventHandler::SSLErrorHandlerDelegate::
354 ContinueSSLRequest() { 373 ContinueSSLRequest() {
355 DVLOG(3) << "SSLErrorHandlerDelegate::ContinueSSLRequest"; 374 DVLOG(3) << "SSLErrorHandlerDelegate::ContinueSSLRequest";
356 callbacks_->ContinueSSLRequest(); 375 callbacks_->ContinueSSLRequest();
357 } 376 }
358 377
378 WebSocketHost::ReceiveQuotaMultiplexer::ReceiveQuotaMultiplexer() {}
379
380 void WebSocketHost::ReceiveQuotaMultiplexer::SetChannel(
381 net::WebSocketChannel* channel) {
382 channel_ = channel;
383 if (!channel) {
384 channel_quota_ = 0;
385 }
386 }
387
388 void WebSocketHost::ReceiveQuotaMultiplexer::SetConsumer(
389 ReceiveQuotaConsumer* consumer) {
390 DCHECK(consumer);
391 current_consumer_ = consumer;
392 }
393
394 // Quota can be added to any consumer at any time.
395 bool WebSocketHost::ReceiveQuotaMultiplexer::AddQuota(
396 ReceiveQuotaProvider* provider,
397 size_t quota) {
398 *provider += quota;
399 return provider == current_consumer_;
400 }
401
402 // Quota can only be used from the current consumer.
403 size_t WebSocketHost::ReceiveQuotaMultiplexer::AvailableQuota() const {
404 DCHECK(current_consumer_);
405 return *current_consumer_;
406 }
407
408 // Quota is only consumed by the current consumer.
409 void WebSocketHost::ReceiveQuotaMultiplexer::ConsumedQuota(size_t quota) {
410 DCHECK_GE(*current_consumer_, quota);
411 *current_consumer_ -= quota;
412 }
413
414 void WebSocketHost::ReceiveQuotaMultiplexer::ReceivedFrame(size_t size) {
415 DCHECK(channel_);
416 DCHECK_GE(channel_quota_, size);
417 channel_quota_ -= size;
418 }
419
420 void WebSocketHost::ReceiveQuotaMultiplexer::PublishMoreQuotaIfAvailable() {
421 if (!channel_)
422 return;
423 DCHECK(current_consumer_);
424 if (*current_consumer_ > channel_quota_) {
425 size_t additional_quota =
426 *current_consumer_ - channel_quota_;
427 channel_quota_ = *current_consumer_;
428 // SendFlowControl may call back into OnDataFrame, so order matters here.
429 channel_->SendFlowControl(additional_quota);
430 }
431 }
432
433 WebSocketHost::QueuedFrame::QueuedFrame(bool fin,
434 OpCode type,
435 const std::vector<char>& data)
436 : fin(fin), type(type), data(data) {}
437
438 WebSocketHost::QueuedFrame::QueuedFrame(QueuedFrame&& rhs)
439 : fin(rhs.fin), type(rhs.type), data(std::move(rhs.data)) {}
440
441 WebSocketHost::QueuedFrame::~QueuedFrame() {}
442
443 WebSocketHost::QueuedFrame& WebSocketHost::QueuedFrame::operator=(
444 QueuedFrame&& rhs) {
445 if (this == &rhs)
446 return *this;
447 fin = rhs.fin;
448 type = rhs.type;
449 data = std::move(rhs.data);
450 return *this;
451 }
452
453 struct WebSocketHost::DropChannelParameters {
454 DropChannelParameters(bool was_clean,
455 uint16_t code,
456 const std::string& reason)
457 : was_clean(was_clean), code(code), reason(reason) {}
458
459 bool was_clean;
460 uint16_t code;
461 std::string reason;
462 };
463
464 class WebSocketHost::BlobReceiverClient final
465 : public WebSocketBlobReceiver::Client {
466 public:
467 explicit BlobReceiverClient(WebSocketHost* host) : host_(host) {}
468
469 // Implementation of WebSocketBlobReceiver::Client
470 void BlobCreated(scoped_ptr<storage::BlobDataHandle> blob_data_handle,
471 uint64_t size) override {
472 host_->FinishReceivingBlob(std::move(blob_data_handle), size);
473 // |this| may be destroyed here.
474 }
475
476 void BlobFailed(int net_error_code) override {
477 host_->BlobReceiveFailed(net_error_code);
478 // |this| is destroyed here.
479 }
480
481 void AddFlowControlQuota(size_t quota) override {
482 if (host_->receive_quota_multiplexer_.AddQuota(&host_->blob_receiver_quota_,
483 quota)) {
484 host_->FlushQueueAndPublishQuotaIfAvailable();
485 // |this| may be destroyed here.
486 }
487 }
488
489 private:
490 WebSocketHost* host_;
491
492 DISALLOW_COPY_AND_ASSIGN(BlobReceiverClient);
493 };
494
359 WebSocketHost::WebSocketHost(int routing_id, 495 WebSocketHost::WebSocketHost(int routing_id,
360 WebSocketDispatcherHost* dispatcher, 496 WebSocketDispatcherHost* dispatcher,
361 net::URLRequestContext* url_request_context, 497 net::URLRequestContext* url_request_context,
362 base::TimeDelta delay) 498 base::TimeDelta delay)
363 : dispatcher_(dispatcher), 499 : dispatcher_(dispatcher),
364 url_request_context_(url_request_context), 500 url_request_context_(url_request_context),
365 routing_id_(routing_id), 501 routing_id_(routing_id),
366 delay_(delay), 502 delay_(delay),
367 pending_flow_control_quota_(0), 503 pending_flow_control_quota_(0),
368 handshake_succeeded_(false), 504 handshake_succeeded_(false),
505 binary_type_(WebSocketBinaryType::BLOB),
506 renderer_quota_(0),
507 blob_receiver_quota_(0),
369 weak_ptr_factory_(this) { 508 weak_ptr_factory_(this) {
370 DVLOG(1) << "WebSocketHost: created routing_id=" << routing_id; 509 DVLOG(1) << "WebSocketHost: created routing_id=" << routing_id;
371 } 510 }
372 511
373 WebSocketHost::~WebSocketHost() {} 512 WebSocketHost::~WebSocketHost() {}
374 513
375 void WebSocketHost::GoAway() { 514 void WebSocketHost::GoAway() {
376 OnDropChannel(false, static_cast<uint16_t>(net::kWebSocketErrorGoingAway), 515 OnDropChannel(false, static_cast<uint16_t>(net::kWebSocketErrorGoingAway),
377 ""); 516 "");
378 } 517 }
379 518
380 bool WebSocketHost::OnMessageReceived(const IPC::Message& message) { 519 bool WebSocketHost::OnMessageReceived(const IPC::Message& message) {
381 bool handled = true; 520 bool handled = true;
382 IPC_BEGIN_MESSAGE_MAP(WebSocketHost, message) 521 IPC_BEGIN_MESSAGE_MAP(WebSocketHost, message)
383 IPC_MESSAGE_HANDLER(WebSocketHostMsg_AddChannelRequest, OnAddChannelRequest) 522 IPC_MESSAGE_HANDLER(WebSocketHostMsg_AddChannelRequest, OnAddChannelRequest)
384 IPC_MESSAGE_HANDLER(WebSocketHostMsg_SendBlob, OnSendBlob) 523 IPC_MESSAGE_HANDLER(WebSocketHostMsg_SendBlob, OnSendBlob)
524 IPC_MESSAGE_HANDLER(WebSocketHostMsg_BinaryTypeChanged, OnBinaryTypeChanged)
525 IPC_MESSAGE_HANDLER(WebSocketHostMsg_BlobConfirmed, OnBlobConfirmed)
385 IPC_MESSAGE_HANDLER(WebSocketMsg_SendFrame, OnSendFrame) 526 IPC_MESSAGE_HANDLER(WebSocketMsg_SendFrame, OnSendFrame)
386 IPC_MESSAGE_HANDLER(WebSocketMsg_FlowControl, OnFlowControl) 527 IPC_MESSAGE_HANDLER(WebSocketMsg_FlowControl, OnFlowControl)
387 IPC_MESSAGE_HANDLER(WebSocketMsg_DropChannel, OnDropChannel) 528 IPC_MESSAGE_HANDLER(WebSocketMsg_DropChannel, OnDropChannel)
388 IPC_MESSAGE_UNHANDLED(handled = false) 529 IPC_MESSAGE_UNHANDLED(handled = false)
389 IPC_END_MESSAGE_MAP() 530 IPC_END_MESSAGE_MAP()
390 return handled; 531 return handled;
391 } 532 }
392 533
393 void WebSocketHost::OnAddChannelRequest( 534 void WebSocketHost::OnAddChannelRequest(
394 const GURL& socket_url, 535 const GURL& socket_url,
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 // after channel_->SendAddChannelRequest() below. 579 // after channel_->SendAddChannelRequest() below.
439 // We post OnFlowControl() here using |weak_ptr_factory_| instead of 580 // We post OnFlowControl() here using |weak_ptr_factory_| instead of
440 // calling SendFlowControl directly, because |this| may have been deleted 581 // calling SendFlowControl directly, because |this| may have been deleted
441 // after channel_->SendAddChannelRequest(). 582 // after channel_->SendAddChannelRequest().
442 base::ThreadTaskRunnerHandle::Get()->PostTask( 583 base::ThreadTaskRunnerHandle::Get()->PostTask(
443 FROM_HERE, base::Bind(&WebSocketHost::OnFlowControl, 584 FROM_HERE, base::Bind(&WebSocketHost::OnFlowControl,
444 weak_ptr_factory_.GetWeakPtr(), 585 weak_ptr_factory_.GetWeakPtr(),
445 pending_flow_control_quota_)); 586 pending_flow_control_quota_));
446 pending_flow_control_quota_ = 0; 587 pending_flow_control_quota_ = 0;
447 } 588 }
589 receive_quota_multiplexer_.SetChannel(channel_.get());
590 receive_quota_multiplexer_.SetConsumer(&renderer_quota_);
448 591
449 channel_->SendAddChannelRequest(socket_url, requested_protocols, origin); 592 channel_->SendAddChannelRequest(socket_url, requested_protocols, origin);
450 // |this| may have been deleted here. 593 // |this| may have been deleted here.
451 } 594 }
452 595
453 void WebSocketHost::OnSendBlob(const std::string& uuid, 596 void WebSocketHost::OnSendBlob(const std::string& uuid,
454 uint64_t expected_size) { 597 uint64_t expected_size) {
455 DVLOG(3) << "WebSocketHost::OnSendBlob" 598 DVLOG(3) << "WebSocketHost::OnSendBlob"
456 << " routing_id=" << routing_id_ << " uuid=" << uuid 599 << " routing_id=" << routing_id_ << " uuid=" << uuid
457 << " expected_size=" << expected_size; 600 << " expected_size=" << expected_size;
458 601
459 DCHECK(channel_); 602 DCHECK(channel_);
460 if (blob_sender_) { 603 if (blob_sender_) {
461 bad_message::ReceivedBadMessage( 604 bad_message::ReceivedBadMessage(
462 dispatcher_, bad_message::WSH_SEND_BLOB_DURING_BLOB_SEND); 605 dispatcher_, bad_message::WSH_SEND_BLOB_DURING_BLOB_SEND);
463 return; 606 return;
464 } 607 }
465 blob_sender_.reset(new WebSocketBlobSender( 608 blob_sender_.reset(new WebSocketBlobSender(
466 make_scoped_ptr(new SendChannelImpl(channel_.get())))); 609 make_scoped_ptr(new SendChannelImpl(channel_.get()))));
467 StoragePartition* partition = dispatcher_->storage_partition(); 610 StoragePartition* partition = dispatcher_->storage_partition();
468 storage::FileSystemContext* file_system_context = 611 storage::FileSystemContext* file_system_context =
469 partition->GetFileSystemContext(); 612 partition->GetFileSystemContext();
470 613
471 net::WebSocketEventInterface::ChannelState channel_state = 614 ChannelState channel_state = CHANNEL_ALIVE;
472 net::WebSocketEventInterface::CHANNEL_ALIVE;
473 615
474 // This use of base::Unretained is safe because the WebSocketBlobSender object 616 // 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. 617 // is owned by this object and will not call it back after destruction.
476 int rv = blob_sender_->Start( 618 int rv = blob_sender_->Start(
477 uuid, expected_size, dispatcher_->blob_storage_context(), 619 uuid, expected_size, dispatcher_->blob_storage_context(),
478 file_system_context, 620 file_system_context,
479 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE).get(), 621 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE).get(),
480 &channel_state, 622 &channel_state,
481 base::Bind(&WebSocketHost::BlobSendComplete, base::Unretained(this))); 623 base::Bind(&WebSocketHost::BlobSendComplete, base::Unretained(this)));
482 if (channel_state == net::WebSocketEventInterface::CHANNEL_ALIVE && 624 if (channel_state == CHANNEL_ALIVE && rv != net::ERR_IO_PENDING)
483 rv != net::ERR_IO_PENDING)
484 BlobSendComplete(rv); 625 BlobSendComplete(rv);
485 // |this| may be destroyed here. 626 // |this| may be destroyed here.
486 } 627 }
487 628
488 void WebSocketHost::OnSendFrame(bool fin, 629 void WebSocketHost::OnSendFrame(bool fin,
489 WebSocketMessageType type, 630 WebSocketMessageType type,
490 const std::vector<char>& data) { 631 const std::vector<char>& data) {
491 DVLOG(3) << "WebSocketHost::OnSendFrame" 632 DVLOG(3) << "WebSocketHost::OnSendFrame"
492 << " routing_id=" << routing_id_ << " fin=" << fin 633 << " routing_id=" << routing_id_ << " fin=" << fin
493 << " type=" << type << " data is " << data.size() << " bytes"; 634 << " type=" << type << " data is " << data.size() << " bytes";
494 635
636 if (pending_drop_channel_)
637 return;
638
495 DCHECK(channel_); 639 DCHECK(channel_);
496 if (blob_sender_) { 640 if (blob_sender_) {
497 bad_message::ReceivedBadMessage( 641 bad_message::ReceivedBadMessage(
498 dispatcher_, bad_message::WSH_SEND_FRAME_DURING_BLOB_SEND); 642 dispatcher_, bad_message::WSH_SEND_FRAME_DURING_BLOB_SEND);
499 return; 643 return;
500 } 644 }
501 channel_->SendFrame(fin, MessageTypeToOpCode(type), data); 645 channel_->SendFrame(fin, MessageTypeToOpCode(type), data);
502 } 646 }
503 647
504 void WebSocketHost::OnFlowControl(int64_t quota) { 648 void WebSocketHost::OnFlowControl(int64_t quota) {
505 DVLOG(3) << "WebSocketHost::OnFlowControl" 649 DVLOG(3) << "WebSocketHost::OnFlowControl"
506 << " routing_id=" << routing_id_ << " quota=" << quota; 650 << " routing_id=" << routing_id_ << " quota=" << quota;
651 if (quota < 0) {
652 bad_message::ReceivedBadMessage(dispatcher_,
653 bad_message::WSH_NEGATIVE_QUOTA);
654 return;
655 }
507 656
508 if (!channel_) { 657 if (!channel_) {
509 // WebSocketChannel is not yet created due to the delay introduced by 658 // WebSocketChannel is not yet created due to the delay introduced by
510 // per-renderer WebSocket throttling. 659 // per-renderer WebSocket throttling.
511 // SendFlowControl() is called after WebSocketChannel is created. 660 // SendFlowControl() is called after WebSocketChannel is created.
512 pending_flow_control_quota_ += quota; 661 pending_flow_control_quota_ += quota;
513 return; 662 return;
514 } 663 }
515 664
516 channel_->SendFlowControl(quota); 665 if (receive_quota_multiplexer_.AddQuota(&renderer_quota_, quota)) {
666 FlushQueueAndPublishQuotaIfAvailable();
667 // |this| may be destroyed here.
668 }
517 } 669 }
518 670
519 void WebSocketHost::OnDropChannel(bool was_clean, 671 void WebSocketHost::OnDropChannel(bool was_clean,
520 uint16_t code, 672 uint16_t code,
521 const std::string& reason) { 673 const std::string& reason) {
522 DVLOG(3) << "WebSocketHost::OnDropChannel" 674 DVLOG(3) << "WebSocketHost::OnDropChannel"
523 << " routing_id=" << routing_id_ << " was_clean=" << was_clean 675 << " routing_id=" << routing_id_ << " was_clean=" << was_clean
524 << " code=" << code << " reason=\"" << reason << "\""; 676 << " code=" << code << " reason=\"" << reason << "\"";
525 677
526 if (!channel_) { 678 if (!channel_) {
527 // WebSocketChannel is not yet created due to the delay introduced by 679 // WebSocketChannel is not yet created due to the delay introduced by
528 // per-renderer WebSocket throttling. 680 // per-renderer WebSocket throttling.
529 WebSocketDispatcherHost::WebSocketHostState result = 681 WebSocketDispatcherHost::WebSocketHostState result =
530 dispatcher_->DoDropChannel(routing_id_, false, 682 dispatcher_->DoDropChannel(routing_id_, false,
531 net::kWebSocketErrorAbnormalClosure, ""); 683 net::kWebSocketErrorAbnormalClosure, "");
532 DCHECK_EQ(WebSocketDispatcherHost::WEBSOCKET_HOST_DELETED, result); 684 DCHECK_EQ(WEBSOCKET_HOST_DELETED, result);
533 return; 685 return;
534 } 686 }
535 687
688 if (pending_drop_channel_)
689 return;
690
536 blob_sender_.reset(); 691 blob_sender_.reset();
537 // TODO(yhirano): Handle |was_clean| appropriately. 692 // TODO(yhirano): Handle |was_clean| appropriately.
538 channel_->StartClosingHandshake(code, reason); 693 channel_->StartClosingHandshake(code, reason);
539 } 694 }
540 695
696 void WebSocketHost::OnBinaryTypeChanged(WebSocketBinaryType new_type) {
697 DVLOG(3) << "WebSocketHost::OnSetBinaryType"
698 << " routing_id= " << routing_id_
699 << " new_type=" << static_cast<int>(new_type);
700
701 binary_type_ = new_type;
702 }
703
704 void WebSocketHost::OnBlobConfirmed() {
705 DVLOG(3) << "WebSocketHost::OnBlobConfirmed"
706 << " routing_id= " << routing_id_;
707
708 if (unconfirmed_blob_queue_.empty()) {
709 ReceivedBadMessage(dispatcher_,
710 bad_message::WSH_UNSOLICITED_BLOB_CONFIRMATION);
711 return;
712 }
713 unconfirmed_blob_queue_.pop();
714 if (pending_drop_channel_ && !ShouldDelayDropChannel()) {
715 DoDelayedDropChannel();
716 // |this| is destroyed here.
717 }
718 }
719
541 void WebSocketHost::BlobSendComplete(int result) { 720 void WebSocketHost::BlobSendComplete(int result) {
542 DVLOG(3) << "WebSocketHost::BlobSendComplete" 721 DVLOG(3) << "WebSocketHost::BlobSendComplete"
543 << " routing_id=" << routing_id_ 722 << " routing_id=" << routing_id_
544 << " result=" << net::ErrorToString(result); 723 << " result=" << net::ErrorToString(result);
545 724
546 // All paths through this method must reset blob_sender_, so take ownership 725 // All paths through this method must reset blob_sender_, so take ownership
547 // at the beginning. 726 // at the beginning.
548 scoped_ptr<WebSocketBlobSender> blob_sender(std::move(blob_sender_)); 727 scoped_ptr<WebSocketBlobSender> blob_sender(std::move(blob_sender_));
549 switch (result) { 728 switch (result) {
550 case net::OK: 729 case net::OK:
(...skipping 17 matching lines...) Expand all
568 747
569 default: 748 default:
570 ignore_result(dispatcher_->NotifyFailure( 749 ignore_result(dispatcher_->NotifyFailure(
571 routing_id_, 750 routing_id_,
572 "Failed to load Blob: error code = " + net::ErrorToString(result))); 751 "Failed to load Blob: error code = " + net::ErrorToString(result)));
573 // |this| is destroyed here. 752 // |this| is destroyed here.
574 return; 753 return;
575 } 754 }
576 } 755 }
577 756
757 bool WebSocketHost::ShouldQueue(size_t data_size) {
758 return (!data_frame_queue_.empty() ||
759 receive_quota_multiplexer_.AvailableQuota() < data_size ||
760 (blob_receiver_ && blob_receiver_->finish_called()));
761 }
762
763 void WebSocketHost::AppendToQueue(bool fin,
764 OpCode type,
765 const std::vector<char>& data) {
766 data_frame_queue_.emplace(fin, type, data);
767 }
768
769 void WebSocketHost::FlushQueueAndPublishQuotaIfAvailable() {
770 while (!data_frame_queue_.empty() &&
771 receive_quota_multiplexer_.AvailableQuota() >=
772 data_frame_queue_.front().data.size()) {
773 const QueuedFrame& front = data_frame_queue_.front();
774 if (blob_receiver_ && blob_receiver_->finish_called())
775 return; // without consuming the message.
776 bool started_blob_receive = false;
777 if (SendFrameInternal(front.fin, front.type, front.data,
778 &started_blob_receive) == CHANNEL_DELETED) {
779 // |this| has been destroyed here.
780 return;
781 }
782 if (started_blob_receive)
783 return; // without consuming the message.
784 data_frame_queue_.pop();
785 }
786 if (data_frame_queue_.empty()) {
787 if (pending_drop_channel_ && !ShouldDelayDropChannel()) {
788 DoDelayedDropChannel();
789 // |this| is destroyed here. No need to publish more quota.
790 return;
791 }
792 receive_quota_multiplexer_.PublishMoreQuotaIfAvailable();
793 // |this| may be destroyed here.
794 }
795 }
796
797 ChannelState WebSocketHost::SendFrameInternal(bool fin,
798 OpCode type,
799 const std::vector<char>& data,
800 bool* started_blob_receive) {
801 receive_quota_multiplexer_.ConsumedQuota(data.size());
802 if (blob_receiver_) {
803 DCHECK_NE(type, WebSocketFrameHeader::kOpCodeText);
804 int rv = blob_receiver_->AppendData(data);
805 if (rv != net::ERR_IO_PENDING && rv < 0) {
806 BlobReceiveFailed(rv);
807 // |this| is destroyed.
808 return CHANNEL_DELETED;
809 }
810 if (fin) {
811 int rv = blob_receiver_->Finish();
812 if (rv != net::ERR_IO_PENDING && rv < 0) {
813 BlobReceiveFailed(rv);
814 // |this| is destroyed.
815 return CHANNEL_DELETED;
816 }
817 }
818 return CHANNEL_ALIVE;
819 }
820
821 if (type == WebSocketFrameHeader::kOpCodeBinary &&
822 binary_type_ == WebSocketBinaryType::BLOB) {
823 StartReceivingBlob(fin, data);
824 *started_blob_receive = true;
825 return CHANNEL_ALIVE;
826 }
827
828 return StateCast(dispatcher_->SendFrame(routing_id_, fin,
829 OpCodeToMessageType(type), data));
830 }
831
832 void WebSocketHost::StartReceivingBlob(bool fin,
833 const std::vector<char>& data) {
834 DCHECK(!blob_receiver_);
835
836 blob_receiver_.reset(
837 new WebSocketBlobReceiver(make_scoped_ptr(new BlobReceiverClient(this)),
838 dispatcher_->blob_storage_context()));
839 receive_quota_multiplexer_.SetConsumer(&blob_receiver_quota_);
840 DCHECK_EQ(receive_quota_multiplexer_.AvailableQuota(), 0u);
841 blob_receiver_->Start();
842 }
843
844 void WebSocketHost::FinishReceivingBlob(
845 scoped_ptr<storage::BlobDataHandle> blob_data_handle,
846 uint64_t size) {
847 const std::string& uuid = blob_data_handle->uuid();
848 unconfirmed_blob_queue_.push(std::move(blob_data_handle));
849 if (dispatcher_->BlobReceived(routing_id_, uuid, size) ==
850 WEBSOCKET_HOST_DELETED) {
851 // |this| has been destroyed.
852 return;
853 }
854 blob_receiver_.reset();
855 receive_quota_multiplexer_.SetConsumer(&renderer_quota_);
856 blob_receiver_quota_ = 0;
857 FlushQueueAndPublishQuotaIfAvailable();
858 // |this| may be destroyed here.
859 }
860
861 void WebSocketHost::BlobReceiveFailed(int net_error_code) {
862 ignore_result(dispatcher_->NotifyFailure(
863 routing_id_,
864 "Blob receive failed: " + net::ErrorToString(net_error_code)));
865 // |this| is destroyed here.
866 }
867
868 bool WebSocketHost::ShouldDelayDropChannel() const {
869 return blob_receiver_ || !data_frame_queue_.empty() ||
870 !unconfirmed_blob_queue_.empty();
871 }
872
873 void WebSocketHost::SetPendingDropChannel(bool was_clean,
874 uint16_t code,
875 const std::string& reason) {
876 DCHECK(!pending_drop_channel_);
877 pending_drop_channel_.reset(
878 new DropChannelParameters(was_clean, code, reason));
879 // Should not send any more messages on the channel.
880 blob_sender_.reset();
881 // Should not supply any more quota to the channel.
882 receive_quota_multiplexer_.SetChannel(nullptr);
883 }
884
885 void WebSocketHost::DoDelayedDropChannel() {
886 DCHECK(!ShouldDelayDropChannel());
887 scoped_ptr<DropChannelParameters> parameters =
888 std::move(pending_drop_channel_);
889 DVLOG(3)
890 << "WebSocketHost::DoDelayedDropChannel() performing delayed DropChannel"
891 << " routing_id=" << routing_id_ << " was_clean=" << parameters->was_clean
892 << " code=" << parameters->code << " reason=\"" << parameters->reason
893 << "\"";
894 ignore_result(dispatcher_->DoDropChannel(routing_id_, parameters->was_clean,
895 parameters->code,
896 parameters->reason));
897 // |this| is destroyed here.
898 }
899
578 } // namespace content 900 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/websocket_host.h ('k') | content/common/websocket.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698