blob: 66c8a3c2f129aaec0f763ef09d42e5ba36392bda [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"
23#include "testing/platform_test.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]eec34d7d2009-12-07 22:09:2335class LoadLog;
[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]955fc2e72010-02-08 20:37:3041 // Get the domain for this SpdySession.
[email protected]d1eda932009-11-04 01:03:1042 const std::string& domain() const { return domain_; }
[email protected]aea80602009-09-18 00:55:0843
[email protected]955fc2e72010-02-08 20:37:3044 // Connect the Spdy Socket.
[email protected]aea80602009-09-18 00:55:0845 // Returns net::Error::OK on success.
46 // Note that this call does not wait for the connect to complete. Callers can
[email protected]955fc2e72010-02-08 20:37:3047 // immediately start using the SpdySession while it connects.
[email protected]aea80602009-09-18 00:55:0848 net::Error Connect(const std::string& group_name,
[email protected]ac790b42009-12-02 04:31:3149 const HostResolver::RequestInfo& host,
[email protected]eec34d7d2009-12-07 22:09:2350 RequestPriority priority,
51 LoadLog* load_log);
[email protected]aea80602009-09-18 00:55:0852
[email protected]a677f2b2009-11-22 00:43:0053 // Get a stream for a given |request|. In the typical case, this will involve
54 // the creation of a new stream (and will send the SYN frame). If the server
55 // initiates a stream, it might already exist for a given path. The server
56 // might also not have initiated the stream yet, but indicated it will via
57 // X-Associated-Content.
58 // Returns the new or existing stream. Never returns NULL.
[email protected]955fc2e72010-02-08 20:37:3059 scoped_refptr<SpdyStream> GetOrCreateStream(const HttpRequestInfo& request,
[email protected]dac358042009-12-18 02:07:4860 const UploadDataStream* upload_data, LoadLog* log);
[email protected]aea80602009-09-18 00:55:0861
[email protected]ff57bb82009-11-12 06:52:1462 // Write a data frame to the stream.
63 // Used to create and queue a data frame for the given stream.
[email protected]955fc2e72010-02-08 20:37:3064 int WriteStreamData(spdy::SpdyStreamId stream_id, net::IOBuffer* data,
[email protected]ff57bb82009-11-12 06:52:1465 int len);
66
[email protected]aea80602009-09-18 00:55:0867 // Cancel a stream.
[email protected]955fc2e72010-02-08 20:37:3068 bool CancelStream(spdy::SpdyStreamId stream_id);
[email protected]aea80602009-09-18 00:55:0869
70 // Check if a stream is active.
[email protected]955fc2e72010-02-08 20:37:3071 bool IsStreamActive(spdy::SpdyStreamId stream_id) const;
[email protected]aea80602009-09-18 00:55:0872
73 // The LoadState is used for informing the user of the current network
74 // status, such as "resolving host", "connecting", etc.
75 LoadState GetLoadState() const;
[email protected]d1eda932009-11-04 01:03:1076
[email protected]34437af82009-11-06 02:28:4977 // Enable or disable SSL.
78 static void SetSSLMode(bool enable) { use_ssl_ = enable; }
[email protected]85c0ed82009-12-15 23:14:1479 static bool SSLMode() { return use_ssl_; }
[email protected]34437af82009-11-06 02:28:4980
[email protected]aea80602009-09-18 00:55:0881 protected:
[email protected]955fc2e72010-02-08 20:37:3082 friend class SpdySessionPool;
[email protected]aea80602009-09-18 00:55:0883
[email protected]60253bd2009-12-01 01:16:3984 enum State {
85 IDLE,
86 CONNECTING,
87 CONNECTED,
88 CLOSED
89 };
90
[email protected]aea80602009-09-18 00:55:0891 // Provide access to the framer for testing.
[email protected]955fc2e72010-02-08 20:37:3092 spdy::SpdyFramer* GetFramer() { return &spdy_framer_; }
[email protected]aea80602009-09-18 00:55:0893
[email protected]955fc2e72010-02-08 20:37:3094 // Create a new SpdySession.
[email protected]aea80602009-09-18 00:55:0895 // |host| is the hostname that this session connects to.
[email protected]955fc2e72010-02-08 20:37:3096 SpdySession(const std::string& host, 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]955fc2e72010-02-08 20:37:30111 // Used by SpdySessionPool to initialize with a pre-existing socket.
[email protected]1f14a912009-12-21 20:32:44112 void InitializeWithSocket(ClientSocketHandle* connection);
113
[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]955fc2e72010-02-08 20:37:30122 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::SpdyFinStreamControlFrame* frame);
[email protected]aea80602009-09-18 00:55:08127
128 // IO Callbacks
[email protected]18c53ae2009-10-01 18:18:52129 void OnTCPConnect(int result);
130 void OnSSLConnect(int result);
[email protected]aea80602009-09-18 00:55:08131 void OnReadComplete(int result);
132 void OnWriteComplete(int result);
133
134 // Start reading from the socket.
135 void ReadSocket();
136
137 // Write current data to the socket.
138 void WriteSocketLater();
139 void WriteSocket();
140
141 // Get a new stream id.
142 int GetNewStreamId();
143
[email protected]60253bd2009-12-01 01:16:39144 // Closes this session. This will close all active streams and mark
145 // the session as permanently closed.
[email protected]353f6162009-12-10 18:04:12146 // |err| should not be OK; this function is intended to be called on
147 // error.
148 void CloseSessionOnError(net::Error err);
[email protected]60253bd2009-12-01 01:16:39149
[email protected]aea80602009-09-18 00:55:08150 // Track active streams in the active stream list.
[email protected]955fc2e72010-02-08 20:37:30151 void ActivateStream(SpdyStream* stream);
152 void DeactivateStream(spdy::SpdyStreamId id);
[email protected]aea80602009-09-18 00:55:08153
154 // Check if we have a pending pushed-stream for this url
155 // Returns the stream if found (and returns it from the pending
156 // list), returns NULL otherwise.
[email protected]955fc2e72010-02-08 20:37:30157 scoped_refptr<SpdyStream> GetPushStream(const std::string& url);
[email protected]aea80602009-09-18 00:55:08158
[email protected]dcc6bbb2009-12-09 19:09:01159 void GetSSLInfo(SSLInfo* ssl_info);
160
[email protected]955fc2e72010-02-08 20:37:30161 // Callbacks for the Spdy session.
162 CompletionCallbackImpl<SpdySession> connect_callback_;
163 CompletionCallbackImpl<SpdySession> ssl_connect_callback_;
164 CompletionCallbackImpl<SpdySession> read_callback_;
165 CompletionCallbackImpl<SpdySession> write_callback_;
[email protected]aea80602009-09-18 00:55:08166
167 // The domain this session is connected to.
168 std::string domain_;
169
[email protected]18c53ae2009-10-01 18:18:52170 SSLConfig ssl_config_;
171
[email protected]aea80602009-09-18 00:55:08172 scoped_refptr<HttpNetworkSession> session_;
173
174 // The socket handle for this session.
[email protected]1f14a912009-12-21 20:32:44175 scoped_ptr<ClientSocketHandle> connection_;
[email protected]aea80602009-09-18 00:55:08176
177 // The read buffer used to read data from the socket.
[email protected]230cadd2009-09-22 16:33:59178 scoped_refptr<IOBuffer> read_buffer_;
[email protected]aea80602009-09-18 00:55:08179 bool read_pending_;
180
181 int stream_hi_water_mark_; // The next stream id to use.
182
[email protected]93300672009-10-24 13:22:51183 // TODO(mbelshe): We need to track these stream lists better.
184 // I suspect it is possible to remove a stream from
185 // one list, but not the other.
[email protected]aea80602009-09-18 00:55:08186
[email protected]a677f2b2009-11-22 00:43:00187 // Map from stream id to all active streams. Streams are active in the sense
[email protected]955fc2e72010-02-08 20:37:30188 // that they have a consumer (typically SpdyNetworkTransaction and regardless
[email protected]a677f2b2009-11-22 00:43:00189 // of whether or not there is currently any ongoing IO [might be waiting for
190 // the server to start pushing the stream]) or there are still network events
191 // incoming even though the consumer has already gone away (cancellation).
192 // TODO(willchan): Perhaps we should separate out cancelled streams and move
193 // them into a separate ActiveStreamMap, and not deliver network events to
194 // them?
195 ActiveStreamMap active_streams_;
196 // List of all the streams that have already started to be pushed by the
197 // server, but do not have consumers yet.
[email protected]aea80602009-09-18 00:55:08198 ActiveStreamList pushed_streams_;
[email protected]a677f2b2009-11-22 00:43:00199 // List of streams declared in X-Associated-Content headers, but do not have
200 // consumers yet.
[email protected]18c53ae2009-10-01 18:18:52201 // The key is a string representing the path of the URI being pushed.
[email protected]2931238b2009-11-19 01:19:51202 PendingStreamMap pending_streams_;
[email protected]aea80602009-09-18 00:55:08203
204 // As we gather data to be sent, we put it into the output queue.
[email protected]aea80602009-09-18 00:55:08205 OutputQueue queue_;
206
[email protected]aea80602009-09-18 00:55:08207 // The packet we are currently sending.
[email protected]e1245352009-11-30 19:42:42208 bool write_pending_; // Will be true when a write is in progress.
[email protected]955fc2e72010-02-08 20:37:30209 SpdyIOBuffer in_flight_write_; // This is the write buffer in progress.
[email protected]e1245352009-11-30 19:42:42210
211 // Flag if we have a pending message scheduled for WriteSocket.
[email protected]aea80602009-09-18 00:55:08212 bool delayed_write_pending_;
[email protected]aea80602009-09-18 00:55:08213
[email protected]955fc2e72010-02-08 20:37:30214 // Flag if we're using an SSL connection for this SpdySession.
[email protected]dcc6bbb2009-12-09 19:09:01215 bool is_secure_;
216
[email protected]955fc2e72010-02-08 20:37:30217 // Spdy Frame state.
218 spdy::SpdyFramer spdy_framer_;
[email protected]aea80602009-09-18 00:55:08219
[email protected]60253bd2009-12-01 01:16:39220 // If an error has occurred on the session, the session is effectively
221 // dead. Record this error here. When no error has occurred, |error_| will
222 // be OK.
223 net::Error error_;
224 State state_;
225
[email protected]9b010802009-12-27 22:55:30226 // Some statistics counters for the session.
227 int streams_initiated_count_;
228 int streams_pushed_count_;
229 int streams_pushed_and_claimed_count_;
230 int streams_abandoned_count_;
231
[email protected]affe8fe2009-10-14 20:06:05232 static bool use_ssl_;
[email protected]aea80602009-09-18 00:55:08233};
234
235} // namespace net
236
[email protected]dab9c7d2010-02-06 21:44:32237#endif // NET_SPDY_SPDY_SESSION_H_