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

Unified Diff: net/websockets/websocket_job.cc

Issue 723343002: Update from https://crrev.com/304121 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 6 years, 1 month 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/websockets/websocket_job.h ('k') | net/websockets/websocket_job_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/websockets/websocket_job.cc
diff --git a/net/websockets/websocket_job.cc b/net/websockets/websocket_job.cc
deleted file mode 100644
index eb653fa5a97619d7c40d06cdb640a1a34a7f70fb..0000000000000000000000000000000000000000
--- a/net/websockets/websocket_job.cc
+++ /dev/null
@@ -1,693 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/websockets/websocket_job.h"
-
-#include <algorithm>
-
-#include "base/bind.h"
-#include "base/lazy_instance.h"
-#include "net/base/io_buffer.h"
-#include "net/base/net_errors.h"
-#include "net/base/net_log.h"
-#include "net/cookies/cookie_store.h"
-#include "net/http/http_network_session.h"
-#include "net/http/http_transaction_factory.h"
-#include "net/http/http_util.h"
-#include "net/spdy/spdy_session.h"
-#include "net/spdy/spdy_session_pool.h"
-#include "net/url_request/url_request_context.h"
-#include "net/websockets/websocket_handshake_handler.h"
-#include "net/websockets/websocket_net_log_params.h"
-#include "net/websockets/websocket_throttle.h"
-#include "url/gurl.h"
-
-static const int kMaxPendingSendAllowed = 32768; // 32 kilobytes.
-
-namespace {
-
-// lower-case header names.
-const char* const kCookieHeaders[] = {
- "cookie", "cookie2"
-};
-const char* const kSetCookieHeaders[] = {
- "set-cookie", "set-cookie2"
-};
-
-net::SocketStreamJob* WebSocketJobFactory(
- const GURL& url, net::SocketStream::Delegate* delegate,
- net::URLRequestContext* context, net::CookieStore* cookie_store) {
- net::WebSocketJob* job = new net::WebSocketJob(delegate);
- job->InitSocketStream(new net::SocketStream(url, job, context, cookie_store));
- return job;
-}
-
-class WebSocketJobInitSingleton {
- private:
- friend struct base::DefaultLazyInstanceTraits<WebSocketJobInitSingleton>;
- WebSocketJobInitSingleton() {
- net::SocketStreamJob::RegisterProtocolFactory("ws", WebSocketJobFactory);
- net::SocketStreamJob::RegisterProtocolFactory("wss", WebSocketJobFactory);
- }
-};
-
-static base::LazyInstance<WebSocketJobInitSingleton> g_websocket_job_init =
- LAZY_INSTANCE_INITIALIZER;
-
-} // anonymous namespace
-
-namespace net {
-
-// static
-void WebSocketJob::EnsureInit() {
- g_websocket_job_init.Get();
-}
-
-WebSocketJob::WebSocketJob(SocketStream::Delegate* delegate)
- : delegate_(delegate),
- state_(INITIALIZED),
- waiting_(false),
- handshake_request_(new WebSocketHandshakeRequestHandler),
- handshake_response_(new WebSocketHandshakeResponseHandler),
- started_to_send_handshake_request_(false),
- handshake_request_sent_(0),
- response_cookies_save_index_(0),
- spdy_protocol_version_(0),
- save_next_cookie_running_(false),
- callback_pending_(false),
- weak_ptr_factory_(this),
- weak_ptr_factory_for_send_pending_(this) {
-}
-
-WebSocketJob::~WebSocketJob() {
- DCHECK_EQ(CLOSED, state_);
- DCHECK(!delegate_);
- DCHECK(!socket_.get());
-}
-
-void WebSocketJob::Connect() {
- DCHECK(socket_.get());
- DCHECK_EQ(state_, INITIALIZED);
- state_ = CONNECTING;
- socket_->Connect();
-}
-
-bool WebSocketJob::SendData(const char* data, int len) {
- switch (state_) {
- case INITIALIZED:
- return false;
-
- case CONNECTING:
- return SendHandshakeRequest(data, len);
-
- case OPEN:
- {
- scoped_refptr<IOBufferWithSize> buffer = new IOBufferWithSize(len);
- memcpy(buffer->data(), data, len);
- if (current_send_buffer_.get() || !send_buffer_queue_.empty()) {
- send_buffer_queue_.push_back(buffer);
- return true;
- }
- current_send_buffer_ = new DrainableIOBuffer(buffer.get(), len);
- return SendDataInternal(current_send_buffer_->data(),
- current_send_buffer_->BytesRemaining());
- }
-
- case CLOSING:
- case CLOSED:
- return false;
- }
- return false;
-}
-
-void WebSocketJob::Close() {
- if (state_ == CLOSED)
- return;
-
- state_ = CLOSING;
- if (current_send_buffer_.get()) {
- // Will close in SendPending.
- return;
- }
- state_ = CLOSED;
- CloseInternal();
-}
-
-void WebSocketJob::RestartWithAuth(const AuthCredentials& credentials) {
- state_ = CONNECTING;
- socket_->RestartWithAuth(credentials);
-}
-
-void WebSocketJob::DetachDelegate() {
- state_ = CLOSED;
- WebSocketThrottle::GetInstance()->RemoveFromQueue(this);
-
- scoped_refptr<WebSocketJob> protect(this);
- weak_ptr_factory_.InvalidateWeakPtrs();
- weak_ptr_factory_for_send_pending_.InvalidateWeakPtrs();
-
- delegate_ = NULL;
- if (socket_.get())
- socket_->DetachDelegate();
- socket_ = NULL;
- if (!callback_.is_null()) {
- waiting_ = false;
- callback_.Reset();
- Release(); // Balanced with OnStartOpenConnection().
- }
-}
-
-int WebSocketJob::OnStartOpenConnection(
- SocketStream* socket, const CompletionCallback& callback) {
- DCHECK(callback_.is_null());
- state_ = CONNECTING;
-
- addresses_ = socket->address_list();
- if (!WebSocketThrottle::GetInstance()->PutInQueue(this)) {
- return ERR_WS_THROTTLE_QUEUE_TOO_LARGE;
- }
-
- if (delegate_) {
- int result = delegate_->OnStartOpenConnection(socket, callback);
- DCHECK_EQ(OK, result);
- }
- if (waiting_) {
- // PutInQueue() may set |waiting_| true for throttling. In this case,
- // Wakeup() will be called later.
- callback_ = callback;
- AddRef(); // Balanced when callback_ is cleared.
- return ERR_IO_PENDING;
- }
- return TrySpdyStream();
-}
-
-void WebSocketJob::OnConnected(
- SocketStream* socket, int max_pending_send_allowed) {
- if (state_ == CLOSED)
- return;
- DCHECK_EQ(CONNECTING, state_);
- if (delegate_)
- delegate_->OnConnected(socket, max_pending_send_allowed);
-}
-
-void WebSocketJob::OnSentData(SocketStream* socket, int amount_sent) {
- DCHECK_NE(INITIALIZED, state_);
- DCHECK_GT(amount_sent, 0);
- if (state_ == CLOSED)
- return;
- if (state_ == CONNECTING) {
- OnSentHandshakeRequest(socket, amount_sent);
- return;
- }
- if (delegate_) {
- DCHECK(state_ == OPEN || state_ == CLOSING);
- if (!current_send_buffer_.get()) {
- VLOG(1)
- << "OnSentData current_send_buffer=NULL amount_sent=" << amount_sent;
- return;
- }
- current_send_buffer_->DidConsume(amount_sent);
- if (current_send_buffer_->BytesRemaining() > 0)
- return;
-
- // We need to report amount_sent of original buffer size, instead of
- // amount sent to |socket|.
- amount_sent = current_send_buffer_->size();
- DCHECK_GT(amount_sent, 0);
- current_send_buffer_ = NULL;
- if (!weak_ptr_factory_for_send_pending_.HasWeakPtrs()) {
- base::MessageLoopForIO::current()->PostTask(
- FROM_HERE,
- base::Bind(&WebSocketJob::SendPending,
- weak_ptr_factory_for_send_pending_.GetWeakPtr()));
- }
- delegate_->OnSentData(socket, amount_sent);
- }
-}
-
-void WebSocketJob::OnReceivedData(
- SocketStream* socket, const char* data, int len) {
- DCHECK_NE(INITIALIZED, state_);
- if (state_ == CLOSED)
- return;
- if (state_ == CONNECTING) {
- OnReceivedHandshakeResponse(socket, data, len);
- return;
- }
- DCHECK(state_ == OPEN || state_ == CLOSING);
- if (delegate_ && len > 0)
- delegate_->OnReceivedData(socket, data, len);
-}
-
-void WebSocketJob::OnClose(SocketStream* socket) {
- state_ = CLOSED;
- WebSocketThrottle::GetInstance()->RemoveFromQueue(this);
-
- scoped_refptr<WebSocketJob> protect(this);
- weak_ptr_factory_.InvalidateWeakPtrs();
-
- SocketStream::Delegate* delegate = delegate_;
- delegate_ = NULL;
- socket_ = NULL;
- if (!callback_.is_null()) {
- waiting_ = false;
- callback_.Reset();
- Release(); // Balanced with OnStartOpenConnection().
- }
- if (delegate)
- delegate->OnClose(socket);
-}
-
-void WebSocketJob::OnAuthRequired(
- SocketStream* socket, AuthChallengeInfo* auth_info) {
- if (delegate_)
- delegate_->OnAuthRequired(socket, auth_info);
-}
-
-void WebSocketJob::OnSSLCertificateError(
- SocketStream* socket, const SSLInfo& ssl_info, bool fatal) {
- if (delegate_)
- delegate_->OnSSLCertificateError(socket, ssl_info, fatal);
-}
-
-void WebSocketJob::OnError(const SocketStream* socket, int error) {
- if (delegate_ && error != ERR_PROTOCOL_SWITCHED)
- delegate_->OnError(socket, error);
-}
-
-void WebSocketJob::OnCreatedSpdyStream(int result) {
- DCHECK(spdy_websocket_stream_.get());
- DCHECK(socket_.get());
- DCHECK_NE(ERR_IO_PENDING, result);
-
- if (state_ == CLOSED) {
- result = ERR_ABORTED;
- } else if (result == OK) {
- state_ = CONNECTING;
- result = ERR_PROTOCOL_SWITCHED;
- } else {
- spdy_websocket_stream_.reset();
- }
-
- CompleteIO(result);
-}
-
-void WebSocketJob::OnSentSpdyHeaders() {
- DCHECK_NE(INITIALIZED, state_);
- if (state_ != CONNECTING)
- return;
- size_t original_length = handshake_request_->original_length();
- handshake_request_.reset();
- if (delegate_)
- delegate_->OnSentData(socket_.get(), original_length);
-}
-
-void WebSocketJob::OnSpdyResponseHeadersUpdated(
- const SpdyHeaderBlock& response_headers) {
- DCHECK_NE(INITIALIZED, state_);
- if (state_ != CONNECTING)
- return;
- // TODO(toyoshim): Fallback to non-spdy connection?
- handshake_response_->ParseResponseHeaderBlock(response_headers,
- challenge_,
- spdy_protocol_version_);
-
- SaveCookiesAndNotifyHeadersComplete();
-}
-
-void WebSocketJob::OnSentSpdyData(size_t bytes_sent) {
- DCHECK_NE(INITIALIZED, state_);
- DCHECK_NE(CONNECTING, state_);
- if (state_ == CLOSED)
- return;
- if (!spdy_websocket_stream_.get())
- return;
- OnSentData(socket_.get(), static_cast<int>(bytes_sent));
-}
-
-void WebSocketJob::OnReceivedSpdyData(scoped_ptr<SpdyBuffer> buffer) {
- DCHECK_NE(INITIALIZED, state_);
- DCHECK_NE(CONNECTING, state_);
- if (state_ == CLOSED)
- return;
- if (!spdy_websocket_stream_.get())
- return;
- if (buffer) {
- OnReceivedData(
- socket_.get(), buffer->GetRemainingData(), buffer->GetRemainingSize());
- } else {
- OnReceivedData(socket_.get(), NULL, 0);
- }
-}
-
-void WebSocketJob::OnCloseSpdyStream() {
- spdy_websocket_stream_.reset();
- OnClose(socket_.get());
-}
-
-bool WebSocketJob::SendHandshakeRequest(const char* data, int len) {
- DCHECK_EQ(state_, CONNECTING);
- if (started_to_send_handshake_request_)
- return false;
- if (!handshake_request_->ParseRequest(data, len))
- return false;
-
- AddCookieHeaderAndSend();
- return true;
-}
-
-void WebSocketJob::AddCookieHeaderAndSend() {
- bool allow = true;
- if (delegate_ && !delegate_->CanGetCookies(socket_.get(), GetURLForCookies()))
- allow = false;
-
- if (socket_.get() && delegate_ && state_ == CONNECTING) {
- handshake_request_->RemoveHeaders(kCookieHeaders,
- arraysize(kCookieHeaders));
- if (allow && socket_->cookie_store()) {
- // Add cookies, including HttpOnly cookies.
- CookieOptions cookie_options;
- cookie_options.set_include_httponly();
- socket_->cookie_store()->GetCookiesWithOptionsAsync(
- GetURLForCookies(), cookie_options,
- base::Bind(&WebSocketJob::LoadCookieCallback,
- weak_ptr_factory_.GetWeakPtr()));
- } else {
- DoSendData();
- }
- }
-}
-
-void WebSocketJob::LoadCookieCallback(const std::string& cookie) {
- if (!cookie.empty())
- // TODO(tyoshino): Sending cookie means that connection doesn't need
- // PRIVACY_MODE_ENABLED as cookies may be server-bound and channel id
- // wouldn't negatively affect privacy anyway. Need to restart connection
- // or refactor to determine cookie status prior to connecting.
- handshake_request_->AppendHeaderIfMissing("Cookie", cookie);
- DoSendData();
-}
-
-void WebSocketJob::DoSendData() {
- if (spdy_websocket_stream_.get()) {
- scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock);
- handshake_request_->GetRequestHeaderBlock(
- socket_->url(), headers.get(), &challenge_, spdy_protocol_version_);
- spdy_websocket_stream_->SendRequest(headers.Pass());
- } else {
- const std::string& handshake_request =
- handshake_request_->GetRawRequest();
- handshake_request_sent_ = 0;
- socket_->net_log()->AddEvent(
- NetLog::TYPE_WEB_SOCKET_SEND_REQUEST_HEADERS,
- base::Bind(&NetLogWebSocketHandshakeCallback, &handshake_request));
- socket_->SendData(handshake_request.data(),
- handshake_request.size());
- }
- // Just buffered in |handshake_request_|.
- started_to_send_handshake_request_ = true;
-}
-
-void WebSocketJob::OnSentHandshakeRequest(
- SocketStream* socket, int amount_sent) {
- DCHECK_EQ(state_, CONNECTING);
- handshake_request_sent_ += amount_sent;
- DCHECK_LE(handshake_request_sent_, handshake_request_->raw_length());
- if (handshake_request_sent_ >= handshake_request_->raw_length()) {
- // handshake request has been sent.
- // notify original size of handshake request to delegate.
- // Reset the handshake_request_ first in case this object is deleted by the
- // delegate.
- size_t original_length = handshake_request_->original_length();
- handshake_request_.reset();
- if (delegate_)
- delegate_->OnSentData(socket, original_length);
- }
-}
-
-void WebSocketJob::OnReceivedHandshakeResponse(
- SocketStream* socket, const char* data, int len) {
- DCHECK_EQ(state_, CONNECTING);
- if (handshake_response_->HasResponse()) {
- // If we already has handshake response, received data should be frame
- // data, not handshake message.
- received_data_after_handshake_.insert(
- received_data_after_handshake_.end(), data, data + len);
- return;
- }
-
- size_t response_length = handshake_response_->ParseRawResponse(data, len);
- if (!handshake_response_->HasResponse()) {
- // not yet. we need more data.
- return;
- }
- // handshake message is completed.
- std::string raw_response = handshake_response_->GetRawResponse();
- socket_->net_log()->AddEvent(
- NetLog::TYPE_WEB_SOCKET_READ_RESPONSE_HEADERS,
- base::Bind(&NetLogWebSocketHandshakeCallback, &raw_response));
- if (len - response_length > 0) {
- // If we received extra data, it should be frame data.
- DCHECK(received_data_after_handshake_.empty());
- received_data_after_handshake_.assign(data + response_length, data + len);
- }
- SaveCookiesAndNotifyHeadersComplete();
-}
-
-void WebSocketJob::SaveCookiesAndNotifyHeadersComplete() {
- // handshake message is completed.
- DCHECK(handshake_response_->HasResponse());
-
- // Extract cookies from the handshake response into a temporary vector.
- response_cookies_.clear();
- response_cookies_save_index_ = 0;
-
- handshake_response_->GetHeaders(
- kSetCookieHeaders, arraysize(kSetCookieHeaders), &response_cookies_);
-
- // Now, loop over the response cookies, and attempt to persist each.
- SaveNextCookie();
-}
-
-void WebSocketJob::NotifyHeadersComplete() {
- // Remove cookie headers, with malformed headers preserved.
- // Actual handshake should be done in Blink.
- handshake_response_->RemoveHeaders(
- kSetCookieHeaders, arraysize(kSetCookieHeaders));
- std::string handshake_response = handshake_response_->GetResponse();
- handshake_response_.reset();
- std::vector<char> received_data(handshake_response.begin(),
- handshake_response.end());
- received_data.insert(received_data.end(),
- received_data_after_handshake_.begin(),
- received_data_after_handshake_.end());
- received_data_after_handshake_.clear();
-
- state_ = OPEN;
-
- DCHECK(!received_data.empty());
- if (delegate_)
- delegate_->OnReceivedData(
- socket_.get(), &received_data.front(), received_data.size());
-
- WebSocketThrottle::GetInstance()->RemoveFromQueue(this);
-}
-
-void WebSocketJob::SaveNextCookie() {
- if (!socket_.get() || !delegate_ || state_ != CONNECTING)
- return;
-
- callback_pending_ = false;
- save_next_cookie_running_ = true;
-
- if (socket_->cookie_store()) {
- GURL url_for_cookies = GetURLForCookies();
-
- CookieOptions options;
- options.set_include_httponly();
-
- // Loop as long as SetCookieWithOptionsAsync completes synchronously. Since
- // CookieMonster's asynchronous operation APIs queue the callback to run it
- // on the thread where the API was called, there won't be race. I.e. unless
- // the callback is run synchronously, it won't be run in parallel with this
- // method.
- while (!callback_pending_ &&
- response_cookies_save_index_ < response_cookies_.size()) {
- std::string cookie = response_cookies_[response_cookies_save_index_];
- response_cookies_save_index_++;
-
- if (!delegate_->CanSetCookie(
- socket_.get(), url_for_cookies, cookie, &options))
- continue;
-
- callback_pending_ = true;
- socket_->cookie_store()->SetCookieWithOptionsAsync(
- url_for_cookies, cookie, options,
- base::Bind(&WebSocketJob::OnCookieSaved,
- weak_ptr_factory_.GetWeakPtr()));
- }
- }
-
- save_next_cookie_running_ = false;
-
- if (callback_pending_)
- return;
-
- response_cookies_.clear();
- response_cookies_save_index_ = 0;
-
- NotifyHeadersComplete();
-}
-
-void WebSocketJob::OnCookieSaved(bool cookie_status) {
- // Tell the caller of SetCookieWithOptionsAsync() that this completion
- // callback is invoked.
- // - If the caller checks callback_pending earlier than this callback, the
- // caller exits to let this method continue iteration.
- // - Otherwise, the caller continues iteration.
- callback_pending_ = false;
-
- // Resume SaveNextCookie if the caller of SetCookieWithOptionsAsync() exited
- // the loop. Otherwise, return.
- if (save_next_cookie_running_)
- return;
-
- SaveNextCookie();
-}
-
-GURL WebSocketJob::GetURLForCookies() const {
- GURL url = socket_->url();
- std::string scheme = socket_->is_secure() ? "https" : "http";
- url::Replacements<char> replacements;
- replacements.SetScheme(scheme.c_str(), url::Component(0, scheme.length()));
- return url.ReplaceComponents(replacements);
-}
-
-const AddressList& WebSocketJob::address_list() const {
- return addresses_;
-}
-
-int WebSocketJob::TrySpdyStream() {
- if (!socket_.get())
- return ERR_FAILED;
-
- // Check if we have a SPDY session available.
- HttpTransactionFactory* factory =
- socket_->context()->http_transaction_factory();
- if (!factory)
- return OK;
- scoped_refptr<HttpNetworkSession> session = factory->GetSession();
- if (!session.get() || !session->params().enable_websocket_over_spdy)
- return OK;
- SpdySessionPool* spdy_pool = session->spdy_session_pool();
- PrivacyMode privacy_mode = socket_->privacy_mode();
- const SpdySessionKey key(HostPortPair::FromURL(socket_->url()),
- socket_->proxy_server(), privacy_mode);
- // Forbid wss downgrade to SPDY without SSL.
- // TODO(toyoshim): Does it realize the same policy with HTTP?
- base::WeakPtr<SpdySession> spdy_session =
- spdy_pool->FindAvailableSession(key, *socket_->net_log());
- if (!spdy_session)
- return OK;
-
- SSLInfo ssl_info;
- bool was_npn_negotiated;
- NextProto protocol_negotiated = kProtoUnknown;
- bool use_ssl = spdy_session->GetSSLInfo(
- &ssl_info, &was_npn_negotiated, &protocol_negotiated);
- if (socket_->is_secure() && !use_ssl)
- return OK;
-
- // Create SpdyWebSocketStream.
- spdy_protocol_version_ = spdy_session->GetProtocolVersion();
- spdy_websocket_stream_.reset(new SpdyWebSocketStream(spdy_session, this));
-
- int result = spdy_websocket_stream_->InitializeStream(
- socket_->url(), MEDIUM, *socket_->net_log());
- if (result == OK) {
- OnConnected(socket_.get(), kMaxPendingSendAllowed);
- return ERR_PROTOCOL_SWITCHED;
- }
- if (result != ERR_IO_PENDING) {
- spdy_websocket_stream_.reset();
- return OK;
- }
-
- return ERR_IO_PENDING;
-}
-
-void WebSocketJob::SetWaiting() {
- waiting_ = true;
-}
-
-bool WebSocketJob::IsWaiting() const {
- return waiting_;
-}
-
-void WebSocketJob::Wakeup() {
- if (!waiting_)
- return;
- waiting_ = false;
- DCHECK(!callback_.is_null());
- base::MessageLoopForIO::current()->PostTask(
- FROM_HERE,
- base::Bind(&WebSocketJob::RetryPendingIO,
- weak_ptr_factory_.GetWeakPtr()));
-}
-
-void WebSocketJob::RetryPendingIO() {
- int result = TrySpdyStream();
-
- // In the case of ERR_IO_PENDING, CompleteIO() will be called from
- // OnCreatedSpdyStream().
- if (result != ERR_IO_PENDING)
- CompleteIO(result);
-}
-
-void WebSocketJob::CompleteIO(int result) {
- // |callback_| may be null if OnClose() or DetachDelegate() was called.
- if (!callback_.is_null()) {
- CompletionCallback callback = callback_;
- callback_.Reset();
- callback.Run(result);
- Release(); // Balanced with OnStartOpenConnection().
- }
-}
-
-bool WebSocketJob::SendDataInternal(const char* data, int length) {
- if (spdy_websocket_stream_.get())
- return ERR_IO_PENDING == spdy_websocket_stream_->SendData(data, length);
- if (socket_.get())
- return socket_->SendData(data, length);
- return false;
-}
-
-void WebSocketJob::CloseInternal() {
- if (spdy_websocket_stream_.get())
- spdy_websocket_stream_->Close();
- if (socket_.get())
- socket_->Close();
-}
-
-void WebSocketJob::SendPending() {
- if (current_send_buffer_.get())
- return;
-
- // Current buffer has been sent. Try next if any.
- if (send_buffer_queue_.empty()) {
- // No more data to send.
- if (state_ == CLOSING)
- CloseInternal();
- return;
- }
-
- scoped_refptr<IOBufferWithSize> next_buffer = send_buffer_queue_.front();
- send_buffer_queue_.pop_front();
- current_send_buffer_ =
- new DrainableIOBuffer(next_buffer.get(), next_buffer->size());
- SendDataInternal(current_send_buffer_->data(),
- current_send_buffer_->BytesRemaining());
-}
-
-} // namespace net
« no previous file with comments | « net/websockets/websocket_job.h ('k') | net/websockets/websocket_job_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698