// 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 <list> #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_read_queue.h" #include "net/spdy/spdy_session.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: // |spdy_session| must not be NULL. SpdyHttpStream(const base::WeakPtr<SpdySession>& spdy_session, bool direct); virtual ~SpdyHttpStream(); 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, RequestPriority priority, const BoundNetLog& net_log, const CompletionCallback& callback) OVERRIDE; virtual int SendRequest(const HttpRequestHeaders& headers, HttpResponseInfo* response, const CompletionCallback& callback) OVERRIDE; virtual UploadProgress GetUploadProgress() const OVERRIDE; virtual int ReadResponseHeaders(const CompletionCallback& callback) 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; // Must not be called if a NULL SpdySession was pssed into the // constructor. virtual bool IsConnectionReused() const OVERRIDE; virtual void SetConnectionReused() OVERRIDE; virtual bool IsConnectionReusable() const OVERRIDE; virtual int64 GetTotalReceivedBytes() const OVERRIDE; virtual bool GetLoadTimingInfo( LoadTimingInfo* load_timing_info) const OVERRIDE; virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE; virtual void GetSSLCertRequestInfo( SSLCertRequestInfo* cert_request_info) OVERRIDE; virtual bool IsSpdyHttpStream() const OVERRIDE; virtual void Drain(HttpNetworkSession* session) OVERRIDE; virtual void SetPriority(RequestPriority priority) OVERRIDE; // SpdyStream::Delegate implementation. virtual void OnRequestHeadersSent() OVERRIDE; virtual SpdyResponseHeadersStatus OnResponseHeadersUpdated( const SpdyHeaderBlock& response_headers) OVERRIDE; virtual void OnDataReceived(scoped_ptr<SpdyBuffer> buffer) OVERRIDE; virtual void OnDataSent() OVERRIDE; virtual void OnClose(int status) OVERRIDE; private: // Must be called only when |request_info_| is non-NULL. bool HasUploadData() const; void OnStreamCreated(const CompletionCallback& callback, int rv); // Reads the remaining data (whether chunked or not) from the // request body stream and sends it if there's any. The read and // subsequent sending may happen asynchronously. Must be called only // when HasUploadData() is true. void ReadAndSendRequestBodyData(); // Called when data has just been read from the request body stream; // does the actual sending of data. void OnRequestBodyReadCompleted(int status); // Call the user callback. void DoCallback(int rv); void ScheduleBufferedReadCallback(); // Returns true if the callback is invoked. bool DoBufferedReadCallback(); bool ShouldWaitForMoreBufferedData() const; const base::WeakPtr<SpdySession> spdy_session_; bool is_reused_; SpdyStreamRequest stream_request_; base::WeakPtr<SpdyStream> stream_; bool stream_closed_; // Set only when |stream_closed_| is true. int closed_stream_status_; SpdyStreamId closed_stream_id_; bool closed_stream_has_load_timing_info_; LoadTimingInfo closed_stream_load_timing_info_; int64 closed_stream_received_bytes_; // The request to send. const HttpRequestInfo* request_info_; // |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<HttpResponseInfo> push_response_info_; // We don't use SpdyStream's |response_header_status_| as we // sometimes call back into our delegate before it is updated. SpdyResponseHeadersStatus response_headers_status_; // We buffer the response body as it arrives asynchronously from the stream. SpdyReadQueue response_body_queue_; CompletionCallback callback_; // User provided buffer for the ReadResponseBody() response. scoped_refptr<IOBuffer> user_buffer_; int user_buffer_len_; // Temporary buffer used to read the request body from UploadDataStream. scoped_refptr<IOBufferWithSize> request_body_buf_; int request_body_buf_size_; // 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_; base::WeakPtrFactory<SpdyHttpStream> weak_factory_; DISALLOW_COPY_AND_ASSIGN(SpdyHttpStream); }; } // namespace net #endif // NET_SPDY_SPDY_HTTP_STREAM_H_