blob: c8e3f1effc97e8bd19993ef6c44ae4b15a906ad2 [file] [log] [blame]
[email protected]aea80602009-09-18 00:55:081// 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]18c53ae2009-10-01 18:18:5218#include "net/base/ssl_config_service.h"
[email protected]aea80602009-09-18 00:55:0819#include "net/base/upload_data_stream.h"
20#include "net/flip/flip_framer.h"
21#include "net/flip/flip_protocol.h"
22#include "net/flip/flip_session_pool.h"
23#include "net/socket/client_socket.h"
24#include "net/socket/client_socket_handle.h"
25#include "testing/platform_test.h"
26
27namespace net {
28
29class FlipStreamImpl;
30class HttpNetworkSession;
31class HttpRequestInfo;
32class HttpResponseInfo;
33
34// A callback interface for HTTP content retrieved from the Flip stream.
35class FlipDelegate {
36 public:
37 virtual ~FlipDelegate() {}
38 virtual const HttpRequestInfo* request() = 0;
39 virtual const UploadDataStream* data() = 0;
40
41 virtual void OnRequestSent(int status) = 0;
42 virtual void OnResponseReceived(HttpResponseInfo* response) = 0;
43 virtual void OnDataReceived(const char* buffer, int bytes) = 0;
44 virtual void OnClose(int status) = 0;
45 virtual void OnCancel() = 0;
46};
47
48class PrioritizedIOBuffer {
49 public:
50 PrioritizedIOBuffer() : buffer_(0), priority_(0) {}
51 PrioritizedIOBuffer(IOBufferWithSize* buffer, int priority)
52 : buffer_(buffer),
53 priority_(priority),
54 position_(++order_) {
55 }
56
57 IOBuffer* buffer() const { return buffer_; }
58
[email protected]b172068c2009-10-09 16:56:4059 size_t size() const { return buffer_->size(); }
[email protected]aea80602009-09-18 00:55:0860
61 void release() { buffer_ = NULL; }
62
63 int priority() { return priority_; }
64
65 // Supports sorting.
66 bool operator<(const PrioritizedIOBuffer& other) const {
67 if (priority_ != other.priority_)
68 return priority_ > other.priority_;
69 return position_ >= other.position_;
70 }
71
72 private:
73 scoped_refptr<IOBufferWithSize> buffer_;
74 int priority_;
75 int position_;
76 static int order_; // Maintains a FIFO order for equal priorities.
77};
78
79class FlipSession : public base::RefCounted<FlipSession>,
80 public flip::FlipFramerVisitorInterface {
81 public:
82 // Factory for finding open sessions.
83 // TODO(mbelshe): Break this out into a connection pool class?
84 static FlipSession* GetFlipSession(const HostResolver::RequestInfo&,
85 HttpNetworkSession* session);
86 virtual ~FlipSession();
87
88 // Get the domain for this FlipSession.
89 std::string domain() { return domain_; }
90
91 // Connect the FLIP Socket.
92 // Returns net::Error::OK on success.
93 // Note that this call does not wait for the connect to complete. Callers can
94 // immediately start using the FlipSession while it connects.
95 net::Error Connect(const std::string& group_name,
96 const HostResolver::RequestInfo& host, int priority);
97
98 // Create a new stream.
99 // FlipDelegate must remain valid until the stream is either cancelled by the
100 // creator via CancelStream or the FlipDelegate OnClose or OnCancel callbacks
101 // have been made.
102 // Once the stream is created, the delegate should wait for a callback.
103 int CreateStream(FlipDelegate* delegate);
104
105 // Cancel a stream.
106 bool CancelStream(int id);
107
108 // Check if a stream is active.
109 bool IsStreamActive(int id);
110
111 // The LoadState is used for informing the user of the current network
112 // status, such as "resolving host", "connecting", etc.
113 LoadState GetLoadState() const;
114 protected:
115 friend class FlipNetworkTransactionTest;
116 friend class FlipSessionPool;
117
118 // Provide access to the framer for testing.
119 flip::FlipFramer* GetFramer() { return &flip_framer_; }
120
121 // Create a new FlipSession.
122 // |host| is the hostname that this session connects to.
123 FlipSession(std::string host, HttpNetworkSession* session);
124
125 // Closes all open streams. Used as part of shutdown.
126 void CloseAllStreams(net::Error code);
127
128 private:
129 // FlipFramerVisitorInterface
130 virtual void OnError(flip::FlipFramer*);
131 virtual void OnStreamFrameData(flip::FlipStreamId stream_id,
132 const char* data,
[email protected]aeac1e42009-10-10 00:26:01133 size_t len);
[email protected]aea80602009-09-18 00:55:08134 virtual void OnControl(const flip::FlipControlFrame* frame);
135 virtual void OnLameDuck();
136
137 // Control frame handlers.
138 void OnSyn(const flip::FlipSynStreamControlFrame* frame,
139 const flip::FlipHeaderBlock* headers);
140 void OnSynReply(const flip::FlipSynReplyControlFrame* frame,
141 const flip::FlipHeaderBlock* headers);
142 void OnFin(const flip::FlipFinStreamControlFrame* frame);
143
144 // IO Callbacks
[email protected]18c53ae2009-10-01 18:18:52145 void OnTCPConnect(int result);
146 void OnSSLConnect(int result);
[email protected]aea80602009-09-18 00:55:08147 void OnReadComplete(int result);
148 void OnWriteComplete(int result);
149
150 // Start reading from the socket.
151 void ReadSocket();
152
153 // Write current data to the socket.
154 void WriteSocketLater();
155 void WriteSocket();
156
157 // Get a new stream id.
158 int GetNewStreamId();
159
160 // Track active streams in the active stream list.
[email protected]ba051e312009-10-07 22:12:33161 FlipStreamImpl* ActivateStream(flip::FlipStreamId id, FlipDelegate* delegate);
162 void DeactivateStream(flip::FlipStreamId id);
[email protected]aea80602009-09-18 00:55:08163
164 // Check if we have a pending pushed-stream for this url
165 // Returns the stream if found (and returns it from the pending
166 // list), returns NULL otherwise.
167 FlipStreamImpl* GetPushStream(std::string url);
168
169 // Callbacks for the Flip session.
170 CompletionCallbackImpl<FlipSession> connect_callback_;
[email protected]18c53ae2009-10-01 18:18:52171 CompletionCallbackImpl<FlipSession> ssl_connect_callback_;
[email protected]aea80602009-09-18 00:55:08172 CompletionCallbackImpl<FlipSession> read_callback_;
173 CompletionCallbackImpl<FlipSession> write_callback_;
174
175 // The domain this session is connected to.
176 std::string domain_;
177
[email protected]18c53ae2009-10-01 18:18:52178 SSLConfig ssl_config_;
179
[email protected]aea80602009-09-18 00:55:08180 scoped_refptr<HttpNetworkSession> session_;
181
182 // The socket handle for this session.
183 ClientSocketHandle connection_;
[email protected]18c53ae2009-10-01 18:18:52184 bool connection_started_; // Is the connect process started.
185 bool connection_ready_; // Is the connection ready for use.
[email protected]aea80602009-09-18 00:55:08186
187 // The read buffer used to read data from the socket.
188 enum { kReadBufferSize = (4 * 1024) };
[email protected]230cadd2009-09-22 16:33:59189 scoped_refptr<IOBuffer> read_buffer_;
[email protected]aea80602009-09-18 00:55:08190 bool read_pending_;
191
192 int stream_hi_water_mark_; // The next stream id to use.
193
194 typedef std::map<int, FlipStreamImpl*> ActiveStreamMap;
195 typedef std::list<FlipStreamImpl*> ActiveStreamList;
196 ActiveStreamMap active_streams_;
197
198 ActiveStreamList pushed_streams_;
[email protected]18c53ae2009-10-01 18:18:52199 // List of streams declared in X-Associated-Content headers.
200 // The key is a string representing the path of the URI being pushed.
201 std::map<std::string, FlipDelegate*> pending_streams_;
[email protected]aea80602009-09-18 00:55:08202
203 // As we gather data to be sent, we put it into the output queue.
204 typedef std::priority_queue<PrioritizedIOBuffer> OutputQueue;
205 OutputQueue queue_;
206
207 // TODO(mbelshe): this is ugly!!
208 // The packet we are currently sending.
209 PrioritizedIOBuffer in_flight_write_;
210 bool delayed_write_pending_;
211 bool write_pending_;
212
213 // Flip Frame state.
214 flip::FlipFramer flip_framer_;
215
216 // This is our weak session pool - one session per domain.
217 static scoped_ptr<FlipSessionPool> session_pool_;
218 static bool disable_compression_;
219};
220
221} // namespace net
222
223#endif // NET_FLIP_FLIP_SESSION_H_
224