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

Unified Diff: net/spdy/spdy_proxy_client_socket.cc

Issue 3391029: Revert 60747 - Add a new class SpdyProxyClientSocket which implements ClientS... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 10 years, 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/spdy/spdy_proxy_client_socket.h ('k') | net/spdy/spdy_proxy_client_socket_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/spdy/spdy_proxy_client_socket.cc
===================================================================
--- net/spdy/spdy_proxy_client_socket.cc (revision 60753)
+++ net/spdy/spdy_proxy_client_socket.cc (working copy)
@@ -1,437 +0,0 @@
-// Copyright (c) 2010 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/spdy/spdy_proxy_client_socket.h"
-
-#include <algorithm> // min
-
-#include "base/logging.h"
-#include "base/string_util.h"
-#include "googleurl/src/gurl.h"
-#include "net/base/auth.h"
-#include "net/base/io_buffer.h"
-#include "net/base/net_util.h"
-#include "net/http/http_auth_cache.h"
-#include "net/http/http_auth_handler_factory.h"
-#include "net/http/http_net_log_params.h"
-#include "net/http/http_proxy_utils.h"
-#include "net/spdy/spdy_http_utils.h"
-
-namespace net {
-
-SpdyProxyClientSocket::SpdyProxyClientSocket(
- SpdyStream* spdy_stream,
- const std::string& user_agent,
- const HostPortPair& endpoint,
- const GURL& url,
- const HostPortPair& proxy_server,
- HttpAuthCache* auth_cache,
- HttpAuthHandlerFactory* auth_handler_factory)
- : ALLOW_THIS_IN_INITIALIZER_LIST(
- io_callback_(this, &SpdyProxyClientSocket::OnIOComplete)),
- next_state_(STATE_NONE),
- spdy_stream_(spdy_stream),
- read_callback_(NULL),
- write_callback_(NULL),
- endpoint_(endpoint),
- auth_(
- new HttpAuthController(HttpAuth::AUTH_PROXY,
- GURL("http://" + proxy_server.ToString()),
- auth_cache,
- auth_handler_factory)),
- user_buffer_(NULL),
- write_buffer_len_(0),
- write_bytes_outstanding_(0),
- eof_has_been_read_(false),
- net_log_(spdy_stream->net_log()) {
- request_.method = "CONNECT";
- request_.url = url;
- if (!user_agent.empty())
- request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
- user_agent);
- spdy_stream_->SetDelegate(this);
- was_ever_used_ = spdy_stream_->WasEverUsed();
-}
-
-SpdyProxyClientSocket::~SpdyProxyClientSocket() {
- Disconnect();
-}
-
-// Sends a SYN_STREAM frame to the proxy with a CONNECT request
-// for the specified endpoint. Waits for the server to send back
-// a SYN_REPLY frame. OK will be returned if the status is 200.
-// ERR_TUNNEL_CONNECTION_FAILED will be returned for any other status.
-// In any of these cases, Read() may be called to retrieve the HTTP
-// response body. Any other return values should be considered fatal.
-// TODO(rch): handle 407 proxy auth requested correctly, perhaps
-// by creating a new stream for the subsequent request.
-// TODO(rch): create a more appropriate error code to disambiguate
-// the HTTPS Proxy tunnel failure from an HTTP Proxy tunnel failure.
-int SpdyProxyClientSocket::Connect(CompletionCallback* callback) {
- DCHECK(!read_callback_);
- if (next_state_ == STATE_DONE)
- return OK;
-
- DCHECK_EQ(STATE_NONE, next_state_);
- next_state_ = STATE_GENERATE_AUTH_TOKEN;
-
- int rv = DoLoop(OK);
- if (rv == ERR_IO_PENDING)
- read_callback_ = callback;
- return rv;
-}
-
-void SpdyProxyClientSocket::Disconnect() {
- next_state_ = STATE_NONE;
- if (spdy_stream_)
- // This will cause OnClose to be invoked, which takes care of
- // cleaning up all the internal state.
- spdy_stream_->Cancel();
-}
-
-bool SpdyProxyClientSocket::IsConnected() const {
- return next_state_ == STATE_DONE && spdy_stream_ != NULL &&
- !spdy_stream_->closed();
-}
-
-bool SpdyProxyClientSocket::IsConnectedAndIdle() const {
- return IsConnected() && !spdy_stream_->is_idle();
-}
-
-void SpdyProxyClientSocket::SetSubresourceSpeculation() {
- // TODO(rch): what should this implementation be?
-}
-
-void SpdyProxyClientSocket::SetOmniboxSpeculation() {
- // TODO(rch): what should this implementation be?
-}
-
-bool SpdyProxyClientSocket::WasEverUsed() const {
- return was_ever_used_ || (spdy_stream_ && spdy_stream_->WasEverUsed());
-}
-
-int SpdyProxyClientSocket::Read(IOBuffer* buf, int buf_len,
- CompletionCallback* callback) {
- DCHECK(!read_callback_);
- DCHECK(!user_buffer_);
-
- if (!spdy_stream_) {
- if (eof_has_been_read_)
- return ERR_CONNECTION_CLOSED;
- eof_has_been_read_ = true;
- return 0;
- }
-
- DCHECK(next_state_ == STATE_DONE);
- DCHECK(buf);
- user_buffer_ = new DrainableIOBuffer(buf, buf_len);
- int result = PopulateUserReadBuffer();
- if (result == 0) {
- DCHECK(callback);
- read_callback_ = callback;
- return ERR_IO_PENDING;
- }
- user_buffer_ = NULL;
- return result;
-}
-
-int SpdyProxyClientSocket::PopulateUserReadBuffer() {
- if (!user_buffer_)
- return ERR_IO_PENDING;
-
- while (!read_buffer_.empty() && user_buffer_->BytesRemaining() > 0) {
- scoped_refptr<DrainableIOBuffer> data = read_buffer_.front();
- const int bytes_to_copy = std::min(user_buffer_->BytesRemaining(),
- data->size());
- memcpy(user_buffer_->data(), data->data(), bytes_to_copy);
- user_buffer_->DidConsume(bytes_to_copy);
- if (bytes_to_copy == data->size()) {
- // Consumed all data from this buffer
- read_buffer_.pop_front();
- } else {
- data->DidConsume(bytes_to_copy);
- }
- }
-
- return user_buffer_->BytesConsumed();
-}
-
-int SpdyProxyClientSocket::Write(IOBuffer* buf, int buf_len,
- CompletionCallback* callback) {
- DCHECK(!write_callback_);
- if (!spdy_stream_)
- return ERR_CONNECTION_CLOSED;
-
- write_bytes_outstanding_= buf_len;
- if (buf_len <= kMaxSpdyFrameChunkSize) {
- int rv = spdy_stream_->WriteStreamData(buf, buf_len, spdy::DATA_FLAG_NONE);
- if (rv == ERR_IO_PENDING) {
- write_callback_ = callback;
- write_buffer_len_ = buf_len;
- }
- return rv;
- }
-
- // Since a SPDY Data frame can only include kMaxSpdyFrameChunkSize bytes
- // we need to send multiple data frames
- for (int i = 0; i < buf_len; i += kMaxSpdyFrameChunkSize) {
- int len = std::min(kMaxSpdyFrameChunkSize, buf_len - i);
- scoped_refptr<DrainableIOBuffer> iobuf(new DrainableIOBuffer(buf, i + len));
- iobuf->SetOffset(i);
- int rv = spdy_stream_->WriteStreamData(iobuf, len, spdy::DATA_FLAG_NONE);
- if (rv > 0) {
- write_bytes_outstanding_ -= rv;
- } else if (rv != ERR_IO_PENDING) {
- return rv;
- }
- }
- if (write_bytes_outstanding_ > 0) {
- write_callback_ = callback;
- write_buffer_len_ = buf_len;
- return ERR_IO_PENDING;
- } else {
- return buf_len;
- }
-}
-
-bool SpdyProxyClientSocket::SetReceiveBufferSize(int32 size) {
- // Since this ClientSocket sits on top of a shared SpdySession, it
- // is not safe for callers to set change this underlying socket.
- return false;
-}
-
-bool SpdyProxyClientSocket::SetSendBufferSize(int32 size) {
- // Since this ClientSocket sits on top of a shared SpdySession, it
- // is not safe for callers to set change this underlying socket.
- return false;
-}
-
-int SpdyProxyClientSocket::GetPeerAddress(AddressList* address) const {
- if (!IsConnected())
- return ERR_UNEXPECTED;
- return spdy_stream_->GetPeerAddress(address);
-}
-
-void SpdyProxyClientSocket::OnIOComplete(int result) {
- DCHECK_NE(STATE_NONE, next_state_);
- int rv = DoLoop(result);
- if (rv != ERR_IO_PENDING) {
- CompletionCallback* c = read_callback_;
- read_callback_ = NULL;
- c->Run(rv);
- }
-}
-
-int SpdyProxyClientSocket::DoLoop(int last_io_result) {
- DCHECK_NE(next_state_, STATE_NONE);
- int rv = last_io_result;
- do {
- State state = next_state_;
- next_state_ = STATE_NONE;
- switch (state) {
- case STATE_GENERATE_AUTH_TOKEN:
- DCHECK_EQ(OK, rv);
- rv = DoGenerateAuthToken();
- break;
- case STATE_GENERATE_AUTH_TOKEN_COMPLETE:
- rv = DoGenerateAuthTokenComplete(rv);
- break;
- case STATE_SEND_REQUEST:
- DCHECK_EQ(OK, rv);
- net_log_.BeginEvent(NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST,
- NULL);
- rv = DoSendRequest();
- break;
- case STATE_SEND_REQUEST_COMPLETE:
- rv = DoSendRequestComplete(rv);
- net_log_.EndEvent(NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_SEND_REQUEST,
- NULL);
- break;
- case STATE_READ_REPLY_COMPLETE:
- rv = DoReadReplyComplete(rv);
- net_log_.EndEvent(NetLog::TYPE_HTTP_TRANSACTION_TUNNEL_READ_HEADERS,
- NULL);
- break;
- default:
- NOTREACHED() << "bad state";
- rv = ERR_UNEXPECTED;
- break;
- }
- } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE &&
- next_state_ != STATE_DONE);
- return rv;
-}
-
-int SpdyProxyClientSocket::DoGenerateAuthToken() {
- next_state_ = STATE_GENERATE_AUTH_TOKEN_COMPLETE;
- return auth_->MaybeGenerateAuthToken(&request_, &io_callback_, net_log_);
-}
-
-int SpdyProxyClientSocket::DoGenerateAuthTokenComplete(int result) {
- DCHECK_NE(ERR_IO_PENDING, result);
- if (result == OK)
- next_state_ = STATE_SEND_REQUEST;
- return result;
-}
-
-int SpdyProxyClientSocket::DoSendRequest() {
- next_state_ = STATE_SEND_REQUEST_COMPLETE;
-
- // Add Proxy-Authentication header if necessary.
- HttpRequestHeaders authorization_headers;
- if (auth_->HaveAuth()) {
- auth_->AddAuthorizationHeader(&authorization_headers);
- }
-
- std::string request_line;
- HttpRequestHeaders request_headers;
- BuildTunnelRequest(request_, authorization_headers, endpoint_, &request_line,
- &request_headers);
- if (net_log_.IsLoggingAll()) {
- net_log_.AddEvent(
- NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
- new NetLogHttpRequestParameter(
- request_line, request_headers));
- }
-
- request_.extra_headers.MergeFrom(request_headers);
- linked_ptr<spdy::SpdyHeaderBlock> headers(new spdy::SpdyHeaderBlock());
- CreateSpdyHeadersFromHttpRequest(request_, headers.get(), true);
- // Reset the URL to be the endpoint of the connection
- (*headers)["url"] = endpoint_.ToString();
- headers->erase("scheme");
- spdy_stream_->set_spdy_headers(headers);
-
- return spdy_stream_->SendRequest(true);
-}
-
-int SpdyProxyClientSocket::DoSendRequestComplete(int result) {
- if (result < 0)
- return result;
-
- // Wait for SYN_REPLY frame from the server
- next_state_ = STATE_READ_REPLY_COMPLETE;
- return ERR_IO_PENDING;
-}
-
-int SpdyProxyClientSocket::DoReadReplyComplete(int result) {
- // We enter this method directly from DoSendRequestComplete, since
- // we are notified by a callback when the SYN_REPLY frame arrives
-
- if (result < 0)
- return result;
-
- next_state_ = STATE_DONE;
- // Require the "HTTP/1.x" status line for SSL CONNECT.
- if (response_.headers->GetParsedHttpVersion() < HttpVersion(1, 0))
- return ERR_TUNNEL_CONNECTION_FAILED;
-
- if (net_log_.IsLoggingAll()) {
- net_log_.AddEvent(
- NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
- new NetLogHttpResponseParameter(response_.headers));
- }
-
- if (response_.headers->response_code() == 200)
- return OK;
- else
- return ERR_TUNNEL_CONNECTION_FAILED;
-}
-
-// SpdyStream::Delegate methods:
-// Called when SYN frame has been sent.
-// Returns true if no more data to be sent after SYN frame.
-bool SpdyProxyClientSocket::OnSendHeadersComplete(int status) {
- DCHECK_EQ(next_state_, STATE_SEND_REQUEST_COMPLETE);
-
- OnIOComplete(status);
-
- // We return true here so that we send |spdy_stream_| into
- // STATE_OPEN (ala WebSockets).
- return true;
-}
-
-int SpdyProxyClientSocket::OnSendBody() {
- // Because we use |spdy_stream_| via STATE_OPEN (ala WebSockets)
- // OnSendBody() should never be called.
- NOTREACHED();
- return ERR_UNEXPECTED;
-}
-
-bool SpdyProxyClientSocket::OnSendBodyComplete(int status) {
- // Because we use |spdy_stream_| via STATE_OPEN (ala WebSockets)
- // OnSendBodyComplete() should never be called.
- NOTREACHED();
- return false;
-}
-
-int SpdyProxyClientSocket::OnResponseReceived(
- const spdy::SpdyHeaderBlock& response,
- base::Time response_time,
- int status) {
- // Save the response
- SpdyHeadersToHttpResponse(response, &response_);
-
- DCHECK_EQ(next_state_, STATE_READ_REPLY_COMPLETE);
-
- OnIOComplete(status);
-
- return OK;
-}
-
-// Called when data is received.
-void SpdyProxyClientSocket::OnDataReceived(const char* data, int length) {
- if (length > 0) {
- // Save the received data.
- scoped_refptr<IOBuffer> io_buffer = new IOBuffer(length);
- memcpy(io_buffer->data(), data, length);
- read_buffer_.push_back(new DrainableIOBuffer(io_buffer, length));
- }
-
- if (read_callback_) {
- int rv = PopulateUserReadBuffer();
- CompletionCallback* c = read_callback_;
- read_callback_ = NULL;
- user_buffer_ = NULL;
- c->Run(rv);
- }
-}
-
-void SpdyProxyClientSocket::OnDataSent(int length) {
- DCHECK(write_callback_);
-
- write_bytes_outstanding_ -= length;
-
- DCHECK_GE(write_bytes_outstanding_, 0);
-
- if (write_bytes_outstanding_ == 0) {
- int rv = write_buffer_len_;
- write_buffer_len_ = 0;
- write_bytes_outstanding_ = 0;
- CompletionCallback* c = write_callback_;
- write_callback_ = NULL;
- c->Run(rv);
- }
-}
-
-void SpdyProxyClientSocket::OnClose(int status) {
- DCHECK(spdy_stream_);
- // If we're in the middle of connecting, we need to make sure
- // we invoke the connect callback.
- CompletionCallback* connect_callback = NULL;
- if (next_state_ != STATE_NONE && next_state_ != STATE_DONE) {
- DCHECK(read_callback_);
- connect_callback = read_callback_;
- }
- was_ever_used_ = spdy_stream_->WasEverUsed();
- spdy_stream_ = NULL;
- read_callback_ = NULL;
- write_callback_ = NULL;
- user_buffer_ = NULL;
- read_buffer_.empty();
- if (connect_callback)
- connect_callback->Run(status);
-}
-
-} // namespace net
« no previous file with comments | « net/spdy/spdy_proxy_client_socket.h ('k') | net/spdy/spdy_proxy_client_socket_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698