• 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_SESSION_H_
6 #define NET_FLIP_FLIP_SESSION_H_
7 
8 #include <deque>
9 #include <list>
10 #include <map>
11 #include <queue>
12 #include <string>
13 
14 #include "base/ref_counted.h"
15 #include "net/base/io_buffer.h"
16 #include "net/base/load_states.h"
17 #include "net/base/net_errors.h"
18 #include "net/base/request_priority.h"
19 #include "net/base/ssl_config_service.h"
20 #include "net/base/upload_data_stream.h"
21 #include "net/flip/flip_framer.h"
22 #include "net/flip/flip_io_buffer.h"
23 #include "net/flip/flip_protocol.h"
24 #include "net/flip/flip_session_pool.h"
25 #include "net/socket/client_socket.h"
26 #include "net/socket/client_socket_handle.h"
27 #include "testing/platform_test.h"
28 
29 namespace net {
30 
31 class FlipStream;
32 class HttpNetworkSession;
33 class HttpRequestInfo;
34 class HttpResponseInfo;
35 class LoadLog;
36 class SSLInfo;
37 
38 class FlipSession : public base::RefCounted<FlipSession>,
39                     public flip::FlipFramerVisitorInterface {
40  public:
41   // Get the domain for this FlipSession.
domain()42   const std::string& domain() const { return domain_; }
43 
44   // Connect the FLIP Socket.
45   // Returns net::Error::OK on success.
46   // Note that this call does not wait for the connect to complete. Callers can
47   // immediately start using the FlipSession while it connects.
48   net::Error Connect(const std::string& group_name,
49                      const HostResolver::RequestInfo& host,
50                      RequestPriority priority,
51                      LoadLog* load_log);
52 
53   // Get a stream for a given |request|.  In the typical case, this will involve
54   // the creation of a new stream (and will send the SYN frame).  If the server
55   // initiates a stream, it might already exist for a given path.  The server
56   // might also not have initiated the stream yet, but indicated it will via
57   // X-Associated-Content.
58   // Returns the new or existing stream.  Never returns NULL.
59   scoped_refptr<FlipStream> GetOrCreateStream(const HttpRequestInfo& request,
60       const UploadDataStream* upload_data, LoadLog* log);
61 
62   // Write a data frame to the stream.
63   // Used to create and queue a data frame for the given stream.
64   int WriteStreamData(flip::FlipStreamId stream_id, net::IOBuffer* data,
65                       int len);
66 
67   // Cancel a stream.
68   bool CancelStream(flip::FlipStreamId stream_id);
69 
70   // Check if a stream is active.
71   bool IsStreamActive(flip::FlipStreamId stream_id) const;
72 
73   // The LoadState is used for informing the user of the current network
74   // status, such as "resolving host", "connecting", etc.
75   LoadState GetLoadState() const;
76 
77   // Enable or disable SSL.
SetSSLMode(bool enable)78   static void SetSSLMode(bool enable) { use_ssl_ = enable; }
SSLMode()79   static bool SSLMode() { return use_ssl_; }
80 
81  protected:
82   friend class FlipSessionPool;
83 
84   enum State {
85     IDLE,
86     CONNECTING,
87     CONNECTED,
88     CLOSED
89   };
90 
91   // Provide access to the framer for testing.
GetFramer()92   flip::FlipFramer* GetFramer() { return &flip_framer_; }
93 
94   // Create a new FlipSession.
95   // |host| is the hostname that this session connects to.
96   FlipSession(const std::string& host, HttpNetworkSession* session);
97 
98   // Closes all open streams.  Used as part of shutdown.
99   void CloseAllStreams(net::Error code);
100 
101  private:
102   friend class base::RefCounted<FlipSession>;
103 
104   typedef std::map<int, scoped_refptr<FlipStream> > ActiveStreamMap;
105   typedef std::list<scoped_refptr<FlipStream> > ActiveStreamList;
106   typedef std::map<std::string, scoped_refptr<FlipStream> > PendingStreamMap;
107   typedef std::priority_queue<FlipIOBuffer> OutputQueue;
108 
109   virtual ~FlipSession();
110 
111   // Used by FlipSessionPool to initialize with a pre-existing socket.
112   void InitializeWithSocket(ClientSocketHandle* connection);
113 
114   // FlipFramerVisitorInterface
115   virtual void OnError(flip::FlipFramer*);
116   virtual void OnStreamFrameData(flip::FlipStreamId stream_id,
117                                  const char* data,
118                                  size_t len);
119   virtual void OnControl(const flip::FlipControlFrame* frame);
120 
121   // Control frame handlers.
122   void OnSyn(const flip::FlipSynStreamControlFrame* frame,
123              const flip::FlipHeaderBlock* headers);
124   void OnSynReply(const flip::FlipSynReplyControlFrame* frame,
125                   const flip::FlipHeaderBlock* headers);
126   void OnFin(const flip::FlipFinStreamControlFrame* frame);
127 
128   // IO Callbacks
129   void OnTCPConnect(int result);
130   void OnSSLConnect(int result);
131   void OnReadComplete(int result);
132   void OnWriteComplete(int result);
133 
134   // Start reading from the socket.
135   void ReadSocket();
136 
137   // Write current data to the socket.
138   void WriteSocketLater();
139   void WriteSocket();
140 
141   // Get a new stream id.
142   int GetNewStreamId();
143 
144   // Closes this session.  This will close all active streams and mark
145   // the session as permanently closed.
146   // |err| should not be OK; this function is intended to be called on
147   // error.
148   void CloseSessionOnError(net::Error err);
149 
150   // Track active streams in the active stream list.
151   void ActivateStream(FlipStream* stream);
152   void DeactivateStream(flip::FlipStreamId id);
153 
154   // Check if we have a pending pushed-stream for this url
155   // Returns the stream if found (and returns it from the pending
156   // list), returns NULL otherwise.
157   scoped_refptr<FlipStream> GetPushStream(const std::string& url);
158 
159   void GetSSLInfo(SSLInfo* ssl_info);
160 
161   // Callbacks for the Flip session.
162   CompletionCallbackImpl<FlipSession> connect_callback_;
163   CompletionCallbackImpl<FlipSession> ssl_connect_callback_;
164   CompletionCallbackImpl<FlipSession> read_callback_;
165   CompletionCallbackImpl<FlipSession> write_callback_;
166 
167   // The domain this session is connected to.
168   std::string domain_;
169 
170   SSLConfig ssl_config_;
171 
172   scoped_refptr<HttpNetworkSession> session_;
173 
174   // The socket handle for this session.
175   scoped_ptr<ClientSocketHandle> connection_;
176 
177   // The read buffer used to read data from the socket.
178   scoped_refptr<IOBuffer> read_buffer_;
179   bool read_pending_;
180 
181   int stream_hi_water_mark_;  // The next stream id to use.
182 
183   // TODO(mbelshe): We need to track these stream lists better.
184   //                I suspect it is possible to remove a stream from
185   //                one list, but not the other.
186 
187   // Map from stream id to all active streams.  Streams are active in the sense
188   // that they have a consumer (typically FlipNetworkTransaction and regardless
189   // of whether or not there is currently any ongoing IO [might be waiting for
190   // the server to start pushing the stream]) or there are still network events
191   // incoming even though the consumer has already gone away (cancellation).
192   // TODO(willchan): Perhaps we should separate out cancelled streams and move
193   // them into a separate ActiveStreamMap, and not deliver network events to
194   // them?
195   ActiveStreamMap active_streams_;
196   // List of all the streams that have already started to be pushed by the
197   // server, but do not have consumers yet.
198   ActiveStreamList pushed_streams_;
199   // List of streams declared in X-Associated-Content headers, but do not have
200   // consumers yet.
201   // The key is a string representing the path of the URI being pushed.
202   PendingStreamMap pending_streams_;
203 
204   // As we gather data to be sent, we put it into the output queue.
205   OutputQueue queue_;
206 
207   // The packet we are currently sending.
208   bool write_pending_;            // Will be true when a write is in progress.
209   FlipIOBuffer in_flight_write_;  // This is the write buffer in progress.
210 
211   // Flag if we have a pending message scheduled for WriteSocket.
212   bool delayed_write_pending_;
213 
214   // Flag if we're using an SSL connection for this FlipSession.
215   bool is_secure_;
216 
217   // Flip Frame state.
218   flip::FlipFramer flip_framer_;
219 
220   // If an error has occurred on the session, the session is effectively
221   // dead.  Record this error here.  When no error has occurred, |error_| will
222   // be OK.
223   net::Error error_;
224   State state_;
225 
226   // Some statistics counters for the session.
227   int streams_initiated_count_;
228   int streams_pushed_count_;
229   int streams_pushed_and_claimed_count_;
230   int streams_abandoned_count_;
231 
232   static bool use_ssl_;
233 };
234 
235 }  // namespace net
236 
237 #endif  // NET_FLIP_FLIP_SESSION_H_
238