Home | History | Annotate | Download | only in flip
      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.
     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.
     78   static void SetSSLMode(bool enable) { use_ssl_ = enable; }
     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.
     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