OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 #include "net/spdy/spdy_session.h" | 5 #include "net/spdy/spdy_session.h" |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/rand_util.h" | 10 #include "base/rand_util.h" |
11 #include "base/stats_counters.h" | 11 #include "base/stats_counters.h" |
12 #include "base/stl_util-inl.h" | 12 #include "base/stl_util-inl.h" |
13 #include "base/string_util.h" | 13 #include "base/string_util.h" |
14 #include "net/base/connection_type_histograms.h" | 14 #include "net/base/connection_type_histograms.h" |
15 #include "net/base/load_flags.h" | 15 #include "net/base/load_flags.h" |
16 #include "net/base/load_log.h" | 16 #include "net/base/net_log.h" |
17 #include "net/base/net_util.h" | 17 #include "net/base/net_util.h" |
18 #include "net/http/http_network_session.h" | 18 #include "net/http/http_network_session.h" |
19 #include "net/http/http_request_info.h" | 19 #include "net/http/http_request_info.h" |
20 #include "net/http/http_response_headers.h" | 20 #include "net/http/http_response_headers.h" |
21 #include "net/http/http_response_info.h" | 21 #include "net/http/http_response_info.h" |
22 #include "net/socket/client_socket.h" | 22 #include "net/socket/client_socket.h" |
23 #include "net/socket/client_socket_factory.h" | 23 #include "net/socket/client_socket_factory.h" |
24 #include "net/socket/ssl_client_socket.h" | 24 #include "net/socket/ssl_client_socket.h" |
25 #include "net/spdy/spdy_frame_builder.h" | 25 #include "net/spdy/spdy_frame_builder.h" |
26 #include "net/spdy/spdy_protocol.h" | 26 #include "net/spdy/spdy_protocol.h" |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 | 252 |
253 // This is a newly initialized session that no client should have a handle to | 253 // This is a newly initialized session that no client should have a handle to |
254 // yet, so there's no need to start writing data as in OnTCPConnect(), but we | 254 // yet, so there's no need to start writing data as in OnTCPConnect(), but we |
255 // should start reading data. | 255 // should start reading data. |
256 ReadSocket(); | 256 ReadSocket(); |
257 } | 257 } |
258 | 258 |
259 net::Error SpdySession::Connect(const std::string& group_name, | 259 net::Error SpdySession::Connect(const std::string& group_name, |
260 const TCPSocketParams& destination, | 260 const TCPSocketParams& destination, |
261 RequestPriority priority, | 261 RequestPriority priority, |
262 LoadLog* load_log) { | 262 const BoundNetLog& net_log) { |
263 DCHECK(priority >= SPDY_PRIORITY_HIGHEST && priority <= SPDY_PRIORITY_LOWEST); | 263 DCHECK(priority >= SPDY_PRIORITY_HIGHEST && priority <= SPDY_PRIORITY_LOWEST); |
264 | 264 |
265 // If the connect process is started, let the caller continue. | 265 // If the connect process is started, let the caller continue. |
266 if (state_ > IDLE) | 266 if (state_ > IDLE) |
267 return net::OK; | 267 return net::OK; |
268 | 268 |
269 state_ = CONNECTING; | 269 state_ = CONNECTING; |
270 | 270 |
271 static StatsCounter spdy_sessions("spdy.sessions"); | 271 static StatsCounter spdy_sessions("spdy.sessions"); |
272 spdy_sessions.Increment(); | 272 spdy_sessions.Increment(); |
273 | 273 |
274 int rv = connection_->Init(group_name, destination, priority, | 274 int rv = connection_->Init(group_name, destination, priority, |
275 &connect_callback_, session_->tcp_socket_pool(), | 275 &connect_callback_, session_->tcp_socket_pool(), |
276 load_log); | 276 net_log); |
277 DCHECK(rv <= 0); | 277 DCHECK(rv <= 0); |
278 | 278 |
279 // If the connect is pending, we still return ok. The APIs enqueue | 279 // If the connect is pending, we still return ok. The APIs enqueue |
280 // work until after the connect completes asynchronously later. | 280 // work until after the connect completes asynchronously later. |
281 if (rv == net::ERR_IO_PENDING) | 281 if (rv == net::ERR_IO_PENDING) |
282 return net::OK; | 282 return net::OK; |
283 OnTCPConnect(rv); | 283 OnTCPConnect(rv); |
284 return static_cast<net::Error>(rv); | 284 return static_cast<net::Error>(rv); |
285 } | 285 } |
286 | 286 |
287 scoped_refptr<SpdyStream> SpdySession::GetOrCreateStream( | 287 scoped_refptr<SpdyStream> SpdySession::GetOrCreateStream( |
288 const HttpRequestInfo& request, | 288 const HttpRequestInfo& request, |
289 const UploadDataStream* upload_data, | 289 const UploadDataStream* upload_data, |
290 LoadLog* log) { | 290 const BoundNetLog& log) { |
291 const GURL& url = request.url; | 291 const GURL& url = request.url; |
292 const std::string& path = url.PathForRequest(); | 292 const std::string& path = url.PathForRequest(); |
293 | 293 |
294 scoped_refptr<SpdyStream> stream; | 294 scoped_refptr<SpdyStream> stream; |
295 | 295 |
296 // Check if we have a push stream for this path. | 296 // Check if we have a push stream for this path. |
297 if (request.method == "GET") { | 297 if (request.method == "GET") { |
298 stream = GetPushStream(path); | 298 stream = GetPushStream(path); |
299 if (stream) { | 299 if (stream) { |
300 DCHECK(streams_pushed_and_claimed_count_ < streams_pushed_count_); | 300 DCHECK(streams_pushed_and_claimed_count_ < streams_pushed_count_); |
301 streams_pushed_and_claimed_count_++; | 301 streams_pushed_and_claimed_count_++; |
302 return stream; | 302 return stream; |
303 } | 303 } |
304 } | 304 } |
305 | 305 |
306 // Check if we have a pending push stream for this url. | 306 // Check if we have a pending push stream for this url. |
307 PendingStreamMap::iterator it; | 307 PendingStreamMap::iterator it; |
308 it = pending_streams_.find(path); | 308 it = pending_streams_.find(path); |
309 if (it != pending_streams_.end()) { | 309 if (it != pending_streams_.end()) { |
310 DCHECK(!it->second); | 310 DCHECK(!it->second); |
311 // Server will assign a stream id when the push stream arrives. Use 0 for | 311 // Server will assign a stream id when the push stream arrives. Use 0 for |
312 // now. | 312 // now. |
313 LoadLog::AddEvent(log, LoadLog::TYPE_SPDY_STREAM_ADOPTED_PUSH_STREAM); | 313 log.AddEvent(NetLog::TYPE_SPDY_STREAM_ADOPTED_PUSH_STREAM); |
314 SpdyStream* stream = new SpdyStream(this, 0, true, log); | 314 SpdyStream* stream = new SpdyStream(this, 0, true, log); |
315 stream->set_path(path); | 315 stream->set_path(path); |
316 it->second = stream; | 316 it->second = stream; |
317 return it->second; | 317 return it->second; |
318 } | 318 } |
319 | 319 |
320 const spdy::SpdyStreamId stream_id = GetNewStreamId(); | 320 const spdy::SpdyStreamId stream_id = GetNewStreamId(); |
321 | 321 |
322 // If we still don't have a stream, activate one now. | 322 // If we still don't have a stream, activate one now. |
323 stream = new SpdyStream(this, stream_id, false, log); | 323 stream = new SpdyStream(this, stream_id, false, log); |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
468 | 468 |
469 if (use_ssl_) { | 469 if (use_ssl_) { |
470 // Add a SSL socket on top of our existing transport socket. | 470 // Add a SSL socket on top of our existing transport socket. |
471 ClientSocket* socket = connection_->release_socket(); | 471 ClientSocket* socket = connection_->release_socket(); |
472 // TODO(mbelshe): Fix the hostname. This is BROKEN without having | 472 // TODO(mbelshe): Fix the hostname. This is BROKEN without having |
473 // a real hostname. | 473 // a real hostname. |
474 socket = session_->socket_factory()->CreateSSLClientSocket( | 474 socket = session_->socket_factory()->CreateSSLClientSocket( |
475 socket, "" /* request_->url.HostNoBrackets() */ , ssl_config_); | 475 socket, "" /* request_->url.HostNoBrackets() */ , ssl_config_); |
476 connection_->set_socket(socket); | 476 connection_->set_socket(socket); |
477 is_secure_ = true; | 477 is_secure_ = true; |
478 // TODO(willchan): Plumb LoadLog into SPDY code. | 478 // TODO(willchan): Plumb NetLog into SPDY code. |
479 int status = connection_->socket()->Connect(&ssl_connect_callback_, NULL); | 479 int status = connection_->socket()->Connect(&ssl_connect_callback_, NULL); |
480 if (status != ERR_IO_PENDING) | 480 if (status != ERR_IO_PENDING) |
481 OnSSLConnect(status); | 481 OnSSLConnect(status); |
482 } else { | 482 } else { |
483 DCHECK_EQ(state_, CONNECTING); | 483 DCHECK_EQ(state_, CONNECTING); |
484 state_ = CONNECTED; | 484 state_ = CONNECTED; |
485 | 485 |
486 // Make sure we get any pending data sent. | 486 // Make sure we get any pending data sent. |
487 WriteSocketLater(); | 487 WriteSocketLater(); |
488 // Start reading | 488 // Start reading |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
889 if (it != pending_streams_.end()) { | 889 if (it != pending_streams_.end()) { |
890 stream = it->second; | 890 stream = it->second; |
891 pending_streams_.erase(it); | 891 pending_streams_.erase(it); |
892 } | 892 } |
893 | 893 |
894 if (stream) { | 894 if (stream) { |
895 CHECK(stream->pushed()); | 895 CHECK(stream->pushed()); |
896 CHECK_EQ(0u, stream->stream_id()); | 896 CHECK_EQ(0u, stream->stream_id()); |
897 stream->set_stream_id(stream_id); | 897 stream->set_stream_id(stream_id); |
898 } else { | 898 } else { |
899 // TODO(mbelshe): can we figure out how to use a LoadLog here? | 899 // TODO(mbelshe): can we figure out how to use a NetLog here? |
900 stream = new SpdyStream(this, stream_id, true, NULL); | 900 stream = new SpdyStream(this, stream_id, true, NULL); |
901 | 901 |
902 // A new HttpResponseInfo object needs to be generated so the call to | 902 // A new HttpResponseInfo object needs to be generated so the call to |
903 // OnResponseReceived below has something to fill in. | 903 // OnResponseReceived below has something to fill in. |
904 // When a SpdyNetworkTransaction is created for this resource, the | 904 // When a SpdyNetworkTransaction is created for this resource, the |
905 // response_info is copied over and this version is destroyed. | 905 // response_info is copied over and this version is destroyed. |
906 // | 906 // |
907 // TODO(cbentzel): Minimize allocations and copies of HttpResponseInfo | 907 // TODO(cbentzel): Minimize allocations and copies of HttpResponseInfo |
908 // object. Should it just be part of SpdyStream? | 908 // object. Should it just be part of SpdyStream? |
909 HttpResponseInfo* response_info = new HttpResponseInfo(); | 909 HttpResponseInfo* response_info = new HttpResponseInfo(); |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1054 | 1054 |
1055 // TODO(willchan): Cancel any streams that are past the GoAway frame's | 1055 // TODO(willchan): Cancel any streams that are past the GoAway frame's |
1056 // |last_accepted_stream_id|. | 1056 // |last_accepted_stream_id|. |
1057 | 1057 |
1058 // Don't bother killing any streams that are still reading. They'll either | 1058 // Don't bother killing any streams that are still reading. They'll either |
1059 // complete successfully or get an ERR_CONNECTION_CLOSED when the socket is | 1059 // complete successfully or get an ERR_CONNECTION_CLOSED when the socket is |
1060 // closed. | 1060 // closed. |
1061 } | 1061 } |
1062 | 1062 |
1063 } // namespace net | 1063 } // namespace net |
OLD | NEW |