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