OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef NET_SPDY_SPDY_SESSION_H_ | 5 #ifndef NET_SPDY_SPDY_SESSION_H_ |
6 #define NET_SPDY_SPDY_SESSION_H_ | 6 #define NET_SPDY_SPDY_SESSION_H_ |
7 | 7 |
8 #include <algorithm> | 8 #include <algorithm> |
9 #include <list> | 9 #include <list> |
10 #include <map> | 10 #include <map> |
11 #include <queue> | 11 #include <queue> |
12 #include <string> | 12 #include <string> |
13 | 13 |
14 #include "base/gtest_prod_util.h" | 14 #include "base/gtest_prod_util.h" |
15 #include "base/memory/ref_counted.h" | 15 #include "base/memory/ref_counted.h" |
16 #include "base/memory/weak_ptr.h" | 16 #include "base/memory/weak_ptr.h" |
17 #include "base/time.h" | 17 #include "base/time.h" |
18 #include "net/base/io_buffer.h" | 18 #include "net/base/io_buffer.h" |
19 #include "net/base/load_states.h" | 19 #include "net/base/load_states.h" |
20 #include "net/base/net_errors.h" | 20 #include "net/base/net_errors.h" |
21 #include "net/base/request_priority.h" | 21 #include "net/base/request_priority.h" |
| 22 #include "net/base/ssl_client_cert_type.h" |
22 #include "net/base/ssl_config_service.h" | 23 #include "net/base/ssl_config_service.h" |
23 #include "net/base/upload_data_stream.h" | 24 #include "net/base/upload_data_stream.h" |
24 #include "net/socket/client_socket_handle.h" | 25 #include "net/socket/client_socket_handle.h" |
25 #include "net/socket/ssl_client_socket.h" | 26 #include "net/socket/ssl_client_socket.h" |
26 #include "net/socket/stream_socket.h" | 27 #include "net/socket/stream_socket.h" |
27 #include "net/spdy/buffered_spdy_framer.h" | 28 #include "net/spdy/buffered_spdy_framer.h" |
28 #include "net/spdy/spdy_credential_state.h" | 29 #include "net/spdy/spdy_credential_state.h" |
29 #include "net/spdy/spdy_io_buffer.h" | 30 #include "net/spdy/spdy_io_buffer.h" |
30 #include "net/spdy/spdy_protocol.h" | 31 #include "net/spdy/spdy_protocol.h" |
31 #include "net/spdy/spdy_session_pool.h" | 32 #include "net/spdy/spdy_session_pool.h" |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 SpdyProtocolErrorDetails_SpdyErrors_mismatch); | 87 SpdyProtocolErrorDetails_SpdyErrors_mismatch); |
87 | 88 |
88 COMPILE_ASSERT(PROTOCOL_ERROR_UNEXPECTED_PING == | 89 COMPILE_ASSERT(PROTOCOL_ERROR_UNEXPECTED_PING == |
89 static_cast<SpdyProtocolErrorDetails>(NUM_STATUS_CODES + | 90 static_cast<SpdyProtocolErrorDetails>(NUM_STATUS_CODES + |
90 STATUS_CODE_INVALID), | 91 STATUS_CODE_INVALID), |
91 SpdyProtocolErrorDetails_SpdyErrors_mismatch); | 92 SpdyProtocolErrorDetails_SpdyErrors_mismatch); |
92 | 93 |
93 class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>, | 94 class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>, |
94 public BufferedSpdyFramerVisitorInterface { | 95 public BufferedSpdyFramerVisitorInterface { |
95 public: | 96 public: |
| 97 // Defines an interface for producing SpdyIOBuffers. |
| 98 class NET_EXPORT_PRIVATE SpdyIOBufferProducer { |
| 99 public: |
| 100 SpdyIOBufferProducer() {} |
| 101 |
| 102 // Returns a newly created SpdyIOBuffer, owned by the caller, or NULL |
| 103 // if not buffer is ready to be produced. |
| 104 virtual SpdyIOBuffer* ProduceNextBuffer(SpdySession* session) = 0; |
| 105 |
| 106 virtual RequestPriority GetPriority() const = 0; |
| 107 |
| 108 virtual ~SpdyIOBufferProducer() {} |
| 109 |
| 110 protected: |
| 111 // Activates |spdy_stream| in |spdy_session|. |
| 112 static void ActivateStream(SpdySession* spdy_session, |
| 113 SpdyStream* spdy_stream); |
| 114 |
| 115 static SpdyIOBuffer* CreateIOBuffer(SpdyFrame* frame, |
| 116 RequestPriority priority, |
| 117 SpdyStream* spdy_stream); |
| 118 |
| 119 private: |
| 120 DISALLOW_COPY_AND_ASSIGN(SpdyIOBufferProducer); |
| 121 }; |
| 122 |
96 // Create a new SpdySession. | 123 // Create a new SpdySession. |
97 // |host_port_proxy_pair| is the host/port that this session connects to, and | 124 // |host_port_proxy_pair| is the host/port that this session connects to, and |
98 // the proxy configuration settings that it's using. | 125 // the proxy configuration settings that it's using. |
99 // |spdy_session_pool| is the SpdySessionPool that owns us. Its lifetime must | 126 // |spdy_session_pool| is the SpdySessionPool that owns us. Its lifetime must |
100 // strictly be greater than |this|. | 127 // strictly be greater than |this|. |
101 // |session| is the HttpNetworkSession. |net_log| is the NetLog that we log | 128 // |session| is the HttpNetworkSession. |net_log| is the NetLog that we log |
102 // network events to. | 129 // network events to. |
103 SpdySession(const HostPortProxyPair& host_port_proxy_pair, | 130 SpdySession(const HostPortProxyPair& host_port_proxy_pair, |
104 SpdySessionPool* spdy_session_pool, | 131 SpdySessionPool* spdy_session_pool, |
105 HttpServerProperties* http_server_properties, | 132 HttpServerProperties* http_server_properties, |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 // For SSL-based sessions, verifies that the server certificate in use by | 177 // For SSL-based sessions, verifies that the server certificate in use by |
151 // this session provides authentication for the domain and no client | 178 // this session provides authentication for the domain and no client |
152 // certificate or channel ID was sent to the original server during the SSL | 179 // certificate or channel ID was sent to the original server during the SSL |
153 // handshake. NOTE: This function can have false negatives on some | 180 // handshake. NOTE: This function can have false negatives on some |
154 // platforms. | 181 // platforms. |
155 // TODO(wtc): rename this function and the Net.SpdyIPPoolDomainMatch | 182 // TODO(wtc): rename this function and the Net.SpdyIPPoolDomainMatch |
156 // histogram because this function does more than verifying domain | 183 // histogram because this function does more than verifying domain |
157 // authentication now. | 184 // authentication now. |
158 bool VerifyDomainAuthentication(const std::string& domain); | 185 bool VerifyDomainAuthentication(const std::string& domain); |
159 | 186 |
| 187 // Records that |stream| has a write available from |producer|. |
| 188 // |producer| will be owned by this SpdySession. |
| 189 void SetStreamHasWriteAvailable(SpdyStream* stream, |
| 190 SpdyIOBufferProducer* producer); |
| 191 |
160 // Send the SYN frame for |stream_id|. This also sends PING message to check | 192 // Send the SYN frame for |stream_id|. This also sends PING message to check |
161 // the status of the connection. | 193 // the status of the connection. |
162 int WriteSynStream( | 194 SpdySynStreamControlFrame* CreateSynStream( |
163 SpdyStreamId stream_id, | 195 SpdyStreamId stream_id, |
164 RequestPriority priority, | 196 RequestPriority priority, |
165 uint8 credential_slot, | 197 uint8 credential_slot, |
166 SpdyControlFlags flags, | 198 SpdyControlFlags flags, |
167 const SpdyHeaderBlock& headers); | 199 const SpdyHeaderBlock& headers); |
168 | 200 |
169 // Write a CREDENTIAL frame to the session. | 201 // Write a CREDENTIAL frame to the session. |
170 int WriteCredentialFrame(const std::string& origin, | 202 SpdyCredentialControlFrame* CreateCredentialFrame(const std::string& origin, |
171 SSLClientCertType type, | 203 SSLClientCertType type, |
172 const std::string& key, | 204 const std::string& key, |
173 const std::string& cert, | 205 const std::string& cert, |
174 RequestPriority priority); | 206 RequestPriority priority); |
175 | 207 |
176 // Write a data frame to the stream. | 208 // Write a data frame to the stream. |
177 // Used to create and queue a data frame for the given stream. | 209 // Used to create and queue a data frame for the given stream. |
178 int WriteStreamData(SpdyStreamId stream_id, net::IOBuffer* data, | 210 SpdyDataFrame* CreateDataFrame(SpdyStreamId stream_id, |
179 int len, | 211 net::IOBuffer* data, int len, |
180 SpdyDataFlags flags); | 212 SpdyDataFlags flags); |
181 | 213 |
182 // Close a stream. | 214 // Close a stream. |
183 void CloseStream(SpdyStreamId stream_id, int status); | 215 void CloseStream(SpdyStreamId stream_id, int status); |
184 | 216 |
| 217 // Close a stream that has been created but is not yet active. |
| 218 void CloseCreatedStream(SpdyStream* stream, int status); |
| 219 |
185 // Reset a stream by sending a RST_STREAM frame with given status code. | 220 // Reset a stream by sending a RST_STREAM frame with given status code. |
186 // Also closes the stream. Was not piggybacked to CloseStream since not | 221 // Also closes the stream. Was not piggybacked to CloseStream since not |
187 // all of the calls to CloseStream necessitate sending a RST_STREAM. | 222 // all of the calls to CloseStream necessitate sending a RST_STREAM. |
188 void ResetStream(SpdyStreamId stream_id, | 223 void ResetStream(SpdyStreamId stream_id, |
189 SpdyStatusCodes status, | 224 SpdyStatusCodes status, |
190 const std::string& description); | 225 const std::string& description); |
191 | 226 |
192 // Check if a stream is active. | 227 // Check if a stream is active. |
193 bool IsStreamActive(SpdyStreamId stream_id) const; | 228 bool IsStreamActive(SpdyStreamId stream_id) const; |
194 | 229 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 bool WasEverUsed() const { | 296 bool WasEverUsed() const { |
262 return connection_->socket()->WasEverUsed(); | 297 return connection_->socket()->WasEverUsed(); |
263 } | 298 } |
264 | 299 |
265 void set_spdy_session_pool(SpdySessionPool* pool) { | 300 void set_spdy_session_pool(SpdySessionPool* pool) { |
266 spdy_session_pool_ = NULL; | 301 spdy_session_pool_ = NULL; |
267 } | 302 } |
268 | 303 |
269 // Returns true if session is not currently active | 304 // Returns true if session is not currently active |
270 bool is_active() const { | 305 bool is_active() const { |
271 return !active_streams_.empty(); | 306 return !active_streams_.empty() || !created_streams_.empty(); |
272 } | 307 } |
273 | 308 |
274 // Access to the number of active and pending streams. These are primarily | 309 // Access to the number of active and pending streams. These are primarily |
275 // available for testing and diagnostics. | 310 // available for testing and diagnostics. |
276 size_t num_active_streams() const { return active_streams_.size(); } | 311 size_t num_active_streams() const { return active_streams_.size(); } |
277 size_t num_unclaimed_pushed_streams() const { | 312 size_t num_unclaimed_pushed_streams() const { |
278 return unclaimed_pushed_streams_.size(); | 313 return unclaimed_pushed_streams_.size(); |
279 } | 314 } |
| 315 size_t num_created_streams() const { return created_streams_.size(); } |
280 | 316 |
281 // Returns true if flow control is enabled for the session. | 317 // Returns true if flow control is enabled for the session. |
282 bool is_flow_control_enabled() const { | 318 bool is_flow_control_enabled() const { |
283 return flow_control_; | 319 return flow_control_; |
284 } | 320 } |
285 | 321 |
286 // Returns the current |initial_send_window_size_|. | 322 // Returns the current |initial_send_window_size_|. |
287 int32 initial_send_window_size() const { | 323 int32 initial_send_window_size() const { |
288 return initial_send_window_size_; | 324 return initial_send_window_size_; |
289 } | 325 } |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 const BoundNetLog* stream_net_log; | 385 const BoundNetLog* stream_net_log; |
350 CompletionCallback callback; | 386 CompletionCallback callback; |
351 }; | 387 }; |
352 typedef std::queue<PendingCreateStream, std::list<PendingCreateStream> > | 388 typedef std::queue<PendingCreateStream, std::list<PendingCreateStream> > |
353 PendingCreateStreamQueue; | 389 PendingCreateStreamQueue; |
354 typedef std::map<int, scoped_refptr<SpdyStream> > ActiveStreamMap; | 390 typedef std::map<int, scoped_refptr<SpdyStream> > ActiveStreamMap; |
355 typedef std::map<std::string, | 391 typedef std::map<std::string, |
356 std::pair<scoped_refptr<SpdyStream>, base::TimeTicks> > PushedStreamMap; | 392 std::pair<scoped_refptr<SpdyStream>, base::TimeTicks> > PushedStreamMap; |
357 typedef std::priority_queue<SpdyIOBuffer> OutputQueue; | 393 typedef std::priority_queue<SpdyIOBuffer> OutputQueue; |
358 | 394 |
| 395 typedef std::set<scoped_refptr<SpdyStream> > CreatedStreamSet; |
| 396 typedef std::map<SpdyIOBufferProducer*, SpdyStream*> StreamProducerMap; |
| 397 class SpdyIOBufferProducerCompare { |
| 398 public: |
| 399 bool operator() (const SpdyIOBufferProducer* lhs, |
| 400 const SpdyIOBufferProducer* rhs) const { |
| 401 return lhs->GetPriority() < rhs->GetPriority(); |
| 402 } |
| 403 }; |
| 404 typedef std::priority_queue<SpdyIOBufferProducer*, |
| 405 std::vector<SpdyIOBufferProducer*>, |
| 406 SpdyIOBufferProducerCompare> WriteQueue; |
| 407 |
359 struct CallbackResultPair { | 408 struct CallbackResultPair { |
360 CallbackResultPair(const CompletionCallback& callback_in, int result_in) | 409 CallbackResultPair(const CompletionCallback& callback_in, int result_in) |
361 : callback(callback_in), result(result_in) {} | 410 : callback(callback_in), result(result_in) {} |
362 ~CallbackResultPair(); | 411 ~CallbackResultPair(); |
363 | 412 |
364 CompletionCallback callback; | 413 CompletionCallback callback; |
365 int result; | 414 int result; |
366 }; | 415 }; |
367 | 416 |
368 typedef std::map<const scoped_refptr<SpdyStream>*, CallbackResultPair> | 417 typedef std::map<const scoped_refptr<SpdyStream>*, CallbackResultPair> |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 // Write current data to the socket. | 476 // Write current data to the socket. |
428 void WriteSocketLater(); | 477 void WriteSocketLater(); |
429 void WriteSocket(); | 478 void WriteSocket(); |
430 | 479 |
431 // Get a new stream id. | 480 // Get a new stream id. |
432 int GetNewStreamId(); | 481 int GetNewStreamId(); |
433 | 482 |
434 // Queue a frame for sending. | 483 // Queue a frame for sending. |
435 // |frame| is the frame to send. | 484 // |frame| is the frame to send. |
436 // |priority| is the priority for insertion into the queue. | 485 // |priority| is the priority for insertion into the queue. |
437 // |stream| is the stream which this IO is associated with (or NULL). | 486 void QueueFrame(SpdyFrame* frame, RequestPriority priority); |
438 void QueueFrame(SpdyFrame* frame, RequestPriority priority, | |
439 SpdyStream* stream); | |
440 | 487 |
441 // Track active streams in the active stream list. | 488 // Track active streams in the active stream list. |
442 void ActivateStream(SpdyStream* stream); | 489 void ActivateStream(SpdyStream* stream); |
443 void DeleteStream(SpdyStreamId id, int status); | 490 void DeleteStream(SpdyStreamId id, int status); |
444 | 491 |
445 // Removes this session from the session pool. | 492 // Removes this session from the session pool. |
446 void RemoveFromPool(); | 493 void RemoveFromPool(); |
447 | 494 |
448 // Check if we have a pending pushed-stream for this url | 495 // Check if we have a pending pushed-stream for this url |
449 // Returns the stream if found (and returns it from the pending | 496 // Returns the stream if found (and returns it from the pending |
450 // list), returns NULL otherwise. | 497 // list), returns NULL otherwise. |
451 scoped_refptr<SpdyStream> GetActivePushStream(const std::string& url); | 498 scoped_refptr<SpdyStream> GetActivePushStream(const std::string& url); |
452 | 499 |
453 // Calls OnResponseReceived(). | 500 // Calls OnResponseReceived(). |
454 // Returns true if successful. | 501 // Returns true if successful. |
455 bool Respond(const SpdyHeaderBlock& headers, | 502 bool Respond(const SpdyHeaderBlock& headers, |
456 const scoped_refptr<SpdyStream> stream); | 503 const scoped_refptr<SpdyStream> stream); |
457 | 504 |
458 void RecordPingRTTHistogram(base::TimeDelta duration); | 505 void RecordPingRTTHistogram(base::TimeDelta duration); |
459 void RecordHistograms(); | 506 void RecordHistograms(); |
460 void RecordProtocolErrorHistogram(SpdyProtocolErrorDetails details); | 507 void RecordProtocolErrorHistogram(SpdyProtocolErrorDetails details); |
461 | 508 |
462 // Closes all streams. Used as part of shutdown. | 509 // Closes all streams. Used as part of shutdown. |
463 void CloseAllStreams(net::Error status); | 510 void CloseAllStreams(net::Error status); |
464 | 511 |
| 512 void LogAbandonedStream(const scoped_refptr<SpdyStream>& stream, |
| 513 net::Error status); |
| 514 |
465 // Invokes a user callback for stream creation. We provide this method so it | 515 // Invokes a user callback for stream creation. We provide this method so it |
466 // can be deferred to the MessageLoop, so we avoid re-entrancy problems. | 516 // can be deferred to the MessageLoop, so we avoid re-entrancy problems. |
467 void InvokeUserStreamCreationCallback(scoped_refptr<SpdyStream>* stream); | 517 void InvokeUserStreamCreationCallback(scoped_refptr<SpdyStream>* stream); |
468 | 518 |
469 // Remove old unclaimed pushed streams. | 519 // Remove old unclaimed pushed streams. |
470 void DeleteExpiredPushedStreams(); | 520 void DeleteExpiredPushedStreams(); |
471 | 521 |
472 // BufferedSpdyFramerVisitorInterface: | 522 // BufferedSpdyFramerVisitorInterface: |
473 virtual void OnError(SpdyFramer::SpdyError error_code) OVERRIDE; | 523 virtual void OnError(SpdyFramer::SpdyError error_code) OVERRIDE; |
474 virtual void OnStreamError(SpdyStreamId stream_id, | 524 virtual void OnStreamError(SpdyStreamId stream_id, |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
573 // the server to start pushing the stream]) or there are still network events | 623 // the server to start pushing the stream]) or there are still network events |
574 // incoming even though the consumer has already gone away (cancellation). | 624 // incoming even though the consumer has already gone away (cancellation). |
575 // TODO(willchan): Perhaps we should separate out cancelled streams and move | 625 // TODO(willchan): Perhaps we should separate out cancelled streams and move |
576 // them into a separate ActiveStreamMap, and not deliver network events to | 626 // them into a separate ActiveStreamMap, and not deliver network events to |
577 // them? | 627 // them? |
578 ActiveStreamMap active_streams_; | 628 ActiveStreamMap active_streams_; |
579 // Map of all the streams that have already started to be pushed by the | 629 // Map of all the streams that have already started to be pushed by the |
580 // server, but do not have consumers yet. | 630 // server, but do not have consumers yet. |
581 PushedStreamMap unclaimed_pushed_streams_; | 631 PushedStreamMap unclaimed_pushed_streams_; |
582 | 632 |
583 // As we gather data to be sent, we put it into the output queue. | 633 // Set of all created streams but that have not yet sent any frames. |
584 OutputQueue queue_; | 634 CreatedStreamSet created_streams_; |
| 635 |
| 636 // As streams have data to be sent, we put them into the write queue. |
| 637 WriteQueue write_queue_; |
| 638 |
| 639 // Mapping from SpdyIOBufferProducers to their corresponding SpdyStream |
| 640 // so that when a stream is destroyed, we can remove the corresponding |
| 641 // producer from |write_queue_|. |
| 642 StreamProducerMap stream_producers_; |
585 | 643 |
586 // The packet we are currently sending. | 644 // The packet we are currently sending. |
587 bool write_pending_; // Will be true when a write is in progress. | 645 bool write_pending_; // Will be true when a write is in progress. |
588 SpdyIOBuffer in_flight_write_; // This is the write buffer in progress. | 646 SpdyIOBuffer in_flight_write_; // This is the write buffer in progress. |
589 | 647 |
590 // Flag if we have a pending message scheduled for WriteSocket. | 648 // Flag if we have a pending message scheduled for WriteSocket. |
591 bool delayed_write_pending_; | 649 bool delayed_write_pending_; |
592 | 650 |
593 // Flag if we're using an SSL connection for this SpdySession. | 651 // Flag if we're using an SSL connection for this SpdySession. |
594 bool is_secure_; | 652 bool is_secure_; |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
684 base::TimeDelta hung_interval_; | 742 base::TimeDelta hung_interval_; |
685 | 743 |
686 // This SPDY proxy is allowed to push resources from origins that are | 744 // This SPDY proxy is allowed to push resources from origins that are |
687 // different from those of their associated streams. | 745 // different from those of their associated streams. |
688 HostPortPair trusted_spdy_proxy_; | 746 HostPortPair trusted_spdy_proxy_; |
689 }; | 747 }; |
690 | 748 |
691 } // namespace net | 749 } // namespace net |
692 | 750 |
693 #endif // NET_SPDY_SPDY_SESSION_H_ | 751 #endif // NET_SPDY_SPDY_SESSION_H_ |
OLD | NEW |