| OLD | NEW |
| 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 "net/websockets/websocket_channel.h" | 5 #include "net/websockets/websocket_channel.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <limits.h> // for INT_MAX | 8 #include <limits.h> // for INT_MAX |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 std::vector<scoped_ptr<WebSocketFrame>> frames_; | 146 std::vector<scoped_ptr<WebSocketFrame>> frames_; |
| 147 | 147 |
| 148 // The total size of the payload data in |frames_|. This will be used to | 148 // The total size of the payload data in |frames_|. This will be used to |
| 149 // measure the throughput of the link. | 149 // measure the throughput of the link. |
| 150 // TODO(ricea): Measure the throughput of the link. | 150 // TODO(ricea): Measure the throughput of the link. |
| 151 uint64_t total_bytes_; | 151 uint64_t total_bytes_; |
| 152 }; | 152 }; |
| 153 | 153 |
| 154 void WebSocketChannel::SendBuffer::AddFrame(scoped_ptr<WebSocketFrame> frame) { | 154 void WebSocketChannel::SendBuffer::AddFrame(scoped_ptr<WebSocketFrame> frame) { |
| 155 total_bytes_ += frame->header.payload_length; | 155 total_bytes_ += frame->header.payload_length; |
| 156 frames_.push_back(frame.Pass()); | 156 frames_.push_back(std::move(frame)); |
| 157 } | 157 } |
| 158 | 158 |
| 159 // Implementation of WebSocketStream::ConnectDelegate that simply forwards the | 159 // Implementation of WebSocketStream::ConnectDelegate that simply forwards the |
| 160 // calls on to the WebSocketChannel that created it. | 160 // calls on to the WebSocketChannel that created it. |
| 161 class WebSocketChannel::ConnectDelegate | 161 class WebSocketChannel::ConnectDelegate |
| 162 : public WebSocketStream::ConnectDelegate { | 162 : public WebSocketStream::ConnectDelegate { |
| 163 public: | 163 public: |
| 164 explicit ConnectDelegate(WebSocketChannel* creator) : creator_(creator) {} | 164 explicit ConnectDelegate(WebSocketChannel* creator) : creator_(creator) {} |
| 165 | 165 |
| 166 void OnSuccess(scoped_ptr<WebSocketStream> stream) override { | 166 void OnSuccess(scoped_ptr<WebSocketStream> stream) override { |
| 167 creator_->OnConnectSuccess(stream.Pass()); | 167 creator_->OnConnectSuccess(std::move(stream)); |
| 168 // |this| may have been deleted. | 168 // |this| may have been deleted. |
| 169 } | 169 } |
| 170 | 170 |
| 171 void OnFailure(const std::string& message) override { | 171 void OnFailure(const std::string& message) override { |
| 172 creator_->OnConnectFailure(message); | 172 creator_->OnConnectFailure(message); |
| 173 // |this| has been deleted. | 173 // |this| has been deleted. |
| 174 } | 174 } |
| 175 | 175 |
| 176 void OnStartOpeningHandshake( | 176 void OnStartOpeningHandshake( |
| 177 scoped_ptr<WebSocketHandshakeRequestInfo> request) override { | 177 scoped_ptr<WebSocketHandshakeRequestInfo> request) override { |
| 178 creator_->OnStartOpeningHandshake(request.Pass()); | 178 creator_->OnStartOpeningHandshake(std::move(request)); |
| 179 } | 179 } |
| 180 | 180 |
| 181 void OnFinishOpeningHandshake( | 181 void OnFinishOpeningHandshake( |
| 182 scoped_ptr<WebSocketHandshakeResponseInfo> response) override { | 182 scoped_ptr<WebSocketHandshakeResponseInfo> response) override { |
| 183 creator_->OnFinishOpeningHandshake(response.Pass()); | 183 creator_->OnFinishOpeningHandshake(std::move(response)); |
| 184 } | 184 } |
| 185 | 185 |
| 186 void OnSSLCertificateError( | 186 void OnSSLCertificateError( |
| 187 scoped_ptr<WebSocketEventInterface::SSLErrorCallbacks> | 187 scoped_ptr<WebSocketEventInterface::SSLErrorCallbacks> |
| 188 ssl_error_callbacks, | 188 ssl_error_callbacks, |
| 189 const SSLInfo& ssl_info, | 189 const SSLInfo& ssl_info, |
| 190 bool fatal) override { | 190 bool fatal) override { |
| 191 creator_->OnSSLCertificateError( | 191 creator_->OnSSLCertificateError(std::move(ssl_error_callbacks), ssl_info, |
| 192 ssl_error_callbacks.Pass(), ssl_info, fatal); | 192 fatal); |
| 193 } | 193 } |
| 194 | 194 |
| 195 private: | 195 private: |
| 196 // A pointer to the WebSocketChannel that created this object. There is no | 196 // A pointer to the WebSocketChannel that created this object. There is no |
| 197 // danger of this pointer being stale, because deleting the WebSocketChannel | 197 // danger of this pointer being stale, because deleting the WebSocketChannel |
| 198 // cancels the connect process, deleting this object and preventing its | 198 // cancels the connect process, deleting this object and preventing its |
| 199 // callbacks from being called. | 199 // callbacks from being called. |
| 200 WebSocketChannel* const creator_; | 200 WebSocketChannel* const creator_; |
| 201 | 201 |
| 202 DISALLOW_COPY_AND_ASSIGN(ConnectDelegate); | 202 DISALLOW_COPY_AND_ASSIGN(ConnectDelegate); |
| 203 }; | 203 }; |
| 204 | 204 |
| 205 class WebSocketChannel::HandshakeNotificationSender | 205 class WebSocketChannel::HandshakeNotificationSender |
| 206 : public base::SupportsWeakPtr<HandshakeNotificationSender> { | 206 : public base::SupportsWeakPtr<HandshakeNotificationSender> { |
| 207 public: | 207 public: |
| 208 explicit HandshakeNotificationSender(WebSocketChannel* channel); | 208 explicit HandshakeNotificationSender(WebSocketChannel* channel); |
| 209 ~HandshakeNotificationSender(); | 209 ~HandshakeNotificationSender(); |
| 210 | 210 |
| 211 static void Send(base::WeakPtr<HandshakeNotificationSender> sender); | 211 static void Send(base::WeakPtr<HandshakeNotificationSender> sender); |
| 212 | 212 |
| 213 ChannelState SendImmediately(WebSocketEventInterface* event_interface); | 213 ChannelState SendImmediately(WebSocketEventInterface* event_interface); |
| 214 | 214 |
| 215 const WebSocketHandshakeRequestInfo* handshake_request_info() const { | 215 const WebSocketHandshakeRequestInfo* handshake_request_info() const { |
| 216 return handshake_request_info_.get(); | 216 return handshake_request_info_.get(); |
| 217 } | 217 } |
| 218 | 218 |
| 219 void set_handshake_request_info( | 219 void set_handshake_request_info( |
| 220 scoped_ptr<WebSocketHandshakeRequestInfo> request_info) { | 220 scoped_ptr<WebSocketHandshakeRequestInfo> request_info) { |
| 221 handshake_request_info_ = request_info.Pass(); | 221 handshake_request_info_ = std::move(request_info); |
| 222 } | 222 } |
| 223 | 223 |
| 224 const WebSocketHandshakeResponseInfo* handshake_response_info() const { | 224 const WebSocketHandshakeResponseInfo* handshake_response_info() const { |
| 225 return handshake_response_info_.get(); | 225 return handshake_response_info_.get(); |
| 226 } | 226 } |
| 227 | 227 |
| 228 void set_handshake_response_info( | 228 void set_handshake_response_info( |
| 229 scoped_ptr<WebSocketHandshakeResponseInfo> response_info) { | 229 scoped_ptr<WebSocketHandshakeResponseInfo> response_info) { |
| 230 handshake_response_info_ = response_info.Pass(); | 230 handshake_response_info_ = std::move(response_info); |
| 231 } | 231 } |
| 232 | 232 |
| 233 private: | 233 private: |
| 234 WebSocketChannel* owner_; | 234 WebSocketChannel* owner_; |
| 235 scoped_ptr<WebSocketHandshakeRequestInfo> handshake_request_info_; | 235 scoped_ptr<WebSocketHandshakeRequestInfo> handshake_request_info_; |
| 236 scoped_ptr<WebSocketHandshakeResponseInfo> handshake_response_info_; | 236 scoped_ptr<WebSocketHandshakeResponseInfo> handshake_response_info_; |
| 237 }; | 237 }; |
| 238 | 238 |
| 239 WebSocketChannel::HandshakeNotificationSender::HandshakeNotificationSender( | 239 WebSocketChannel::HandshakeNotificationSender::HandshakeNotificationSender( |
| 240 WebSocketChannel* channel) | 240 WebSocketChannel* channel) |
| 241 : owner_(channel) {} | 241 : owner_(channel) {} |
| 242 | 242 |
| 243 WebSocketChannel::HandshakeNotificationSender::~HandshakeNotificationSender() {} | 243 WebSocketChannel::HandshakeNotificationSender::~HandshakeNotificationSender() {} |
| 244 | 244 |
| 245 void WebSocketChannel::HandshakeNotificationSender::Send( | 245 void WebSocketChannel::HandshakeNotificationSender::Send( |
| 246 base::WeakPtr<HandshakeNotificationSender> sender) { | 246 base::WeakPtr<HandshakeNotificationSender> sender) { |
| 247 // Do nothing if |sender| is already destructed. | 247 // Do nothing if |sender| is already destructed. |
| 248 if (sender) { | 248 if (sender) { |
| 249 WebSocketChannel* channel = sender->owner_; | 249 WebSocketChannel* channel = sender->owner_; |
| 250 sender->SendImmediately(channel->event_interface_.get()); | 250 sender->SendImmediately(channel->event_interface_.get()); |
| 251 } | 251 } |
| 252 } | 252 } |
| 253 | 253 |
| 254 ChannelState WebSocketChannel::HandshakeNotificationSender::SendImmediately( | 254 ChannelState WebSocketChannel::HandshakeNotificationSender::SendImmediately( |
| 255 WebSocketEventInterface* event_interface) { | 255 WebSocketEventInterface* event_interface) { |
| 256 | 256 |
| 257 if (handshake_request_info_.get()) { | 257 if (handshake_request_info_.get()) { |
| 258 if (CHANNEL_DELETED == event_interface->OnStartOpeningHandshake( | 258 if (CHANNEL_DELETED == |
| 259 handshake_request_info_.Pass())) | 259 event_interface->OnStartOpeningHandshake( |
| 260 std::move(handshake_request_info_))) |
| 260 return CHANNEL_DELETED; | 261 return CHANNEL_DELETED; |
| 261 } | 262 } |
| 262 | 263 |
| 263 if (handshake_response_info_.get()) { | 264 if (handshake_response_info_.get()) { |
| 264 if (CHANNEL_DELETED == event_interface->OnFinishOpeningHandshake( | 265 if (CHANNEL_DELETED == |
| 265 handshake_response_info_.Pass())) | 266 event_interface->OnFinishOpeningHandshake( |
| 267 std::move(handshake_response_info_))) |
| 266 return CHANNEL_DELETED; | 268 return CHANNEL_DELETED; |
| 267 | 269 |
| 268 // TODO(yhirano): We can release |this| to save memory because | 270 // TODO(yhirano): We can release |this| to save memory because |
| 269 // there will be no more opening handshake notification. | 271 // there will be no more opening handshake notification. |
| 270 } | 272 } |
| 271 | 273 |
| 272 return CHANNEL_ALIVE; | 274 return CHANNEL_ALIVE; |
| 273 } | 275 } |
| 274 | 276 |
| 275 WebSocketChannel::PendingReceivedFrame::PendingReceivedFrame( | 277 WebSocketChannel::PendingReceivedFrame::PendingReceivedFrame( |
| (...skipping 17 matching lines...) Expand all Loading... |
| 293 | 295 |
| 294 void WebSocketChannel::PendingReceivedFrame::DidConsume(uint64_t bytes) { | 296 void WebSocketChannel::PendingReceivedFrame::DidConsume(uint64_t bytes) { |
| 295 DCHECK_LE(offset_, size_); | 297 DCHECK_LE(offset_, size_); |
| 296 DCHECK_LE(bytes, size_ - offset_); | 298 DCHECK_LE(bytes, size_ - offset_); |
| 297 offset_ += bytes; | 299 offset_ += bytes; |
| 298 } | 300 } |
| 299 | 301 |
| 300 WebSocketChannel::WebSocketChannel( | 302 WebSocketChannel::WebSocketChannel( |
| 301 scoped_ptr<WebSocketEventInterface> event_interface, | 303 scoped_ptr<WebSocketEventInterface> event_interface, |
| 302 URLRequestContext* url_request_context) | 304 URLRequestContext* url_request_context) |
| 303 : event_interface_(event_interface.Pass()), | 305 : event_interface_(std::move(event_interface)), |
| 304 url_request_context_(url_request_context), | 306 url_request_context_(url_request_context), |
| 305 send_quota_low_water_mark_(kDefaultSendQuotaLowWaterMark), | 307 send_quota_low_water_mark_(kDefaultSendQuotaLowWaterMark), |
| 306 send_quota_high_water_mark_(kDefaultSendQuotaHighWaterMark), | 308 send_quota_high_water_mark_(kDefaultSendQuotaHighWaterMark), |
| 307 current_send_quota_(0), | 309 current_send_quota_(0), |
| 308 current_receive_quota_(0), | 310 current_receive_quota_(0), |
| 309 closing_handshake_timeout_(base::TimeDelta::FromSeconds( | 311 closing_handshake_timeout_( |
| 310 kClosingHandshakeTimeoutSeconds)), | 312 base::TimeDelta::FromSeconds(kClosingHandshakeTimeoutSeconds)), |
| 311 underlying_connection_close_timeout_(base::TimeDelta::FromSeconds( | 313 underlying_connection_close_timeout_(base::TimeDelta::FromSeconds( |
| 312 kUnderlyingConnectionCloseTimeoutSeconds)), | 314 kUnderlyingConnectionCloseTimeoutSeconds)), |
| 313 has_received_close_frame_(false), | 315 has_received_close_frame_(false), |
| 314 received_close_code_(0), | 316 received_close_code_(0), |
| 315 state_(FRESHLY_CONSTRUCTED), | 317 state_(FRESHLY_CONSTRUCTED), |
| 316 notification_sender_(new HandshakeNotificationSender(this)), | 318 notification_sender_(new HandshakeNotificationSender(this)), |
| 317 sending_text_message_(false), | 319 sending_text_message_(false), |
| 318 receiving_text_message_(false), | 320 receiving_text_message_(false), |
| 319 expecting_to_handle_continuation_(false), | 321 expecting_to_handle_continuation_(false), |
| 320 initial_frame_forwarded_(false) {} | 322 initial_frame_forwarded_(false) {} |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 552 if (!socket_url.SchemeIsWSOrWSS()) { | 554 if (!socket_url.SchemeIsWSOrWSS()) { |
| 553 // TODO(ricea): Kill the renderer (this error should have been caught by | 555 // TODO(ricea): Kill the renderer (this error should have been caught by |
| 554 // Javascript). | 556 // Javascript). |
| 555 ignore_result(event_interface_->OnFailChannel("Invalid scheme")); | 557 ignore_result(event_interface_->OnFailChannel("Invalid scheme")); |
| 556 // |this| is deleted here. | 558 // |this| is deleted here. |
| 557 return; | 559 return; |
| 558 } | 560 } |
| 559 socket_url_ = socket_url; | 561 socket_url_ = socket_url; |
| 560 scoped_ptr<WebSocketStream::ConnectDelegate> connect_delegate( | 562 scoped_ptr<WebSocketStream::ConnectDelegate> connect_delegate( |
| 561 new ConnectDelegate(this)); | 563 new ConnectDelegate(this)); |
| 562 stream_request_ = creator.Run(socket_url_, | 564 stream_request_ = creator.Run(socket_url_, requested_subprotocols, origin, |
| 563 requested_subprotocols, | 565 url_request_context_, BoundNetLog(), |
| 564 origin, | 566 std::move(connect_delegate)); |
| 565 url_request_context_, | |
| 566 BoundNetLog(), | |
| 567 connect_delegate.Pass()); | |
| 568 SetState(CONNECTING); | 567 SetState(CONNECTING); |
| 569 } | 568 } |
| 570 | 569 |
| 571 void WebSocketChannel::OnConnectSuccess(scoped_ptr<WebSocketStream> stream) { | 570 void WebSocketChannel::OnConnectSuccess(scoped_ptr<WebSocketStream> stream) { |
| 572 DCHECK(stream); | 571 DCHECK(stream); |
| 573 DCHECK_EQ(CONNECTING, state_); | 572 DCHECK_EQ(CONNECTING, state_); |
| 574 | 573 |
| 575 stream_ = stream.Pass(); | 574 stream_ = std::move(stream); |
| 576 | 575 |
| 577 SetState(CONNECTED); | 576 SetState(CONNECTED); |
| 578 | 577 |
| 579 if (event_interface_->OnAddChannelResponse(stream_->GetSubProtocol(), | 578 if (event_interface_->OnAddChannelResponse(stream_->GetSubProtocol(), |
| 580 stream_->GetExtensions()) == | 579 stream_->GetExtensions()) == |
| 581 CHANNEL_DELETED) | 580 CHANNEL_DELETED) |
| 582 return; | 581 return; |
| 583 | 582 |
| 584 // TODO(ricea): Get flow control information from the WebSocketStream once we | 583 // TODO(ricea): Get flow control information from the WebSocketStream once we |
| 585 // have a multiplexing WebSocketStream. | 584 // have a multiplexing WebSocketStream. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 612 ChannelState result = event_interface_->OnFailChannel(message_copy); | 611 ChannelState result = event_interface_->OnFailChannel(message_copy); |
| 613 DCHECK_EQ(CHANNEL_DELETED, result); | 612 DCHECK_EQ(CHANNEL_DELETED, result); |
| 614 // |this| has been deleted. | 613 // |this| has been deleted. |
| 615 } | 614 } |
| 616 | 615 |
| 617 void WebSocketChannel::OnSSLCertificateError( | 616 void WebSocketChannel::OnSSLCertificateError( |
| 618 scoped_ptr<WebSocketEventInterface::SSLErrorCallbacks> ssl_error_callbacks, | 617 scoped_ptr<WebSocketEventInterface::SSLErrorCallbacks> ssl_error_callbacks, |
| 619 const SSLInfo& ssl_info, | 618 const SSLInfo& ssl_info, |
| 620 bool fatal) { | 619 bool fatal) { |
| 621 ignore_result(event_interface_->OnSSLCertificateError( | 620 ignore_result(event_interface_->OnSSLCertificateError( |
| 622 ssl_error_callbacks.Pass(), socket_url_, ssl_info, fatal)); | 621 std::move(ssl_error_callbacks), socket_url_, ssl_info, fatal)); |
| 623 } | 622 } |
| 624 | 623 |
| 625 void WebSocketChannel::OnStartOpeningHandshake( | 624 void WebSocketChannel::OnStartOpeningHandshake( |
| 626 scoped_ptr<WebSocketHandshakeRequestInfo> request) { | 625 scoped_ptr<WebSocketHandshakeRequestInfo> request) { |
| 627 DCHECK(!notification_sender_->handshake_request_info()); | 626 DCHECK(!notification_sender_->handshake_request_info()); |
| 628 | 627 |
| 629 // Because it is hard to handle an IPC error synchronously is difficult, | 628 // Because it is hard to handle an IPC error synchronously is difficult, |
| 630 // we asynchronously notify the information. | 629 // we asynchronously notify the information. |
| 631 notification_sender_->set_handshake_request_info(request.Pass()); | 630 notification_sender_->set_handshake_request_info(std::move(request)); |
| 632 ScheduleOpeningHandshakeNotification(); | 631 ScheduleOpeningHandshakeNotification(); |
| 633 } | 632 } |
| 634 | 633 |
| 635 void WebSocketChannel::OnFinishOpeningHandshake( | 634 void WebSocketChannel::OnFinishOpeningHandshake( |
| 636 scoped_ptr<WebSocketHandshakeResponseInfo> response) { | 635 scoped_ptr<WebSocketHandshakeResponseInfo> response) { |
| 637 DCHECK(!notification_sender_->handshake_response_info()); | 636 DCHECK(!notification_sender_->handshake_response_info()); |
| 638 | 637 |
| 639 // Because it is hard to handle an IPC error synchronously is difficult, | 638 // Because it is hard to handle an IPC error synchronously is difficult, |
| 640 // we asynchronously notify the information. | 639 // we asynchronously notify the information. |
| 641 notification_sender_->set_handshake_response_info(response.Pass()); | 640 notification_sender_->set_handshake_response_info(std::move(response)); |
| 642 ScheduleOpeningHandshakeNotification(); | 641 ScheduleOpeningHandshakeNotification(); |
| 643 } | 642 } |
| 644 | 643 |
| 645 void WebSocketChannel::ScheduleOpeningHandshakeNotification() { | 644 void WebSocketChannel::ScheduleOpeningHandshakeNotification() { |
| 646 base::ThreadTaskRunnerHandle::Get()->PostTask( | 645 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 647 FROM_HERE, base::Bind(HandshakeNotificationSender::Send, | 646 FROM_HERE, base::Bind(HandshakeNotificationSender::Send, |
| 648 notification_sender_->AsWeakPtr())); | 647 notification_sender_->AsWeakPtr())); |
| 649 } | 648 } |
| 650 | 649 |
| 651 ChannelState WebSocketChannel::WriteFrames() { | 650 ChannelState WebSocketChannel::WriteFrames() { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 669 } | 668 } |
| 670 | 669 |
| 671 ChannelState WebSocketChannel::OnWriteDone(bool synchronous, int result) { | 670 ChannelState WebSocketChannel::OnWriteDone(bool synchronous, int result) { |
| 672 DCHECK_NE(FRESHLY_CONSTRUCTED, state_); | 671 DCHECK_NE(FRESHLY_CONSTRUCTED, state_); |
| 673 DCHECK_NE(CONNECTING, state_); | 672 DCHECK_NE(CONNECTING, state_); |
| 674 DCHECK_NE(ERR_IO_PENDING, result); | 673 DCHECK_NE(ERR_IO_PENDING, result); |
| 675 DCHECK(data_being_sent_); | 674 DCHECK(data_being_sent_); |
| 676 switch (result) { | 675 switch (result) { |
| 677 case OK: | 676 case OK: |
| 678 if (data_to_send_next_) { | 677 if (data_to_send_next_) { |
| 679 data_being_sent_ = data_to_send_next_.Pass(); | 678 data_being_sent_ = std::move(data_to_send_next_); |
| 680 if (!synchronous) | 679 if (!synchronous) |
| 681 return WriteFrames(); | 680 return WriteFrames(); |
| 682 } else { | 681 } else { |
| 683 data_being_sent_.reset(); | 682 data_being_sent_.reset(); |
| 684 if (current_send_quota_ < send_quota_low_water_mark_) { | 683 if (current_send_quota_ < send_quota_low_water_mark_) { |
| 685 // TODO(ricea): Increase low_water_mark and high_water_mark if | 684 // TODO(ricea): Increase low_water_mark and high_water_mark if |
| 686 // throughput is high, reduce them if throughput is low. Low water | 685 // throughput is high, reduce them if throughput is low. Low water |
| 687 // mark needs to be >= the bandwidth delay product *of the IPC | 686 // mark needs to be >= the bandwidth delay product *of the IPC |
| 688 // channel*. Because factors like context-switch time, thread wake-up | 687 // channel*. Because factors like context-switch time, thread wake-up |
| 689 // time, and bus speed come into play it is complex and probably needs | 688 // time, and bus speed come into play it is complex and probably needs |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1011 header.payload_length = size; | 1010 header.payload_length = size; |
| 1012 frame->data = buffer; | 1011 frame->data = buffer; |
| 1013 | 1012 |
| 1014 if (data_being_sent_) { | 1013 if (data_being_sent_) { |
| 1015 // Either the link to the WebSocket server is saturated, or several messages | 1014 // Either the link to the WebSocket server is saturated, or several messages |
| 1016 // are being sent in a batch. | 1015 // are being sent in a batch. |
| 1017 // TODO(ricea): Keep some statistics to work out the situation and adjust | 1016 // TODO(ricea): Keep some statistics to work out the situation and adjust |
| 1018 // quota appropriately. | 1017 // quota appropriately. |
| 1019 if (!data_to_send_next_) | 1018 if (!data_to_send_next_) |
| 1020 data_to_send_next_.reset(new SendBuffer); | 1019 data_to_send_next_.reset(new SendBuffer); |
| 1021 data_to_send_next_->AddFrame(frame.Pass()); | 1020 data_to_send_next_->AddFrame(std::move(frame)); |
| 1022 return CHANNEL_ALIVE; | 1021 return CHANNEL_ALIVE; |
| 1023 } | 1022 } |
| 1024 | 1023 |
| 1025 data_being_sent_.reset(new SendBuffer); | 1024 data_being_sent_.reset(new SendBuffer); |
| 1026 data_being_sent_->AddFrame(frame.Pass()); | 1025 data_being_sent_->AddFrame(std::move(frame)); |
| 1027 return WriteFrames(); | 1026 return WriteFrames(); |
| 1028 } | 1027 } |
| 1029 | 1028 |
| 1030 ChannelState WebSocketChannel::FailChannel(const std::string& message, | 1029 ChannelState WebSocketChannel::FailChannel(const std::string& message, |
| 1031 uint16_t code, | 1030 uint16_t code, |
| 1032 const std::string& reason) { | 1031 const std::string& reason) { |
| 1033 DCHECK_NE(FRESHLY_CONSTRUCTED, state_); | 1032 DCHECK_NE(FRESHLY_CONSTRUCTED, state_); |
| 1034 DCHECK_NE(CONNECTING, state_); | 1033 DCHECK_NE(CONNECTING, state_); |
| 1035 DCHECK_NE(CLOSED, state_); | 1034 DCHECK_NE(CLOSED, state_); |
| 1036 | 1035 |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1144 } | 1143 } |
| 1145 | 1144 |
| 1146 void WebSocketChannel::CloseTimeout() { | 1145 void WebSocketChannel::CloseTimeout() { |
| 1147 stream_->Close(); | 1146 stream_->Close(); |
| 1148 SetState(CLOSED); | 1147 SetState(CLOSED); |
| 1149 DoDropChannel(false, kWebSocketErrorAbnormalClosure, ""); | 1148 DoDropChannel(false, kWebSocketErrorAbnormalClosure, ""); |
| 1150 // |this| has been deleted. | 1149 // |this| has been deleted. |
| 1151 } | 1150 } |
| 1152 | 1151 |
| 1153 } // namespace net | 1152 } // namespace net |
| OLD | NEW |