1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef NET_SPDY_SPDY_HTTP_STREAM_H_
6#define NET_SPDY_SPDY_HTTP_STREAM_H_
7
8#include <list>
9
10#include "base/basictypes.h"
11#include "base/memory/ref_counted.h"
12#include "base/memory/weak_ptr.h"
13#include "net/base/completion_callback.h"
14#include "net/base/net_log.h"
15#include "net/http/http_stream.h"
16#include "net/spdy/spdy_read_queue.h"
17#include "net/spdy/spdy_session.h"
18#include "net/spdy/spdy_stream.h"
19
20namespace net {
21
22class DrainableIOBuffer;
23struct HttpRequestInfo;
24class HttpResponseInfo;
25class IOBuffer;
26class SpdySession;
27class UploadDataStream;
28
29// The SpdyHttpStream is a HTTP-specific type of stream known to a SpdySession.
30class NET_EXPORT_PRIVATE SpdyHttpStream : public SpdyStream::Delegate,
31                                          public HttpStream {
32 public:
33  // |spdy_session| must not be NULL.
34  SpdyHttpStream(const base::WeakPtr<SpdySession>& spdy_session, bool direct);
35  virtual ~SpdyHttpStream();
36
37  SpdyStream* stream() { return stream_.get(); }
38
39  // Cancels any callbacks from being invoked and deletes the stream.
40  void Cancel();
41
42  // HttpStream implementation.
43
44  virtual int InitializeStream(const HttpRequestInfo* request_info,
45                               RequestPriority priority,
46                               const BoundNetLog& net_log,
47                               const CompletionCallback& callback) OVERRIDE;
48
49  virtual int SendRequest(const HttpRequestHeaders& headers,
50                          HttpResponseInfo* response,
51                          const CompletionCallback& callback) OVERRIDE;
52  virtual UploadProgress GetUploadProgress() const OVERRIDE;
53  virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE;
54  virtual int ReadResponseBody(IOBuffer* buf,
55                               int buf_len,
56                               const CompletionCallback& callback) OVERRIDE;
57  virtual void Close(bool not_reusable) OVERRIDE;
58  virtual HttpStream* RenewStreamForAuth() OVERRIDE;
59  virtual bool IsResponseBodyComplete() const OVERRIDE;
60  virtual bool CanFindEndOfResponse() const OVERRIDE;
61
62  // Must not be called if a NULL SpdySession was pssed into the
63  // constructor.
64  virtual bool IsConnectionReused() const OVERRIDE;
65
66  virtual void SetConnectionReused() OVERRIDE;
67  virtual bool IsConnectionReusable() const OVERRIDE;
68  virtual int64 GetTotalReceivedBytes() const OVERRIDE;
69  virtual bool GetLoadTimingInfo(
70      LoadTimingInfo* load_timing_info) const OVERRIDE;
71  virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE;
72  virtual void GetSSLCertRequestInfo(
73      SSLCertRequestInfo* cert_request_info) OVERRIDE;
74  virtual bool IsSpdyHttpStream() const OVERRIDE;
75  virtual void Drain(HttpNetworkSession* session) OVERRIDE;
76  virtual void SetPriority(RequestPriority priority) OVERRIDE;
77
78  // SpdyStream::Delegate implementation.
79  virtual void OnRequestHeadersSent() OVERRIDE;
80  virtual SpdyResponseHeadersStatus OnResponseHeadersUpdated(
81      const SpdyHeaderBlock& response_headers) OVERRIDE;
82  virtual void OnDataReceived(scoped_ptr<SpdyBuffer> buffer) OVERRIDE;
83  virtual void OnDataSent() OVERRIDE;
84  virtual void OnClose(int status) OVERRIDE;
85
86 private:
87  // Must be called only when |request_info_| is non-NULL.
88  bool HasUploadData() const;
89
90  void OnStreamCreated(const CompletionCallback& callback, int rv);
91
92  // Reads the remaining data (whether chunked or not) from the
93  // request body stream and sends it if there's any. The read and
94  // subsequent sending may happen asynchronously. Must be called only
95  // when HasUploadData() is true.
96  void ReadAndSendRequestBodyData();
97
98  // Called when data has just been read from the request body stream;
99  // does the actual sending of data.
100  void OnRequestBodyReadCompleted(int status);
101
102  // Call the user callback.
103  void DoCallback(int rv);
104
105  void ScheduleBufferedReadCallback();
106
107  // Returns true if the callback is invoked.
108  bool DoBufferedReadCallback();
109  bool ShouldWaitForMoreBufferedData() const;
110
111  const base::WeakPtr<SpdySession> spdy_session_;
112  bool is_reused_;
113  SpdyStreamRequest stream_request_;
114  base::WeakPtr<SpdyStream> stream_;
115
116  bool stream_closed_;
117
118  // Set only when |stream_closed_| is true.
119  int closed_stream_status_;
120  SpdyStreamId closed_stream_id_;
121  bool closed_stream_has_load_timing_info_;
122  LoadTimingInfo closed_stream_load_timing_info_;
123  int64 closed_stream_received_bytes_;
124
125  // The request to send.
126  const HttpRequestInfo* request_info_;
127
128  // |response_info_| is the HTTP response data object which is filled in
129  // when a SYN_REPLY comes in for the stream.
130  // It is not owned by this stream object, or point to |push_response_info_|.
131  HttpResponseInfo* response_info_;
132
133  scoped_ptr<HttpResponseInfo> push_response_info_;
134
135  // We don't use SpdyStream's |response_header_status_| as we
136  // sometimes call back into our delegate before it is updated.
137  SpdyResponseHeadersStatus response_headers_status_;
138
139  // We buffer the response body as it arrives asynchronously from the stream.
140  SpdyReadQueue response_body_queue_;
141
142  CompletionCallback callback_;
143
144  // User provided buffer for the ReadResponseBody() response.
145  scoped_refptr<IOBuffer> user_buffer_;
146  int user_buffer_len_;
147
148  // Temporary buffer used to read the request body from UploadDataStream.
149  scoped_refptr<IOBufferWithSize> request_body_buf_;
150  int request_body_buf_size_;
151
152  // Is there a scheduled read callback pending.
153  bool buffered_read_callback_pending_;
154  // Has more data been received from the network during the wait for the
155  // scheduled read callback.
156  bool more_read_data_pending_;
157
158  // Is this spdy stream direct to the origin server (or to a proxy).
159  bool direct_;
160
161  base::WeakPtrFactory<SpdyHttpStream> weak_factory_;
162
163  DISALLOW_COPY_AND_ASSIGN(SpdyHttpStream);
164};
165
166}  // namespace net
167
168#endif  // NET_SPDY_SPDY_HTTP_STREAM_H_
169