[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 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" |
[email protected] | 18c53ae | 2009-10-01 18:18:52 | [diff] [blame] | 18 | #include "net/base/ssl_config_service.h" |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 19 | #include "net/base/upload_data_stream.h" |
| 20 | #include "net/flip/flip_framer.h" |
[email protected] | eebc0b4 | 2009-11-04 00:17:13 | [diff] [blame] | 21 | #include "net/flip/flip_io_buffer.h" |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 22 | #include "net/flip/flip_protocol.h" |
| 23 | #include "net/flip/flip_session_pool.h" |
| 24 | #include "net/socket/client_socket.h" |
| 25 | #include "net/socket/client_socket_handle.h" |
| 26 | #include "testing/platform_test.h" |
| 27 | |
| 28 | namespace net { |
| 29 | |
[email protected] | cd314c82 | 2009-10-29 03:13:06 | [diff] [blame] | 30 | class FlipStream; |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 31 | class HttpNetworkSession; |
| 32 | class HttpRequestInfo; |
| 33 | class HttpResponseInfo; |
| 34 | |
[email protected] | 2329792 | 2009-10-28 20:12:36 | [diff] [blame] | 35 | // The FlipDelegate interface is an interface so that the FlipSession |
| 36 | // can interact with the provider of a given Flip stream. |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 37 | class FlipDelegate { |
| 38 | public: |
| 39 | virtual ~FlipDelegate() {} |
[email protected] | 2329792 | 2009-10-28 20:12:36 | [diff] [blame] | 40 | |
| 41 | // Accessors from the delegate. |
| 42 | |
| 43 | // The delegate provides access to the HttpRequestInfo for use by the flip |
| 44 | // session. |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 45 | virtual const HttpRequestInfo* request() = 0; |
[email protected] | 2329792 | 2009-10-28 20:12:36 | [diff] [blame] | 46 | |
| 47 | // The delegate provides access to an UploadDataStream for use by the |
| 48 | // flip session. If the delegate is not uploading content, this call |
| 49 | // must return NULL. |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 50 | virtual const UploadDataStream* data() = 0; |
| 51 | |
[email protected] | 2329792 | 2009-10-28 20:12:36 | [diff] [blame] | 52 | // Callbacks. |
| 53 | |
| 54 | // Called by the FlipSession when UploadData has been sent. If the |
| 55 | // request has no upload data, this call will never be called. This |
| 56 | // callback may be called multiple times if large amounts of data are |
| 57 | // being uploaded. This callback will only be called prior to the |
| 58 | // OnRequestSent callback. |
| 59 | // |result| contains the number of bytes written or an error code. |
| 60 | virtual void OnUploadDataSent(int result) = 0; |
| 61 | |
| 62 | // Called by the FlipSession when the Request has been entirely sent. |
| 63 | // If the request contains upload data, all upload data has been sent. |
| 64 | // |result| contains an error code if a failure has occurred or OK |
| 65 | // on success. |
| 66 | virtual void OnRequestSent(int result) = 0; |
| 67 | |
| 68 | // Called by the FlipSession when a response (e.g. a SYN_REPLY) has been |
| 69 | // received for this request. This callback will never be called prior |
| 70 | // to the OnRequestSent() callback. |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 71 | virtual void OnResponseReceived(HttpResponseInfo* response) = 0; |
[email protected] | 2329792 | 2009-10-28 20:12:36 | [diff] [blame] | 72 | |
| 73 | // Called by the FlipSession when response data has been received for this |
| 74 | // request. This callback may be called multiple times as data arrives |
| 75 | // from the network, and will never be called prior to OnResponseReceived. |
| 76 | // |buffer| contains the data received. The delegate must copy any data |
| 77 | // from this buffer before returning from this callback. |
| 78 | // |bytes| is the number of bytes received or an error. |
| 79 | // A zero-length count does not indicate end-of-stream. |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 80 | virtual void OnDataReceived(const char* buffer, int bytes) = 0; |
[email protected] | 2329792 | 2009-10-28 20:12:36 | [diff] [blame] | 81 | |
| 82 | // Called by the FlipSession when the request is finished. This callback |
| 83 | // will always be called at the end of the request and signals to the |
| 84 | // delegate that the delegate can be torn down. No further callbacks to the |
| 85 | // delegate will be made after this call. |
| 86 | // |status| is an error code or OK. |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 87 | virtual void OnClose(int status) = 0; |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 88 | }; |
| 89 | |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 90 | class FlipSession : public base::RefCounted<FlipSession>, |
| 91 | public flip::FlipFramerVisitorInterface { |
| 92 | public: |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 93 | // Get the domain for this FlipSession. |
[email protected] | d1eda93 | 2009-11-04 01:03:10 | [diff] [blame] | 94 | const std::string& domain() const { return domain_; } |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 95 | |
| 96 | // Connect the FLIP Socket. |
| 97 | // Returns net::Error::OK on success. |
| 98 | // Note that this call does not wait for the connect to complete. Callers can |
| 99 | // immediately start using the FlipSession while it connects. |
| 100 | net::Error Connect(const std::string& group_name, |
| 101 | const HostResolver::RequestInfo& host, int priority); |
| 102 | |
| 103 | // Create a new stream. |
| 104 | // FlipDelegate must remain valid until the stream is either cancelled by the |
| 105 | // creator via CancelStream or the FlipDelegate OnClose or OnCancel callbacks |
| 106 | // have been made. |
| 107 | // Once the stream is created, the delegate should wait for a callback. |
| 108 | int CreateStream(FlipDelegate* delegate); |
| 109 | |
| 110 | // Cancel a stream. |
| 111 | bool CancelStream(int id); |
| 112 | |
| 113 | // Check if a stream is active. |
[email protected] | d1eda93 | 2009-11-04 01:03:10 | [diff] [blame] | 114 | bool IsStreamActive(int id) const; |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 115 | |
| 116 | // The LoadState is used for informing the user of the current network |
| 117 | // status, such as "resolving host", "connecting", etc. |
| 118 | LoadState GetLoadState() const; |
[email protected] | d1eda93 | 2009-11-04 01:03:10 | [diff] [blame] | 119 | |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 120 | protected: |
[email protected] | 72552f0 | 2009-10-28 15:25:01 | [diff] [blame] | 121 | friend class FlipNetworkTransactionTest; |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 122 | friend class FlipSessionPool; |
[email protected] | 650e2cae | 2009-10-21 23:52:07 | [diff] [blame] | 123 | friend class HttpNetworkLayer; // Temporary for server. |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 124 | |
| 125 | // Provide access to the framer for testing. |
| 126 | flip::FlipFramer* GetFramer() { return &flip_framer_; } |
| 127 | |
| 128 | // Create a new FlipSession. |
| 129 | // |host| is the hostname that this session connects to. |
| 130 | FlipSession(std::string host, HttpNetworkSession* session); |
| 131 | |
| 132 | // Closes all open streams. Used as part of shutdown. |
| 133 | void CloseAllStreams(net::Error code); |
| 134 | |
[email protected] | affe8fe | 2009-10-14 20:06:05 | [diff] [blame] | 135 | // Enable or disable SSL. This is only to be used for testing. |
| 136 | static void SetSSLMode(bool enable) { use_ssl_ = enable; } |
| 137 | |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 138 | private: |
[email protected] | 5389bc7 | 2009-11-05 23:34:24 | [diff] [blame^] | 139 | friend class base::RefCounted<FlipSession>; |
| 140 | virtual ~FlipSession(); |
| 141 | |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 142 | // FlipFramerVisitorInterface |
| 143 | virtual void OnError(flip::FlipFramer*); |
| 144 | virtual void OnStreamFrameData(flip::FlipStreamId stream_id, |
| 145 | const char* data, |
[email protected] | aeac1e4 | 2009-10-10 00:26:01 | [diff] [blame] | 146 | size_t len); |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 147 | virtual void OnControl(const flip::FlipControlFrame* frame); |
| 148 | virtual void OnLameDuck(); |
| 149 | |
| 150 | // Control frame handlers. |
| 151 | void OnSyn(const flip::FlipSynStreamControlFrame* frame, |
| 152 | const flip::FlipHeaderBlock* headers); |
| 153 | void OnSynReply(const flip::FlipSynReplyControlFrame* frame, |
| 154 | const flip::FlipHeaderBlock* headers); |
| 155 | void OnFin(const flip::FlipFinStreamControlFrame* frame); |
| 156 | |
| 157 | // IO Callbacks |
[email protected] | 18c53ae | 2009-10-01 18:18:52 | [diff] [blame] | 158 | void OnTCPConnect(int result); |
| 159 | void OnSSLConnect(int result); |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 160 | void OnReadComplete(int result); |
| 161 | void OnWriteComplete(int result); |
| 162 | |
| 163 | // Start reading from the socket. |
| 164 | void ReadSocket(); |
| 165 | |
| 166 | // Write current data to the socket. |
| 167 | void WriteSocketLater(); |
| 168 | void WriteSocket(); |
| 169 | |
| 170 | // Get a new stream id. |
| 171 | int GetNewStreamId(); |
| 172 | |
| 173 | // Track active streams in the active stream list. |
[email protected] | cd314c82 | 2009-10-29 03:13:06 | [diff] [blame] | 174 | FlipStream* ActivateStream(flip::FlipStreamId id, FlipDelegate* delegate); |
[email protected] | ba051e31 | 2009-10-07 22:12:33 | [diff] [blame] | 175 | void DeactivateStream(flip::FlipStreamId id); |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 176 | |
| 177 | // Check if we have a pending pushed-stream for this url |
| 178 | // Returns the stream if found (and returns it from the pending |
| 179 | // list), returns NULL otherwise. |
[email protected] | cd314c82 | 2009-10-29 03:13:06 | [diff] [blame] | 180 | FlipStream* GetPushStream(std::string url); |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 181 | |
| 182 | // Callbacks for the Flip session. |
| 183 | CompletionCallbackImpl<FlipSession> connect_callback_; |
[email protected] | 18c53ae | 2009-10-01 18:18:52 | [diff] [blame] | 184 | CompletionCallbackImpl<FlipSession> ssl_connect_callback_; |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 185 | CompletionCallbackImpl<FlipSession> read_callback_; |
| 186 | CompletionCallbackImpl<FlipSession> write_callback_; |
| 187 | |
| 188 | // The domain this session is connected to. |
| 189 | std::string domain_; |
| 190 | |
[email protected] | 18c53ae | 2009-10-01 18:18:52 | [diff] [blame] | 191 | SSLConfig ssl_config_; |
| 192 | |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 193 | scoped_refptr<HttpNetworkSession> session_; |
| 194 | |
| 195 | // The socket handle for this session. |
| 196 | ClientSocketHandle connection_; |
[email protected] | 18c53ae | 2009-10-01 18:18:52 | [diff] [blame] | 197 | bool connection_started_; // Is the connect process started. |
| 198 | bool connection_ready_; // Is the connection ready for use. |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 199 | |
| 200 | // The read buffer used to read data from the socket. |
| 201 | enum { kReadBufferSize = (4 * 1024) }; |
[email protected] | 230cadd | 2009-09-22 16:33:59 | [diff] [blame] | 202 | scoped_refptr<IOBuffer> read_buffer_; |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 203 | bool read_pending_; |
| 204 | |
| 205 | int stream_hi_water_mark_; // The next stream id to use. |
| 206 | |
[email protected] | 9330067 | 2009-10-24 13:22:51 | [diff] [blame] | 207 | // TODO(mbelshe): We need to track these stream lists better. |
| 208 | // I suspect it is possible to remove a stream from |
| 209 | // one list, but not the other. |
[email protected] | cd314c82 | 2009-10-29 03:13:06 | [diff] [blame] | 210 | typedef std::map<int, FlipStream*> ActiveStreamMap; |
| 211 | typedef std::list<FlipStream*> ActiveStreamList; |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 212 | ActiveStreamMap active_streams_; |
| 213 | |
| 214 | ActiveStreamList pushed_streams_; |
[email protected] | 18c53ae | 2009-10-01 18:18:52 | [diff] [blame] | 215 | // List of streams declared in X-Associated-Content headers. |
| 216 | // The key is a string representing the path of the URI being pushed. |
| 217 | std::map<std::string, FlipDelegate*> pending_streams_; |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 218 | |
| 219 | // As we gather data to be sent, we put it into the output queue. |
[email protected] | eebc0b4 | 2009-11-04 00:17:13 | [diff] [blame] | 220 | typedef std::priority_queue<FlipIOBuffer> OutputQueue; |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 221 | OutputQueue queue_; |
| 222 | |
| 223 | // TODO(mbelshe): this is ugly!! |
| 224 | // The packet we are currently sending. |
[email protected] | eebc0b4 | 2009-11-04 00:17:13 | [diff] [blame] | 225 | FlipIOBuffer in_flight_write_; |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 226 | bool delayed_write_pending_; |
| 227 | bool write_pending_; |
| 228 | |
| 229 | // Flip Frame state. |
| 230 | flip::FlipFramer flip_framer_; |
| 231 | |
[email protected] | affe8fe | 2009-10-14 20:06:05 | [diff] [blame] | 232 | static bool use_ssl_; |
[email protected] | aea8060 | 2009-09-18 00:55:08 | [diff] [blame] | 233 | }; |
| 234 | |
| 235 | } // namespace net |
| 236 | |
| 237 | #endif // NET_FLIP_FLIP_SESSION_H_ |