| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/http/http_stream_factory_impl_job.h" | 5 #include "net/http/http_stream_factory_impl_job.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/stl_util-inl.h" | 8 #include "base/stl_util-inl.h" |
| 9 #include "base/string_number_conversions.h" | 9 #include "base/string_number_conversions.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 GURL::Replacements replacements; | 38 GURL::Replacements replacements; |
| 39 // new_sheme and new_port need to be in scope here because GURL::Replacements | 39 // new_sheme and new_port need to be in scope here because GURL::Replacements |
| 40 // references the memory contained by them directly. | 40 // references the memory contained by them directly. |
| 41 const std::string new_scheme = "https"; | 41 const std::string new_scheme = "https"; |
| 42 const std::string new_port = base::IntToString(443); | 42 const std::string new_port = base::IntToString(443); |
| 43 replacements.SetSchemeStr(new_scheme); | 43 replacements.SetSchemeStr(new_scheme); |
| 44 replacements.SetPortStr(new_port); | 44 replacements.SetPortStr(new_port); |
| 45 return original_url.ReplaceComponents(replacements); | 45 return original_url.ReplaceComponents(replacements); |
| 46 } | 46 } |
| 47 | 47 |
| 48 // Parameters associated with the creation of a Job. |
| 49 class JobCreationParameters : public NetLog::EventParameters { |
| 50 public: |
| 51 JobCreationParameters(const std::string& url) : url_(url) {} |
| 52 |
| 53 virtual Value* ToValue() const { |
| 54 DictionaryValue* dict = new DictionaryValue(); |
| 55 dict->SetString("url", url_); |
| 56 return dict; |
| 57 } |
| 58 |
| 59 private: |
| 60 const std::string url_; |
| 61 }; |
| 62 |
| 48 } // namespace | 63 } // namespace |
| 49 | 64 |
| 50 HttpStreamFactoryImpl::Job::Job(HttpStreamFactoryImpl* stream_factory, | 65 HttpStreamFactoryImpl::Job::Job(HttpStreamFactoryImpl* stream_factory, |
| 51 HttpNetworkSession* session) | 66 HttpNetworkSession* session) |
| 52 : request_(NULL), | 67 : request_(NULL), |
| 53 ALLOW_THIS_IN_INITIALIZER_LIST(io_callback_(this, &Job::OnIOComplete)), | 68 ALLOW_THIS_IN_INITIALIZER_LIST(io_callback_(this, &Job::OnIOComplete)), |
| 54 connection_(new ClientSocketHandle), | 69 connection_(new ClientSocketHandle), |
| 55 session_(session), | 70 session_(session), |
| 56 stream_factory_(stream_factory), | 71 stream_factory_(stream_factory), |
| 57 next_state_(STATE_NONE), | 72 next_state_(STATE_NONE), |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 return LOAD_STATE_RESOLVING_PROXY_FOR_URL; | 142 return LOAD_STATE_RESOLVING_PROXY_FOR_URL; |
| 128 case STATE_CREATE_STREAM_COMPLETE: | 143 case STATE_CREATE_STREAM_COMPLETE: |
| 129 return connection_->GetLoadState(); | 144 return connection_->GetLoadState(); |
| 130 case STATE_INIT_CONNECTION_COMPLETE: | 145 case STATE_INIT_CONNECTION_COMPLETE: |
| 131 return LOAD_STATE_SENDING_REQUEST; | 146 return LOAD_STATE_SENDING_REQUEST; |
| 132 default: | 147 default: |
| 133 return LOAD_STATE_IDLE; | 148 return LOAD_STATE_IDLE; |
| 134 } | 149 } |
| 135 } | 150 } |
| 136 | 151 |
| 152 void HttpStreamFactoryImpl::Job::Orphan(const Request* request) { |
| 153 DCHECK_EQ(request_, request); |
| 154 request_ = NULL; |
| 155 } |
| 156 |
| 137 bool HttpStreamFactoryImpl::Job::was_alternate_protocol_available() const { | 157 bool HttpStreamFactoryImpl::Job::was_alternate_protocol_available() const { |
| 138 return was_alternate_protocol_available_; | 158 return was_alternate_protocol_available_; |
| 139 } | 159 } |
| 140 | 160 |
| 141 bool HttpStreamFactoryImpl::Job::was_npn_negotiated() const { | 161 bool HttpStreamFactoryImpl::Job::was_npn_negotiated() const { |
| 142 return was_npn_negotiated_; | 162 return was_npn_negotiated_; |
| 143 } | 163 } |
| 144 | 164 |
| 145 bool HttpStreamFactoryImpl::Job::using_spdy() const { | 165 bool HttpStreamFactoryImpl::Job::using_spdy() const { |
| 146 return using_spdy_; | 166 return using_spdy_; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 158 DCHECK(using_ssl_); | 178 DCHECK(using_ssl_); |
| 159 DCHECK(!establishing_tunnel_); | 179 DCHECK(!establishing_tunnel_); |
| 160 DCHECK(connection_.get() && connection_->socket()); | 180 DCHECK(connection_.get() && connection_->socket()); |
| 161 SSLClientSocket* ssl_socket = | 181 SSLClientSocket* ssl_socket = |
| 162 static_cast<SSLClientSocket*>(connection_->socket()); | 182 static_cast<SSLClientSocket*>(connection_->socket()); |
| 163 ssl_socket->GetSSLInfo(&ssl_info_); | 183 ssl_socket->GetSSLInfo(&ssl_info_); |
| 164 } | 184 } |
| 165 | 185 |
| 166 void HttpStreamFactoryImpl::Job::OnStreamReadyCallback() { | 186 void HttpStreamFactoryImpl::Job::OnStreamReadyCallback() { |
| 167 DCHECK(stream_.get()); | 187 DCHECK(stream_.get()); |
| 168 request_->Complete(was_alternate_protocol_available(), | 188 DCHECK(!IsPreconnecting()); |
| 169 was_npn_negotiated(), | 189 if (IsOrphaned()) { |
| 170 using_spdy(), | 190 stream_factory_->OnOrphanedJobComplete(this); |
| 171 net_log_.source()); | 191 } else { |
| 172 request_->OnStreamReady(ssl_config_, proxy_info_, stream_.release()); | 192 request_->Complete(was_alternate_protocol_available(), |
| 193 was_npn_negotiated(), |
| 194 using_spdy(), |
| 195 net_log_.source()); |
| 196 request_->OnStreamReady(this, ssl_config_, proxy_info_, stream_.release()); |
| 197 } |
| 173 // |this| may be deleted after this call. | 198 // |this| may be deleted after this call. |
| 174 } | 199 } |
| 175 | 200 |
| 176 void HttpStreamFactoryImpl::Job::OnSpdySessionReadyCallback() { | 201 void HttpStreamFactoryImpl::Job::OnSpdySessionReadyCallback() { |
| 177 DCHECK(!stream_.get()); | 202 DCHECK(!stream_.get()); |
| 203 DCHECK(!IsPreconnecting()); |
| 178 DCHECK(using_spdy()); | 204 DCHECK(using_spdy()); |
| 179 DCHECK(new_spdy_session_); | 205 DCHECK(new_spdy_session_); |
| 180 scoped_refptr<SpdySession> spdy_session = new_spdy_session_; | 206 scoped_refptr<SpdySession> spdy_session = new_spdy_session_; |
| 181 new_spdy_session_ = NULL; | 207 new_spdy_session_ = NULL; |
| 182 stream_factory_->OnSpdySessionReady(this, spdy_session, spdy_session_direct_); | 208 if (IsOrphaned()) { |
| 209 // TODO(willchan): This is actually probably yet another opportunity for |
| 210 // improving SPDY late binding. Investigate getting this to work. It'll |
| 211 // probably make a bigger difference when we have ip connection pooling. |
| 212 stream_factory_->OnOrphanedJobComplete(this); |
| 213 } else { |
| 214 request_->OnSpdySessionReady(this, spdy_session, spdy_session_direct_); |
| 215 } |
| 183 // |this| may be deleted after this call. | 216 // |this| may be deleted after this call. |
| 184 } | 217 } |
| 185 | 218 |
| 186 void HttpStreamFactoryImpl::Job::OnStreamFailedCallback(int result) { | 219 void HttpStreamFactoryImpl::Job::OnStreamFailedCallback(int result) { |
| 187 request_->OnStreamFailed(result, ssl_config_); | 220 DCHECK(!IsPreconnecting()); |
| 221 if (IsOrphaned()) |
| 222 stream_factory_->OnOrphanedJobComplete(this); |
| 223 else |
| 224 request_->OnStreamFailed(this, result, ssl_config_); |
| 188 // |this| may be deleted after this call. | 225 // |this| may be deleted after this call. |
| 189 } | 226 } |
| 190 | 227 |
| 191 void HttpStreamFactoryImpl::Job::OnCertificateErrorCallback( | 228 void HttpStreamFactoryImpl::Job::OnCertificateErrorCallback( |
| 192 int result, const SSLInfo& ssl_info) { | 229 int result, const SSLInfo& ssl_info) { |
| 193 request_->OnCertificateError(result, ssl_config_, ssl_info); | 230 DCHECK(!IsPreconnecting()); |
| 231 if (IsOrphaned()) |
| 232 stream_factory_->OnOrphanedJobComplete(this); |
| 233 else |
| 234 request_->OnCertificateError(this, result, ssl_config_, ssl_info); |
| 194 // |this| may be deleted after this call. | 235 // |this| may be deleted after this call. |
| 195 } | 236 } |
| 196 | 237 |
| 197 void HttpStreamFactoryImpl::Job::OnNeedsProxyAuthCallback( | 238 void HttpStreamFactoryImpl::Job::OnNeedsProxyAuthCallback( |
| 198 const HttpResponseInfo& response, | 239 const HttpResponseInfo& response, |
| 199 HttpAuthController* auth_controller) { | 240 HttpAuthController* auth_controller) { |
| 200 request_->OnNeedsProxyAuth( | 241 DCHECK(!IsPreconnecting()); |
| 201 response, ssl_config_, proxy_info_, auth_controller); | 242 if (IsOrphaned()) |
| 243 stream_factory_->OnOrphanedJobComplete(this); |
| 244 else |
| 245 request_->OnNeedsProxyAuth( |
| 246 this, response, ssl_config_, proxy_info_, auth_controller); |
| 202 // |this| may be deleted after this call. | 247 // |this| may be deleted after this call. |
| 203 } | 248 } |
| 204 | 249 |
| 205 void HttpStreamFactoryImpl::Job::OnNeedsClientAuthCallback( | 250 void HttpStreamFactoryImpl::Job::OnNeedsClientAuthCallback( |
| 206 SSLCertRequestInfo* cert_info) { | 251 SSLCertRequestInfo* cert_info) { |
| 207 request_->OnNeedsClientAuth(ssl_config_, cert_info); | 252 DCHECK(!IsPreconnecting()); |
| 253 if (IsOrphaned()) |
| 254 stream_factory_->OnOrphanedJobComplete(this); |
| 255 else |
| 256 request_->OnNeedsClientAuth(this, ssl_config_, cert_info); |
| 208 // |this| may be deleted after this call. | 257 // |this| may be deleted after this call. |
| 209 } | 258 } |
| 210 | 259 |
| 211 void HttpStreamFactoryImpl::Job::OnHttpsProxyTunnelResponseCallback( | 260 void HttpStreamFactoryImpl::Job::OnHttpsProxyTunnelResponseCallback( |
| 212 const HttpResponseInfo& response_info, | 261 const HttpResponseInfo& response_info, |
| 213 HttpStream* stream) { | 262 HttpStream* stream) { |
| 214 request_->OnHttpsProxyTunnelResponse( | 263 DCHECK(!IsPreconnecting()); |
| 215 response_info, ssl_config_, proxy_info_, stream); | 264 if (IsOrphaned()) |
| 265 stream_factory_->OnOrphanedJobComplete(this); |
| 266 else |
| 267 request_->OnHttpsProxyTunnelResponse( |
| 268 this, response_info, ssl_config_, proxy_info_, stream); |
| 216 // |this| may be deleted after this call. | 269 // |this| may be deleted after this call. |
| 217 } | 270 } |
| 218 | 271 |
| 219 void HttpStreamFactoryImpl::Job::OnPreconnectsComplete() { | 272 void HttpStreamFactoryImpl::Job::OnPreconnectsComplete() { |
| 220 stream_factory_->OnPreconnectsComplete(this); | 273 DCHECK(!request_); |
| 274 if (IsOrphaned()) |
| 275 stream_factory_->OnOrphanedJobComplete(this); |
| 276 else |
| 277 stream_factory_->OnPreconnectsComplete(this); |
| 221 // |this| may be deleted after this call. | 278 // |this| may be deleted after this call. |
| 222 } | 279 } |
| 223 | 280 |
| 224 void HttpStreamFactoryImpl::Job::OnIOComplete(int result) { | 281 void HttpStreamFactoryImpl::Job::OnIOComplete(int result) { |
| 225 RunLoop(result); | 282 RunLoop(result); |
| 226 } | 283 } |
| 227 | 284 |
| 228 int HttpStreamFactoryImpl::Job::RunLoop(int result) { | 285 int HttpStreamFactoryImpl::Job::RunLoop(int result) { |
| 229 result = DoLoop(result); | 286 result = DoLoop(result); |
| 230 | 287 |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 515 HostPortProxyPair(endpoint_, proxy_info_.proxy_server()); | 572 HostPortProxyPair(endpoint_, proxy_info_.proxy_server()); |
| 516 } | 573 } |
| 517 if (session_->spdy_session_pool()->HasSession(spdy_session_key)) { | 574 if (session_->spdy_session_pool()->HasSession(spdy_session_key)) { |
| 518 // If we're preconnecting, but we already have a SpdySession, we don't | 575 // If we're preconnecting, but we already have a SpdySession, we don't |
| 519 // actually need to preconnect any sockets, so we're done. | 576 // actually need to preconnect any sockets, so we're done. |
| 520 if (IsPreconnecting()) | 577 if (IsPreconnecting()) |
| 521 return OK; | 578 return OK; |
| 522 using_spdy_ = true; | 579 using_spdy_ = true; |
| 523 next_state_ = STATE_CREATE_STREAM; | 580 next_state_ = STATE_CREATE_STREAM; |
| 524 return OK; | 581 return OK; |
| 525 } else if (!IsPreconnecting()) { | 582 } else if (request_) { |
| 526 // Update the spdy session key for the request that launched this job. | 583 // Update the spdy session key for the request that launched this job. |
| 527 request_->SetSpdySessionKey(spdy_session_key); | 584 request_->SetSpdySessionKey(spdy_session_key); |
| 528 } | 585 } |
| 529 } | 586 } |
| 530 | 587 |
| 531 // Build the string used to uniquely identify connections of this type. | 588 // Build the string used to uniquely identify connections of this type. |
| 532 // Determine the host and port to connect to. | 589 // Determine the host and port to connect to. |
| 533 std::string connection_group = endpoint_.ToString(); | 590 std::string connection_group = endpoint_.ToString(); |
| 534 DCHECK(!connection_group.empty()); | 591 DCHECK(!connection_group.empty()); |
| 535 | 592 |
| (...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1127 NOTREACHED(); | 1184 NOTREACHED(); |
| 1128 break; | 1185 break; |
| 1129 } | 1186 } |
| 1130 } | 1187 } |
| 1131 | 1188 |
| 1132 bool HttpStreamFactoryImpl::Job::IsPreconnecting() const { | 1189 bool HttpStreamFactoryImpl::Job::IsPreconnecting() const { |
| 1133 DCHECK_GE(num_streams_, 0); | 1190 DCHECK_GE(num_streams_, 0); |
| 1134 return num_streams_ > 0; | 1191 return num_streams_ > 0; |
| 1135 } | 1192 } |
| 1136 | 1193 |
| 1194 bool HttpStreamFactoryImpl::Job::IsOrphaned() const { |
| 1195 return !IsPreconnecting() && !request_; |
| 1196 } |
| 1197 |
| 1137 } // namespace net | 1198 } // namespace net |
| OLD | NEW |