• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2009 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_FLIP_FLIP_STREAM_H_
6 #define NET_FLIP_FLIP_STREAM_H_
7 
8 #include <string>
9 #include <list>
10 
11 #include "base/basictypes.h"
12 #include "base/ref_counted.h"
13 #include "base/scoped_ptr.h"
14 #include "base/singleton.h"
15 #include "net/base/bandwidth_metrics.h"
16 #include "net/base/completion_callback.h"
17 #include "net/base/io_buffer.h"
18 #include "net/base/load_log.h"
19 #include "net/flip/flip_framer.h"
20 #include "net/flip/flip_protocol.h"
21 
22 namespace net {
23 
24 class FlipSession;
25 class HttpRequestInfo;
26 class HttpResponseInfo;
27 class UploadData;
28 class UploadDataStream;
29 
30 // The FlipStream is used by the FlipSession to represent each stream known
31 // on the FlipSession.
32 // Streams can be created either by the client or by the server.  When they
33 // are initiated by the client, both the FlipSession and client object (such as
34 // a FlipNetworkTransaction) will maintain a reference to the stream.  When
35 // initiated by the server, only the FlipSession will maintain any reference,
36 // until such a time as a client object requests a stream for the path.
37 class FlipStream : public base::RefCounted<FlipStream> {
38  public:
39   // FlipStream constructor
40   FlipStream(FlipSession* session, flip::FlipStreamId stream_id, bool pushed,
41              LoadLog* log);
42 
43   // Ideally I'd use two abstract classes as interfaces for these two sections,
44   // but since we're ref counted, I can't make both abstract classes inherit
45   // from RefCounted or we'll have two separate ref counts for the same object.
46   // TODO(willchan): Consider using linked_ptr here orcreating proxy wrappers
47   // for FlipStream to provide the appropriate interface.
48 
49   // ===================================================
50   // Interface for [Http|Flip]NetworkTransaction to use.
51 
52   // Sends the request.  If |upload_data| is non-NULL, sends that in the request
53   // body.  |callback| is used when this completes asynchronously.  Note that
54   // the actual SYN_STREAM packet will have already been sent by this point.
55   // Also note that FlipStream takes ownership of |upload_data|.
56   int SendRequest(UploadDataStream* upload_data,
57                   HttpResponseInfo* response,
58                   CompletionCallback* callback);
59 
60   // Reads the response headers.  Returns a net error code.
61   int ReadResponseHeaders(CompletionCallback* callback);
62 
63   // Reads the response body.  Returns a net error code or the number of bytes
64   // read.
65   int ReadResponseBody(
66       IOBuffer* buf, int buf_len, CompletionCallback* callback);
67 
68   // Cancels the stream.  Note that this does not immediately cause deletion of
69   // the stream.  This function is used to cancel any callbacks from being
70   // invoked.  TODO(willchan): It should also free up any memory associated with
71   // the stream, such as IOBuffers.
72   void Cancel();
73 
74   // Returns the number of bytes uploaded.
75   uint64 GetUploadProgress() const;
76 
77   const HttpResponseInfo* GetResponseInfo() const;
78 
79   // Is this stream a pushed stream from the server.
pushed()80   bool pushed() const { return pushed_; }
81 
82   // =================================
83   // Interface for FlipSession to use.
84 
stream_id()85   flip::FlipStreamId stream_id() const { return stream_id_; }
set_stream_id(flip::FlipStreamId stream_id)86   void set_stream_id(flip::FlipStreamId stream_id) { stream_id_ = stream_id; }
87 
88   // For pushed streams, we track a path to identify them.
path()89   const std::string& path() const { return path_; }
set_path(const std::string & path)90   void set_path(const std::string& path) { path_ = path; }
91 
priority()92   int priority() const { return priority_; }
set_priority(int priority)93   void set_priority(int priority) { priority_ = priority; }
94 
95   // Called by the FlipSession when a response (e.g. a SYN_REPLY) has been
96   // received for this stream.  |path| is the path of the URL for a server
97   // initiated stream, otherwise is empty.
98   void OnResponseReceived(const HttpResponseInfo& response);
99 
100   // Called by the FlipSession when response data has been received for this
101   // stream.  This callback may be called multiple times as data arrives
102   // from the network, and will never be called prior to OnResponseReceived.
103   // |buffer| contains the data received.  The stream must copy any data
104   //          from this buffer before returning from this callback.
105   // |length| is the number of bytes received or an error.
106   //         A zero-length count does not indicate end-of-stream.
107   // Returns true on success and false on error.
108   bool OnDataReceived(const char* buffer, int bytes);
109 
110   // Called by the FlipSession when a write has completed.  This callback
111   // will be called multiple times for each write which completes.  Writes
112   // include the SYN_STREAM write and also DATA frame writes.
113   // |result| is the number of bytes written or a net error code.
114   void OnWriteComplete(int status);
115 
116   // Called by the FlipSession when the request is finished.  This callback
117   // will always be called at the end of the request and signals to the
118   // stream that the stream has no more network events.  No further callbacks
119   // to the stream will be made after this call.
120   // |status| is an error code or OK.
121   void OnClose(int status);
122 
cancelled()123   bool cancelled() const { return cancelled_; }
124 
125  private:
126   friend class base::RefCounted<FlipStream>;
127 
128   enum State {
129     STATE_NONE,
130     STATE_SEND_HEADERS,
131     STATE_SEND_HEADERS_COMPLETE,
132     STATE_SEND_BODY,
133     STATE_SEND_BODY_COMPLETE,
134     STATE_READ_HEADERS,
135     STATE_READ_HEADERS_COMPLETE,
136     STATE_READ_BODY,
137     STATE_READ_BODY_COMPLETE,
138     STATE_DONE
139   };
140 
141   ~FlipStream();
142 
143   // Try to make progress sending/receiving the request/response.
144   int DoLoop(int result);
145 
146   // Call the user callback.
147   void DoCallback(int rv);
148 
149   // The implementations of each state of the state machine.
150   int DoSendHeaders();
151   int DoSendHeadersComplete(int result);
152   int DoSendBody();
153   int DoSendBodyComplete(int result);
154   int DoReadHeaders();
155   int DoReadHeadersComplete(int result);
156   int DoReadBody();
157   int DoReadBodyComplete(int result);
158 
159   // Update the histograms.  Can safely be called repeatedly, but should only
160   // be called after the stream has completed.
161   void UpdateHistograms();
162 
163   flip::FlipStreamId stream_id_;
164   std::string path_;
165   int priority_;
166   const bool pushed_;
167   // We buffer the response body as it arrives asynchronously from the stream.
168   // TODO(mbelshe):  is this infinite buffering?
169   std::list<scoped_refptr<IOBufferWithSize> > response_body_;
170   bool download_finished_;
171   ScopedBandwidthMetrics metrics_;
172 
173   scoped_refptr<FlipSession> session_;
174 
175   HttpResponseInfo* response_;
176   scoped_ptr<UploadDataStream> request_body_stream_;
177 
178   bool response_complete_;  // TODO(mbelshe): fold this into the io_state.
179   State io_state_;
180 
181   // Since we buffer the response, we also buffer the response status.
182   // Not valid until response_complete_ is true.
183   int response_status_;
184 
185   CompletionCallback* user_callback_;
186 
187   // User provided buffer for the ReadResponseBody() response.
188   scoped_refptr<IOBuffer> user_buffer_;
189   int user_buffer_len_;
190 
191   bool cancelled_;
192 
193   scoped_refptr<LoadLog> load_log_;
194 
195   base::TimeTicks send_time_;
196   base::TimeTicks recv_first_byte_time_;
197   base::TimeTicks recv_last_byte_time_;
198   int send_bytes_;
199   int recv_bytes_;
200   bool histograms_recorded_;
201 
202   DISALLOW_COPY_AND_ASSIGN(FlipStream);
203 };
204 
205 }  // namespace net
206 
207 #endif  // NET_FLIP_FLIP_STREAM_H_
208