blob: 8ef87595a8355c90afeeb297876233dba6973414 [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
[email protected]33c477b2010-05-13 19:21:0714#include "base/linked_ptr.h"
[email protected]aea80602009-09-18 00:55:0815#include "base/ref_counted.h"
16#include "net/base/io_buffer.h"
17#include "net/base/load_states.h"
18#include "net/base/net_errors.h"
[email protected]635909f2010-05-12 18:19:3619#include "net/base/net_log.h"
[email protected]ac790b42009-12-02 04:31:3120#include "net/base/request_priority.h"
[email protected]18c53ae2009-10-01 18:18:5221#include "net/base/ssl_config_service.h"
[email protected]aea80602009-09-18 00:55:0822#include "net/base/upload_data_stream.h"
[email protected]aea80602009-09-18 00:55:0823#include "net/socket/client_socket.h"
24#include "net/socket/client_socket_handle.h"
[email protected]7fc5b09a2010-02-27 00:07:3825#include "net/socket/tcp_client_socket_pool.h"
[email protected]dab9c7d2010-02-06 21:44:3226#include "net/spdy/spdy_framer.h"
27#include "net/spdy/spdy_io_buffer.h"
28#include "net/spdy/spdy_protocol.h"
29#include "net/spdy/spdy_session_pool.h"
[email protected]eb6e29ac2010-05-04 01:31:1330#include "testing/gtest/include/gtest/gtest_prod.h" // For FRIEND_TEST
[email protected]aea80602009-09-18 00:55:0831
32namespace net {
33
[email protected]955fc2e72010-02-08 20:37:3034class SpdyStream;
[email protected]aea80602009-09-18 00:55:0835class HttpNetworkSession;
[email protected]8c76ae22010-04-20 22:15:4336struct HttpRequestInfo;
[email protected]aea80602009-09-18 00:55:0837class HttpResponseInfo;
[email protected]9e743cd2010-03-16 07:03:5338class BoundNetLog;
[email protected]dcc6bbb2009-12-09 19:09:0139class SSLInfo;
[email protected]aea80602009-09-18 00:55:0840
[email protected]955fc2e72010-02-08 20:37:3041class SpdySession : public base::RefCounted<SpdySession>,
42 public spdy::SpdyFramerVisitorInterface {
[email protected]aea80602009-09-18 00:55:0843 public:
[email protected]807c01a2010-04-21 16:57:4544 // Create a new SpdySession.
45 // |host_port_pair| is the host/port that this session connects to.
[email protected]635909f2010-05-12 18:19:3646 // |session| is the HttpNetworkSession. |net_log| is the NetLog that we log
47 // network events to.
48 SpdySession(const HostPortPair& host_port_pair, HttpNetworkSession* session,
[email protected]44297002010-05-16 00:59:1049 NetLog* net_log);
[email protected]807c01a2010-04-21 16:57:4550
[email protected]367ead42010-02-26 00:15:2151 const HostPortPair& host_port_pair() const { return host_port_pair_; }
[email protected]aea80602009-09-18 00:55:0852
[email protected]955fc2e72010-02-08 20:37:3053 // Connect the Spdy Socket.
[email protected]aea80602009-09-18 00:55:0854 // Returns net::Error::OK on success.
55 // Note that this call does not wait for the connect to complete. Callers can
[email protected]955fc2e72010-02-08 20:37:3056 // immediately start using the SpdySession while it connects.
[email protected]aea80602009-09-18 00:55:0857 net::Error Connect(const std::string& group_name,
[email protected]7fc5b09a2010-02-27 00:07:3858 const TCPSocketParams& destination,
[email protected]635909f2010-05-12 18:19:3659 RequestPriority priority);
[email protected]aea80602009-09-18 00:55:0860
[email protected]a677f2b2009-11-22 00:43:0061 // Get a stream for a given |request|. In the typical case, this will involve
62 // the creation of a new stream (and will send the SYN frame). If the server
63 // initiates a stream, it might already exist for a given path. The server
64 // might also not have initiated the stream yet, but indicated it will via
65 // X-Associated-Content.
66 // Returns the new or existing stream. Never returns NULL.
[email protected]33c477b2010-05-13 19:21:0767 scoped_refptr<SpdyStream> GetOrCreateStream(
68 const HttpRequestInfo& request,
69 const UploadDataStream* upload_data,
70 const BoundNetLog& stream_net_log);
[email protected]aea80602009-09-18 00:55:0871
[email protected]807c01a2010-04-21 16:57:4572 // Used by SpdySessionPool to initialize with a pre-existing SSL socket.
73 void InitializeWithSSLSocket(ClientSocketHandle* connection);
74
[email protected]ff57bb82009-11-12 06:52:1475 // Write a data frame to the stream.
76 // Used to create and queue a data frame for the given stream.
[email protected]955fc2e72010-02-08 20:37:3077 int WriteStreamData(spdy::SpdyStreamId stream_id, net::IOBuffer* data,
[email protected]ff57bb82009-11-12 06:52:1478 int len);
79
[email protected]aea80602009-09-18 00:55:0880 // Cancel a stream.
[email protected]955fc2e72010-02-08 20:37:3081 bool CancelStream(spdy::SpdyStreamId stream_id);
[email protected]aea80602009-09-18 00:55:0882
83 // Check if a stream is active.
[email protected]955fc2e72010-02-08 20:37:3084 bool IsStreamActive(spdy::SpdyStreamId stream_id) const;
[email protected]aea80602009-09-18 00:55:0885
86 // The LoadState is used for informing the user of the current network
87 // status, such as "resolving host", "connecting", etc.
88 LoadState GetLoadState() const;
[email protected]d1eda932009-11-04 01:03:1089
[email protected]807c01a2010-04-21 16:57:4590 // Closes all open streams. Used as part of shutdown.
91 void CloseAllStreams(net::Error code);
92
[email protected]34437af82009-11-06 02:28:4993 // Enable or disable SSL.
94 static void SetSSLMode(bool enable) { use_ssl_ = enable; }
[email protected]85c0ed82009-12-15 23:14:1495 static bool SSLMode() { return use_ssl_; }
[email protected]34437af82009-11-06 02:28:4996
[email protected]807c01a2010-04-21 16:57:4597 private:
98 friend class base::RefCounted<SpdySession>;
[email protected]3264fc32010-05-10 16:48:0499 FRIEND_TEST(SpdySessionTest, GetPushStream);
[email protected]aea80602009-09-18 00:55:08100
[email protected]60253bd2009-12-01 01:16:39101 enum State {
102 IDLE,
103 CONNECTING,
104 CONNECTED,
105 CLOSED
106 };
107
[email protected]955fc2e72010-02-08 20:37:30108 typedef std::map<int, scoped_refptr<SpdyStream> > ActiveStreamMap;
109 typedef std::list<scoped_refptr<SpdyStream> > ActiveStreamList;
110 typedef std::map<std::string, scoped_refptr<SpdyStream> > PendingStreamMap;
111 typedef std::priority_queue<SpdyIOBuffer> OutputQueue;
[email protected]a677f2b2009-11-22 00:43:00112
[email protected]955fc2e72010-02-08 20:37:30113 virtual ~SpdySession();
[email protected]5389bc72009-11-05 23:34:24114
[email protected]955fc2e72010-02-08 20:37:30115 // SpdyFramerVisitorInterface
116 virtual void OnError(spdy::SpdyFramer*);
117 virtual void OnStreamFrameData(spdy::SpdyStreamId stream_id,
[email protected]aea80602009-09-18 00:55:08118 const char* data,
[email protected]aeac1e42009-10-10 00:26:01119 size_t len);
[email protected]955fc2e72010-02-08 20:37:30120 virtual void OnControl(const spdy::SpdyControlFrame* frame);
[email protected]aea80602009-09-18 00:55:08121
122 // Control frame handlers.
[email protected]651b77c2010-03-10 19:29:42123 void OnSyn(const spdy::SpdySynStreamControlFrame& frame,
[email protected]33c477b2010-05-13 19:21:07124 const linked_ptr<spdy::SpdyHeaderBlock>& headers);
[email protected]651b77c2010-03-10 19:29:42125 void OnSynReply(const spdy::SpdySynReplyControlFrame& frame,
[email protected]33c477b2010-05-13 19:21:07126 const linked_ptr<spdy::SpdyHeaderBlock>& headers);
[email protected]651b77c2010-03-10 19:29:42127 void OnFin(const spdy::SpdyRstStreamControlFrame& frame);
128 void OnGoAway(const spdy::SpdyGoAwayControlFrame& frame);
[email protected]74188f22010-04-09 20:18:50129 void OnSettings(const spdy::SpdySettingsControlFrame& frame);
[email protected]aea80602009-09-18 00:55:08130
131 // IO Callbacks
[email protected]18c53ae2009-10-01 18:18:52132 void OnTCPConnect(int result);
133 void OnSSLConnect(int result);
[email protected]aea80602009-09-18 00:55:08134 void OnReadComplete(int result);
135 void OnWriteComplete(int result);
136
[email protected]74188f22010-04-09 20:18:50137 // Send relevant SETTINGS. This is generally called on connection setup.
138 void SendSettings();
139
[email protected]aea80602009-09-18 00:55:08140 // Start reading from the socket.
141 void ReadSocket();
142
143 // Write current data to the socket.
144 void WriteSocketLater();
145 void WriteSocket();
146
147 // Get a new stream id.
148 int GetNewStreamId();
149
[email protected]74188f22010-04-09 20:18:50150 // Queue a frame for sending.
151 // |frame| is the frame to send.
152 // |priority| is the priority for insertion into the queue.
153 // |stream| is the stream which this IO is associated with (or NULL).
154 void QueueFrame(spdy::SpdyFrame* frame, spdy::SpdyPriority priority,
155 SpdyStream* stream);
156
[email protected]60253bd2009-12-01 01:16:39157 // Closes this session. This will close all active streams and mark
158 // the session as permanently closed.
[email protected]353f6162009-12-10 18:04:12159 // |err| should not be OK; this function is intended to be called on
160 // error.
161 void CloseSessionOnError(net::Error err);
[email protected]60253bd2009-12-01 01:16:39162
[email protected]aea80602009-09-18 00:55:08163 // Track active streams in the active stream list.
[email protected]955fc2e72010-02-08 20:37:30164 void ActivateStream(SpdyStream* stream);
165 void DeactivateStream(spdy::SpdyStreamId id);
[email protected]aea80602009-09-18 00:55:08166
[email protected]4b4762a2010-04-23 16:04:14167 // Removes this session from the session pool.
168 void RemoveFromPool();
169
[email protected]aea80602009-09-18 00:55:08170 // Check if we have a pending pushed-stream for this url
171 // Returns the stream if found (and returns it from the pending
172 // list), returns NULL otherwise.
[email protected]955fc2e72010-02-08 20:37:30173 scoped_refptr<SpdyStream> GetPushStream(const std::string& url);
[email protected]aea80602009-09-18 00:55:08174
[email protected]3f662f12010-03-25 19:56:12175 // Creates an HttpResponseInfo instance, and calls OnResponseReceived().
176 // Returns true if successful.
177 bool Respond(const spdy::SpdyHeaderBlock& headers,
178 const scoped_refptr<SpdyStream> stream);
179
[email protected]dcc6bbb2009-12-09 19:09:01180 void GetSSLInfo(SSLInfo* ssl_info);
181
[email protected]955fc2e72010-02-08 20:37:30182 // Callbacks for the Spdy session.
183 CompletionCallbackImpl<SpdySession> connect_callback_;
184 CompletionCallbackImpl<SpdySession> ssl_connect_callback_;
185 CompletionCallbackImpl<SpdySession> read_callback_;
186 CompletionCallbackImpl<SpdySession> write_callback_;
[email protected]aea80602009-09-18 00:55:08187
188 // The domain this session is connected to.
[email protected]367ead42010-02-26 00:15:21189 const HostPortPair host_port_pair_;
[email protected]aea80602009-09-18 00:55:08190
[email protected]18c53ae2009-10-01 18:18:52191 SSLConfig ssl_config_;
192
[email protected]aea80602009-09-18 00:55:08193 scoped_refptr<HttpNetworkSession> session_;
194
195 // The socket handle for this session.
[email protected]1f14a912009-12-21 20:32:44196 scoped_ptr<ClientSocketHandle> connection_;
[email protected]aea80602009-09-18 00:55:08197
198 // The read buffer used to read data from the socket.
[email protected]230cadd2009-09-22 16:33:59199 scoped_refptr<IOBuffer> read_buffer_;
[email protected]aea80602009-09-18 00:55:08200 bool read_pending_;
201
202 int stream_hi_water_mark_; // The next stream id to use.
203
[email protected]93300672009-10-24 13:22:51204 // TODO(mbelshe): We need to track these stream lists better.
205 // I suspect it is possible to remove a stream from
206 // one list, but not the other.
[email protected]aea80602009-09-18 00:55:08207
[email protected]a677f2b2009-11-22 00:43:00208 // Map from stream id to all active streams. Streams are active in the sense
[email protected]955fc2e72010-02-08 20:37:30209 // that they have a consumer (typically SpdyNetworkTransaction and regardless
[email protected]a677f2b2009-11-22 00:43:00210 // of whether or not there is currently any ongoing IO [might be waiting for
211 // the server to start pushing the stream]) or there are still network events
212 // incoming even though the consumer has already gone away (cancellation).
213 // TODO(willchan): Perhaps we should separate out cancelled streams and move
214 // them into a separate ActiveStreamMap, and not deliver network events to
215 // them?
216 ActiveStreamMap active_streams_;
217 // List of all the streams that have already started to be pushed by the
218 // server, but do not have consumers yet.
[email protected]aea80602009-09-18 00:55:08219 ActiveStreamList pushed_streams_;
[email protected]a677f2b2009-11-22 00:43:00220 // List of streams declared in X-Associated-Content headers, but do not have
221 // consumers yet.
[email protected]18c53ae2009-10-01 18:18:52222 // The key is a string representing the path of the URI being pushed.
[email protected]2931238b2009-11-19 01:19:51223 PendingStreamMap pending_streams_;
[email protected]aea80602009-09-18 00:55:08224
225 // As we gather data to be sent, we put it into the output queue.
[email protected]aea80602009-09-18 00:55:08226 OutputQueue queue_;
227
[email protected]aea80602009-09-18 00:55:08228 // The packet we are currently sending.
[email protected]e1245352009-11-30 19:42:42229 bool write_pending_; // Will be true when a write is in progress.
[email protected]955fc2e72010-02-08 20:37:30230 SpdyIOBuffer in_flight_write_; // This is the write buffer in progress.
[email protected]e1245352009-11-30 19:42:42231
232 // Flag if we have a pending message scheduled for WriteSocket.
[email protected]aea80602009-09-18 00:55:08233 bool delayed_write_pending_;
[email protected]aea80602009-09-18 00:55:08234
[email protected]955fc2e72010-02-08 20:37:30235 // Flag if we're using an SSL connection for this SpdySession.
[email protected]dcc6bbb2009-12-09 19:09:01236 bool is_secure_;
237
[email protected]955fc2e72010-02-08 20:37:30238 // Spdy Frame state.
239 spdy::SpdyFramer spdy_framer_;
[email protected]aea80602009-09-18 00:55:08240
[email protected]60253bd2009-12-01 01:16:39241 // If an error has occurred on the session, the session is effectively
242 // dead. Record this error here. When no error has occurred, |error_| will
243 // be OK.
244 net::Error error_;
245 State state_;
246
[email protected]9b010802009-12-27 22:55:30247 // Some statistics counters for the session.
248 int streams_initiated_count_;
249 int streams_pushed_count_;
250 int streams_pushed_and_claimed_count_;
251 int streams_abandoned_count_;
252
[email protected]4b4762a2010-04-23 16:04:14253 bool in_session_pool_; // True if the session is currently in the pool.
254
[email protected]635909f2010-05-12 18:19:36255 BoundNetLog net_log_;
256
[email protected]affe8fe2009-10-14 20:06:05257 static bool use_ssl_;
[email protected]aea80602009-09-18 00:55:08258};
259
260} // namespace net
261
[email protected]dab9c7d2010-02-06 21:44:32262#endif // NET_SPDY_SPDY_SESSION_H_