// 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. #ifndef NET_SPDY_SPDY_HTTP_STREAM_H_ #define NET_SPDY_SPDY_HTTP_STREAM_H_ #include #include "base/basictypes.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "net/base/completion_callback.h" #include "net/base/net_log.h" #include "net/http/http_stream.h" #include "net/spdy/spdy_stream.h" namespace net { class DrainableIOBuffer; struct HttpRequestInfo; class HttpResponseInfo; class IOBuffer; class SpdySession; class UploadDataStream; // The SpdyHttpStream is a HTTP-specific type of stream known to a SpdySession. class NET_EXPORT_PRIVATE SpdyHttpStream : public SpdyStream::Delegate, public HttpStream { public: SpdyHttpStream(SpdySession* spdy_session, bool direct); virtual ~SpdyHttpStream(); // Initializes this SpdyHttpStream by wrapping an existing SpdyStream. void InitializeWithExistingStream(SpdyStream* spdy_stream); SpdyStream* stream() { return stream_.get(); } // Cancels any callbacks from being invoked and deletes the stream. void Cancel(); // HttpStream implementation. virtual int InitializeStream(const HttpRequestInfo* request_info, const BoundNetLog& net_log, const CompletionCallback& callback) OVERRIDE; virtual int SendRequest(const HttpRequestHeaders& headers, UploadDataStream* request_body, HttpResponseInfo* response, const CompletionCallback& callback) OVERRIDE; virtual UploadProgress GetUploadProgress() const OVERRIDE; virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE; virtual const HttpResponseInfo* GetResponseInfo() const OVERRIDE; virtual int ReadResponseBody(IOBuffer* buf, int buf_len, const CompletionCallback& callback) OVERRIDE; virtual void Close(bool not_reusable) OVERRIDE; virtual HttpStream* RenewStreamForAuth() OVERRIDE; virtual bool IsResponseBodyComplete() const OVERRIDE; virtual bool CanFindEndOfResponse() const OVERRIDE; virtual bool IsMoreDataBuffered() const OVERRIDE; virtual bool IsConnectionReused() const OVERRIDE; virtual void SetConnectionReused() OVERRIDE; virtual bool IsConnectionReusable() const OVERRIDE; virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE; virtual void GetSSLCertRequestInfo( SSLCertRequestInfo* cert_request_info) OVERRIDE; virtual bool IsSpdyHttpStream() const OVERRIDE; virtual void LogNumRttVsBytesMetrics() const OVERRIDE {} virtual void Drain(HttpNetworkSession* session) OVERRIDE; // SpdyStream::Delegate implementation. virtual bool OnSendHeadersComplete(int status) OVERRIDE; virtual int OnSendBody() OVERRIDE; virtual int OnSendBodyComplete(int status, bool* eof) OVERRIDE; virtual int OnResponseReceived(const SpdyHeaderBlock& response, base::Time response_time, int status) OVERRIDE; virtual void OnHeadersSent() OVERRIDE; virtual int OnDataReceived(const char* buffer, int bytes) OVERRIDE; virtual void OnDataSent(int length) OVERRIDE; virtual void OnClose(int status) OVERRIDE; private: FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionSpdy2Test, FlowControlStallResume); FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionSpdy3Test, FlowControlStallResume); FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionSpdy3Test, FlowControlStallResumeAfterSettings); FRIEND_TEST_ALL_PREFIXES(SpdyNetworkTransactionSpdy3Test, FlowControlNegativeSendWindowSize); // Reads the data (whether chunked or not) from the request body stream and // sends the data by calling WriteStreamData on the underlying SpdyStream. int SendData(); // Call the user callback. void DoCallback(int rv); int OnRequestBodyReadCompleted(int status); void ScheduleBufferedReadCallback(); // Returns true if the callback is invoked. bool DoBufferedReadCallback(); bool ShouldWaitForMoreBufferedData() const; base::WeakPtrFactory weak_factory_; scoped_refptr stream_; scoped_refptr spdy_session_; // The request to send. const HttpRequestInfo* request_info_; UploadDataStream* request_body_stream_; // |response_info_| is the HTTP response data object which is filled in // when a SYN_REPLY comes in for the stream. // It is not owned by this stream object, or point to |push_response_info_|. HttpResponseInfo* response_info_; scoped_ptr push_response_info_; bool download_finished_; bool response_headers_received_; // Indicates waiting for more HEADERS. // We buffer the response body as it arrives asynchronously from the stream. // TODO(mbelshe): is this infinite buffering? std::list > response_body_; CompletionCallback callback_; // User provided buffer for the ReadResponseBody() response. scoped_refptr user_buffer_; int user_buffer_len_; // Temporary buffer used to read the request body from UploadDataStream. scoped_refptr raw_request_body_buf_; // Wraps raw_request_body_buf_ to read the remaining data progressively. scoped_refptr request_body_buf_; // Is there a scheduled read callback pending. bool buffered_read_callback_pending_; // Has more data been received from the network during the wait for the // scheduled read callback. bool more_read_data_pending_; // Is this spdy stream direct to the origin server (or to a proxy). bool direct_; DISALLOW_COPY_AND_ASSIGN(SpdyHttpStream); }; } // namespace net #endif // NET_SPDY_SPDY_HTTP_STREAM_H_