1// Copyright (c) 2011 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_STREAM_H_
6#define NET_SPDY_SPDY_STREAM_H_
7#pragma once
8
9#include <string>
10#include <vector>
11
12#include "base/basictypes.h"
13#include "base/memory/linked_ptr.h"
14#include "base/memory/ref_counted.h"
15#include "base/memory/scoped_ptr.h"
16#include "googleurl/src/gurl.h"
17#include "net/base/bandwidth_metrics.h"
18#include "net/base/io_buffer.h"
19#include "net/base/upload_data.h"
20#include "net/base/net_log.h"
21#include "net/spdy/spdy_framer.h"
22#include "net/spdy/spdy_protocol.h"
23
24namespace net {
25
26class AddressList;
27class IPEndPoint;
28class SpdySession;
29class SSLCertRequestInfo;
30class SSLInfo;
31
32// The SpdyStream is used by the SpdySession to represent each stream known
33// on the SpdySession.  This class provides interfaces for SpdySession to use.
34// Streams can be created either by the client or by the server.  When they
35// are initiated by the client, both the SpdySession and client object (such as
36// a SpdyNetworkTransaction) will maintain a reference to the stream.  When
37// initiated by the server, only the SpdySession will maintain any reference,
38// until such a time as a client object requests a stream for the path.
39class SpdyStream
40    : public base::RefCounted<SpdyStream>,
41      public ChunkCallback {
42 public:
43  // Delegate handles protocol specific behavior of spdy stream.
44  class Delegate {
45   public:
46    Delegate() {}
47
48    // Called when SYN frame has been sent.
49    // Returns true if no more data to be sent after SYN frame.
50    virtual bool OnSendHeadersComplete(int status) = 0;
51
52    // Called when stream is ready to send data.
53    // Returns network error code. OK when it successfully sent data.
54    virtual int OnSendBody() = 0;
55
56    // Called when data has been sent. |status| indicates network error
57    // or number of bytes that has been sent. On return, |eof| is set to true
58    // if no more data is available to send in the request body.
59    // Returns network error code. OK when it successfully sent data.
60    virtual int OnSendBodyComplete(int status, bool* eof) = 0;
61
62    // Called when the SYN_STREAM, SYN_REPLY, or HEADERS frames are received.
63    // Normal streams will receive a SYN_REPLY and optional HEADERS frames.
64    // Pushed streams will receive a SYN_STREAM and optional HEADERS frames.
65    // Because a stream may have a SYN_* frame and multiple HEADERS frames,
66    // this callback may be called multiple times.
67    // |status| indicates network error. Returns network error code.
68    virtual int OnResponseReceived(const spdy::SpdyHeaderBlock& response,
69                                   base::Time response_time,
70                                   int status) = 0;
71
72    // Called when data is received.
73    virtual void OnDataReceived(const char* data, int length) = 0;
74
75    // Called when data is sent.
76    virtual void OnDataSent(int length) = 0;
77
78    // Called when SpdyStream is closed.
79    virtual void OnClose(int status) = 0;
80
81    // Sets the callback to be invoked when a new chunk is available to upload.
82    virtual void set_chunk_callback(ChunkCallback* callback) = 0;
83
84   protected:
85    friend class base::RefCounted<Delegate>;
86    virtual ~Delegate() {}
87
88   private:
89    DISALLOW_COPY_AND_ASSIGN(Delegate);
90  };
91
92  // SpdyStream constructor
93  SpdyStream(SpdySession* session,
94             spdy::SpdyStreamId stream_id,
95             bool pushed,
96             const BoundNetLog& net_log);
97
98  // Set new |delegate|. |delegate| must not be NULL.
99  // If it already received SYN_REPLY or data, OnResponseReceived() or
100  // OnDataReceived() will be called.
101  void SetDelegate(Delegate* delegate);
102  Delegate* GetDelegate() { return delegate_; }
103
104  // Detach delegate from the stream. It will cancel the stream if it was not
105  // cancelled yet.  It is safe to call multiple times.
106  void DetachDelegate();
107
108  // Is this stream a pushed stream from the server.
109  bool pushed() const { return pushed_; }
110
111  spdy::SpdyStreamId stream_id() const { return stream_id_; }
112  void set_stream_id(spdy::SpdyStreamId stream_id) { stream_id_ = stream_id; }
113
114  bool response_received() const { return response_received_; }
115  void set_response_received() { response_received_ = true; }
116
117  // For pushed streams, we track a path to identify them.
118  const std::string& path() const { return path_; }
119  void set_path(const std::string& path) { path_ = path; }
120
121  int priority() const { return priority_; }
122  void set_priority(int priority) { priority_ = priority; }
123
124  int send_window_size() const { return send_window_size_; }
125  void set_send_window_size(int window_size) {
126    send_window_size_ = window_size;
127  }
128
129  int recv_window_size() const { return recv_window_size_; }
130  void set_recv_window_size(int window_size) {
131    recv_window_size_ = window_size;
132  }
133
134  void set_stalled_by_flow_control(bool stalled) {
135    stalled_by_flow_control_ = stalled;
136  }
137
138  // Increases |send_window_size_| with delta extracted from a WINDOW_UPDATE
139  // frame; sends a RST_STREAM if delta overflows |send_window_size_| and
140  // removes the stream from the session.
141  void IncreaseSendWindowSize(int delta_window_size);
142
143  // Decreases |send_window_size_| by the given number of bytes.
144  void DecreaseSendWindowSize(int delta_window_size);
145
146  int GetPeerAddress(AddressList* address) const;
147  int GetLocalAddress(IPEndPoint* address) const;
148
149  // Returns true if the underlying transport socket ever had any reads or
150  // writes.
151  bool WasEverUsed() const;
152
153  // Increases |recv_window_size_| by the given number of bytes, also sends
154  // a WINDOW_UPDATE frame.
155  void IncreaseRecvWindowSize(int delta_window_size);
156
157  // Decreases |recv_window_size_| by the given number of bytes, called
158  // whenever data is read.  May also send a RST_STREAM and remove the
159  // stream from the session if the resultant |recv_window_size_| is
160  // negative, since that would be a flow control violation.
161  void DecreaseRecvWindowSize(int delta_window_size);
162
163  const BoundNetLog& net_log() const { return net_log_; }
164
165  const linked_ptr<spdy::SpdyHeaderBlock>& spdy_headers() const;
166  void set_spdy_headers(const linked_ptr<spdy::SpdyHeaderBlock>& headers);
167  base::Time GetRequestTime() const;
168  void SetRequestTime(base::Time t);
169
170  // Called by the SpdySession when a response (e.g. a SYN_STREAM or SYN_REPLY)
171  // has been received for this stream. Returns a status code.
172  int OnResponseReceived(const spdy::SpdyHeaderBlock& response);
173
174  // Called by the SpdySession when late-bound headers are received for a
175  // stream. Returns a status code.
176  int OnHeaders(const spdy::SpdyHeaderBlock& headers);
177
178  // Called by the SpdySession when response data has been received for this
179  // stream.  This callback may be called multiple times as data arrives
180  // from the network, and will never be called prior to OnResponseReceived.
181  // |buffer| contains the data received.  The stream must copy any data
182  //          from this buffer before returning from this callback.
183  // |length| is the number of bytes received or an error.
184  //         A zero-length count does not indicate end-of-stream.
185  void OnDataReceived(const char* buffer, int bytes);
186
187  // Called by the SpdySession when a write has completed.  This callback
188  // will be called multiple times for each write which completes.  Writes
189  // include the SYN_STREAM write and also DATA frame writes.
190  // |result| is the number of bytes written or a net error code.
191  void OnWriteComplete(int bytes);
192
193  // Called by the SpdySession when the request is finished.  This callback
194  // will always be called at the end of the request and signals to the
195  // stream that the stream has no more network events.  No further callbacks
196  // to the stream will be made after this call.
197  // |status| is an error code or OK.
198  void OnClose(int status);
199
200  void Cancel();
201  bool cancelled() const { return cancelled_; }
202  bool closed() const { return io_state_ == STATE_DONE; }
203
204  // Interface for Spdy[Http|WebSocket]Stream to use.
205
206  // Sends the request.
207  // For non push stream, it will send SYN_STREAM frame.
208  int SendRequest(bool has_upload_data);
209
210  // Sends DATA frame.
211  int WriteStreamData(IOBuffer* data, int length,
212                      spdy::SpdyDataFlags flags);
213
214  // Fills SSL info in |ssl_info| and returns true when SSL is in use.
215  bool GetSSLInfo(SSLInfo* ssl_info, bool* was_npn_negotiated);
216
217  // Fills SSL Certificate Request info |cert_request_info| and returns
218  // true when SSL is in use.
219  bool GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info);
220
221  bool is_idle() const {
222    return io_state_ == STATE_OPEN || io_state_ == STATE_DONE;
223  }
224
225  int response_status() const { return response_status_; }
226
227  // Returns true if the URL for this stream is known.
228  bool HasUrl() const;
229
230  // Get the URL associated with this stream.  Only valid when has_url() is
231  // true.
232  GURL GetUrl() const;
233
234  // ChunkCallback methods.
235  virtual void OnChunkAvailable();
236
237 private:
238  enum State {
239    STATE_NONE,
240    STATE_SEND_HEADERS,
241    STATE_SEND_HEADERS_COMPLETE,
242    STATE_SEND_BODY,
243    STATE_SEND_BODY_COMPLETE,
244    STATE_WAITING_FOR_RESPONSE,
245    STATE_OPEN,
246    STATE_DONE
247  };
248
249  friend class base::RefCounted<SpdyStream>;
250  virtual ~SpdyStream();
251
252  // Try to make progress sending/receiving the request/response.
253  int DoLoop(int result);
254
255  // The implementations of each state of the state machine.
256  int DoSendHeaders();
257  int DoSendHeadersComplete(int result);
258  int DoSendBody();
259  int DoSendBodyComplete(int result);
260  int DoReadHeaders();
261  int DoReadHeadersComplete(int result);
262  int DoOpen(int result);
263
264  // Update the histograms.  Can safely be called repeatedly, but should only
265  // be called after the stream has completed.
266  void UpdateHistograms();
267
268  // When a server pushed stream is first created, this function is posted on
269  // the MessageLoop to replay all the data that the server has already sent.
270  void PushedStreamReplayData();
271
272  // There is a small period of time between when a server pushed stream is
273  // first created, and the pushed data is replayed. Any data received during
274  // this time should continue to be buffered.
275  bool continue_buffering_data_;
276
277  spdy::SpdyStreamId stream_id_;
278  std::string path_;
279  int priority_;
280
281  // Flow control variables.
282  bool stalled_by_flow_control_;
283  int send_window_size_;
284  int recv_window_size_;
285
286  const bool pushed_;
287  ScopedBandwidthMetrics metrics_;
288  bool response_received_;
289
290  scoped_refptr<SpdySession> session_;
291
292  // The transaction should own the delegate.
293  SpdyStream::Delegate* delegate_;
294
295  // The request to send.
296  linked_ptr<spdy::SpdyHeaderBlock> request_;
297
298  // The time at which the request was made that resulted in this response.
299  // For cached responses, this time could be "far" in the past.
300  base::Time request_time_;
301
302  linked_ptr<spdy::SpdyHeaderBlock> response_;
303  base::Time response_time_;
304
305  State io_state_;
306
307  // Since we buffer the response, we also buffer the response status.
308  // Not valid until the stream is closed.
309  int response_status_;
310
311  bool cancelled_;
312  bool has_upload_data_;
313
314  BoundNetLog net_log_;
315
316  base::TimeTicks send_time_;
317  base::TimeTicks recv_first_byte_time_;
318  base::TimeTicks recv_last_byte_time_;
319  int send_bytes_;
320  int recv_bytes_;
321  // Data received before delegate is attached.
322  std::vector<scoped_refptr<IOBufferWithSize> > pending_buffers_;
323
324  DISALLOW_COPY_AND_ASSIGN(SpdyStream);
325};
326
327}  // namespace net
328
329#endif  // NET_SPDY_SPDY_STREAM_H_
330