Chromium Code Reviews| Index: content/browser/renderer_host/websocket_host.cc |
| diff --git a/content/browser/renderer_host/websocket_host.cc b/content/browser/renderer_host/websocket_host.cc |
| index 84caa8cfb1157d3f0ee3c015e851be977879b449..a8ed959709fcf056c5dfe9365b6091570efef50e 100644 |
| --- a/content/browser/renderer_host/websocket_host.cc |
| +++ b/content/browser/renderer_host/websocket_host.cc |
| @@ -314,10 +314,15 @@ void WebSocketEventHandler::SSLErrorHandlerDelegate::ContinueSSLRequest() { |
| WebSocketHost::WebSocketHost(int routing_id, |
| WebSocketDispatcherHost* dispatcher, |
| - net::URLRequestContext* url_request_context) |
| + net::URLRequestContext* url_request_context, |
| + int delay_in_ms) |
| : dispatcher_(dispatcher), |
| url_request_context_(url_request_context), |
| - routing_id_(routing_id) { |
| + routing_id_(routing_id), |
| + delay_in_ms_(delay_in_ms), |
| + pending_flow_control_quota_(-1), |
| + handshake_succeeded_(false), |
| + weak_ptr_factory_(this) { |
| DVLOG(1) << "WebSocketHost: created routing_id=" << routing_id; |
| } |
| @@ -351,11 +356,43 @@ void WebSocketHost::OnAddChannelRequest( |
| << origin.string() << "\""; |
| DCHECK(!channel_); |
| + if (delay_in_ms_ > 0) { |
| + base::MessageLoop::current()->PostDelayedTask( |
| + FROM_HERE, |
| + base::Bind(&WebSocketHost::AddChannel, |
| + weak_ptr_factory_.GetWeakPtr(), |
| + socket_url, |
| + requested_protocols, |
| + origin, |
| + render_frame_id), |
| + base::TimeDelta::FromMilliseconds(delay_in_ms_)); |
| + } else { |
| + AddChannel(socket_url, requested_protocols, origin, render_frame_id); |
| + } |
| +} |
| + |
| +void WebSocketHost::AddChannel( |
| + const GURL& socket_url, |
| + const std::vector<std::string>& requested_protocols, |
| + const url::Origin& origin, |
| + int render_frame_id) { |
| + DVLOG(3) << "WebSocketHost::AddChannel" |
| + << " routing_id=" << routing_id_ << " socket_url=\"" << socket_url |
| + << "\" requested_protocols=\"" |
| + << JoinString(requested_protocols, ", ") << "\" origin=\"" |
| + << origin.string() << "\""; |
| + |
| + DCHECK(!channel_); |
| + |
| scoped_ptr<net::WebSocketEventInterface> event_interface( |
| new WebSocketEventHandler(dispatcher_, routing_id_, render_frame_id)); |
| channel_.reset( |
| new net::WebSocketChannel(event_interface.Pass(), url_request_context_)); |
| channel_->SendAddChannelRequest(socket_url, requested_protocols, origin); |
| + |
| + if (pending_flow_control_quota_ >= 0) { |
| + channel_->SendFlowControl(pending_flow_control_quota_); |
|
Adam Rice
2015/03/03 15:10:03
I suggest setting pending_flow_control_quota_ to 0
hiroshige
2015/03/04 06:02:38
Done.
|
| + } |
| } |
| void WebSocketHost::OnSendFrame(bool fin, |
| @@ -373,7 +410,14 @@ void WebSocketHost::OnFlowControl(int64 quota) { |
| DVLOG(3) << "WebSocketHost::OnFlowControl" |
| << " routing_id=" << routing_id_ << " quota=" << quota; |
| - DCHECK(channel_); |
| + if (!channel_) { |
| + // WebSocketChannel is not yet created due to the delay introduced by |
| + // Per-renderer WebSocket throttling. |
| + // SendFlowControl() is called after WebSocketChannel is created. |
| + pending_flow_control_quota_ = quota; |
|
Adam Rice
2015/03/03 15:10:02
This should be += because flow control quota is al
hiroshige
2015/03/04 06:02:38
Done.
|
| + return; |
| + } |
| + |
| channel_->SendFlowControl(quota); |
| } |
| @@ -384,7 +428,15 @@ void WebSocketHost::OnDropChannel(bool was_clean, |
| << " routing_id=" << routing_id_ << " was_clean=" << was_clean |
| << " code=" << code << " reason=\"" << reason << "\""; |
| - DCHECK(channel_); |
| + if (!channel_) { |
| + // WebSocketChannel is not yet created due to the delay introduced by |
| + // Per-renderer WebSocket throttling. |
| + WebSocketDispatcherHost::WebSocketHostState result = |
| + dispatcher_->DoDropChannel(routing_id_, was_clean, code, reason); |
|
Adam Rice
2015/03/03 15:10:03
We should not use the values from the renderer in
hiroshige
2015/03/04 06:02:38
Done.
|
| + DCHECK_EQ(WebSocketDispatcherHost::WEBSOCKET_HOST_DELETED, result); |
| + return; |
| + } |
| + |
| // TODO(yhirano): Handle |was_clean| appropriately. |
| channel_->StartClosingHandshake(code, reason); |
| } |