blob: d7f60c00159cd1ea6f3f0df76fd252ef853ce615 [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;
33class HttpRequestInfo;
34class 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]367ead42010-02-26 00:15:2141 const HostPortPair& host_port_pair() const { return host_port_pair_; }
[email protected]aea80602009-09-18 00:55:0842
[email protected]955fc2e72010-02-08 20:37:3043 // Connect the Spdy Socket.
[email protected]aea80602009-09-18 00:55:0844 // Returns net::Error::OK on success.
45 // Note that this call does not wait for the connect to complete. Callers can
[email protected]955fc2e72010-02-08 20:37:3046 // immediately start using the SpdySession while it connects.
[email protected]aea80602009-09-18 00:55:0847 net::Error Connect(const std::string& group_name,
[email protected]7fc5b09a2010-02-27 00:07:3848 const TCPSocketParams& destination,
[email protected]eec34d7d2009-12-07 22:09:2349 RequestPriority priority,
[email protected]9e743cd2010-03-16 07:03:5350 const BoundNetLog& net_log);
[email protected]aea80602009-09-18 00:55:0851
[email protected]a677f2b2009-11-22 00:43:0052 // Get a stream for a given |request|. In the typical case, this will involve
53 // the creation of a new stream (and will send the SYN frame). If the server
54 // initiates a stream, it might already exist for a given path. The server
55 // might also not have initiated the stream yet, but indicated it will via
56 // X-Associated-Content.
57 // Returns the new or existing stream. Never returns NULL.
[email protected]955fc2e72010-02-08 20:37:3058 scoped_refptr<SpdyStream> GetOrCreateStream(const HttpRequestInfo& request,
[email protected]9e743cd2010-03-16 07:03:5359 const UploadDataStream* upload_data, const BoundNetLog& log);
[email protected]aea80602009-09-18 00:55:0860
[email protected]ff57bb82009-11-12 06:52:1461 // Write a data frame to the stream.
62 // Used to create and queue a data frame for the given stream.
[email protected]955fc2e72010-02-08 20:37:3063 int WriteStreamData(spdy::SpdyStreamId stream_id, net::IOBuffer* data,
[email protected]ff57bb82009-11-12 06:52:1464 int len);
65
[email protected]aea80602009-09-18 00:55:0866 // Cancel a stream.
[email protected]955fc2e72010-02-08 20:37:3067 bool CancelStream(spdy::SpdyStreamId stream_id);
[email protected]aea80602009-09-18 00:55:0868
69 // Check if a stream is active.
[email protected]955fc2e72010-02-08 20:37:3070 bool IsStreamActive(spdy::SpdyStreamId stream_id) const;
[email protected]aea80602009-09-18 00:55:0871
72 // The LoadState is used for informing the user of the current network
73 // status, such as "resolving host", "connecting", etc.
74 LoadState GetLoadState() const;
[email protected]d1eda932009-11-04 01:03:1075
[email protected]34437af82009-11-06 02:28:4976 // Enable or disable SSL.
77 static void SetSSLMode(bool enable) { use_ssl_ = enable; }
[email protected]85c0ed82009-12-15 23:14:1478 static bool SSLMode() { return use_ssl_; }
[email protected]34437af82009-11-06 02:28:4979
[email protected]aea80602009-09-18 00:55:0880 protected:
[email protected]955fc2e72010-02-08 20:37:3081 friend class SpdySessionPool;
[email protected]aea80602009-09-18 00:55:0882
[email protected]60253bd2009-12-01 01:16:3983 enum State {
84 IDLE,
85 CONNECTING,
86 CONNECTED,
87 CLOSED
88 };
89
[email protected]aea80602009-09-18 00:55:0890 // Provide access to the framer for testing.
[email protected]955fc2e72010-02-08 20:37:3091 spdy::SpdyFramer* GetFramer() { return &spdy_framer_; }
[email protected]aea80602009-09-18 00:55:0892
[email protected]955fc2e72010-02-08 20:37:3093 // Create a new SpdySession.
[email protected]74188f22010-04-09 20:18:5094 // |host_port_pair| is the host/port that this session connects to.
95 // |session| is the HttpNetworkSession
[email protected]367ead42010-02-26 00:15:2196 SpdySession(const HostPortPair& host_port_pair, HttpNetworkSession* session);
[email protected]aea80602009-09-18 00:55:0897
98 // Closes all open streams. Used as part of shutdown.
99 void CloseAllStreams(net::Error code);
100
101 private:
[email protected]955fc2e72010-02-08 20:37:30102 friend class base::RefCounted<SpdySession>;
[email protected]a677f2b2009-11-22 00:43:00103
[email protected]955fc2e72010-02-08 20:37:30104 typedef std::map<int, scoped_refptr<SpdyStream> > ActiveStreamMap;
105 typedef std::list<scoped_refptr<SpdyStream> > ActiveStreamList;
106 typedef std::map<std::string, scoped_refptr<SpdyStream> > PendingStreamMap;
107 typedef std::priority_queue<SpdyIOBuffer> OutputQueue;
[email protected]a677f2b2009-11-22 00:43:00108
[email protected]955fc2e72010-02-08 20:37:30109 virtual ~SpdySession();
[email protected]5389bc72009-11-05 23:34:24110
[email protected]5fe524e2010-02-20 00:43:22111 // Used by SpdySessionPool to initialize with a pre-existing SSL socket.
112 void InitializeWithSSLSocket(ClientSocketHandle* connection);
[email protected]1f14a912009-12-21 20:32:44113
[email protected]955fc2e72010-02-08 20:37:30114 // SpdyFramerVisitorInterface
115 virtual void OnError(spdy::SpdyFramer*);
116 virtual void OnStreamFrameData(spdy::SpdyStreamId stream_id,
[email protected]aea80602009-09-18 00:55:08117 const char* data,
[email protected]aeac1e42009-10-10 00:26:01118 size_t len);
[email protected]955fc2e72010-02-08 20:37:30119 virtual void OnControl(const spdy::SpdyControlFrame* frame);
[email protected]aea80602009-09-18 00:55:08120
121 // Control frame handlers.
[email protected]651b77c2010-03-10 19:29:42122 void OnSyn(const spdy::SpdySynStreamControlFrame& frame,
123 const spdy::SpdyHeaderBlock& headers);
124 void OnSynReply(const spdy::SpdySynReplyControlFrame& frame,
125 const spdy::SpdyHeaderBlock& headers);
126 void OnFin(const spdy::SpdyRstStreamControlFrame& frame);
127 void OnGoAway(const spdy::SpdyGoAwayControlFrame& frame);
[email protected]74188f22010-04-09 20:18:50128 void OnSettings(const spdy::SpdySettingsControlFrame& frame);
[email protected]aea80602009-09-18 00:55:08129
130 // IO Callbacks
[email protected]18c53ae2009-10-01 18:18:52131 void OnTCPConnect(int result);
132 void OnSSLConnect(int result);
[email protected]aea80602009-09-18 00:55:08133 void OnReadComplete(int result);
134 void OnWriteComplete(int result);
135
[email protected]74188f22010-04-09 20:18:50136 // Send relevant SETTINGS. This is generally called on connection setup.
137 void SendSettings();
138
[email protected]aea80602009-09-18 00:55:08139 // Start reading from the socket.
140 void ReadSocket();
141
142 // Write current data to the socket.
143 void WriteSocketLater();
144 void WriteSocket();
145
146 // Get a new stream id.
147 int GetNewStreamId();
148
[email protected]74188f22010-04-09 20:18:50149 // Queue a frame for sending.
150 // |frame| is the frame to send.
151 // |priority| is the priority for insertion into the queue.
152 // |stream| is the stream which this IO is associated with (or NULL).
153 void QueueFrame(spdy::SpdyFrame* frame, spdy::SpdyPriority priority,
154 SpdyStream* stream);
155
[email protected]60253bd2009-12-01 01:16:39156 // Closes this session. This will close all active streams and mark
157 // the session as permanently closed.
[email protected]353f6162009-12-10 18:04:12158 // |err| should not be OK; this function is intended to be called on
159 // error.
160 void CloseSessionOnError(net::Error err);
[email protected]60253bd2009-12-01 01:16:39161
[email protected]aea80602009-09-18 00:55:08162 // Track active streams in the active stream list.
[email protected]955fc2e72010-02-08 20:37:30163 void ActivateStream(SpdyStream* stream);
164 void DeactivateStream(spdy::SpdyStreamId id);
[email protected]aea80602009-09-18 00:55:08165
166 // Check if we have a pending pushed-stream for this url
167 // Returns the stream if found (and returns it from the pending
168 // list), returns NULL otherwise.
[email protected]955fc2e72010-02-08 20:37:30169 scoped_refptr<SpdyStream> GetPushStream(const std::string& url);
[email protected]aea80602009-09-18 00:55:08170
[email protected]3f662f12010-03-25 19:56:12171 // Creates an HttpResponseInfo instance, and calls OnResponseReceived().
172 // Returns true if successful.
173 bool Respond(const spdy::SpdyHeaderBlock& headers,
174 const scoped_refptr<SpdyStream> stream);
175
[email protected]dcc6bbb2009-12-09 19:09:01176 void GetSSLInfo(SSLInfo* ssl_info);
177
[email protected]955fc2e72010-02-08 20:37:30178 // Callbacks for the Spdy session.
179 CompletionCallbackImpl<SpdySession> connect_callback_;
180 CompletionCallbackImpl<SpdySession> ssl_connect_callback_;
181 CompletionCallbackImpl<SpdySession> read_callback_;
182 CompletionCallbackImpl<SpdySession> write_callback_;
[email protected]aea80602009-09-18 00:55:08183
184 // The domain this session is connected to.
[email protected]367ead42010-02-26 00:15:21185 const HostPortPair host_port_pair_;
[email protected]aea80602009-09-18 00:55:08186
[email protected]18c53ae2009-10-01 18:18:52187 SSLConfig ssl_config_;
188
[email protected]aea80602009-09-18 00:55:08189 scoped_refptr<HttpNetworkSession> session_;
190
191 // The socket handle for this session.
[email protected]1f14a912009-12-21 20:32:44192 scoped_ptr<ClientSocketHandle> connection_;
[email protected]aea80602009-09-18 00:55:08193
194 // The read buffer used to read data from the socket.
[email protected]230cadd2009-09-22 16:33:59195 scoped_refptr<IOBuffer> read_buffer_;
[email protected]aea80602009-09-18 00:55:08196 bool read_pending_;
197
198 int stream_hi_water_mark_; // The next stream id to use.
199
[email protected]93300672009-10-24 13:22:51200 // TODO(mbelshe): We need to track these stream lists better.
201 // I suspect it is possible to remove a stream from
202 // one list, but not the other.
[email protected]aea80602009-09-18 00:55:08203
[email protected]a677f2b2009-11-22 00:43:00204 // Map from stream id to all active streams. Streams are active in the sense
[email protected]955fc2e72010-02-08 20:37:30205 // that they have a consumer (typically SpdyNetworkTransaction and regardless
[email protected]a677f2b2009-11-22 00:43:00206 // of whether or not there is currently any ongoing IO [might be waiting for
207 // the server to start pushing the stream]) or there are still network events
208 // incoming even though the consumer has already gone away (cancellation).
209 // TODO(willchan): Perhaps we should separate out cancelled streams and move
210 // them into a separate ActiveStreamMap, and not deliver network events to
211 // them?
212 ActiveStreamMap active_streams_;
213 // List of all the streams that have already started to be pushed by the
214 // server, but do not have consumers yet.
[email protected]aea80602009-09-18 00:55:08215 ActiveStreamList pushed_streams_;
[email protected]a677f2b2009-11-22 00:43:00216 // List of streams declared in X-Associated-Content headers, but do not have
217 // consumers yet.
[email protected]18c53ae2009-10-01 18:18:52218 // The key is a string representing the path of the URI being pushed.
[email protected]2931238b2009-11-19 01:19:51219 PendingStreamMap pending_streams_;
[email protected]aea80602009-09-18 00:55:08220
221 // As we gather data to be sent, we put it into the output queue.
[email protected]aea80602009-09-18 00:55:08222 OutputQueue queue_;
223
[email protected]aea80602009-09-18 00:55:08224 // The packet we are currently sending.
[email protected]e1245352009-11-30 19:42:42225 bool write_pending_; // Will be true when a write is in progress.
[email protected]955fc2e72010-02-08 20:37:30226 SpdyIOBuffer in_flight_write_; // This is the write buffer in progress.
[email protected]e1245352009-11-30 19:42:42227
228 // Flag if we have a pending message scheduled for WriteSocket.
[email protected]aea80602009-09-18 00:55:08229 bool delayed_write_pending_;
[email protected]aea80602009-09-18 00:55:08230
[email protected]955fc2e72010-02-08 20:37:30231 // Flag if we're using an SSL connection for this SpdySession.
[email protected]dcc6bbb2009-12-09 19:09:01232 bool is_secure_;
233
[email protected]955fc2e72010-02-08 20:37:30234 // Spdy Frame state.
235 spdy::SpdyFramer spdy_framer_;
[email protected]aea80602009-09-18 00:55:08236
[email protected]60253bd2009-12-01 01:16:39237 // If an error has occurred on the session, the session is effectively
238 // dead. Record this error here. When no error has occurred, |error_| will
239 // be OK.
240 net::Error error_;
241 State state_;
242
[email protected]9b010802009-12-27 22:55:30243 // Some statistics counters for the session.
244 int streams_initiated_count_;
245 int streams_pushed_count_;
246 int streams_pushed_and_claimed_count_;
247 int streams_abandoned_count_;
248
[email protected]affe8fe2009-10-14 20:06:05249 static bool use_ssl_;
[email protected]aea80602009-09-18 00:55:08250};
251
252} // namespace net
253
[email protected]dab9c7d2010-02-06 21:44:32254#endif // NET_SPDY_SPDY_SESSION_H_