diff options
author | bashi@chromium.org <bashi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-09 08:52:52 +0000 |
---|---|---|
committer | bashi@chromium.org <bashi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-09 08:52:52 +0000 |
commit | 92b9a3e000136518c489975bebea57bc0f66333f (patch) | |
tree | 449d991930050f215005f4fb3cf361f2b28859bd /net/http | |
parent | 28bea45177fd71fbd4748a5130a0026826323a07 (diff) | |
download | chromium_src-92b9a3e000136518c489975bebea57bc0f66333f.zip chromium_src-92b9a3e000136518c489975bebea57bc0f66333f.tar.gz chromium_src-92b9a3e000136518c489975bebea57bc0f66333f.tar.bz2 |
Introduce HttpStreamBase
This is a part of connection setup logic integration between
Http and WebSocket.
Introduce a base interface for HttpStream and WebSocketStream
so that connection setup logic can handle these classes.
BUG=158725
TEST=net_unittests
Review URL: https://chromiumcodereview.appspot.com/11367004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@166875 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/http')
-rw-r--r-- | net/http/http_network_transaction.cc | 16 | ||||
-rw-r--r-- | net/http/http_network_transaction.h | 8 | ||||
-rw-r--r-- | net/http/http_stream.h | 105 | ||||
-rw-r--r-- | net/http/http_stream_base.h | 133 | ||||
-rw-r--r-- | net/http/http_stream_factory.h | 6 | ||||
-rw-r--r-- | net/http/http_stream_factory_impl_request.cc | 4 | ||||
-rw-r--r-- | net/http/http_stream_factory_impl_request.h | 4 | ||||
-rw-r--r-- | net/http/http_stream_factory_impl_unittest.cc | 6 |
8 files changed, 161 insertions, 121 deletions
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index 0ab553e..9a94ad5 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc @@ -45,6 +45,7 @@ #include "net/http/http_response_info.h" #include "net/http/http_server_properties.h" #include "net/http/http_status_code.h" +#include "net/http/http_stream_base.h" #include "net/http/http_stream_factory.h" #include "net/http/http_util.h" #include "net/http/url_security_manager.h" @@ -152,7 +153,7 @@ HttpNetworkTransaction::~HttpNetworkTransaction() { stream_->Close(true /* not reusable */); } else { // Otherwise, we try to drain the response body. - HttpStream* stream = stream_.release(); + HttpStreamBase* stream = stream_.release(); stream->Drain(session_); } } @@ -287,7 +288,8 @@ void HttpNetworkTransaction::DidDrainBodyForAuthRestart(bool keep_alive) { // We should call connection_->set_idle_time(), but this doesn't occur // often enough to be worth the trouble. stream_->SetConnectionReused(); - new_stream = stream_->RenewStreamForAuth(); + new_stream = + static_cast<HttpStream*>(stream_.get())->RenewStreamForAuth(); } if (!new_stream) { @@ -378,12 +380,13 @@ UploadProgress HttpNetworkTransaction::GetUploadProgress() const { if (!stream_.get()) return UploadProgress(); - return stream_->GetUploadProgress(); + // TODO(bashi): This cast is temporary. Remove later. + return static_cast<HttpStream*>(stream_.get())->GetUploadProgress(); } void HttpNetworkTransaction::OnStreamReady(const SSLConfig& used_ssl_config, const ProxyInfo& used_proxy_info, - HttpStream* stream) { + HttpStreamBase* stream) { DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); DCHECK(stream_request_.get()); @@ -466,7 +469,7 @@ void HttpNetworkTransaction::OnHttpsProxyTunnelResponse( const HttpResponseInfo& response_info, const SSLConfig& used_ssl_config, const ProxyInfo& used_proxy_info, - HttpStream* stream) { + HttpStreamBase* stream) { DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); headers_valid_ = true; @@ -965,7 +968,8 @@ int HttpNetworkTransaction::DoReadBodyComplete(int result) { // Clean up connection if we are done. if (done) { LogTransactionMetrics(); - stream_->LogNumRttVsBytesMetrics(); + // TODO(bashi): This cast is temporary. Remove later. + static_cast<HttpStream*>(stream_.get())->LogNumRttVsBytesMetrics(); stream_->Close(!keep_alive); // Note: we don't reset the stream here. We've closed it, but we still // need it around so that callers can call methods such as diff --git a/net/http/http_network_transaction.h b/net/http/http_network_transaction.h index 633a457..704acd8 100644 --- a/net/http/http_network_transaction.h +++ b/net/http/http_network_transaction.h @@ -26,7 +26,7 @@ namespace net { class HttpAuthController; class HttpNetworkSession; -class HttpStream; +class HttpStreamBase; class HttpStreamRequest; class IOBuffer; class UploadDataStream; @@ -65,7 +65,7 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction // HttpStreamRequest::Delegate methods: virtual void OnStreamReady(const SSLConfig& used_ssl_config, const ProxyInfo& used_proxy_info, - HttpStream* stream) OVERRIDE; + HttpStreamBase* stream) OVERRIDE; virtual void OnStreamFailed(int status, const SSLConfig& used_ssl_config) OVERRIDE; virtual void OnCertificateError(int status, @@ -81,7 +81,7 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction virtual void OnHttpsProxyTunnelResponse(const HttpResponseInfo& response_info, const SSLConfig& used_ssl_config, const ProxyInfo& used_proxy_info, - HttpStream* stream) OVERRIDE; + HttpStreamBase* stream) OVERRIDE; private: FRIEND_TEST_ALL_PREFIXES(HttpNetworkTransactionSpdy2Test, @@ -264,7 +264,7 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction ProxyInfo proxy_info_; scoped_ptr<HttpStreamRequest> stream_request_; - scoped_ptr<HttpStream> stream_; + scoped_ptr<HttpStreamBase> stream_; // True if we've validated the headers that the stream parser has returned. bool headers_valid_; diff --git a/net/http/http_stream.h b/net/http/http_stream.h index d1c4c6e..7fe4753 100644 --- a/net/http/http_stream.h +++ b/net/http/http_stream.h @@ -2,10 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// HttpStream is an interface for reading and writing data to an HttpStream that -// keeps the client agnostic of the actual underlying transport layer. This -// provides an abstraction for both a basic http stream as well as http -// pipelining implementations. The HttpStream subtype is expected to manage the +// HttpStream provides an abstraction for a basic http streams, http pipelining +// implementations, and SPDY. The HttpStream subtype is expected to manage the // underlying transport appropriately. For example, a non-pipelined HttpStream // would return the transport socket to the pool for reuse. SPDY streams on the // other hand leave the transport socket management to the SpdySession. @@ -17,76 +15,21 @@ #include "net/base/completion_callback.h" #include "net/base/net_export.h" #include "net/base/upload_progress.h" +#include "net/http/http_stream_base.h" namespace net { -class BoundNetLog; -class HttpNetworkSession; -class HttpRequestHeaders; -struct HttpRequestInfo; -class HttpResponseInfo; class IOBuffer; -class SSLCertRequestInfo; -class SSLInfo; class UploadDataStream; -class NET_EXPORT_PRIVATE HttpStream { +class NET_EXPORT_PRIVATE HttpStream : public HttpStreamBase { public: HttpStream() {} virtual ~HttpStream() {} - // Initialize stream. Must be called before calling SendRequest(). - // Returns a net error code, possibly ERR_IO_PENDING. - virtual int InitializeStream(const HttpRequestInfo* request_info, - const BoundNetLog& net_log, - const CompletionCallback& callback) = 0; - - // Writes the headers and uploads body data to the underlying socket. - // ERR_IO_PENDING is returned if the operation could not be completed - // synchronously, in which case the result will be passed to the callback - // when available. Returns OK on success. - virtual int SendRequest(const HttpRequestHeaders& request_headers, - UploadDataStream* request_body, - HttpResponseInfo* response, - const CompletionCallback& callback) = 0; - // Queries the UploadDataStream for its progress (bytes sent). virtual UploadProgress GetUploadProgress() const = 0; - // Reads from the underlying socket until the response headers have been - // completely received. ERR_IO_PENDING is returned if the operation could - // not be completed synchronously, in which case the result will be passed - // to the callback when available. Returns OK on success. The response - // headers are available in the HttpResponseInfo returned by GetResponseInfo - virtual int ReadResponseHeaders(const CompletionCallback& callback) = 0; - - // Provides access to HttpResponseInfo (owned by HttpStream). - virtual const HttpResponseInfo* GetResponseInfo() const = 0; - - // Reads response body data, up to |buf_len| bytes. |buf_len| should be a - // reasonable size (<2MB). The number of bytes read is returned, or an - // error is returned upon failure. 0 indicates that the request has been - // fully satisfied and there is no more data to read. - // ERR_CONNECTION_CLOSED is returned when the connection has been closed - // prematurely. ERR_IO_PENDING is returned if the operation could not be - // completed synchronously, in which case the result will be passed to the - // callback when available. If the operation is not completed immediately, - // the socket acquires a reference to the provided buffer until the callback - // is invoked or the socket is destroyed. - virtual int ReadResponseBody(IOBuffer* buf, int buf_len, - const CompletionCallback& callback) = 0; - - // Closes the stream. - // |not_reusable| indicates if the stream can be used for further requests. - // In the case of HTTP, where we re-use the byte-stream (e.g. the connection) - // this means we need to close the connection; in the case of SPDY, where the - // underlying stream is never reused, it has no effect. - // TODO(mbelshe): We should figure out how to fold the not_reusable flag - // into the stream implementation itself so that the caller - // does not need to pass it at all. We might also be able to - // eliminate the SetConnectionReused() below. - virtual void Close(bool not_reusable) = 0; - // Returns a new (not initialized) stream using the same underlying // connection and invalidates the old stream - no further methods should be // called on the old stream. The caller should ensure that the response body @@ -94,55 +37,15 @@ class NET_EXPORT_PRIVATE HttpStream { // subclass does not support renewing the stream, NULL is returned. virtual HttpStream* RenewStreamForAuth() = 0; - // Indicates if the response body has been completely read. - virtual bool IsResponseBodyComplete() const = 0; - - // Indicates that the end of the response is detectable. This means that - // the response headers indicate either chunked encoding or content length. - // If neither is sent, the server must close the connection for us to detect - // the end of the response. - virtual bool CanFindEndOfResponse() const = 0; - // After the response headers have been read and after the response body // is complete, this function indicates if more data (either erroneous or // as part of the next pipelined response) has been read from the socket. virtual bool IsMoreDataBuffered() const = 0; - // A stream exists on top of a connection. If the connection has been used - // to successfully exchange data in the past, error handling for the - // stream is done differently. This method returns true if the underlying - // connection is reused or has been connected and idle for some time. - virtual bool IsConnectionReused() const = 0; - virtual void SetConnectionReused() = 0; - - // Checks whether the current state of the underlying connection - // allows it to be reused. - virtual bool IsConnectionReusable() const = 0; - - // Get the SSLInfo associated with this stream's connection. This should - // only be called for streams over SSL sockets, otherwise the behavior is - // undefined. - virtual void GetSSLInfo(SSLInfo* ssl_info) = 0; - - // Get the SSLCertRequestInfo associated with this stream's connection. - // This should only be called for streams over SSL sockets, otherwise the - // behavior is undefined. - virtual void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) = 0; - - // HACK(willchan): Really, we should move the HttpResponseDrainer logic into - // the HttpStream implementation. This is just a quick hack. - virtual bool IsSpdyHttpStream() const = 0; - // Record histogram of number of round trips taken to download the full // response body vs bytes transferred. virtual void LogNumRttVsBytesMetrics() const = 0; - // In the case of an HTTP error or redirect, flush the response body (usually - // a simple error or "this page has moved") so that we can re-use the - // underlying connection. This stream is responsible for deleting itself when - // draining is complete. - virtual void Drain(HttpNetworkSession* session) = 0; - private: DISALLOW_COPY_AND_ASSIGN(HttpStream); }; diff --git a/net/http/http_stream_base.h b/net/http/http_stream_base.h new file mode 100644 index 0000000..f6a9797 --- /dev/null +++ b/net/http/http_stream_base.h @@ -0,0 +1,133 @@ +// 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. +// +// HttpStreamBase is an interface for reading and writing data to an +// HTTP-like stream that keeps the client agnostic of the actual underlying +// transport layer. This provides an abstraction for HttpStream and +// WebSocketStream. + +#ifndef NET_HTTP_HTTP_STREAM_BASE_H_ +#define NET_HTTP_HTTP_STREAM_BASE_H_ + +#include <string> + +#include "base/basictypes.h" +#include "base/memory/scoped_ptr.h" +#include "net/base/completion_callback.h" +#include "net/base/net_export.h" +#include "net/base/upload_progress.h" + +namespace net { + +class BoundNetLog; +class HttpNetworkSession; +class HttpRequestHeaders; +struct HttpRequestInfo; +class HttpResponseInfo; +class IOBuffer; +class SSLCertRequestInfo; +class SSLInfo; +class UploadDataStream; + +class NET_EXPORT_PRIVATE HttpStreamBase { + public: + HttpStreamBase() {} + virtual ~HttpStreamBase() {} + + // Initialize stream. Must be called before calling SendRequest(). + // Returns a net error code, possibly ERR_IO_PENDING. + virtual int InitializeStream(const HttpRequestInfo* request_info, + const BoundNetLog& net_log, + const CompletionCallback& callback) = 0; + + // Writes the headers and uploads body data to the underlying socket. + // ERR_IO_PENDING is returned if the operation could not be completed + // synchronously, in which case the result will be passed to the callback + // when available. Returns OK on success. + virtual int SendRequest(const HttpRequestHeaders& request_headers, + UploadDataStream* request_body, + HttpResponseInfo* response, + const CompletionCallback& callback) = 0; + + // Reads from the underlying socket until the response headers have been + // completely received. ERR_IO_PENDING is returned if the operation could + // not be completed synchronously, in which case the result will be passed + // to the callback when available. Returns OK on success. The response + // headers are available in the HttpResponseInfo returned by GetResponseInfo + virtual int ReadResponseHeaders(const CompletionCallback& callback) = 0; + + // Provides access to HttpResponseInfo (owned by HttpStream). + virtual const HttpResponseInfo* GetResponseInfo() const = 0; + + // Reads response body data, up to |buf_len| bytes. |buf_len| should be a + // reasonable size (<2MB). The number of bytes read is returned, or an + // error is returned upon failure. 0 indicates that the request has been + // fully satisfied and there is no more data to read. + // ERR_CONNECTION_CLOSED is returned when the connection has been closed + // prematurely. ERR_IO_PENDING is returned if the operation could not be + // completed synchronously, in which case the result will be passed to the + // callback when available. If the operation is not completed immediately, + // the socket acquires a reference to the provided buffer until the callback + // is invoked or the socket is destroyed. + virtual int ReadResponseBody(IOBuffer* buf, int buf_len, + const CompletionCallback& callback) = 0; + + // Closes the stream. + // |not_reusable| indicates if the stream can be used for further requests. + // In the case of HTTP, where we re-use the byte-stream (e.g. the connection) + // this means we need to close the connection; in the case of SPDY, where the + // underlying stream is never reused, it has no effect. + // TODO(mbelshe): We should figure out how to fold the not_reusable flag + // into the stream implementation itself so that the caller + // does not need to pass it at all. We might also be able to + // eliminate the SetConnectionReused() below. + virtual void Close(bool not_reusable) = 0; + + // Indicates if the response body has been completely read. + virtual bool IsResponseBodyComplete() const = 0; + + // Indicates that the end of the response is detectable. This means that + // the response headers indicate either chunked encoding or content length. + // If neither is sent, the server must close the connection for us to detect + // the end of the response. + virtual bool CanFindEndOfResponse() const = 0; + + // A stream exists on top of a connection. If the connection has been used + // to successfully exchange data in the past, error handling for the + // stream is done differently. This method returns true if the underlying + // connection is reused or has been connected and idle for some time. + virtual bool IsConnectionReused() const = 0; + virtual void SetConnectionReused() = 0; + + // Checks whether the current state of the underlying connection + // allows it to be reused. + virtual bool IsConnectionReusable() const = 0; + + // Get the SSLInfo associated with this stream's connection. This should + // only be called for streams over SSL sockets, otherwise the behavior is + // undefined. + virtual void GetSSLInfo(SSLInfo* ssl_info) = 0; + + // Get the SSLCertRequestInfo associated with this stream's connection. + // This should only be called for streams over SSL sockets, otherwise the + // behavior is undefined. + virtual void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) = 0; + + // HACK(willchan): Really, we should move the HttpResponseDrainer logic into + // the HttpStream implementation. This is just a quick hack. + virtual bool IsSpdyHttpStream() const = 0; + + // In the case of an HTTP error or redirect, flush the response body (usually + // a simple error or "this page has moved") so that we can re-use the + // underlying connection. This stream is responsible for deleting itself when + // draining is complete. + virtual void Drain(HttpNetworkSession* session) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(HttpStreamBase); +}; + +} // namespace net + +#endif // NET_HTTP_HTTP_STREAM_BASE_H_ diff --git a/net/http/http_stream_factory.h b/net/http/http_stream_factory.h index 7371010..5f6ef2f 100644 --- a/net/http/http_stream_factory.h +++ b/net/http/http_stream_factory.h @@ -33,7 +33,7 @@ class HostPortPair; class HttpAuthController; class HttpResponseInfo; class HttpServerProperties; -class HttpStream; +class HttpStreamBase; class ProxyInfo; class SSLCertRequestInfo; class SSLInfo; @@ -64,7 +64,7 @@ class NET_EXPORT_PRIVATE HttpStreamRequest { virtual void OnStreamReady( const SSLConfig& used_ssl_config, const ProxyInfo& used_proxy_info, - HttpStream* stream) = 0; + HttpStreamBase* stream) = 0; // This is the failure to create a stream case. // |used_ssl_config| indicates the actual SSL configuration used for this @@ -127,7 +127,7 @@ class NET_EXPORT_PRIVATE HttpStreamRequest { const HttpResponseInfo& response_info, const SSLConfig& used_ssl_config, const ProxyInfo& used_proxy_info, - HttpStream* stream) = 0; + HttpStreamBase* stream) = 0; }; virtual ~HttpStreamRequest() {} diff --git a/net/http/http_stream_factory_impl_request.cc b/net/http/http_stream_factory_impl_request.cc index 7f536c8..6195552 100644 --- a/net/http/http_stream_factory_impl_request.cc +++ b/net/http/http_stream_factory_impl_request.cc @@ -98,7 +98,7 @@ void HttpStreamFactoryImpl::Request::OnStreamReady( Job* job, const SSLConfig& used_ssl_config, const ProxyInfo& used_proxy_info, - HttpStream* stream) { + HttpStreamBase* stream) { DCHECK(stream); DCHECK(completed_); @@ -203,7 +203,7 @@ void HttpStreamFactoryImpl::Request::OnHttpsProxyTunnelResponse( const HttpResponseInfo& response_info, const SSLConfig& used_ssl_config, const ProxyInfo& used_proxy_info, - HttpStream* stream) { + HttpStreamBase* stream) { if (!bound_job_.get()) OrphanJobsExcept(job); else diff --git a/net/http/http_stream_factory_impl_request.h b/net/http/http_stream_factory_impl_request.h index ab5ff96..f0b5335 100644 --- a/net/http/http_stream_factory_impl_request.h +++ b/net/http/http_stream_factory_impl_request.h @@ -67,7 +67,7 @@ class HttpStreamFactoryImpl::Request : public HttpStreamRequest { void OnStreamReady(Job* job, const SSLConfig& used_ssl_config, const ProxyInfo& used_proxy_info, - HttpStream* stream); + HttpStreamBase* stream); void OnStreamFailed(Job* job, int status, const SSLConfig& used_ssl_config); void OnCertificateError(Job* job, int status, @@ -86,7 +86,7 @@ class HttpStreamFactoryImpl::Request : public HttpStreamRequest { const HttpResponseInfo& response_info, const SSLConfig& used_ssl_config, const ProxyInfo& used_proxy_info, - HttpStream* stream); + HttpStreamBase* stream); // HttpStreamRequest methods. diff --git a/net/http/http_stream_factory_impl_unittest.cc b/net/http/http_stream_factory_impl_unittest.cc index dbd6a5b..3608e46 100644 --- a/net/http/http_stream_factory_impl_unittest.cc +++ b/net/http/http_stream_factory_impl_unittest.cc @@ -69,7 +69,7 @@ class StreamRequestWaiter : public HttpStreamRequest::Delegate { virtual void OnStreamReady( const SSLConfig& used_ssl_config, const ProxyInfo& used_proxy_info, - HttpStream* stream) OVERRIDE { + HttpStreamBase* stream) OVERRIDE { stream_done_ = true; if (waiting_for_stream_) MessageLoop::current()->Quit(); @@ -96,7 +96,7 @@ class StreamRequestWaiter : public HttpStreamRequest::Delegate { virtual void OnHttpsProxyTunnelResponse(const HttpResponseInfo& response_info, const SSLConfig& used_ssl_config, const ProxyInfo& used_proxy_info, - HttpStream* stream) OVERRIDE {} + HttpStreamBase* stream) OVERRIDE {} void WaitForStream() { while (!stream_done_) { @@ -109,7 +109,7 @@ class StreamRequestWaiter : public HttpStreamRequest::Delegate { private: bool waiting_for_stream_; bool stream_done_; - scoped_ptr<HttpStream> stream_; + scoped_ptr<HttpStreamBase> stream_; DISALLOW_COPY_AND_ASSIGN(StreamRequestWaiter); }; |