blob: 8a23168b9e5fac1f05711c566ee773a38bcce8f1 [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]9e743cd2010-03-16 07:03:5336class BoundNetLog;
[email protected]dcc6bbb2009-12-09 19:09:0137class SSLInfo;
[email protected]aea80602009-09-18 00:55:0838
[email protected]955fc2e72010-02-08 20:37:3039class SpdySession : public base::RefCounted<SpdySession>,
40 public spdy::SpdyFramerVisitorInterface {
[email protected]aea80602009-09-18 00:55:0841 public:
[email protected]807c01a2010-04-21 16:57:4542 // Create a new SpdySession.
43 // |host_port_pair| is the host/port that this session connects to.
[email protected]635909f2010-05-12 18:19:3644 // |session| is the HttpNetworkSession. |net_log| is the NetLog that we log
45 // network events to.
46 SpdySession(const HostPortPair& host_port_pair, HttpNetworkSession* session,
[email protected]44297002010-05-16 00:59:1047 NetLog* net_log);
[email protected]807c01a2010-04-21 16:57:4548
[email protected]367ead42010-02-26 00:15:2149 const HostPortPair& host_port_pair() const { return host_port_pair_; }
[email protected]aea80602009-09-18 00:55:0850
[email protected]955fc2e72010-02-08 20:37:3051 // Connect the Spdy Socket.
[email protected]aea80602009-09-18 00:55:0852 // Returns net::Error::OK on success.
53 // Note that this call does not wait for the connect to complete. Callers can
[email protected]955fc2e72010-02-08 20:37:3054 // immediately start using the SpdySession while it connects.
[email protected]aea80602009-09-18 00:55:0855 net::Error Connect(const std::string& group_name,
[email protected]7fc5b09a2010-02-27 00:07:3856 const TCPSocketParams& destination,
[email protected]635909f2010-05-12 18:19:3657 RequestPriority priority);
[email protected]aea80602009-09-18 00:55:0858
[email protected]9be804c82010-06-24 17:59:4659 // Get a pushed stream for a given |url|.
60 // If the server initiates a stream, it might already exist for a given path.
61 // The server might also not have initiated the stream yet, but indicated it
[email protected]bdbda462010-06-28 17:30:3762 // will via X-Associated-Content. Writes the stream out to |spdy_stream|.
63 // Returns a net error code.
64 int GetPushStream(
[email protected]9be804c82010-06-24 17:59:4665 const GURL& url,
[email protected]bdbda462010-06-28 17:30:3766 scoped_refptr<SpdyStream>* spdy_stream,
[email protected]9be804c82010-06-24 17:59:4667 const BoundNetLog& stream_net_log);
68
[email protected]bdbda462010-06-28 17:30:3769 // Create a new stream for a given |url|. Writes it out to |spdy_stream|.
70 // Returns a net error code.
71 int CreateStream(
[email protected]9be804c82010-06-24 17:59:4672 const GURL& url,
73 RequestPriority priority,
[email protected]bdbda462010-06-28 17:30:3774 scoped_refptr<SpdyStream>* spdy_stream,
[email protected]33c477b2010-05-13 19:21:0775 const BoundNetLog& stream_net_log);
[email protected]aea80602009-09-18 00:55:0876
[email protected]807c01a2010-04-21 16:57:4577 // Used by SpdySessionPool to initialize with a pre-existing SSL socket.
[email protected]26ef6582010-06-24 02:30:4778 // Returns OK on success, or an error on failure.
[email protected]bdbda462010-06-28 17:30:3779 net::Error InitializeWithSSLSocket(ClientSocketHandle* connection,
80 int certificate_error_code);
[email protected]807c01a2010-04-21 16:57:4581
[email protected]9be804c82010-06-24 17:59:4682 // Send the SYN frame for |stream_id|.
83 int WriteSynStream(
84 spdy::SpdyStreamId stream_id,
85 RequestPriority priority,
86 spdy::SpdyControlFlags flags,
87 const linked_ptr<spdy::SpdyHeaderBlock>& headers);
88
[email protected]ff57bb82009-11-12 06:52:1489 // Write a data frame to the stream.
90 // Used to create and queue a data frame for the given stream.
[email protected]955fc2e72010-02-08 20:37:3091 int WriteStreamData(spdy::SpdyStreamId stream_id, net::IOBuffer* data,
[email protected]ff57bb82009-11-12 06:52:1492 int len);
93
[email protected]48599ca2010-06-15 23:10:3694 // Close a stream.
95 void CloseStream(spdy::SpdyStreamId stream_id, int status);
[email protected]aea80602009-09-18 00:55:0896
97 // Check if a stream is active.
[email protected]955fc2e72010-02-08 20:37:3098 bool IsStreamActive(spdy::SpdyStreamId stream_id) const;
[email protected]aea80602009-09-18 00:55:0899
100 // The LoadState is used for informing the user of the current network
101 // status, such as "resolving host", "connecting", etc.
102 LoadState GetLoadState() const;
[email protected]d1eda932009-11-04 01:03:10103
[email protected]48599ca2010-06-15 23:10:36104 // Closes all streams. Used as part of shutdown.
105 void CloseAllStreams(net::Error status);
[email protected]807c01a2010-04-21 16:57:45106
[email protected]9be804c82010-06-24 17:59:46107 // Fills SSL info in |ssl_info| and returns true when SSL is in use.
108 bool GetSSLInfo(SSLInfo* ssl_info, bool* was_npn_negotiated);
109
[email protected]34437af82009-11-06 02:28:49110 // Enable or disable SSL.
111 static void SetSSLMode(bool enable) { use_ssl_ = enable; }
[email protected]85c0ed82009-12-15 23:14:14112 static bool SSLMode() { return use_ssl_; }
[email protected]34437af82009-11-06 02:28:49113
[email protected]807c01a2010-04-21 16:57:45114 private:
115 friend class base::RefCounted<SpdySession>;
[email protected]9be804c82010-06-24 17:59:46116 FRIEND_TEST(SpdySessionTest, GetActivePushStream);
[email protected]aea80602009-09-18 00:55:08117
[email protected]60253bd2009-12-01 01:16:39118 enum State {
119 IDLE,
120 CONNECTING,
121 CONNECTED,
122 CLOSED
123 };
124
[email protected]955fc2e72010-02-08 20:37:30125 typedef std::map<int, scoped_refptr<SpdyStream> > ActiveStreamMap;
[email protected]65d56aa2010-06-14 04:13:40126 // Only HTTP push a stream.
[email protected]9be804c82010-06-24 17:59:46127 typedef std::list<scoped_refptr<SpdyStream> > ActivePushedStreamList;
128 typedef std::map<std::string, scoped_refptr<SpdyStream> > PendingStreamMap;
[email protected]955fc2e72010-02-08 20:37:30129 typedef std::priority_queue<SpdyIOBuffer> OutputQueue;
[email protected]a677f2b2009-11-22 00:43:00130
[email protected]955fc2e72010-02-08 20:37:30131 virtual ~SpdySession();
[email protected]5389bc72009-11-05 23:34:24132
[email protected]955fc2e72010-02-08 20:37:30133 // SpdyFramerVisitorInterface
134 virtual void OnError(spdy::SpdyFramer*);
135 virtual void OnStreamFrameData(spdy::SpdyStreamId stream_id,
[email protected]aea80602009-09-18 00:55:08136 const char* data,
[email protected]aeac1e42009-10-10 00:26:01137 size_t len);
[email protected]955fc2e72010-02-08 20:37:30138 virtual void OnControl(const spdy::SpdyControlFrame* frame);
[email protected]aea80602009-09-18 00:55:08139
140 // Control frame handlers.
[email protected]651b77c2010-03-10 19:29:42141 void OnSyn(const spdy::SpdySynStreamControlFrame& frame,
[email protected]33c477b2010-05-13 19:21:07142 const linked_ptr<spdy::SpdyHeaderBlock>& headers);
[email protected]651b77c2010-03-10 19:29:42143 void OnSynReply(const spdy::SpdySynReplyControlFrame& frame,
[email protected]33c477b2010-05-13 19:21:07144 const linked_ptr<spdy::SpdyHeaderBlock>& headers);
[email protected]651b77c2010-03-10 19:29:42145 void OnFin(const spdy::SpdyRstStreamControlFrame& frame);
146 void OnGoAway(const spdy::SpdyGoAwayControlFrame& frame);
[email protected]74188f22010-04-09 20:18:50147 void OnSettings(const spdy::SpdySettingsControlFrame& frame);
[email protected]aea80602009-09-18 00:55:08148
149 // IO Callbacks
[email protected]18c53ae2009-10-01 18:18:52150 void OnTCPConnect(int result);
151 void OnSSLConnect(int result);
[email protected]aea80602009-09-18 00:55:08152 void OnReadComplete(int result);
153 void OnWriteComplete(int result);
154
[email protected]74188f22010-04-09 20:18:50155 // Send relevant SETTINGS. This is generally called on connection setup.
156 void SendSettings();
157
[email protected]aea80602009-09-18 00:55:08158 // Start reading from the socket.
[email protected]26ef6582010-06-24 02:30:47159 // Returns OK on success, or an error on failure.
160 net::Error ReadSocket();
[email protected]aea80602009-09-18 00:55:08161
162 // Write current data to the socket.
163 void WriteSocketLater();
164 void WriteSocket();
165
166 // Get a new stream id.
167 int GetNewStreamId();
168
[email protected]74188f22010-04-09 20:18:50169 // Queue a frame for sending.
170 // |frame| is the frame to send.
171 // |priority| is the priority for insertion into the queue.
172 // |stream| is the stream which this IO is associated with (or NULL).
173 void QueueFrame(spdy::SpdyFrame* frame, spdy::SpdyPriority priority,
174 SpdyStream* stream);
175
[email protected]60253bd2009-12-01 01:16:39176 // Closes this session. This will close all active streams and mark
177 // the session as permanently closed.
[email protected]353f6162009-12-10 18:04:12178 // |err| should not be OK; this function is intended to be called on
179 // error.
180 void CloseSessionOnError(net::Error err);
[email protected]60253bd2009-12-01 01:16:39181
[email protected]aea80602009-09-18 00:55:08182 // Track active streams in the active stream list.
[email protected]955fc2e72010-02-08 20:37:30183 void ActivateStream(SpdyStream* stream);
[email protected]48599ca2010-06-15 23:10:36184 void DeleteStream(spdy::SpdyStreamId id, int status);
[email protected]aea80602009-09-18 00:55:08185
[email protected]4b4762a2010-04-23 16:04:14186 // Removes this session from the session pool.
187 void RemoveFromPool();
188
[email protected]aea80602009-09-18 00:55:08189 // Check if we have a pending pushed-stream for this url
190 // Returns the stream if found (and returns it from the pending
191 // list), returns NULL otherwise.
[email protected]9be804c82010-06-24 17:59:46192 scoped_refptr<SpdyStream> GetActivePushStream(const std::string& url);
[email protected]aea80602009-09-18 00:55:08193
[email protected]9be804c82010-06-24 17:59:46194 // Calls OnResponseReceived().
[email protected]3f662f12010-03-25 19:56:12195 // Returns true if successful.
196 bool Respond(const spdy::SpdyHeaderBlock& headers,
197 const scoped_refptr<SpdyStream> stream);
198
[email protected]0aebc002010-05-21 06:50:19199 void RecordHistograms();
200
[email protected]955fc2e72010-02-08 20:37:30201 // Callbacks for the Spdy session.
202 CompletionCallbackImpl<SpdySession> connect_callback_;
203 CompletionCallbackImpl<SpdySession> ssl_connect_callback_;
204 CompletionCallbackImpl<SpdySession> read_callback_;
205 CompletionCallbackImpl<SpdySession> write_callback_;
[email protected]aea80602009-09-18 00:55:08206
207 // The domain this session is connected to.
[email protected]367ead42010-02-26 00:15:21208 const HostPortPair host_port_pair_;
[email protected]aea80602009-09-18 00:55:08209
[email protected]18c53ae2009-10-01 18:18:52210 SSLConfig ssl_config_;
211
[email protected]aea80602009-09-18 00:55:08212 scoped_refptr<HttpNetworkSession> session_;
213
214 // The socket handle for this session.
[email protected]1f14a912009-12-21 20:32:44215 scoped_ptr<ClientSocketHandle> connection_;
[email protected]aea80602009-09-18 00:55:08216
217 // The read buffer used to read data from the socket.
[email protected]230cadd2009-09-22 16:33:59218 scoped_refptr<IOBuffer> read_buffer_;
[email protected]aea80602009-09-18 00:55:08219 bool read_pending_;
220
221 int stream_hi_water_mark_; // The next stream id to use.
222
[email protected]93300672009-10-24 13:22:51223 // TODO(mbelshe): We need to track these stream lists better.
224 // I suspect it is possible to remove a stream from
225 // one list, but not the other.
[email protected]aea80602009-09-18 00:55:08226
[email protected]a677f2b2009-11-22 00:43:00227 // Map from stream id to all active streams. Streams are active in the sense
[email protected]955fc2e72010-02-08 20:37:30228 // that they have a consumer (typically SpdyNetworkTransaction and regardless
[email protected]a677f2b2009-11-22 00:43:00229 // of whether or not there is currently any ongoing IO [might be waiting for
230 // the server to start pushing the stream]) or there are still network events
231 // incoming even though the consumer has already gone away (cancellation).
232 // TODO(willchan): Perhaps we should separate out cancelled streams and move
233 // them into a separate ActiveStreamMap, and not deliver network events to
234 // them?
235 ActiveStreamMap active_streams_;
236 // List of all the streams that have already started to be pushed by the
237 // server, but do not have consumers yet.
[email protected]65d56aa2010-06-14 04:13:40238 ActivePushedStreamList pushed_streams_;
[email protected]a677f2b2009-11-22 00:43:00239 // List of streams declared in X-Associated-Content headers, but do not have
240 // consumers yet.
[email protected]18c53ae2009-10-01 18:18:52241 // The key is a string representing the path of the URI being pushed.
[email protected]2931238b2009-11-19 01:19:51242 PendingStreamMap pending_streams_;
[email protected]aea80602009-09-18 00:55:08243
244 // As we gather data to be sent, we put it into the output queue.
[email protected]aea80602009-09-18 00:55:08245 OutputQueue queue_;
246
[email protected]aea80602009-09-18 00:55:08247 // The packet we are currently sending.
[email protected]e1245352009-11-30 19:42:42248 bool write_pending_; // Will be true when a write is in progress.
[email protected]955fc2e72010-02-08 20:37:30249 SpdyIOBuffer in_flight_write_; // This is the write buffer in progress.
[email protected]e1245352009-11-30 19:42:42250
251 // Flag if we have a pending message scheduled for WriteSocket.
[email protected]aea80602009-09-18 00:55:08252 bool delayed_write_pending_;
[email protected]aea80602009-09-18 00:55:08253
[email protected]955fc2e72010-02-08 20:37:30254 // Flag if we're using an SSL connection for this SpdySession.
[email protected]dcc6bbb2009-12-09 19:09:01255 bool is_secure_;
256
[email protected]bdbda462010-06-28 17:30:37257 // Certificate error code when using a secure connection.
258 int certificate_error_code_;
259
[email protected]955fc2e72010-02-08 20:37:30260 // Spdy Frame state.
261 spdy::SpdyFramer spdy_framer_;
[email protected]aea80602009-09-18 00:55:08262
[email protected]60253bd2009-12-01 01:16:39263 // If an error has occurred on the session, the session is effectively
264 // dead. Record this error here. When no error has occurred, |error_| will
265 // be OK.
266 net::Error error_;
267 State state_;
268
[email protected]9b010802009-12-27 22:55:30269 // Some statistics counters for the session.
270 int streams_initiated_count_;
271 int streams_pushed_count_;
272 int streams_pushed_and_claimed_count_;
273 int streams_abandoned_count_;
[email protected]0aebc002010-05-21 06:50:19274 bool sent_settings_; // Did this session send settings when it started.
275 bool received_settings_; // Did this session receive at least one settings
276 // frame.
[email protected]9b010802009-12-27 22:55:30277
[email protected]4b4762a2010-04-23 16:04:14278 bool in_session_pool_; // True if the session is currently in the pool.
279
[email protected]635909f2010-05-12 18:19:36280 BoundNetLog net_log_;
281
[email protected]affe8fe2009-10-14 20:06:05282 static bool use_ssl_;
[email protected]aea80602009-09-18 00:55:08283};
284
285} // namespace net
286
[email protected]dab9c7d2010-02-06 21:44:32287#endif // NET_SPDY_SPDY_SESSION_H_