|  | // 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); | 
|  | ~SpdyHttpStream() override; | 
|  |  | 
|  | SpdyStream* stream() { return stream_.get(); } | 
|  |  | 
|  | // Cancels any callbacks from being invoked and deletes the stream. | 
|  | void Cancel(); | 
|  |  | 
|  | // HttpStream implementation. | 
|  |  | 
|  | int InitializeStream(const HttpRequestInfo* request_info, | 
|  | RequestPriority priority, | 
|  | const BoundNetLog& net_log, | 
|  | const CompletionCallback& callback) override; | 
|  |  | 
|  | int SendRequest(const HttpRequestHeaders& headers, | 
|  | HttpResponseInfo* response, | 
|  | const CompletionCallback& callback) override; | 
|  | UploadProgress GetUploadProgress() const override; | 
|  | int ReadResponseHeaders(const CompletionCallback& callback) override; | 
|  | int ReadResponseBody(IOBuffer* buf, | 
|  | int buf_len, | 
|  | const CompletionCallback& callback) override; | 
|  | void Close(bool not_reusable) override; | 
|  | HttpStream* RenewStreamForAuth() override; | 
|  | bool IsResponseBodyComplete() const override; | 
|  | bool CanFindEndOfResponse() const override; | 
|  |  | 
|  | // Must not be called if a NULL SpdySession was pssed into the | 
|  | // constructor. | 
|  | bool IsConnectionReused() const override; | 
|  |  | 
|  | void SetConnectionReused() override; | 
|  | bool IsConnectionReusable() const override; | 
|  | int64 GetTotalReceivedBytes() const override; | 
|  | bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override; | 
|  | void GetSSLInfo(SSLInfo* ssl_info) override; | 
|  | void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override; | 
|  | bool IsSpdyHttpStream() const override; | 
|  | void Drain(HttpNetworkSession* session) override; | 
|  | void SetPriority(RequestPriority priority) override; | 
|  |  | 
|  | // SpdyStream::Delegate implementation. | 
|  | void OnRequestHeadersSent() override; | 
|  | SpdyResponseHeadersStatus OnResponseHeadersUpdated( | 
|  | const SpdyHeaderBlock& response_headers) override; | 
|  | void OnDataReceived(scoped_ptr<SpdyBuffer> buffer) override; | 
|  | void OnDataSent() override; | 
|  | 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_ |