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

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

Issue 1626453003: [OBSOLETE] Browser-side implementation of WebSocket Blob receive. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add WebSocketHost::ReceiveQuotaMultiplexer 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
« no previous file with comments | « content/browser/renderer_host/websocket_host.h ('k') | content/content_browser.gypi » ('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 <utility> 7 #include <utility>
8 8
9 #include "base/location.h" 9 #include "base/location.h"
10 #include "base/macros.h" 10 #include "base/macros.h"
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 146
147 DISALLOW_COPY_AND_ASSIGN(WebSocketEventHandler); 147 DISALLOW_COPY_AND_ASSIGN(WebSocketEventHandler);
148 }; 148 };
149 149
150 WebSocketEventHandler::WebSocketEventHandler( 150 WebSocketEventHandler::WebSocketEventHandler(
151 WebSocketDispatcherHost* dispatcher, 151 WebSocketDispatcherHost* dispatcher,
152 int routing_id, 152 int routing_id,
153 int render_frame_id) 153 int render_frame_id)
154 : dispatcher_(dispatcher), 154 : dispatcher_(dispatcher),
155 routing_id_(routing_id), 155 routing_id_(routing_id),
156 render_frame_id_(render_frame_id) { 156 render_frame_id_(render_frame_id) {}
157 }
158 157
159 WebSocketEventHandler::~WebSocketEventHandler() { 158 WebSocketEventHandler::~WebSocketEventHandler() {
160 DVLOG(1) << "WebSocketEventHandler destroyed routing_id=" << routing_id_; 159 DVLOG(1) << "WebSocketEventHandler destroyed routing_id=" << routing_id_;
161 } 160 }
162 161
163 ChannelState WebSocketEventHandler::OnAddChannelResponse( 162 ChannelState WebSocketEventHandler::OnAddChannelResponse(
164 const std::string& selected_protocol, 163 const std::string& selected_protocol,
165 const std::string& extensions) { 164 const std::string& extensions) {
166 DVLOG(3) << "WebSocketEventHandler::OnAddChannelResponse" 165 DVLOG(3) << "WebSocketEventHandler::OnAddChannelResponse"
167 << " routing_id=" << routing_id_ 166 << " routing_id=" << routing_id_ << " selected_protocol=\""
168 << " selected_protocol=\"" << selected_protocol << "\"" 167 << selected_protocol << "\""
169 << " extensions=\"" << extensions << "\""; 168 << " extensions=\"" << extensions << "\"";
170 169
171 return StateCast(dispatcher_->SendAddChannelResponse( 170 return StateCast(dispatcher_->SendAddChannelResponse(
172 routing_id_, selected_protocol, extensions)); 171 routing_id_, selected_protocol, extensions));
173 } 172 }
174 173
175 ChannelState WebSocketEventHandler::OnDataFrame( 174 ChannelState WebSocketEventHandler::OnDataFrame(
176 bool fin, 175 bool fin,
177 net::WebSocketFrameHeader::OpCode type, 176 net::WebSocketFrameHeader::OpCode type,
178 const std::vector<char>& data) { 177 const std::vector<char>& data) {
179 DVLOG(3) << "WebSocketEventHandler::OnDataFrame" 178 DVLOG(3) << "WebSocketEventHandler::OnDataFrame"
180 << " routing_id=" << routing_id_ << " fin=" << fin 179 << " routing_id=" << routing_id_ << " fin=" << fin
181 << " type=" << type << " data is " << data.size() << " bytes"; 180 << " type=" << type << " data is " << data.size() << " bytes";
182 181
183 return StateCast(dispatcher_->SendFrame( 182 return StateCast(dispatcher_->SendFrame(routing_id_, fin,
184 routing_id_, fin, OpCodeToMessageType(type), data)); 183 OpCodeToMessageType(type), data));
185 } 184 }
186 185
187 ChannelState WebSocketEventHandler::OnClosingHandshake() { 186 ChannelState WebSocketEventHandler::OnClosingHandshake() {
188 DVLOG(3) << "WebSocketEventHandler::OnClosingHandshake" 187 DVLOG(3) << "WebSocketEventHandler::OnClosingHandshake"
189 << " routing_id=" << routing_id_; 188 << " routing_id=" << routing_id_;
190 189
191 return StateCast(dispatcher_->NotifyClosingHandshake(routing_id_)); 190 return StateCast(dispatcher_->NotifyClosingHandshake(routing_id_));
192 } 191 }
193 192
194 ChannelState WebSocketEventHandler::OnFlowControl(int64_t quota) { 193 ChannelState WebSocketEventHandler::OnFlowControl(int64_t quota) {
195 DVLOG(3) << "WebSocketEventHandler::OnFlowControl" 194 DVLOG(3) << "WebSocketEventHandler::OnFlowControl"
196 << " routing_id=" << routing_id_ << " quota=" << quota; 195 << " routing_id=" << routing_id_ << " quota=" << quota;
197 196
198 return StateCast(dispatcher_->SendFlowControl(routing_id_, quota)); 197 return StateCast(dispatcher_->SendFlowControl(routing_id_, quota));
199 } 198 }
200 199
201 ChannelState WebSocketEventHandler::OnDropChannel(bool was_clean, 200 ChannelState WebSocketEventHandler::OnDropChannel(bool was_clean,
202 uint16_t code, 201 uint16_t code,
203 const std::string& reason) { 202 const std::string& reason) {
204 DVLOG(3) << "WebSocketEventHandler::OnDropChannel" 203 DVLOG(3) << "WebSocketEventHandler::OnDropChannel"
205 << " routing_id=" << routing_id_ << " was_clean=" << was_clean 204 << " routing_id=" << routing_id_ << " was_clean=" << was_clean
206 << " code=" << code << " reason=\"" << reason << "\""; 205 << " code=" << code << " reason=\"" << reason << "\"";
207 206
208 return StateCast( 207 return StateCast(
209 dispatcher_->DoDropChannel(routing_id_, was_clean, code, reason)); 208 dispatcher_->DoDropChannel(routing_id_, was_clean, code, reason));
210 } 209 }
211 210
212 ChannelState WebSocketEventHandler::OnFailChannel(const std::string& message) { 211 ChannelState WebSocketEventHandler::OnFailChannel(const std::string& message) {
213 DVLOG(3) << "WebSocketEventHandler::OnFailChannel" 212 DVLOG(3) << "WebSocketEventHandler::OnFailChannel"
214 << " routing_id=" << routing_id_ 213 << " routing_id=" << routing_id_ << " message=\"" << message << "\"";
215 << " message=\"" << message << "\"";
216 214
217 return StateCast(dispatcher_->NotifyFailure(routing_id_, message)); 215 return StateCast(dispatcher_->NotifyFailure(routing_id_, message));
218 } 216 }
219 217
220 ChannelState WebSocketEventHandler::OnStartOpeningHandshake( 218 ChannelState WebSocketEventHandler::OnStartOpeningHandshake(
221 scoped_ptr<net::WebSocketHandshakeRequestInfo> request) { 219 scoped_ptr<net::WebSocketHandshakeRequestInfo> request) {
222 bool should_send = dispatcher_->CanReadRawCookies(); 220 bool should_send = dispatcher_->CanReadRawCookies();
223 DVLOG(3) << "WebSocketEventHandler::OnStartOpeningHandshake " 221 DVLOG(3) << "WebSocketEventHandler::OnStartOpeningHandshake "
224 << "should_send=" << should_send; 222 << "should_send=" << should_send;
225 223
226 if (!should_send) 224 if (!should_send)
227 return WebSocketEventInterface::CHANNEL_ALIVE; 225 return WebSocketEventInterface::CHANNEL_ALIVE;
228 226
229 WebSocketHandshakeRequest request_to_pass; 227 WebSocketHandshakeRequest request_to_pass;
230 request_to_pass.url.Swap(&request->url); 228 request_to_pass.url.Swap(&request->url);
231 net::HttpRequestHeaders::Iterator it(request->headers); 229 net::HttpRequestHeaders::Iterator it(request->headers);
232 while (it.GetNext()) 230 while (it.GetNext())
233 request_to_pass.headers.push_back(std::make_pair(it.name(), it.value())); 231 request_to_pass.headers.push_back(std::make_pair(it.name(), it.value()));
234 request_to_pass.headers_text = 232 request_to_pass.headers_text =
235 base::StringPrintf("GET %s HTTP/1.1\r\n", 233 base::StringPrintf("GET %s HTTP/1.1\r\n",
236 request_to_pass.url.spec().c_str()) + 234 request_to_pass.url.spec().c_str()) +
237 request->headers.ToString(); 235 request->headers.ToString();
238 request_to_pass.request_time = request->request_time; 236 request_to_pass.request_time = request->request_time;
239 237
240 return StateCast(dispatcher_->NotifyStartOpeningHandshake(routing_id_, 238 return StateCast(
241 request_to_pass)); 239 dispatcher_->NotifyStartOpeningHandshake(routing_id_, request_to_pass));
242 } 240 }
243 241
244 ChannelState WebSocketEventHandler::OnFinishOpeningHandshake( 242 ChannelState WebSocketEventHandler::OnFinishOpeningHandshake(
245 scoped_ptr<net::WebSocketHandshakeResponseInfo> response) { 243 scoped_ptr<net::WebSocketHandshakeResponseInfo> response) {
246 bool should_send = dispatcher_->CanReadRawCookies(); 244 bool should_send = dispatcher_->CanReadRawCookies();
247 DVLOG(3) << "WebSocketEventHandler::OnFinishOpeningHandshake " 245 DVLOG(3) << "WebSocketEventHandler::OnFinishOpeningHandshake "
248 << "should_send=" << should_send; 246 << "should_send=" << should_send;
249 247
250 if (!should_send) 248 if (!should_send)
251 return WebSocketEventInterface::CHANNEL_ALIVE; 249 return WebSocketEventInterface::CHANNEL_ALIVE;
252 250
253 WebSocketHandshakeResponse response_to_pass; 251 WebSocketHandshakeResponse response_to_pass;
254 response_to_pass.url.Swap(&response->url); 252 response_to_pass.url.Swap(&response->url);
255 response_to_pass.status_code = response->status_code; 253 response_to_pass.status_code = response->status_code;
256 response_to_pass.status_text.swap(response->status_text); 254 response_to_pass.status_text.swap(response->status_text);
257 void* iter = NULL; 255 void* iter = NULL;
258 std::string name, value; 256 std::string name, value;
259 while (response->headers->EnumerateHeaderLines(&iter, &name, &value)) 257 while (response->headers->EnumerateHeaderLines(&iter, &name, &value))
260 response_to_pass.headers.push_back(std::make_pair(name, value)); 258 response_to_pass.headers.push_back(std::make_pair(name, value));
261 response_to_pass.headers_text = 259 response_to_pass.headers_text =
262 net::HttpUtil::ConvertHeadersBackToHTTPResponse( 260 net::HttpUtil::ConvertHeadersBackToHTTPResponse(
263 response->headers->raw_headers()); 261 response->headers->raw_headers());
264 response_to_pass.response_time = response->response_time; 262 response_to_pass.response_time = response->response_time;
265 263
266 return StateCast(dispatcher_->NotifyFinishOpeningHandshake(routing_id_, 264 return StateCast(
267 response_to_pass)); 265 dispatcher_->NotifyFinishOpeningHandshake(routing_id_, response_to_pass));
268 } 266 }
269 267
270 ChannelState WebSocketEventHandler::OnSSLCertificateError( 268 ChannelState WebSocketEventHandler::OnSSLCertificateError(
271 scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks, 269 scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks,
272 const GURL& url, 270 const GURL& url,
273 const net::SSLInfo& ssl_info, 271 const net::SSLInfo& ssl_info,
274 bool fatal) { 272 bool fatal) {
275 DVLOG(3) << "WebSocketEventHandler::OnSSLCertificateError" 273 DVLOG(3) << "WebSocketEventHandler::OnSSLCertificateError"
276 << " routing_id=" << routing_id_ << " url=" << url.spec() 274 << " routing_id=" << routing_id_ << " url=" << url.spec()
277 << " cert_status=" << ssl_info.cert_status << " fatal=" << fatal; 275 << " cert_status=" << ssl_info.cert_status << " fatal=" << fatal;
278 ssl_error_handler_delegate_.reset( 276 ssl_error_handler_delegate_.reset(
279 new SSLErrorHandlerDelegate(std::move(callbacks))); 277 new SSLErrorHandlerDelegate(std::move(callbacks)));
280 SSLManager::OnSSLCertificateSubresourceError( 278 SSLManager::OnSSLCertificateSubresourceError(
281 ssl_error_handler_delegate_->GetWeakPtr(), url, 279 ssl_error_handler_delegate_->GetWeakPtr(), url,
282 dispatcher_->render_process_id(), render_frame_id_, ssl_info, fatal); 280 dispatcher_->render_process_id(), render_frame_id_, ssl_info, fatal);
283 // The above method is always asynchronous. 281 // The above method is always asynchronous.
284 return WebSocketEventInterface::CHANNEL_ALIVE; 282 return WebSocketEventInterface::CHANNEL_ALIVE;
285 } 283 }
286 284
287 WebSocketEventHandler::SSLErrorHandlerDelegate::SSLErrorHandlerDelegate( 285 WebSocketEventHandler::SSLErrorHandlerDelegate::SSLErrorHandlerDelegate(
288 scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks) 286 scoped_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks)
289 : callbacks_(std::move(callbacks)), weak_ptr_factory_(this) {} 287 : callbacks_(std::move(callbacks)), weak_ptr_factory_(this) {}
290 288
291 WebSocketEventHandler::SSLErrorHandlerDelegate::~SSLErrorHandlerDelegate() {} 289 WebSocketEventHandler::SSLErrorHandlerDelegate::~SSLErrorHandlerDelegate() {}
292 290
293 base::WeakPtr<SSLErrorHandler::Delegate> 291 base::WeakPtr<SSLErrorHandler::Delegate>
294 WebSocketEventHandler::SSLErrorHandlerDelegate::GetWeakPtr() { 292 WebSocketEventHandler::SSLErrorHandlerDelegate::GetWeakPtr() {
(...skipping 10 matching lines...) Expand all
305 callbacks_->CancelSSLRequest(error, ssl_info); 303 callbacks_->CancelSSLRequest(error, ssl_info);
306 } 304 }
307 305
308 void WebSocketEventHandler::SSLErrorHandlerDelegate::ContinueSSLRequest() { 306 void WebSocketEventHandler::SSLErrorHandlerDelegate::ContinueSSLRequest() {
309 DVLOG(3) << "SSLErrorHandlerDelegate::ContinueSSLRequest"; 307 DVLOG(3) << "SSLErrorHandlerDelegate::ContinueSSLRequest";
310 callbacks_->ContinueSSLRequest(); 308 callbacks_->ContinueSSLRequest();
311 } 309 }
312 310
313 } // namespace 311 } // namespace
314 312
313 WebSocketHost::ReceiveQuotaMultiplexer::ReceiveQuotaMultiplexer()
314 : channel_(nullptr), published_quota_(0), current_consumer_(nullptr) {}
315
316 // Quota can be added to any consumer at any time.
317 bool WebSocketHost::ReceiveQuotaMultiplexer::AddQuota(
318 ReceiveQuotaProvider* provider,
319 int64_t quota) {
320 DCHECK(channel_);
321 DCHECK_GE(quota, 0);
322 *provider += quota;
323 if (provider == current_consumer_) {
324 PublishMoreQuotaIfNeeded();
325 return true;
326 }
327 return false;
328 }
329
330 // Quota can only be used from the current consumer.
331 int64_t WebSocketHost::ReceiveQuotaMultiplexer::AvailableQuota() const {
332 DCHECK(current_consumer_);
333 return *current_consumer_;
334 }
335
336 // Quota is only consumed by the current consumer.
337 void WebSocketHost::ReceiveQuotaMultiplexer::ConsumedQuota(int64_t quota) {
338 DCHECK_GE(quota, 0);
339 DCHECK_GE(*current_consumer_, quota);
340 DCHECK_GE(published_quota_, *current_consumer_);
341 *current_consumer_ -= quota;
342 published_quota_ -= quota;
343 }
344
345 // Changing the current consumer may result in more quota being published.
346 void WebSocketHost::ReceiveQuotaMultiplexer::SetConsumer(
347 ReceiveQuotaConsumer* consumer) {
348 DCHECK(channel_);
349 DCHECK(consumer);
350 current_consumer_ = consumer;
351 PublishMoreQuotaIfNeeded();
352 }
353
354 void WebSocketHost::ReceiveQuotaMultiplexer::PublishMoreQuotaIfNeeded() {
355 DCHECK(channel_);
356 DCHECK(current_consumer_);
357 if (*current_consumer_ > published_quota_) {
358 channel_->SendFlowControl(published_quota_ - *current_consumer_);
359 published_quota_ = *current_consumer_;
360 }
361 }
362
315 WebSocketHost::WebSocketHost(int routing_id, 363 WebSocketHost::WebSocketHost(int routing_id,
316 WebSocketDispatcherHost* dispatcher, 364 WebSocketDispatcherHost* dispatcher,
317 net::URLRequestContext* url_request_context, 365 net::URLRequestContext* url_request_context,
318 base::TimeDelta delay) 366 base::TimeDelta delay)
319 : dispatcher_(dispatcher), 367 : dispatcher_(dispatcher),
320 url_request_context_(url_request_context), 368 url_request_context_(url_request_context),
321 routing_id_(routing_id), 369 routing_id_(routing_id),
322 delay_(delay), 370 delay_(delay),
323 pending_flow_control_quota_(0), 371 pending_flow_control_quota_(0),
324 handshake_succeeded_(false), 372 handshake_succeeded_(false),
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 ""); 495 "");
448 DCHECK_EQ(WebSocketDispatcherHost::WEBSOCKET_HOST_DELETED, result); 496 DCHECK_EQ(WebSocketDispatcherHost::WEBSOCKET_HOST_DELETED, result);
449 return; 497 return;
450 } 498 }
451 499
452 // TODO(yhirano): Handle |was_clean| appropriately. 500 // TODO(yhirano): Handle |was_clean| appropriately.
453 channel_->StartClosingHandshake(code, reason); 501 channel_->StartClosingHandshake(code, reason);
454 } 502 }
455 503
456 } // namespace content 504 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/websocket_host.h ('k') | content/content_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698