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

Side by Side Diff: content/browser/renderer_host/websocket_dispatcher_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_dispatcher_host.h" 5 #include "content/browser/renderer_host/websocket_dispatcher_host.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm>
9 #include <string> 10 #include <string>
10 #include <vector> 11 #include <vector>
11 12
12 #include "base/callback.h" 13 #include "base/callback.h"
13 #include "base/logging.h" 14 #include "base/logging.h"
14 #include "base/numerics/safe_conversions.h" 15 #include "base/numerics/safe_conversions.h"
15 #include "base/rand_util.h" 16 #include "base/rand_util.h"
16 #include "base/stl_util.h" 17 #include "base/stl_util.h"
17 #include "content/browser/child_process_security_policy_impl.h" 18 #include "content/browser/child_process_security_policy_impl.h"
19 #include "content/browser/fileapi/chrome_blob_storage_context.h"
18 #include "content/browser/renderer_host/websocket_host.h" 20 #include "content/browser/renderer_host/websocket_host.h"
19 #include "content/common/websocket_messages.h" 21 #include "content/common/websocket_messages.h"
20 22
21 namespace content { 23 namespace content {
22 24
23 namespace { 25 namespace {
24 26
25 // Many methods defined in this file return a WebSocketHostState enum 27 // Many methods defined in this file return a WebSocketHostState enum
26 // value. Make WebSocketHostState visible at file scope so it doesn't have to be 28 // value. Make WebSocketHostState visible at file scope so it doesn't have to be
27 // fully-qualified every time. 29 // fully-qualified every time.
28 typedef WebSocketDispatcherHost::WebSocketHostState WebSocketHostState; 30 typedef WebSocketDispatcherHost::WebSocketHostState WebSocketHostState;
29 31
30 // Max number of pending connections per WebSocketDispatcherHost 32 // Max number of pending connections per WebSocketDispatcherHost
31 // used for per-renderer WebSocket throttling. 33 // used for per-renderer WebSocket throttling.
32 const int kMaxPendingWebSocketConnections = 255; 34 const int kMaxPendingWebSocketConnections = 255;
33 35
34 } // namespace 36 } // namespace
35 37
36 WebSocketDispatcherHost::WebSocketDispatcherHost( 38 WebSocketDispatcherHost::WebSocketDispatcherHost(
37 int process_id, 39 int process_id,
38 const GetRequestContextCallback& get_context_callback) 40 const GetRequestContextCallback& get_context_callback,
41 ChromeBlobStorageContext* blob_storage_context,
42 StoragePartition* storage_partition)
39 : BrowserMessageFilter(WebSocketMsgStart), 43 : BrowserMessageFilter(WebSocketMsgStart),
40 process_id_(process_id), 44 process_id_(process_id),
41 get_context_callback_(get_context_callback), 45 get_context_callback_(get_context_callback),
42 websocket_host_factory_( 46 websocket_host_factory_(
43 base::Bind(&WebSocketDispatcherHost::CreateWebSocketHost, 47 base::Bind(&WebSocketDispatcherHost::CreateWebSocketHost,
44 base::Unretained(this))), 48 base::Unretained(this))),
45 num_pending_connections_(0), 49 num_pending_connections_(0),
46 num_current_succeeded_connections_(0), 50 num_current_succeeded_connections_(0),
47 num_previous_succeeded_connections_(0), 51 num_previous_succeeded_connections_(0),
48 num_current_failed_connections_(0), 52 num_current_failed_connections_(0),
49 num_previous_failed_connections_(0) {} 53 num_previous_failed_connections_(0),
54 blob_storage_context_(blob_storage_context),
55 storage_partition_(storage_partition) {}
50 56
51 WebSocketDispatcherHost::WebSocketDispatcherHost( 57 WebSocketDispatcherHost::WebSocketDispatcherHost(
52 int process_id, 58 int process_id,
53 const GetRequestContextCallback& get_context_callback, 59 const GetRequestContextCallback& get_context_callback,
54 const WebSocketHostFactory& websocket_host_factory) 60 const WebSocketHostFactory& websocket_host_factory)
55 : BrowserMessageFilter(WebSocketMsgStart), 61 : BrowserMessageFilter(WebSocketMsgStart),
56 process_id_(process_id), 62 process_id_(process_id),
57 get_context_callback_(get_context_callback), 63 get_context_callback_(get_context_callback),
58 websocket_host_factory_(websocket_host_factory), 64 websocket_host_factory_(websocket_host_factory),
59 num_pending_connections_(0), 65 num_pending_connections_(0),
60 num_current_succeeded_connections_(0), 66 num_current_succeeded_connections_(0),
61 num_previous_succeeded_connections_(0), 67 num_previous_succeeded_connections_(0),
62 num_current_failed_connections_(0), 68 num_current_failed_connections_(0),
63 num_previous_failed_connections_(0) {} 69 num_previous_failed_connections_(0),
70 storage_partition_(nullptr) {}
64 71
65 WebSocketHost* WebSocketDispatcherHost::CreateWebSocketHost( 72 WebSocketHost* WebSocketDispatcherHost::CreateWebSocketHost(
66 int routing_id, 73 int routing_id,
67 base::TimeDelta delay) { 74 base::TimeDelta delay) {
68 return new WebSocketHost( 75 return new WebSocketHost(
69 routing_id, this, get_context_callback_.Run(), delay); 76 routing_id, this, get_context_callback_.Run(), delay);
70 } 77 }
71 78
72 bool WebSocketDispatcherHost::OnMessageReceived(const IPC::Message& message) { 79 bool WebSocketDispatcherHost::OnMessageReceived(const IPC::Message& message) {
73 switch (message.type()) { 80 switch (message.type()) {
74 case WebSocketHostMsg_AddChannelRequest::ID: 81 case WebSocketHostMsg_AddChannelRequest::ID:
82 case WebSocketHostMsg_SendBlob::ID:
75 case WebSocketMsg_SendFrame::ID: 83 case WebSocketMsg_SendFrame::ID:
76 case WebSocketMsg_FlowControl::ID: 84 case WebSocketMsg_FlowControl::ID:
77 case WebSocketMsg_DropChannel::ID: 85 case WebSocketMsg_DropChannel::ID:
78 break; 86 break;
79 87
80 default: 88 default:
81 // Every message that has not been handled by a previous filter passes 89 // Every message that has not been handled by a previous filter passes
82 // through here, so it is good to pass them on as efficiently as possible. 90 // through here, so it is good to pass them on as efficiently as possible.
83 return false; 91 return false;
84 } 92 }
85 93
86 int routing_id = message.routing_id(); 94 int routing_id = message.routing_id();
87 WebSocketHost* host = GetHost(routing_id); 95 WebSocketHost* host = GetHost(routing_id);
88 if (message.type() == WebSocketHostMsg_AddChannelRequest::ID) { 96 if (message.type() == WebSocketHostMsg_AddChannelRequest::ID) {
89 if (host) { 97 if (host) {
90 DVLOG(1) << "routing_id=" << routing_id << " already in use."; 98 DVLOG(1) << "routing_id=" << routing_id << " already in use.";
91 // The websocket multiplexing spec says to should drop the physical 99 // The websocket multiplexing spec says to should drop the physical
92 // connection in this case, but there isn't a real physical connection 100 // connection in this case, but there isn't a real physical connection
93 // to the renderer, and killing the renderer for this would seem to be a 101 // to the renderer, and killing the renderer for this would seem to be a
94 // little extreme. So for now just ignore the bogus request. 102 // little extreme. So for now just ignore the bogus request.
95 return true; // We handled the message (by ignoring it). 103 return true; // We handled the message (by ignoring it).
96 } 104 }
97 if (num_pending_connections_ >= kMaxPendingWebSocketConnections) { 105 if (num_pending_connections_ >= kMaxPendingWebSocketConnections) {
98 if(!Send(new WebSocketMsg_NotifyFailure(routing_id, 106 if (!Send(new WebSocketMsg_NotifyFailure(
99 "Error in connection establishment: net::ERR_INSUFFICIENT_RESOURCES" 107 routing_id,
100 ))) { 108 "Error in connection establishment: "
109 "net::ERR_INSUFFICIENT_RESOURCES"))) {
101 DVLOG(1) << "Sending of message type " 110 DVLOG(1) << "Sending of message type "
102 << "WebSocketMsg_NotifyFailure failed."; 111 << "WebSocketMsg_NotifyFailure failed.";
103 } 112 }
104 return true; 113 return true;
105 } 114 }
106 host = websocket_host_factory_.Run(routing_id, CalculateDelay()); 115 host = websocket_host_factory_.Run(routing_id, CalculateDelay());
107 hosts_.insert(WebSocketHostTable::value_type(routing_id, host)); 116 hosts_.insert(WebSocketHostTable::value_type(routing_id, host));
108 ++num_pending_connections_; 117 ++num_pending_connections_;
109 if (!throttling_period_timer_.IsRunning()) 118 if (!throttling_period_timer_.IsRunning())
110 throttling_period_timer_.Start( 119 throttling_period_timer_.Start(
111 FROM_HERE, 120 FROM_HERE,
112 base::TimeDelta::FromMinutes(2), 121 base::TimeDelta::FromMinutes(2),
113 this, 122 this,
114 &WebSocketDispatcherHost::ThrottlingPeriodTimerCallback); 123 &WebSocketDispatcherHost::ThrottlingPeriodTimerCallback);
115 } 124 }
116 if (!host) { 125 if (!host) {
117 DVLOG(1) << "Received invalid routing ID " << routing_id 126 DVLOG(1) << "Received invalid routing ID " << routing_id
118 << " from renderer."; 127 << " from renderer.";
119 return true; // We handled the message (by ignoring it). 128 return true; // We handled the message (by ignoring it).
120 } 129 }
121 return host->OnMessageReceived(message); 130 return host->OnMessageReceived(message);
122 } 131 }
123 132
124 bool WebSocketDispatcherHost::CanReadRawCookies() const { 133 bool WebSocketDispatcherHost::CanReadRawCookies() const {
125 ChildProcessSecurityPolicyImpl* policy = 134 ChildProcessSecurityPolicyImpl* policy =
126 ChildProcessSecurityPolicyImpl::GetInstance(); 135 ChildProcessSecurityPolicyImpl::GetInstance();
127 return policy->CanReadRawCookies(process_id_); 136 return policy->CanReadRawCookies(process_id_);
128 } 137 }
129 138
139 storage::BlobStorageContext* WebSocketDispatcherHost::blob_storage_context()
140 const {
141 DCHECK(blob_storage_context_);
142 return blob_storage_context_->context();
143 }
144
130 WebSocketHost* WebSocketDispatcherHost::GetHost(int routing_id) const { 145 WebSocketHost* WebSocketDispatcherHost::GetHost(int routing_id) const {
131 WebSocketHostTable::const_iterator it = hosts_.find(routing_id); 146 WebSocketHostTable::const_iterator it = hosts_.find(routing_id);
132 return it == hosts_.end() ? NULL : it->second; 147 return it == hosts_.end() ? NULL : it->second;
133 } 148 }
134 149
135 WebSocketHostState WebSocketDispatcherHost::SendOrDrop(IPC::Message* message) { 150 WebSocketHostState WebSocketDispatcherHost::SendOrDrop(IPC::Message* message) {
136 const uint32_t message_type = message->type(); 151 const uint32_t message_type = message->type();
137 const int32_t message_routing_id = message->routing_id(); 152 const int32_t message_routing_id = message->routing_id();
138 if (!Send(message)) { 153 if (!Send(message)) {
139 message = NULL; 154 message = NULL;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 int routing_id, 210 int routing_id,
196 const std::string& message) { 211 const std::string& message) {
197 if (SendOrDrop(new WebSocketMsg_NotifyFailure( 212 if (SendOrDrop(new WebSocketMsg_NotifyFailure(
198 routing_id, message)) == WEBSOCKET_HOST_DELETED) { 213 routing_id, message)) == WEBSOCKET_HOST_DELETED) {
199 return WEBSOCKET_HOST_DELETED; 214 return WEBSOCKET_HOST_DELETED;
200 } 215 }
201 DeleteWebSocketHost(routing_id); 216 DeleteWebSocketHost(routing_id);
202 return WEBSOCKET_HOST_DELETED; 217 return WEBSOCKET_HOST_DELETED;
203 } 218 }
204 219
220 WebSocketHostState WebSocketDispatcherHost::BlobSendComplete(int routing_id) {
221 return SendOrDrop(new WebSocketMsg_BlobSendComplete(routing_id));
222 }
223
205 WebSocketHostState WebSocketDispatcherHost::DoDropChannel( 224 WebSocketHostState WebSocketDispatcherHost::DoDropChannel(
206 int routing_id, 225 int routing_id,
207 bool was_clean, 226 bool was_clean,
208 uint16_t code, 227 uint16_t code,
209 const std::string& reason) { 228 const std::string& reason) {
210 if (SendOrDrop( 229 if (SendOrDrop(
211 new WebSocketMsg_DropChannel(routing_id, was_clean, code, reason)) == 230 new WebSocketMsg_DropChannel(routing_id, was_clean, code, reason)) ==
212 WEBSOCKET_HOST_DELETED) 231 WEBSOCKET_HOST_DELETED)
213 return WEBSOCKET_HOST_DELETED; 232 return WEBSOCKET_HOST_DELETED;
214 DeleteWebSocketHost(routing_id); 233 DeleteWebSocketHost(routing_id);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 num_current_succeeded_connections_ = 0; 301 num_current_succeeded_connections_ = 0;
283 302
284 if (num_pending_connections_ == 0 && 303 if (num_pending_connections_ == 0 &&
285 num_previous_failed_connections_ == 0 && 304 num_previous_failed_connections_ == 0 &&
286 num_previous_succeeded_connections_ == 0) { 305 num_previous_succeeded_connections_ == 0) {
287 throttling_period_timer_.Stop(); 306 throttling_period_timer_.Stop();
288 } 307 }
289 } 308 }
290 309
291 } // namespace content 310 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698