| 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 |