blob: 32d1d0cb7de904e0fc066601b2ccd492050167bc [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
[email protected]dab9c7d2010-02-06 21:44:325#ifndef NET_SPDY_SPDY_SESSION_H_
6#define NET_SPDY_SPDY_SESSION_H_
[email protected]aea80602009-09-18 00:55:087
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]ac790b42009-12-02 04:31:3118#include "net/base/request_priority.h"
[email protected]18c53ae2009-10-01 18:18:5219#include "net/base/ssl_config_service.h"
[email protected]aea80602009-09-18 00:55:0820#include "net/base/upload_data_stream.h"
[email protected]aea80602009-09-18 00:55:0821#include "net/socket/client_socket.h"
22#include "net/socket/client_socket_handle.h"
[email protected]7fc5b09a2010-02-27 00:07:3823#include "net/socket/tcp_client_socket_pool.h"
[email protected]dab9c7d2010-02-06 21:44:3224#include "net/spdy/spdy_framer.h"
25#include "net/spdy/spdy_io_buffer.h"
26#include "net/spdy/spdy_protocol.h"
27#include "net/spdy/spdy_session_pool.h"
[email protected]aea80602009-09-18 00:55:0828
29namespace net {
30
[email protected]955fc2e72010-02-08 20:37:3031class SpdyStream;
[email protected]aea80602009-09-18 00:55:0832class HttpNetworkSession;
[email protected]8c76ae22010-04-20 22:15:4333struct HttpRequestInfo;
[email protected]aea80602009-09-18 00:55:0834class HttpResponseInfo;
[email protected]9e743cd2010-03-16 07:03:5335class BoundNetLog;
[email protected]dcc6bbb2009-12-09 19:09:0136class SSLInfo;
[email protected]aea80602009-09-18 00:55:0837
[email protected]955fc2e72010-02-08 20:37:3038class SpdySession : public base::RefCounted<SpdySession>,
39 public spdy::SpdyFramerVisitorInterface {
[email protected]aea80602009-09-18 00:55:0840 public:
[email protected]807c01a2010-04-21 16:57:4541 // Create a new SpdySession.
42 // |host_port_pair| is the host/port that this session connects to.
43 // |session| is the HttpNetworkSession
44 SpdySession(const HostPortPair& host_port_pair, HttpNetworkSession* session);
45
[email protected]367ead42010-02-26 00:15:2146 const HostPortPair& host_port_pair() const { return host_port_pair_; }
[email protected]aea80602009-09-18 00:55:0847
[email protected]955fc2e72010-02-08 20:37:3048 // Connect the Spdy Socket.
[email protected]aea80602009-09-18 00:55:0849 // Returns net::Error::OK on success.
50 // Note that this call does not wait for the connect to complete. Callers can
[email protected]955fc2e72010-02-08 20:37:3051 // immediately start using the SpdySession while it connects.
[email protected]aea80602009-09-18 00:55:0852 net::Error Connect(const std::string& group_name,
[email protected]7fc5b09a2010-02-27 00:07:3853 const TCPSocketParams& destination,
[email protected]eec34d7d2009-12-07 22:09:2354 RequestPriority priority,
[email protected]9e743cd2010-03-16 07:03:5355 const BoundNetLog& net_log);
[email protected]aea80602009-09-18 00:55:0856
[email protected]a677f2b2009-11-22 00:43:0057 // Get a stream for a given |request|. In the typical case, this will involve
58 // the creation of a new stream (and will send the SYN frame). If the server
59 // initiates a stream, it might already exist for a given path. The server
60 // might also not have initiated the stream yet, but indicated it will via
61 // X-Associated-Content.
62 // Returns the new or existing stream. Never returns NULL.
[email protected]955fc2e72010-02-08 20:37:3063 scoped_refptr<SpdyStream> GetOrCreateStream(const HttpRequestInfo& request,
[email protected]9e743cd2010-03-16 07:03:5364 const UploadDataStream* upload_data, const BoundNetLog& log);
[email protected]aea80602009-09-18 00:55:0865
[email protected]807c01a2010-04-21 16:57:4566 // Used by SpdySessionPool to initialize with a pre-existing SSL socket.
67 void InitializeWithSSLSocket(ClientSocketHandle* connection);
68
[email protected]ff57bb82009-11-12 06:52:1469 // Write a data frame to the stream.
70 // Used to create and queue a data frame for the given stream.
[email protected]955fc2e72010-02-08 20:37:3071 int WriteStreamData(spdy::SpdyStreamId stream_id, net::IOBuffer* data,
[email protected]ff57bb82009-11-12 06:52:1472 int len);
73
[email protected]aea80602009-09-18 00:55:0874 // Cancel a stream.
[email protected]955fc2e72010-02-08 20:37:3075 bool CancelStream(spdy::SpdyStreamId stream_id);
[email protected]aea80602009-09-18 00:55:0876
77 // Check if a stream is active.
[email protected]955fc2e72010-02-08 20:37:3078 bool IsStreamActive(spdy::SpdyStreamId stream_id) const;
[email protected]aea80602009-09-18 00:55:0879
80 // The LoadState is used for informing the user of the current network
81 // status, such as "resolving host", "connecting", etc.
82 LoadState GetLoadState() const;
[email protected]d1eda932009-11-04 01:03:1083
[email protected]807c01a2010-04-21 16:57:4584 // Closes all open streams. Used as part of shutdown.
85 void CloseAllStreams(net::Error code);
86
[email protected]34437af82009-11-06 02:28:4987 // Enable or disable SSL.
88 static void SetSSLMode(bool enable) { use_ssl_ = enable; }
[email protected]85c0ed82009-12-15 23:14:1489 static bool SSLMode() { return use_ssl_; }
[email protected]34437af82009-11-06 02:28:4990
[email protected]807c01a2010-04-21 16:57:4591 private:
92 friend class base::RefCounted<SpdySession>;
[email protected]aea80602009-09-18 00:55:0893
[email protected]60253bd2009-12-01 01:16:3994 enum State {
95 IDLE,
96 CONNECTING,
97 CONNECTED,
98 CLOSED
99 };
100
[email protected]955fc2e72010-02-08 20:37:30101 typedef std::map<int, scoped_refptr<SpdyStream> > ActiveStreamMap;
102 typedef std::list<scoped_refptr<SpdyStream> > ActiveStreamList;
103 typedef std::map<std::string, scoped_refptr<SpdyStream> > PendingStreamMap;
104 typedef std::priority_queue<SpdyIOBuffer> OutputQueue;
[email protected]a677f2b2009-11-22 00:43:00105
[email protected]955fc2e72010-02-08 20:37:30106 virtual ~SpdySession();
[email protected]5389bc72009-11-05 23:34:24107
[email protected]955fc2e72010-02-08 20:37:30108 // SpdyFramerVisitorInterface
109 virtual void OnError(spdy::SpdyFramer*);
110 virtual void OnStreamFrameData(spdy::SpdyStreamId stream_id,
[email protected]aea80602009-09-18 00:55:08111 const char* data,
[email protected]aeac1e42009-10-10 00:26:01112 size_t len);
[email protected]955fc2e72010-02-08 20:37:30113 virtual void OnControl(const spdy::SpdyControlFrame* frame);
[email protected]aea80602009-09-18 00:55:08114
115 // Control frame handlers.
[email protected]651b77c2010-03-10 19:29:42116 void OnSyn(const spdy::SpdySynStreamControlFrame& frame,
117 const spdy::SpdyHeaderBlock& headers);
118 void OnSynReply(const spdy::SpdySynReplyControlFrame& frame,
119 const spdy::SpdyHeaderBlock& headers);
120 void OnFin(const spdy::SpdyRstStreamControlFrame& frame);
121 void OnGoAway(const spdy::SpdyGoAwayControlFrame& frame);
[email protected]74188f22010-04-09 20:18:50122 void OnSettings(const spdy::SpdySettingsControlFrame& frame);
[email protected]aea80602009-09-18 00:55:08123
124 // IO Callbacks
[email protected]18c53ae2009-10-01 18:18:52125 void OnTCPConnect(int result);
126 void OnSSLConnect(int result);
[email protected]aea80602009-09-18 00:55:08127 void OnReadComplete(int result);
128 void OnWriteComplete(int result);
129
[email protected]74188f22010-04-09 20:18:50130 // Send relevant SETTINGS. This is generally called on connection setup.
131 void SendSettings();
132
[email protected]aea80602009-09-18 00:55:08133 // Start reading from the socket.
134 void ReadSocket();
135
136 // Write current data to the socket.
137 void WriteSocketLater();
138 void WriteSocket();
139
140 // Get a new stream id.
141 int GetNewStreamId();
142
[email protected]74188f22010-04-09 20:18:50143 // Queue a frame for sending.
144 // |frame| is the frame to send.
145 // |priority| is the priority for insertion into the queue.
146 // |stream| is the stream which this IO is associated with (or NULL).
147 void QueueFrame(spdy::SpdyFrame* frame, spdy::SpdyPriority priority,
148 SpdyStream* stream);
149
[email protected]60253bd2009-12-01 01:16:39150 // Closes this session. This will close all active streams and mark
151 // the session as permanently closed.
[email protected]353f6162009-12-10 18:04:12152 // |err| should not be OK; this function is intended to be called on
153 // error.
154 void CloseSessionOnError(net::Error err);
[email protected]60253bd2009-12-01 01:16:39155
[email protected]aea80602009-09-18 00:55:08156 // Track active streams in the active stream list.
[email protected]955fc2e72010-02-08 20:37:30157 void ActivateStream(SpdyStream* stream);
158 void DeactivateStream(spdy::SpdyStreamId id);
[email protected]aea80602009-09-18 00:55:08159
160 // Check if we have a pending pushed-stream for this url
161 // Returns the stream if found (and returns it from the pending
162 // list), returns NULL otherwise.
[email protected]955fc2e72010-02-08 20:37:30163 scoped_refptr<SpdyStream> GetPushStream(const std::string& url);
[email protected]aea80602009-09-18 00:55:08164
[email protected]3f662f12010-03-25 19:56:12165 // Creates an HttpResponseInfo instance, and calls OnResponseReceived().
166 // Returns true if successful.
167 bool Respond(const spdy::SpdyHeaderBlock& headers,
168 const scoped_refptr<SpdyStream> stream);
169
[email protected]dcc6bbb2009-12-09 19:09:01170 void GetSSLInfo(SSLInfo* ssl_info);
171
[email protected]955fc2e72010-02-08 20:37:30172 // Callbacks for the Spdy session.
173 CompletionCallbackImpl<SpdySession> connect_callback_;
174 CompletionCallbackImpl<SpdySession> ssl_connect_callback_;
175 CompletionCallbackImpl<SpdySession> read_callback_;
176 CompletionCallbackImpl<SpdySession> write_callback_;
[email protected]aea80602009-09-18 00:55:08177
178 // The domain this session is connected to.
[email protected]367ead42010-02-26 00:15:21179 const HostPortPair host_port_pair_;
[email protected]aea80602009-09-18 00:55:08180
[email protected]18c53ae2009-10-01 18:18:52181 SSLConfig ssl_config_;
182
[email protected]aea80602009-09-18 00:55:08183 scoped_refptr<HttpNetworkSession> session_;
184
185 // The socket handle for this session.
[email protected]1f14a912009-12-21 20:32:44186 scoped_ptr<ClientSocketHandle> connection_;
[email protected]aea80602009-09-18 00:55:08187
188 // The read buffer used to read data from the socket.
[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
[email protected]93300672009-10-24 13:22:51194 // TODO(mbelshe): We need to track these stream lists better.
195 // I suspect it is possible to remove a stream from
196 // one list, but not the other.
[email protected]aea80602009-09-18 00:55:08197
[email protected]a677f2b2009-11-22 00:43:00198 // Map from stream id to all active streams. Streams are active in the sense
[email protected]955fc2e72010-02-08 20:37:30199 // that they have a consumer (typically SpdyNetworkTransaction and regardless
[email protected]a677f2b2009-11-22 00:43:00200 // of whether or not there is currently any ongoing IO [might be waiting for
201 // the server to start pushing the stream]) or there are still network events
202 // incoming even though the consumer has already gone away (cancellation).
203 // TODO(willchan): Perhaps we should separate out cancelled streams and move
204 // them into a separate ActiveStreamMap, and not deliver network events to
205 // them?
206 ActiveStreamMap active_streams_;
207 // List of all the streams that have already started to be pushed by the
208 // server, but do not have consumers yet.
[email protected]aea80602009-09-18 00:55:08209 ActiveStreamList pushed_streams_;
[email protected]a677f2b2009-11-22 00:43:00210 // List of streams declared in X-Associated-Content headers, but do not have
211 // consumers yet.
[email protected]18c53ae2009-10-01 18:18:52212 // The key is a string representing the path of the URI being pushed.
[email protected]2931238b2009-11-19 01:19:51213 PendingStreamMap pending_streams_;
[email protected]aea80602009-09-18 00:55:08214
215 // As we gather data to be sent, we put it into the output queue.
[email protected]aea80602009-09-18 00:55:08216 OutputQueue queue_;
217
[email protected]aea80602009-09-18 00:55:08218 // The packet we are currently sending.
[email protected]e1245352009-11-30 19:42:42219 bool write_pending_; // Will be true when a write is in progress.
[email protected]955fc2e72010-02-08 20:37:30220 SpdyIOBuffer in_flight_write_; // This is the write buffer in progress.
[email protected]e1245352009-11-30 19:42:42221
222 // Flag if we have a pending message scheduled for WriteSocket.
[email protected]aea80602009-09-18 00:55:08223 bool delayed_write_pending_;
[email protected]aea80602009-09-18 00:55:08224
[email protected]955fc2e72010-02-08 20:37:30225 // Flag if we're using an SSL connection for this SpdySession.
[email protected]dcc6bbb2009-12-09 19:09:01226 bool is_secure_;
227
[email protected]955fc2e72010-02-08 20:37:30228 // Spdy Frame state.
229 spdy::SpdyFramer spdy_framer_;
[email protected]aea80602009-09-18 00:55:08230
[email protected]60253bd2009-12-01 01:16:39231 // If an error has occurred on the session, the session is effectively
232 // dead. Record this error here. When no error has occurred, |error_| will
233 // be OK.
234 net::Error error_;
235 State state_;
236
[email protected]9b010802009-12-27 22:55:30237 // Some statistics counters for the session.
238 int streams_initiated_count_;
239 int streams_pushed_count_;
240 int streams_pushed_and_claimed_count_;
241 int streams_abandoned_count_;
242
[email protected]affe8fe2009-10-14 20:06:05243 static bool use_ssl_;
[email protected]aea80602009-09-18 00:55:08244};
245
246} // namespace net
247
[email protected]dab9c7d2010-02-06 21:44:32248#endif // NET_SPDY_SPDY_SESSION_H_