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 |