OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "net/http/http_network_transaction.h" | |
6 | |
7 #include <set> | |
8 #include <vector> | |
9 | |
10 #include "base/bind.h" | |
11 #include "base/bind_helpers.h" | |
12 #include "base/compiler_specific.h" | |
13 #include "base/format_macros.h" | |
14 #include "base/memory/scoped_ptr.h" | |
15 #include "base/metrics/field_trial.h" | |
16 #include "base/metrics/histogram.h" | |
17 #include "base/profiler/scoped_tracker.h" | |
18 #include "base/stl_util.h" | |
19 #include "base/strings/string_number_conversions.h" | |
20 #include "base/strings/string_util.h" | |
21 #include "base/strings/stringprintf.h" | |
22 #include "base/time/time.h" | |
23 #include "base/values.h" | |
24 #include "build/build_config.h" | |
25 #include "net/base/auth.h" | |
26 #include "net/base/host_port_pair.h" | |
27 #include "net/base/io_buffer.h" | |
28 #include "net/base/load_flags.h" | |
29 #include "net/base/load_timing_info.h" | |
30 #include "net/base/net_errors.h" | |
31 #include "net/base/net_util.h" | |
32 #include "net/base/upload_data_stream.h" | |
33 #include "net/http/http_auth.h" | |
34 #include "net/http/http_auth_handler.h" | |
35 #include "net/http/http_auth_handler_factory.h" | |
36 #include "net/http/http_basic_stream.h" | |
37 #include "net/http/http_chunked_decoder.h" | |
38 #include "net/http/http_network_session.h" | |
39 #include "net/http/http_proxy_client_socket.h" | |
40 #include "net/http/http_proxy_client_socket_pool.h" | |
41 #include "net/http/http_request_headers.h" | |
42 #include "net/http/http_request_info.h" | |
43 #include "net/http/http_response_headers.h" | |
44 #include "net/http/http_response_info.h" | |
45 #include "net/http/http_server_properties.h" | |
46 #include "net/http/http_status_code.h" | |
47 #include "net/http/http_stream.h" | |
48 #include "net/http/http_stream_factory.h" | |
49 #include "net/http/http_util.h" | |
50 #include "net/http/transport_security_state.h" | |
51 #include "net/http/url_security_manager.h" | |
52 #include "net/socket/client_socket_factory.h" | |
53 #include "net/socket/socks_client_socket_pool.h" | |
54 #include "net/socket/ssl_client_socket.h" | |
55 #include "net/socket/ssl_client_socket_pool.h" | |
56 #include "net/socket/transport_client_socket_pool.h" | |
57 #include "net/spdy/hpack_huffman_aggregator.h" | |
58 #include "net/spdy/spdy_http_stream.h" | |
59 #include "net/spdy/spdy_session.h" | |
60 #include "net/spdy/spdy_session_pool.h" | |
61 #include "net/ssl/ssl_cert_request_info.h" | |
62 #include "net/ssl/ssl_connection_status_flags.h" | |
63 #include "url/gurl.h" | |
64 #include "url/url_canon.h" | |
65 | |
66 namespace net { | |
67 | |
68 namespace { | |
69 | |
70 void ProcessAlternateProtocol( | |
71 HttpNetworkSession* session, | |
72 const HttpResponseHeaders& headers, | |
73 const HostPortPair& http_host_port_pair) { | |
74 if (!headers.HasHeader(kAlternateProtocolHeader)) | |
75 return; | |
76 | |
77 std::vector<std::string> alternate_protocol_values; | |
78 void* iter = NULL; | |
79 std::string alternate_protocol_str; | |
80 while (headers.EnumerateHeader(&iter, kAlternateProtocolHeader, | |
81 &alternate_protocol_str)) { | |
82 alternate_protocol_values.push_back(alternate_protocol_str); | |
83 } | |
84 | |
85 session->http_stream_factory()->ProcessAlternateProtocol( | |
86 session->http_server_properties(), | |
87 alternate_protocol_values, | |
88 http_host_port_pair, | |
89 *session); | |
90 } | |
91 | |
92 base::Value* NetLogSSLVersionFallbackCallback( | |
93 const GURL* url, | |
94 int net_error, | |
95 uint16 version_before, | |
96 uint16 version_after, | |
97 NetLog::LogLevel /* log_level */) { | |
98 base::DictionaryValue* dict = new base::DictionaryValue(); | |
99 dict->SetString("host_and_port", GetHostAndPort(*url)); | |
100 dict->SetInteger("net_error", net_error); | |
101 dict->SetInteger("version_before", version_before); | |
102 dict->SetInteger("version_after", version_after); | |
103 return dict; | |
104 } | |
105 | |
106 } // namespace | |
107 | |
108 //----------------------------------------------------------------------------- | |
109 | |
110 HttpNetworkTransaction::HttpNetworkTransaction(RequestPriority priority, | |
111 HttpNetworkSession* session) | |
112 : pending_auth_target_(HttpAuth::AUTH_NONE), | |
113 io_callback_(base::Bind(&HttpNetworkTransaction::OnIOComplete, | |
114 base::Unretained(this))), | |
115 session_(session), | |
116 request_(NULL), | |
117 priority_(priority), | |
118 headers_valid_(false), | |
119 fallback_error_code_(ERR_SSL_INAPPROPRIATE_FALLBACK), | |
120 request_headers_(), | |
121 read_buf_len_(0), | |
122 total_received_bytes_(0), | |
123 next_state_(STATE_NONE), | |
124 establishing_tunnel_(false), | |
125 websocket_handshake_stream_base_create_helper_(NULL) { | |
126 session->ssl_config_service()->GetSSLConfig(&server_ssl_config_); | |
127 session->GetNextProtos(&server_ssl_config_.next_protos); | |
128 proxy_ssl_config_ = server_ssl_config_; | |
129 } | |
130 | |
131 HttpNetworkTransaction::~HttpNetworkTransaction() { | |
132 if (stream_.get()) { | |
133 HttpResponseHeaders* headers = GetResponseHeaders(); | |
134 // TODO(mbelshe): The stream_ should be able to compute whether or not the | |
135 // stream should be kept alive. No reason to compute here | |
136 // and pass it in. | |
137 bool try_to_keep_alive = | |
138 next_state_ == STATE_NONE && | |
139 stream_->CanFindEndOfResponse() && | |
140 (!headers || headers->IsKeepAlive()); | |
141 if (!try_to_keep_alive) { | |
142 stream_->Close(true /* not reusable */); | |
143 } else { | |
144 if (stream_->IsResponseBodyComplete()) { | |
145 // If the response body is complete, we can just reuse the socket. | |
146 stream_->Close(false /* reusable */); | |
147 } else if (stream_->IsSpdyHttpStream()) { | |
148 // Doesn't really matter for SpdyHttpStream. Just close it. | |
149 stream_->Close(true /* not reusable */); | |
150 } else { | |
151 // Otherwise, we try to drain the response body. | |
152 HttpStream* stream = stream_.release(); | |
153 stream->Drain(session_); | |
154 } | |
155 } | |
156 } | |
157 | |
158 if (request_ && request_->upload_data_stream) | |
159 request_->upload_data_stream->Reset(); // Invalidate pending callbacks. | |
160 } | |
161 | |
162 int HttpNetworkTransaction::Start(const HttpRequestInfo* request_info, | |
163 const CompletionCallback& callback, | |
164 const BoundNetLog& net_log) { | |
165 net_log_ = net_log; | |
166 request_ = request_info; | |
167 | |
168 if (request_->load_flags & LOAD_DISABLE_CERT_REVOCATION_CHECKING) { | |
169 server_ssl_config_.rev_checking_enabled = false; | |
170 proxy_ssl_config_.rev_checking_enabled = false; | |
171 } | |
172 | |
173 if (request_->load_flags & LOAD_PREFETCH) | |
174 response_.unused_since_prefetch = true; | |
175 | |
176 // Channel ID is disabled if privacy mode is enabled for this request. | |
177 if (request_->privacy_mode == PRIVACY_MODE_ENABLED) | |
178 server_ssl_config_.channel_id_enabled = false; | |
179 | |
180 if (server_ssl_config_.fastradio_padding_enabled) { | |
181 server_ssl_config_.fastradio_padding_eligible = | |
182 session_->ssl_config_service()->SupportsFastradioPadding( | |
183 request_info->url); | |
184 } | |
185 | |
186 next_state_ = STATE_NOTIFY_BEFORE_CREATE_STREAM; | |
187 int rv = DoLoop(OK); | |
188 if (rv == ERR_IO_PENDING) | |
189 callback_ = callback; | |
190 return rv; | |
191 } | |
192 | |
193 int HttpNetworkTransaction::RestartIgnoringLastError( | |
194 const CompletionCallback& callback) { | |
195 DCHECK(!stream_.get()); | |
196 DCHECK(!stream_request_.get()); | |
197 DCHECK_EQ(STATE_NONE, next_state_); | |
198 | |
199 next_state_ = STATE_CREATE_STREAM; | |
200 | |
201 int rv = DoLoop(OK); | |
202 if (rv == ERR_IO_PENDING) | |
203 callback_ = callback; | |
204 return rv; | |
205 } | |
206 | |
207 int HttpNetworkTransaction::RestartWithCertificate( | |
208 X509Certificate* client_cert, const CompletionCallback& callback) { | |
209 // In HandleCertificateRequest(), we always tear down existing stream | |
210 // requests to force a new connection. So we shouldn't have one here. | |
211 DCHECK(!stream_request_.get()); | |
212 DCHECK(!stream_.get()); | |
213 DCHECK_EQ(STATE_NONE, next_state_); | |
214 | |
215 SSLConfig* ssl_config = response_.cert_request_info->is_proxy ? | |
216 &proxy_ssl_config_ : &server_ssl_config_; | |
217 ssl_config->send_client_cert = true; | |
218 ssl_config->client_cert = client_cert; | |
219 session_->ssl_client_auth_cache()->Add( | |
220 response_.cert_request_info->host_and_port, client_cert); | |
221 // Reset the other member variables. | |
222 // Note: this is necessary only with SSL renegotiation. | |
223 ResetStateForRestart(); | |
224 next_state_ = STATE_CREATE_STREAM; | |
225 int rv = DoLoop(OK); | |
226 if (rv == ERR_IO_PENDING) | |
227 callback_ = callback; | |
228 return rv; | |
229 } | |
230 | |
231 int HttpNetworkTransaction::RestartWithAuth( | |
232 const AuthCredentials& credentials, const CompletionCallback& callback) { | |
233 HttpAuth::Target target = pending_auth_target_; | |
234 if (target == HttpAuth::AUTH_NONE) { | |
235 NOTREACHED(); | |
236 return ERR_UNEXPECTED; | |
237 } | |
238 pending_auth_target_ = HttpAuth::AUTH_NONE; | |
239 | |
240 auth_controllers_[target]->ResetAuth(credentials); | |
241 | |
242 DCHECK(callback_.is_null()); | |
243 | |
244 int rv = OK; | |
245 if (target == HttpAuth::AUTH_PROXY && establishing_tunnel_) { | |
246 // In this case, we've gathered credentials for use with proxy | |
247 // authentication of a tunnel. | |
248 DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); | |
249 DCHECK(stream_request_ != NULL); | |
250 auth_controllers_[target] = NULL; | |
251 ResetStateForRestart(); | |
252 rv = stream_request_->RestartTunnelWithProxyAuth(credentials); | |
253 } else { | |
254 // In this case, we've gathered credentials for the server or the proxy | |
255 // but it is not during the tunneling phase. | |
256 DCHECK(stream_request_ == NULL); | |
257 PrepareForAuthRestart(target); | |
258 rv = DoLoop(OK); | |
259 } | |
260 | |
261 if (rv == ERR_IO_PENDING) | |
262 callback_ = callback; | |
263 return rv; | |
264 } | |
265 | |
266 void HttpNetworkTransaction::PrepareForAuthRestart(HttpAuth::Target target) { | |
267 DCHECK(HaveAuth(target)); | |
268 DCHECK(!stream_request_.get()); | |
269 | |
270 bool keep_alive = false; | |
271 // Even if the server says the connection is keep-alive, we have to be | |
272 // able to find the end of each response in order to reuse the connection. | |
273 if (GetResponseHeaders()->IsKeepAlive() && | |
274 stream_->CanFindEndOfResponse()) { | |
275 // If the response body hasn't been completely read, we need to drain | |
276 // it first. | |
277 if (!stream_->IsResponseBodyComplete()) { | |
278 next_state_ = STATE_DRAIN_BODY_FOR_AUTH_RESTART; | |
279 read_buf_ = new IOBuffer(kDrainBodyBufferSize); // A bit bucket. | |
280 read_buf_len_ = kDrainBodyBufferSize; | |
281 return; | |
282 } | |
283 keep_alive = true; | |
284 } | |
285 | |
286 // We don't need to drain the response body, so we act as if we had drained | |
287 // the response body. | |
288 DidDrainBodyForAuthRestart(keep_alive); | |
289 } | |
290 | |
291 void HttpNetworkTransaction::DidDrainBodyForAuthRestart(bool keep_alive) { | |
292 DCHECK(!stream_request_.get()); | |
293 | |
294 if (stream_.get()) { | |
295 total_received_bytes_ += stream_->GetTotalReceivedBytes(); | |
296 HttpStream* new_stream = NULL; | |
297 if (keep_alive && stream_->IsConnectionReusable()) { | |
298 // We should call connection_->set_idle_time(), but this doesn't occur | |
299 // often enough to be worth the trouble. | |
300 stream_->SetConnectionReused(); | |
301 new_stream = stream_->RenewStreamForAuth(); | |
302 } | |
303 | |
304 if (!new_stream) { | |
305 // Close the stream and mark it as not_reusable. Even in the | |
306 // keep_alive case, we've determined that the stream_ is not | |
307 // reusable if new_stream is NULL. | |
308 stream_->Close(true); | |
309 next_state_ = STATE_CREATE_STREAM; | |
310 } else { | |
311 // Renewed streams shouldn't carry over received bytes. | |
312 DCHECK_EQ(0, new_stream->GetTotalReceivedBytes()); | |
313 next_state_ = STATE_INIT_STREAM; | |
314 } | |
315 stream_.reset(new_stream); | |
316 } | |
317 | |
318 // Reset the other member variables. | |
319 ResetStateForAuthRestart(); | |
320 } | |
321 | |
322 bool HttpNetworkTransaction::IsReadyToRestartForAuth() { | |
323 return pending_auth_target_ != HttpAuth::AUTH_NONE && | |
324 HaveAuth(pending_auth_target_); | |
325 } | |
326 | |
327 int HttpNetworkTransaction::Read(IOBuffer* buf, int buf_len, | |
328 const CompletionCallback& callback) { | |
329 DCHECK(buf); | |
330 DCHECK_LT(0, buf_len); | |
331 | |
332 State next_state = STATE_NONE; | |
333 | |
334 scoped_refptr<HttpResponseHeaders> headers(GetResponseHeaders()); | |
335 if (headers_valid_ && headers.get() && stream_request_.get()) { | |
336 // We're trying to read the body of the response but we're still trying | |
337 // to establish an SSL tunnel through an HTTP proxy. We can't read these | |
338 // bytes when establishing a tunnel because they might be controlled by | |
339 // an active network attacker. We don't worry about this for HTTP | |
340 // because an active network attacker can already control HTTP sessions. | |
341 // We reach this case when the user cancels a 407 proxy auth prompt. We | |
342 // also don't worry about this for an HTTPS Proxy, because the | |
343 // communication with the proxy is secure. | |
344 // See http://crbug.com/8473. | |
345 DCHECK(proxy_info_.is_http() || proxy_info_.is_https()); | |
346 DCHECK_EQ(headers->response_code(), HTTP_PROXY_AUTHENTICATION_REQUIRED); | |
347 LOG(WARNING) << "Blocked proxy response with status " | |
348 << headers->response_code() << " to CONNECT request for " | |
349 << GetHostAndPort(request_->url) << "."; | |
350 return ERR_TUNNEL_CONNECTION_FAILED; | |
351 } | |
352 | |
353 // Are we using SPDY or HTTP? | |
354 next_state = STATE_READ_BODY; | |
355 | |
356 read_buf_ = buf; | |
357 read_buf_len_ = buf_len; | |
358 | |
359 next_state_ = next_state; | |
360 int rv = DoLoop(OK); | |
361 if (rv == ERR_IO_PENDING) | |
362 callback_ = callback; | |
363 return rv; | |
364 } | |
365 | |
366 void HttpNetworkTransaction::StopCaching() {} | |
367 | |
368 bool HttpNetworkTransaction::GetFullRequestHeaders( | |
369 HttpRequestHeaders* headers) const { | |
370 // TODO(ttuttle): Make sure we've populated request_headers_. | |
371 *headers = request_headers_; | |
372 return true; | |
373 } | |
374 | |
375 int64 HttpNetworkTransaction::GetTotalReceivedBytes() const { | |
376 int64 total_received_bytes = total_received_bytes_; | |
377 if (stream_) | |
378 total_received_bytes += stream_->GetTotalReceivedBytes(); | |
379 return total_received_bytes; | |
380 } | |
381 | |
382 void HttpNetworkTransaction::DoneReading() {} | |
383 | |
384 const HttpResponseInfo* HttpNetworkTransaction::GetResponseInfo() const { | |
385 return ((headers_valid_ && response_.headers.get()) || | |
386 response_.ssl_info.cert.get() || response_.cert_request_info.get()) | |
387 ? &response_ | |
388 : NULL; | |
389 } | |
390 | |
391 LoadState HttpNetworkTransaction::GetLoadState() const { | |
392 // TODO(wtc): Define a new LoadState value for the | |
393 // STATE_INIT_CONNECTION_COMPLETE state, which delays the HTTP request. | |
394 switch (next_state_) { | |
395 case STATE_CREATE_STREAM: | |
396 return LOAD_STATE_WAITING_FOR_DELEGATE; | |
397 case STATE_CREATE_STREAM_COMPLETE: | |
398 return stream_request_->GetLoadState(); | |
399 case STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE: | |
400 case STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE: | |
401 case STATE_SEND_REQUEST_COMPLETE: | |
402 return LOAD_STATE_SENDING_REQUEST; | |
403 case STATE_READ_HEADERS_COMPLETE: | |
404 return LOAD_STATE_WAITING_FOR_RESPONSE; | |
405 case STATE_READ_BODY_COMPLETE: | |
406 return LOAD_STATE_READING_RESPONSE; | |
407 default: | |
408 return LOAD_STATE_IDLE; | |
409 } | |
410 } | |
411 | |
412 UploadProgress HttpNetworkTransaction::GetUploadProgress() const { | |
413 if (!stream_.get()) | |
414 return UploadProgress(); | |
415 | |
416 return stream_->GetUploadProgress(); | |
417 } | |
418 | |
419 void HttpNetworkTransaction::SetQuicServerInfo( | |
420 QuicServerInfo* quic_server_info) {} | |
421 | |
422 bool HttpNetworkTransaction::GetLoadTimingInfo( | |
423 LoadTimingInfo* load_timing_info) const { | |
424 if (!stream_ || !stream_->GetLoadTimingInfo(load_timing_info)) | |
425 return false; | |
426 | |
427 load_timing_info->proxy_resolve_start = | |
428 proxy_info_.proxy_resolve_start_time(); | |
429 load_timing_info->proxy_resolve_end = proxy_info_.proxy_resolve_end_time(); | |
430 load_timing_info->send_start = send_start_time_; | |
431 load_timing_info->send_end = send_end_time_; | |
432 return true; | |
433 } | |
434 | |
435 void HttpNetworkTransaction::SetPriority(RequestPriority priority) { | |
436 priority_ = priority; | |
437 if (stream_request_) | |
438 stream_request_->SetPriority(priority); | |
439 if (stream_) | |
440 stream_->SetPriority(priority); | |
441 } | |
442 | |
443 void HttpNetworkTransaction::SetWebSocketHandshakeStreamCreateHelper( | |
444 WebSocketHandshakeStreamBase::CreateHelper* create_helper) { | |
445 websocket_handshake_stream_base_create_helper_ = create_helper; | |
446 } | |
447 | |
448 void HttpNetworkTransaction::SetBeforeNetworkStartCallback( | |
449 const BeforeNetworkStartCallback& callback) { | |
450 before_network_start_callback_ = callback; | |
451 } | |
452 | |
453 void HttpNetworkTransaction::SetBeforeProxyHeadersSentCallback( | |
454 const BeforeProxyHeadersSentCallback& callback) { | |
455 before_proxy_headers_sent_callback_ = callback; | |
456 } | |
457 | |
458 int HttpNetworkTransaction::ResumeNetworkStart() { | |
459 DCHECK_EQ(next_state_, STATE_CREATE_STREAM); | |
460 return DoLoop(OK); | |
461 } | |
462 | |
463 void HttpNetworkTransaction::OnStreamReady(const SSLConfig& used_ssl_config, | |
464 const ProxyInfo& used_proxy_info, | |
465 HttpStream* stream) { | |
466 DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); | |
467 DCHECK(stream_request_.get()); | |
468 | |
469 if (stream_) | |
470 total_received_bytes_ += stream_->GetTotalReceivedBytes(); | |
471 stream_.reset(stream); | |
472 server_ssl_config_ = used_ssl_config; | |
473 proxy_info_ = used_proxy_info; | |
474 response_.was_npn_negotiated = stream_request_->was_npn_negotiated(); | |
475 response_.npn_negotiated_protocol = SSLClientSocket::NextProtoToString( | |
476 stream_request_->protocol_negotiated()); | |
477 response_.was_fetched_via_spdy = stream_request_->using_spdy(); | |
478 response_.was_fetched_via_proxy = !proxy_info_.is_direct(); | |
479 if (response_.was_fetched_via_proxy && !proxy_info_.is_empty()) | |
480 response_.proxy_server = proxy_info_.proxy_server().host_port_pair(); | |
481 OnIOComplete(OK); | |
482 } | |
483 | |
484 void HttpNetworkTransaction::OnWebSocketHandshakeStreamReady( | |
485 const SSLConfig& used_ssl_config, | |
486 const ProxyInfo& used_proxy_info, | |
487 WebSocketHandshakeStreamBase* stream) { | |
488 OnStreamReady(used_ssl_config, used_proxy_info, stream); | |
489 } | |
490 | |
491 void HttpNetworkTransaction::OnStreamFailed(int result, | |
492 const SSLConfig& used_ssl_config) { | |
493 DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); | |
494 DCHECK_NE(OK, result); | |
495 DCHECK(stream_request_.get()); | |
496 DCHECK(!stream_.get()); | |
497 server_ssl_config_ = used_ssl_config; | |
498 | |
499 OnIOComplete(result); | |
500 } | |
501 | |
502 void HttpNetworkTransaction::OnCertificateError( | |
503 int result, | |
504 const SSLConfig& used_ssl_config, | |
505 const SSLInfo& ssl_info) { | |
506 DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); | |
507 DCHECK_NE(OK, result); | |
508 DCHECK(stream_request_.get()); | |
509 DCHECK(!stream_.get()); | |
510 | |
511 response_.ssl_info = ssl_info; | |
512 server_ssl_config_ = used_ssl_config; | |
513 | |
514 // TODO(mbelshe): For now, we're going to pass the error through, and that | |
515 // will close the stream_request in all cases. This means that we're always | |
516 // going to restart an entire STATE_CREATE_STREAM, even if the connection is | |
517 // good and the user chooses to ignore the error. This is not ideal, but not | |
518 // the end of the world either. | |
519 | |
520 OnIOComplete(result); | |
521 } | |
522 | |
523 void HttpNetworkTransaction::OnNeedsProxyAuth( | |
524 const HttpResponseInfo& proxy_response, | |
525 const SSLConfig& used_ssl_config, | |
526 const ProxyInfo& used_proxy_info, | |
527 HttpAuthController* auth_controller) { | |
528 DCHECK(stream_request_.get()); | |
529 DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); | |
530 | |
531 establishing_tunnel_ = true; | |
532 response_.headers = proxy_response.headers; | |
533 response_.auth_challenge = proxy_response.auth_challenge; | |
534 headers_valid_ = true; | |
535 server_ssl_config_ = used_ssl_config; | |
536 proxy_info_ = used_proxy_info; | |
537 | |
538 auth_controllers_[HttpAuth::AUTH_PROXY] = auth_controller; | |
539 pending_auth_target_ = HttpAuth::AUTH_PROXY; | |
540 | |
541 DoCallback(OK); | |
542 } | |
543 | |
544 void HttpNetworkTransaction::OnNeedsClientAuth( | |
545 const SSLConfig& used_ssl_config, | |
546 SSLCertRequestInfo* cert_info) { | |
547 DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); | |
548 | |
549 server_ssl_config_ = used_ssl_config; | |
550 response_.cert_request_info = cert_info; | |
551 OnIOComplete(ERR_SSL_CLIENT_AUTH_CERT_NEEDED); | |
552 } | |
553 | |
554 void HttpNetworkTransaction::OnHttpsProxyTunnelResponse( | |
555 const HttpResponseInfo& response_info, | |
556 const SSLConfig& used_ssl_config, | |
557 const ProxyInfo& used_proxy_info, | |
558 HttpStream* stream) { | |
559 DCHECK_EQ(STATE_CREATE_STREAM_COMPLETE, next_state_); | |
560 | |
561 headers_valid_ = true; | |
562 response_ = response_info; | |
563 server_ssl_config_ = used_ssl_config; | |
564 proxy_info_ = used_proxy_info; | |
565 if (stream_) | |
566 total_received_bytes_ += stream_->GetTotalReceivedBytes(); | |
567 stream_.reset(stream); | |
568 stream_request_.reset(); // we're done with the stream request | |
569 OnIOComplete(ERR_HTTPS_PROXY_TUNNEL_RESPONSE); | |
570 } | |
571 | |
572 bool HttpNetworkTransaction::is_https_request() const { | |
573 return request_->url.SchemeIs("https"); | |
574 } | |
575 | |
576 bool HttpNetworkTransaction::UsingHttpProxyWithoutTunnel() const { | |
577 return (proxy_info_.is_http() || proxy_info_.is_https() || | |
578 proxy_info_.is_quic()) && | |
579 !(request_->url.SchemeIs("https") || request_->url.SchemeIsWSOrWSS()); | |
580 } | |
581 | |
582 void HttpNetworkTransaction::DoCallback(int rv) { | |
583 DCHECK_NE(rv, ERR_IO_PENDING); | |
584 DCHECK(!callback_.is_null()); | |
585 | |
586 // Since Run may result in Read being called, clear user_callback_ up front. | |
587 CompletionCallback c = callback_; | |
588 callback_.Reset(); | |
589 c.Run(rv); | |
590 } | |
591 | |
592 void HttpNetworkTransaction::OnIOComplete(int result) { | |
593 // TODO(vadimt): Remove ScopedTracker below once crbug.com/424359 is fixed. | |
594 tracked_objects::ScopedTracker tracking_profile1( | |
595 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
596 "424359 HttpNetworkTransaction::OnIOComplete 1")); | |
597 | |
598 int rv = DoLoop(result); | |
599 | |
600 // TODO(vadimt): Remove ScopedTracker below once crbug.com/424359 is fixed. | |
601 tracked_objects::ScopedTracker tracking_profile2( | |
602 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
603 "424359 HttpNetworkTransaction::OnIOComplete 2")); | |
604 | |
605 if (rv != ERR_IO_PENDING) | |
606 DoCallback(rv); | |
607 } | |
608 | |
609 int HttpNetworkTransaction::DoLoop(int result) { | |
610 DCHECK(next_state_ != STATE_NONE); | |
611 | |
612 int rv = result; | |
613 do { | |
614 State state = next_state_; | |
615 next_state_ = STATE_NONE; | |
616 switch (state) { | |
617 case STATE_NOTIFY_BEFORE_CREATE_STREAM: | |
618 DCHECK_EQ(OK, rv); | |
619 rv = DoNotifyBeforeCreateStream(); | |
620 break; | |
621 case STATE_CREATE_STREAM: | |
622 DCHECK_EQ(OK, rv); | |
623 rv = DoCreateStream(); | |
624 break; | |
625 case STATE_CREATE_STREAM_COMPLETE: | |
626 rv = DoCreateStreamComplete(rv); | |
627 break; | |
628 case STATE_INIT_STREAM: | |
629 DCHECK_EQ(OK, rv); | |
630 rv = DoInitStream(); | |
631 break; | |
632 case STATE_INIT_STREAM_COMPLETE: | |
633 rv = DoInitStreamComplete(rv); | |
634 break; | |
635 case STATE_GENERATE_PROXY_AUTH_TOKEN: | |
636 DCHECK_EQ(OK, rv); | |
637 rv = DoGenerateProxyAuthToken(); | |
638 break; | |
639 case STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE: | |
640 rv = DoGenerateProxyAuthTokenComplete(rv); | |
641 break; | |
642 case STATE_GENERATE_SERVER_AUTH_TOKEN: | |
643 DCHECK_EQ(OK, rv); | |
644 rv = DoGenerateServerAuthToken(); | |
645 break; | |
646 case STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE: | |
647 rv = DoGenerateServerAuthTokenComplete(rv); | |
648 break; | |
649 case STATE_INIT_REQUEST_BODY: | |
650 DCHECK_EQ(OK, rv); | |
651 rv = DoInitRequestBody(); | |
652 break; | |
653 case STATE_INIT_REQUEST_BODY_COMPLETE: | |
654 rv = DoInitRequestBodyComplete(rv); | |
655 break; | |
656 case STATE_BUILD_REQUEST: | |
657 DCHECK_EQ(OK, rv); | |
658 net_log_.BeginEvent(NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST); | |
659 rv = DoBuildRequest(); | |
660 break; | |
661 case STATE_BUILD_REQUEST_COMPLETE: | |
662 rv = DoBuildRequestComplete(rv); | |
663 break; | |
664 case STATE_SEND_REQUEST: | |
665 DCHECK_EQ(OK, rv); | |
666 rv = DoSendRequest(); | |
667 break; | |
668 case STATE_SEND_REQUEST_COMPLETE: | |
669 rv = DoSendRequestComplete(rv); | |
670 net_log_.EndEventWithNetErrorCode( | |
671 NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST, rv); | |
672 break; | |
673 case STATE_READ_HEADERS: | |
674 DCHECK_EQ(OK, rv); | |
675 net_log_.BeginEvent(NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS); | |
676 rv = DoReadHeaders(); | |
677 break; | |
678 case STATE_READ_HEADERS_COMPLETE: | |
679 rv = DoReadHeadersComplete(rv); | |
680 net_log_.EndEventWithNetErrorCode( | |
681 NetLog::TYPE_HTTP_TRANSACTION_READ_HEADERS, rv); | |
682 break; | |
683 case STATE_READ_BODY: | |
684 DCHECK_EQ(OK, rv); | |
685 net_log_.BeginEvent(NetLog::TYPE_HTTP_TRANSACTION_READ_BODY); | |
686 rv = DoReadBody(); | |
687 break; | |
688 case STATE_READ_BODY_COMPLETE: | |
689 rv = DoReadBodyComplete(rv); | |
690 net_log_.EndEventWithNetErrorCode( | |
691 NetLog::TYPE_HTTP_TRANSACTION_READ_BODY, rv); | |
692 break; | |
693 case STATE_DRAIN_BODY_FOR_AUTH_RESTART: | |
694 DCHECK_EQ(OK, rv); | |
695 net_log_.BeginEvent( | |
696 NetLog::TYPE_HTTP_TRANSACTION_DRAIN_BODY_FOR_AUTH_RESTART); | |
697 rv = DoDrainBodyForAuthRestart(); | |
698 break; | |
699 case STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE: | |
700 rv = DoDrainBodyForAuthRestartComplete(rv); | |
701 net_log_.EndEventWithNetErrorCode( | |
702 NetLog::TYPE_HTTP_TRANSACTION_DRAIN_BODY_FOR_AUTH_RESTART, rv); | |
703 break; | |
704 default: | |
705 NOTREACHED() << "bad state"; | |
706 rv = ERR_FAILED; | |
707 break; | |
708 } | |
709 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); | |
710 | |
711 return rv; | |
712 } | |
713 | |
714 int HttpNetworkTransaction::DoNotifyBeforeCreateStream() { | |
715 next_state_ = STATE_CREATE_STREAM; | |
716 bool defer = false; | |
717 if (!before_network_start_callback_.is_null()) | |
718 before_network_start_callback_.Run(&defer); | |
719 if (!defer) | |
720 return OK; | |
721 return ERR_IO_PENDING; | |
722 } | |
723 | |
724 int HttpNetworkTransaction::DoCreateStream() { | |
725 next_state_ = STATE_CREATE_STREAM_COMPLETE; | |
726 if (ForWebSocketHandshake()) { | |
727 stream_request_.reset( | |
728 session_->http_stream_factory_for_websocket() | |
729 ->RequestWebSocketHandshakeStream( | |
730 *request_, | |
731 priority_, | |
732 server_ssl_config_, | |
733 proxy_ssl_config_, | |
734 this, | |
735 websocket_handshake_stream_base_create_helper_, | |
736 net_log_)); | |
737 } else { | |
738 stream_request_.reset( | |
739 session_->http_stream_factory()->RequestStream( | |
740 *request_, | |
741 priority_, | |
742 server_ssl_config_, | |
743 proxy_ssl_config_, | |
744 this, | |
745 net_log_)); | |
746 } | |
747 DCHECK(stream_request_.get()); | |
748 return ERR_IO_PENDING; | |
749 } | |
750 | |
751 int HttpNetworkTransaction::DoCreateStreamComplete(int result) { | |
752 if (result == OK) { | |
753 next_state_ = STATE_INIT_STREAM; | |
754 DCHECK(stream_.get()); | |
755 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { | |
756 result = HandleCertificateRequest(result); | |
757 } else if (result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) { | |
758 // Return OK and let the caller read the proxy's error page | |
759 next_state_ = STATE_NONE; | |
760 return OK; | |
761 } else if (result == ERR_HTTP_1_1_REQUIRED || | |
762 result == ERR_PROXY_HTTP_1_1_REQUIRED) { | |
763 return HandleHttp11Required(result); | |
764 } | |
765 | |
766 // Handle possible handshake errors that may have occurred if the stream | |
767 // used SSL for one or more of the layers. | |
768 result = HandleSSLHandshakeError(result); | |
769 | |
770 // At this point we are done with the stream_request_. | |
771 stream_request_.reset(); | |
772 return result; | |
773 } | |
774 | |
775 int HttpNetworkTransaction::DoInitStream() { | |
776 DCHECK(stream_.get()); | |
777 next_state_ = STATE_INIT_STREAM_COMPLETE; | |
778 return stream_->InitializeStream(request_, priority_, net_log_, io_callback_); | |
779 } | |
780 | |
781 int HttpNetworkTransaction::DoInitStreamComplete(int result) { | |
782 if (result == OK) { | |
783 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; | |
784 } else { | |
785 if (result < 0) | |
786 result = HandleIOError(result); | |
787 | |
788 // The stream initialization failed, so this stream will never be useful. | |
789 if (stream_) | |
790 total_received_bytes_ += stream_->GetTotalReceivedBytes(); | |
791 stream_.reset(); | |
792 } | |
793 | |
794 return result; | |
795 } | |
796 | |
797 int HttpNetworkTransaction::DoGenerateProxyAuthToken() { | |
798 next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN_COMPLETE; | |
799 if (!ShouldApplyProxyAuth()) | |
800 return OK; | |
801 HttpAuth::Target target = HttpAuth::AUTH_PROXY; | |
802 if (!auth_controllers_[target].get()) | |
803 auth_controllers_[target] = | |
804 new HttpAuthController(target, | |
805 AuthURL(target), | |
806 session_->http_auth_cache(), | |
807 session_->http_auth_handler_factory()); | |
808 return auth_controllers_[target]->MaybeGenerateAuthToken(request_, | |
809 io_callback_, | |
810 net_log_); | |
811 } | |
812 | |
813 int HttpNetworkTransaction::DoGenerateProxyAuthTokenComplete(int rv) { | |
814 DCHECK_NE(ERR_IO_PENDING, rv); | |
815 if (rv == OK) | |
816 next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN; | |
817 return rv; | |
818 } | |
819 | |
820 int HttpNetworkTransaction::DoGenerateServerAuthToken() { | |
821 next_state_ = STATE_GENERATE_SERVER_AUTH_TOKEN_COMPLETE; | |
822 HttpAuth::Target target = HttpAuth::AUTH_SERVER; | |
823 if (!auth_controllers_[target].get()) { | |
824 auth_controllers_[target] = | |
825 new HttpAuthController(target, | |
826 AuthURL(target), | |
827 session_->http_auth_cache(), | |
828 session_->http_auth_handler_factory()); | |
829 if (request_->load_flags & LOAD_DO_NOT_USE_EMBEDDED_IDENTITY) | |
830 auth_controllers_[target]->DisableEmbeddedIdentity(); | |
831 } | |
832 if (!ShouldApplyServerAuth()) | |
833 return OK; | |
834 return auth_controllers_[target]->MaybeGenerateAuthToken(request_, | |
835 io_callback_, | |
836 net_log_); | |
837 } | |
838 | |
839 int HttpNetworkTransaction::DoGenerateServerAuthTokenComplete(int rv) { | |
840 DCHECK_NE(ERR_IO_PENDING, rv); | |
841 if (rv == OK) | |
842 next_state_ = STATE_INIT_REQUEST_BODY; | |
843 return rv; | |
844 } | |
845 | |
846 void HttpNetworkTransaction::BuildRequestHeaders( | |
847 bool using_http_proxy_without_tunnel) { | |
848 request_headers_.SetHeader(HttpRequestHeaders::kHost, | |
849 GetHostAndOptionalPort(request_->url)); | |
850 | |
851 // For compat with HTTP/1.0 servers and proxies: | |
852 if (using_http_proxy_without_tunnel) { | |
853 request_headers_.SetHeader(HttpRequestHeaders::kProxyConnection, | |
854 "keep-alive"); | |
855 } else { | |
856 request_headers_.SetHeader(HttpRequestHeaders::kConnection, "keep-alive"); | |
857 } | |
858 | |
859 // Add a content length header? | |
860 if (request_->upload_data_stream) { | |
861 if (request_->upload_data_stream->is_chunked()) { | |
862 request_headers_.SetHeader( | |
863 HttpRequestHeaders::kTransferEncoding, "chunked"); | |
864 } else { | |
865 request_headers_.SetHeader( | |
866 HttpRequestHeaders::kContentLength, | |
867 base::Uint64ToString(request_->upload_data_stream->size())); | |
868 } | |
869 } else if (request_->method == "POST" || request_->method == "PUT" || | |
870 request_->method == "HEAD") { | |
871 // An empty POST/PUT request still needs a content length. As for HEAD, | |
872 // IE and Safari also add a content length header. Presumably it is to | |
873 // support sending a HEAD request to an URL that only expects to be sent a | |
874 // POST or some other method that normally would have a message body. | |
875 request_headers_.SetHeader(HttpRequestHeaders::kContentLength, "0"); | |
876 } | |
877 | |
878 // Honor load flags that impact proxy caches. | |
879 if (request_->load_flags & LOAD_BYPASS_CACHE) { | |
880 request_headers_.SetHeader(HttpRequestHeaders::kPragma, "no-cache"); | |
881 request_headers_.SetHeader(HttpRequestHeaders::kCacheControl, "no-cache"); | |
882 } else if (request_->load_flags & LOAD_VALIDATE_CACHE) { | |
883 request_headers_.SetHeader(HttpRequestHeaders::kCacheControl, "max-age=0"); | |
884 } | |
885 | |
886 if (ShouldApplyProxyAuth() && HaveAuth(HttpAuth::AUTH_PROXY)) | |
887 auth_controllers_[HttpAuth::AUTH_PROXY]->AddAuthorizationHeader( | |
888 &request_headers_); | |
889 if (ShouldApplyServerAuth() && HaveAuth(HttpAuth::AUTH_SERVER)) | |
890 auth_controllers_[HttpAuth::AUTH_SERVER]->AddAuthorizationHeader( | |
891 &request_headers_); | |
892 | |
893 request_headers_.MergeFrom(request_->extra_headers); | |
894 | |
895 if (using_http_proxy_without_tunnel && | |
896 !before_proxy_headers_sent_callback_.is_null()) | |
897 before_proxy_headers_sent_callback_.Run(proxy_info_, &request_headers_); | |
898 | |
899 response_.did_use_http_auth = | |
900 request_headers_.HasHeader(HttpRequestHeaders::kAuthorization) || | |
901 request_headers_.HasHeader(HttpRequestHeaders::kProxyAuthorization); | |
902 } | |
903 | |
904 int HttpNetworkTransaction::DoInitRequestBody() { | |
905 next_state_ = STATE_INIT_REQUEST_BODY_COMPLETE; | |
906 int rv = OK; | |
907 if (request_->upload_data_stream) | |
908 rv = request_->upload_data_stream->Init(io_callback_); | |
909 return rv; | |
910 } | |
911 | |
912 int HttpNetworkTransaction::DoInitRequestBodyComplete(int result) { | |
913 if (result == OK) | |
914 next_state_ = STATE_BUILD_REQUEST; | |
915 return result; | |
916 } | |
917 | |
918 int HttpNetworkTransaction::DoBuildRequest() { | |
919 next_state_ = STATE_BUILD_REQUEST_COMPLETE; | |
920 headers_valid_ = false; | |
921 | |
922 // This is constructed lazily (instead of within our Start method), so that | |
923 // we have proxy info available. | |
924 if (request_headers_.IsEmpty()) { | |
925 bool using_http_proxy_without_tunnel = UsingHttpProxyWithoutTunnel(); | |
926 BuildRequestHeaders(using_http_proxy_without_tunnel); | |
927 } | |
928 | |
929 return OK; | |
930 } | |
931 | |
932 int HttpNetworkTransaction::DoBuildRequestComplete(int result) { | |
933 if (result == OK) | |
934 next_state_ = STATE_SEND_REQUEST; | |
935 return result; | |
936 } | |
937 | |
938 int HttpNetworkTransaction::DoSendRequest() { | |
939 send_start_time_ = base::TimeTicks::Now(); | |
940 next_state_ = STATE_SEND_REQUEST_COMPLETE; | |
941 | |
942 return stream_->SendRequest(request_headers_, &response_, io_callback_); | |
943 } | |
944 | |
945 int HttpNetworkTransaction::DoSendRequestComplete(int result) { | |
946 send_end_time_ = base::TimeTicks::Now(); | |
947 if (result < 0) | |
948 return HandleIOError(result); | |
949 response_.network_accessed = true; | |
950 next_state_ = STATE_READ_HEADERS; | |
951 return OK; | |
952 } | |
953 | |
954 int HttpNetworkTransaction::DoReadHeaders() { | |
955 next_state_ = STATE_READ_HEADERS_COMPLETE; | |
956 return stream_->ReadResponseHeaders(io_callback_); | |
957 } | |
958 | |
959 int HttpNetworkTransaction::DoReadHeadersComplete(int result) { | |
960 // We can get a certificate error or ERR_SSL_CLIENT_AUTH_CERT_NEEDED here | |
961 // due to SSL renegotiation. | |
962 if (IsCertificateError(result)) { | |
963 // We don't handle a certificate error during SSL renegotiation, so we | |
964 // have to return an error that's not in the certificate error range | |
965 // (-2xx). | |
966 LOG(ERROR) << "Got a server certificate with error " << result | |
967 << " during SSL renegotiation"; | |
968 result = ERR_CERT_ERROR_IN_SSL_RENEGOTIATION; | |
969 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { | |
970 // TODO(wtc): Need a test case for this code path! | |
971 DCHECK(stream_.get()); | |
972 DCHECK(is_https_request()); | |
973 response_.cert_request_info = new SSLCertRequestInfo; | |
974 stream_->GetSSLCertRequestInfo(response_.cert_request_info.get()); | |
975 result = HandleCertificateRequest(result); | |
976 if (result == OK) | |
977 return result; | |
978 } | |
979 | |
980 if (result == ERR_HTTP_1_1_REQUIRED || | |
981 result == ERR_PROXY_HTTP_1_1_REQUIRED) { | |
982 return HandleHttp11Required(result); | |
983 } | |
984 | |
985 // ERR_CONNECTION_CLOSED is treated differently at this point; if partial | |
986 // response headers were received, we do the best we can to make sense of it | |
987 // and send it back up the stack. | |
988 // | |
989 // TODO(davidben): Consider moving this to HttpBasicStream, It's a little | |
990 // bizarre for SPDY. Assuming this logic is useful at all. | |
991 // TODO(davidben): Bubble the error code up so we do not cache? | |
992 if (result == ERR_CONNECTION_CLOSED && response_.headers.get()) | |
993 result = OK; | |
994 | |
995 if (result < 0) | |
996 return HandleIOError(result); | |
997 | |
998 DCHECK(response_.headers.get()); | |
999 | |
1000 // On a 408 response from the server ("Request Timeout") on a stale socket, | |
1001 // retry the request. | |
1002 // Headers can be NULL because of http://crbug.com/384554. | |
1003 if (response_.headers.get() && response_.headers->response_code() == 408 && | |
1004 stream_->IsConnectionReused()) { | |
1005 net_log_.AddEventWithNetErrorCode( | |
1006 NetLog::TYPE_HTTP_TRANSACTION_RESTART_AFTER_ERROR, | |
1007 response_.headers->response_code()); | |
1008 // This will close the socket - it would be weird to try and reuse it, even | |
1009 // if the server doesn't actually close it. | |
1010 ResetConnectionAndRequestForResend(); | |
1011 return OK; | |
1012 } | |
1013 | |
1014 // Like Net.HttpResponseCode, but only for MAIN_FRAME loads. | |
1015 if (request_->load_flags & LOAD_MAIN_FRAME) { | |
1016 const int response_code = response_.headers->response_code(); | |
1017 UMA_HISTOGRAM_ENUMERATION( | |
1018 "Net.HttpResponseCode_Nxx_MainFrame", response_code/100, 10); | |
1019 } | |
1020 | |
1021 net_log_.AddEvent( | |
1022 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS, | |
1023 base::Bind(&HttpResponseHeaders::NetLogCallback, response_.headers)); | |
1024 | |
1025 if (response_.headers->GetParsedHttpVersion() < HttpVersion(1, 0)) { | |
1026 // HTTP/0.9 doesn't support the PUT method, so lack of response headers | |
1027 // indicates a buggy server. See: | |
1028 // https://bugzilla.mozilla.org/show_bug.cgi?id=193921 | |
1029 if (request_->method == "PUT") | |
1030 return ERR_METHOD_NOT_SUPPORTED; | |
1031 } | |
1032 | |
1033 // Check for an intermediate 100 Continue response. An origin server is | |
1034 // allowed to send this response even if we didn't ask for it, so we just | |
1035 // need to skip over it. | |
1036 // We treat any other 1xx in this same way (although in practice getting | |
1037 // a 1xx that isn't a 100 is rare). | |
1038 // Unless this is a WebSocket request, in which case we pass it on up. | |
1039 if (response_.headers->response_code() / 100 == 1 && | |
1040 !ForWebSocketHandshake()) { | |
1041 response_.headers = new HttpResponseHeaders(std::string()); | |
1042 next_state_ = STATE_READ_HEADERS; | |
1043 return OK; | |
1044 } | |
1045 | |
1046 ProcessAlternateProtocol(session_, *response_.headers.get(), | |
1047 HostPortPair::FromURL(request_->url)); | |
1048 | |
1049 int rv = HandleAuthChallenge(); | |
1050 if (rv != OK) | |
1051 return rv; | |
1052 | |
1053 if (is_https_request()) | |
1054 stream_->GetSSLInfo(&response_.ssl_info); | |
1055 | |
1056 headers_valid_ = true; | |
1057 | |
1058 if (session_->huffman_aggregator()) { | |
1059 session_->huffman_aggregator()->AggregateTransactionCharacterCounts( | |
1060 *request_, | |
1061 request_headers_, | |
1062 proxy_info_.proxy_server(), | |
1063 *response_.headers.get()); | |
1064 } | |
1065 return OK; | |
1066 } | |
1067 | |
1068 int HttpNetworkTransaction::DoReadBody() { | |
1069 DCHECK(read_buf_.get()); | |
1070 DCHECK_GT(read_buf_len_, 0); | |
1071 DCHECK(stream_ != NULL); | |
1072 | |
1073 next_state_ = STATE_READ_BODY_COMPLETE; | |
1074 return stream_->ReadResponseBody( | |
1075 read_buf_.get(), read_buf_len_, io_callback_); | |
1076 } | |
1077 | |
1078 int HttpNetworkTransaction::DoReadBodyComplete(int result) { | |
1079 // We are done with the Read call. | |
1080 bool done = false; | |
1081 if (result <= 0) { | |
1082 DCHECK_NE(ERR_IO_PENDING, result); | |
1083 done = true; | |
1084 } | |
1085 | |
1086 bool keep_alive = false; | |
1087 if (stream_->IsResponseBodyComplete()) { | |
1088 // Note: Just because IsResponseBodyComplete is true, we're not | |
1089 // necessarily "done". We're only "done" when it is the last | |
1090 // read on this HttpNetworkTransaction, which will be signified | |
1091 // by a zero-length read. | |
1092 // TODO(mbelshe): The keepalive property is really a property of | |
1093 // the stream. No need to compute it here just to pass back | |
1094 // to the stream's Close function. | |
1095 // TODO(rtenneti): CanFindEndOfResponse should return false if there are no | |
1096 // ResponseHeaders. | |
1097 if (stream_->CanFindEndOfResponse()) { | |
1098 HttpResponseHeaders* headers = GetResponseHeaders(); | |
1099 if (headers) | |
1100 keep_alive = headers->IsKeepAlive(); | |
1101 } | |
1102 } | |
1103 | |
1104 // Clean up connection if we are done. | |
1105 if (done) { | |
1106 stream_->Close(!keep_alive); | |
1107 // Note: we don't reset the stream here. We've closed it, but we still | |
1108 // need it around so that callers can call methods such as | |
1109 // GetUploadProgress() and have them be meaningful. | |
1110 // TODO(mbelshe): This means we closed the stream here, and we close it | |
1111 // again in ~HttpNetworkTransaction. Clean that up. | |
1112 | |
1113 // The next Read call will return 0 (EOF). | |
1114 } | |
1115 | |
1116 // Clear these to avoid leaving around old state. | |
1117 read_buf_ = NULL; | |
1118 read_buf_len_ = 0; | |
1119 | |
1120 return result; | |
1121 } | |
1122 | |
1123 int HttpNetworkTransaction::DoDrainBodyForAuthRestart() { | |
1124 // This method differs from DoReadBody only in the next_state_. So we just | |
1125 // call DoReadBody and override the next_state_. Perhaps there is a more | |
1126 // elegant way for these two methods to share code. | |
1127 int rv = DoReadBody(); | |
1128 DCHECK(next_state_ == STATE_READ_BODY_COMPLETE); | |
1129 next_state_ = STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE; | |
1130 return rv; | |
1131 } | |
1132 | |
1133 // TODO(wtc): This method and the DoReadBodyComplete method are almost | |
1134 // the same. Figure out a good way for these two methods to share code. | |
1135 int HttpNetworkTransaction::DoDrainBodyForAuthRestartComplete(int result) { | |
1136 // keep_alive defaults to true because the very reason we're draining the | |
1137 // response body is to reuse the connection for auth restart. | |
1138 bool done = false, keep_alive = true; | |
1139 if (result < 0) { | |
1140 // Error or closed connection while reading the socket. | |
1141 done = true; | |
1142 keep_alive = false; | |
1143 } else if (stream_->IsResponseBodyComplete()) { | |
1144 done = true; | |
1145 } | |
1146 | |
1147 if (done) { | |
1148 DidDrainBodyForAuthRestart(keep_alive); | |
1149 } else { | |
1150 // Keep draining. | |
1151 next_state_ = STATE_DRAIN_BODY_FOR_AUTH_RESTART; | |
1152 } | |
1153 | |
1154 return OK; | |
1155 } | |
1156 | |
1157 int HttpNetworkTransaction::HandleCertificateRequest(int error) { | |
1158 // There are two paths through which the server can request a certificate | |
1159 // from us. The first is during the initial handshake, the second is | |
1160 // during SSL renegotiation. | |
1161 // | |
1162 // In both cases, we want to close the connection before proceeding. | |
1163 // We do this for two reasons: | |
1164 // First, we don't want to keep the connection to the server hung for a | |
1165 // long time while the user selects a certificate. | |
1166 // Second, even if we did keep the connection open, NSS has a bug where | |
1167 // restarting the handshake for ClientAuth is currently broken. | |
1168 DCHECK_EQ(error, ERR_SSL_CLIENT_AUTH_CERT_NEEDED); | |
1169 | |
1170 if (stream_.get()) { | |
1171 // Since we already have a stream, we're being called as part of SSL | |
1172 // renegotiation. | |
1173 DCHECK(!stream_request_.get()); | |
1174 total_received_bytes_ += stream_->GetTotalReceivedBytes(); | |
1175 stream_->Close(true); | |
1176 stream_.reset(); | |
1177 } | |
1178 | |
1179 // The server is asking for a client certificate during the initial | |
1180 // handshake. | |
1181 stream_request_.reset(); | |
1182 | |
1183 // If the user selected one of the certificates in client_certs or declined | |
1184 // to provide one for this server before, use the past decision | |
1185 // automatically. | |
1186 scoped_refptr<X509Certificate> client_cert; | |
1187 bool found_cached_cert = session_->ssl_client_auth_cache()->Lookup( | |
1188 response_.cert_request_info->host_and_port, &client_cert); | |
1189 if (!found_cached_cert) | |
1190 return error; | |
1191 | |
1192 // Check that the certificate selected is still a certificate the server | |
1193 // is likely to accept, based on the criteria supplied in the | |
1194 // CertificateRequest message. | |
1195 if (client_cert.get()) { | |
1196 const std::vector<std::string>& cert_authorities = | |
1197 response_.cert_request_info->cert_authorities; | |
1198 | |
1199 bool cert_still_valid = cert_authorities.empty() || | |
1200 client_cert->IsIssuedByEncoded(cert_authorities); | |
1201 if (!cert_still_valid) | |
1202 return error; | |
1203 } | |
1204 | |
1205 // TODO(davidben): Add a unit test which covers this path; we need to be | |
1206 // able to send a legitimate certificate and also bypass/clear the | |
1207 // SSL session cache. | |
1208 SSLConfig* ssl_config = response_.cert_request_info->is_proxy ? | |
1209 &proxy_ssl_config_ : &server_ssl_config_; | |
1210 ssl_config->send_client_cert = true; | |
1211 ssl_config->client_cert = client_cert; | |
1212 next_state_ = STATE_CREATE_STREAM; | |
1213 // Reset the other member variables. | |
1214 // Note: this is necessary only with SSL renegotiation. | |
1215 ResetStateForRestart(); | |
1216 return OK; | |
1217 } | |
1218 | |
1219 int HttpNetworkTransaction::HandleHttp11Required(int error) { | |
1220 DCHECK(error == ERR_HTTP_1_1_REQUIRED || | |
1221 error == ERR_PROXY_HTTP_1_1_REQUIRED); | |
1222 | |
1223 if (error == ERR_HTTP_1_1_REQUIRED) { | |
1224 HttpServerProperties::ForceHTTP11(&server_ssl_config_); | |
1225 } else { | |
1226 HttpServerProperties::ForceHTTP11(&proxy_ssl_config_); | |
1227 } | |
1228 ResetConnectionAndRequestForResend(); | |
1229 return OK; | |
1230 } | |
1231 | |
1232 void HttpNetworkTransaction::HandleClientAuthError(int error) { | |
1233 if (server_ssl_config_.send_client_cert && | |
1234 (error == ERR_SSL_PROTOCOL_ERROR || IsClientCertificateError(error))) { | |
1235 session_->ssl_client_auth_cache()->Remove( | |
1236 HostPortPair::FromURL(request_->url)); | |
1237 } | |
1238 } | |
1239 | |
1240 // TODO(rch): This does not correctly handle errors when an SSL proxy is | |
1241 // being used, as all of the errors are handled as if they were generated | |
1242 // by the endpoint host, request_->url, rather than considering if they were | |
1243 // generated by the SSL proxy. http://crbug.com/69329 | |
1244 int HttpNetworkTransaction::HandleSSLHandshakeError(int error) { | |
1245 DCHECK(request_); | |
1246 HandleClientAuthError(error); | |
1247 | |
1248 bool should_fallback = false; | |
1249 uint16 version_max = server_ssl_config_.version_max; | |
1250 | |
1251 switch (error) { | |
1252 case ERR_CONNECTION_CLOSED: | |
1253 case ERR_SSL_PROTOCOL_ERROR: | |
1254 case ERR_SSL_VERSION_OR_CIPHER_MISMATCH: | |
1255 if (version_max >= SSL_PROTOCOL_VERSION_TLS1 && | |
1256 version_max > server_ssl_config_.version_min) { | |
1257 // This could be a TLS-intolerant server or a server that chose a | |
1258 // cipher suite defined only for higher protocol versions (such as | |
1259 // an SSL 3.0 server that chose a TLS-only cipher suite). Fall | |
1260 // back to the next lower version and retry. | |
1261 // NOTE: if the SSLClientSocket class doesn't support TLS 1.1, | |
1262 // specifying TLS 1.1 in version_max will result in a TLS 1.0 | |
1263 // handshake, so falling back from TLS 1.1 to TLS 1.0 will simply | |
1264 // repeat the TLS 1.0 handshake. To avoid this problem, the default | |
1265 // version_max should match the maximum protocol version supported | |
1266 // by the SSLClientSocket class. | |
1267 version_max--; | |
1268 | |
1269 // Fallback to the lower SSL version. | |
1270 // While SSL 3.0 fallback should be eliminated because of security | |
1271 // reasons, there is a high risk of breaking the servers if this is | |
1272 // done in general. | |
1273 should_fallback = true; | |
1274 } | |
1275 break; | |
1276 case ERR_CONNECTION_RESET: | |
1277 if (version_max >= SSL_PROTOCOL_VERSION_TLS1_1 && | |
1278 version_max > server_ssl_config_.version_min) { | |
1279 // Some network devices that inspect application-layer packets seem to | |
1280 // inject TCP reset packets to break the connections when they see TLS | |
1281 // 1.1 in ClientHello or ServerHello. See http://crbug.com/130293. | |
1282 // | |
1283 // Only allow ERR_CONNECTION_RESET to trigger a fallback from TLS 1.1 or | |
1284 // 1.2. We don't lose much in this fallback because the explicit IV for | |
1285 // CBC mode in TLS 1.1 is approximated by record splitting in TLS | |
1286 // 1.0. The fallback will be more painful for TLS 1.2 when we have GCM | |
1287 // support. | |
1288 // | |
1289 // ERR_CONNECTION_RESET is a common network error, so we don't want it | |
1290 // to trigger a version fallback in general, especially the TLS 1.0 -> | |
1291 // SSL 3.0 fallback, which would drop TLS extensions. | |
1292 version_max--; | |
1293 should_fallback = true; | |
1294 } | |
1295 break; | |
1296 case ERR_SSL_BAD_RECORD_MAC_ALERT: | |
1297 if (version_max >= SSL_PROTOCOL_VERSION_TLS1_1 && | |
1298 version_max > server_ssl_config_.version_min) { | |
1299 // Some broken SSL devices negotiate TLS 1.0 when sent a TLS 1.1 or | |
1300 // 1.2 ClientHello, but then return a bad_record_mac alert. See | |
1301 // crbug.com/260358. In order to make the fallback as minimal as | |
1302 // possible, this fallback is only triggered for >= TLS 1.1. | |
1303 version_max--; | |
1304 should_fallback = true; | |
1305 } | |
1306 break; | |
1307 case ERR_SSL_INAPPROPRIATE_FALLBACK: | |
1308 // The server told us that we should not have fallen back. A buggy server | |
1309 // could trigger ERR_SSL_INAPPROPRIATE_FALLBACK with the initial | |
1310 // connection. |fallback_error_code_| is initialised to | |
1311 // ERR_SSL_INAPPROPRIATE_FALLBACK to catch this case. | |
1312 error = fallback_error_code_; | |
1313 break; | |
1314 } | |
1315 | |
1316 if (should_fallback) { | |
1317 net_log_.AddEvent( | |
1318 NetLog::TYPE_SSL_VERSION_FALLBACK, | |
1319 base::Bind(&NetLogSSLVersionFallbackCallback, | |
1320 &request_->url, error, server_ssl_config_.version_max, | |
1321 version_max)); | |
1322 fallback_error_code_ = error; | |
1323 server_ssl_config_.version_max = version_max; | |
1324 server_ssl_config_.version_fallback = true; | |
1325 ResetConnectionAndRequestForResend(); | |
1326 error = OK; | |
1327 } | |
1328 | |
1329 return error; | |
1330 } | |
1331 | |
1332 // This method determines whether it is safe to resend the request after an | |
1333 // IO error. It can only be called in response to request header or body | |
1334 // write errors or response header read errors. It should not be used in | |
1335 // other cases, such as a Connect error. | |
1336 int HttpNetworkTransaction::HandleIOError(int error) { | |
1337 // Because the peer may request renegotiation with client authentication at | |
1338 // any time, check and handle client authentication errors. | |
1339 HandleClientAuthError(error); | |
1340 | |
1341 switch (error) { | |
1342 // If we try to reuse a connection that the server is in the process of | |
1343 // closing, we may end up successfully writing out our request (or a | |
1344 // portion of our request) only to find a connection error when we try to | |
1345 // read from (or finish writing to) the socket. | |
1346 case ERR_CONNECTION_RESET: | |
1347 case ERR_CONNECTION_CLOSED: | |
1348 case ERR_CONNECTION_ABORTED: | |
1349 // There can be a race between the socket pool checking checking whether a | |
1350 // socket is still connected, receiving the FIN, and sending/reading data | |
1351 // on a reused socket. If we receive the FIN between the connectedness | |
1352 // check and writing/reading from the socket, we may first learn the socket | |
1353 // is disconnected when we get a ERR_SOCKET_NOT_CONNECTED. This will most | |
1354 // likely happen when trying to retrieve its IP address. | |
1355 // See http://crbug.com/105824 for more details. | |
1356 case ERR_SOCKET_NOT_CONNECTED: | |
1357 // If a socket is closed on its initial request, HttpStreamParser returns | |
1358 // ERR_EMPTY_RESPONSE. This may still be close/reuse race if the socket was | |
1359 // preconnected but failed to be used before the server timed it out. | |
1360 case ERR_EMPTY_RESPONSE: | |
1361 if (ShouldResendRequest()) { | |
1362 net_log_.AddEventWithNetErrorCode( | |
1363 NetLog::TYPE_HTTP_TRANSACTION_RESTART_AFTER_ERROR, error); | |
1364 ResetConnectionAndRequestForResend(); | |
1365 error = OK; | |
1366 } | |
1367 break; | |
1368 case ERR_SPDY_PING_FAILED: | |
1369 case ERR_SPDY_SERVER_REFUSED_STREAM: | |
1370 case ERR_QUIC_HANDSHAKE_FAILED: | |
1371 net_log_.AddEventWithNetErrorCode( | |
1372 NetLog::TYPE_HTTP_TRANSACTION_RESTART_AFTER_ERROR, error); | |
1373 ResetConnectionAndRequestForResend(); | |
1374 error = OK; | |
1375 break; | |
1376 } | |
1377 return error; | |
1378 } | |
1379 | |
1380 void HttpNetworkTransaction::ResetStateForRestart() { | |
1381 ResetStateForAuthRestart(); | |
1382 if (stream_) | |
1383 total_received_bytes_ += stream_->GetTotalReceivedBytes(); | |
1384 stream_.reset(); | |
1385 } | |
1386 | |
1387 void HttpNetworkTransaction::ResetStateForAuthRestart() { | |
1388 send_start_time_ = base::TimeTicks(); | |
1389 send_end_time_ = base::TimeTicks(); | |
1390 | |
1391 pending_auth_target_ = HttpAuth::AUTH_NONE; | |
1392 read_buf_ = NULL; | |
1393 read_buf_len_ = 0; | |
1394 headers_valid_ = false; | |
1395 request_headers_.Clear(); | |
1396 response_ = HttpResponseInfo(); | |
1397 establishing_tunnel_ = false; | |
1398 } | |
1399 | |
1400 HttpResponseHeaders* HttpNetworkTransaction::GetResponseHeaders() const { | |
1401 return response_.headers.get(); | |
1402 } | |
1403 | |
1404 bool HttpNetworkTransaction::ShouldResendRequest() const { | |
1405 bool connection_is_proven = stream_->IsConnectionReused(); | |
1406 bool has_received_headers = GetResponseHeaders() != NULL; | |
1407 | |
1408 // NOTE: we resend a request only if we reused a keep-alive connection. | |
1409 // This automatically prevents an infinite resend loop because we'll run | |
1410 // out of the cached keep-alive connections eventually. | |
1411 if (connection_is_proven && !has_received_headers) | |
1412 return true; | |
1413 return false; | |
1414 } | |
1415 | |
1416 void HttpNetworkTransaction::ResetConnectionAndRequestForResend() { | |
1417 if (stream_.get()) { | |
1418 stream_->Close(true); | |
1419 stream_.reset(); | |
1420 } | |
1421 | |
1422 // We need to clear request_headers_ because it contains the real request | |
1423 // headers, but we may need to resend the CONNECT request first to recreate | |
1424 // the SSL tunnel. | |
1425 request_headers_.Clear(); | |
1426 next_state_ = STATE_CREATE_STREAM; // Resend the request. | |
1427 } | |
1428 | |
1429 bool HttpNetworkTransaction::ShouldApplyProxyAuth() const { | |
1430 return UsingHttpProxyWithoutTunnel(); | |
1431 } | |
1432 | |
1433 bool HttpNetworkTransaction::ShouldApplyServerAuth() const { | |
1434 return !(request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA); | |
1435 } | |
1436 | |
1437 int HttpNetworkTransaction::HandleAuthChallenge() { | |
1438 scoped_refptr<HttpResponseHeaders> headers(GetResponseHeaders()); | |
1439 DCHECK(headers.get()); | |
1440 | |
1441 int status = headers->response_code(); | |
1442 if (status != HTTP_UNAUTHORIZED && | |
1443 status != HTTP_PROXY_AUTHENTICATION_REQUIRED) | |
1444 return OK; | |
1445 HttpAuth::Target target = status == HTTP_PROXY_AUTHENTICATION_REQUIRED ? | |
1446 HttpAuth::AUTH_PROXY : HttpAuth::AUTH_SERVER; | |
1447 if (target == HttpAuth::AUTH_PROXY && proxy_info_.is_direct()) | |
1448 return ERR_UNEXPECTED_PROXY_AUTH; | |
1449 | |
1450 // This case can trigger when an HTTPS server responds with a "Proxy | |
1451 // authentication required" status code through a non-authenticating | |
1452 // proxy. | |
1453 if (!auth_controllers_[target].get()) | |
1454 return ERR_UNEXPECTED_PROXY_AUTH; | |
1455 | |
1456 int rv = auth_controllers_[target]->HandleAuthChallenge( | |
1457 headers, (request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA) != 0, false, | |
1458 net_log_); | |
1459 if (auth_controllers_[target]->HaveAuthHandler()) | |
1460 pending_auth_target_ = target; | |
1461 | |
1462 scoped_refptr<AuthChallengeInfo> auth_info = | |
1463 auth_controllers_[target]->auth_info(); | |
1464 if (auth_info.get()) | |
1465 response_.auth_challenge = auth_info; | |
1466 | |
1467 return rv; | |
1468 } | |
1469 | |
1470 bool HttpNetworkTransaction::HaveAuth(HttpAuth::Target target) const { | |
1471 return auth_controllers_[target].get() && | |
1472 auth_controllers_[target]->HaveAuth(); | |
1473 } | |
1474 | |
1475 GURL HttpNetworkTransaction::AuthURL(HttpAuth::Target target) const { | |
1476 switch (target) { | |
1477 case HttpAuth::AUTH_PROXY: { | |
1478 if (!proxy_info_.proxy_server().is_valid() || | |
1479 proxy_info_.proxy_server().is_direct()) { | |
1480 return GURL(); // There is no proxy server. | |
1481 } | |
1482 const char* scheme = proxy_info_.is_https() ? "https://" : "http://"; | |
1483 return GURL(scheme + | |
1484 proxy_info_.proxy_server().host_port_pair().ToString()); | |
1485 } | |
1486 case HttpAuth::AUTH_SERVER: | |
1487 if (ForWebSocketHandshake()) { | |
1488 const GURL& url = request_->url; | |
1489 url::Replacements<char> ws_to_http; | |
1490 if (url.SchemeIs("ws")) { | |
1491 ws_to_http.SetScheme("http", url::Component(0, 4)); | |
1492 } else { | |
1493 DCHECK(url.SchemeIs("wss")); | |
1494 ws_to_http.SetScheme("https", url::Component(0, 5)); | |
1495 } | |
1496 return url.ReplaceComponents(ws_to_http); | |
1497 } | |
1498 return request_->url; | |
1499 default: | |
1500 return GURL(); | |
1501 } | |
1502 } | |
1503 | |
1504 bool HttpNetworkTransaction::ForWebSocketHandshake() const { | |
1505 return websocket_handshake_stream_base_create_helper_ && | |
1506 request_->url.SchemeIsWSOrWSS(); | |
1507 } | |
1508 | |
1509 #define STATE_CASE(s) \ | |
1510 case s: \ | |
1511 description = base::StringPrintf("%s (0x%08X)", #s, s); \ | |
1512 break | |
1513 | |
1514 std::string HttpNetworkTransaction::DescribeState(State state) { | |
1515 std::string description; | |
1516 switch (state) { | |
1517 STATE_CASE(STATE_NOTIFY_BEFORE_CREATE_STREAM); | |
1518 STATE_CASE(STATE_CREATE_STREAM); | |
1519 STATE_CASE(STATE_CREATE_STREAM_COMPLETE); | |
1520 STATE_CASE(STATE_INIT_REQUEST_BODY); | |
1521 STATE_CASE(STATE_INIT_REQUEST_BODY_COMPLETE); | |
1522 STATE_CASE(STATE_BUILD_REQUEST); | |
1523 STATE_CASE(STATE_BUILD_REQUEST_COMPLETE); | |
1524 STATE_CASE(STATE_SEND_REQUEST); | |
1525 STATE_CASE(STATE_SEND_REQUEST_COMPLETE); | |
1526 STATE_CASE(STATE_READ_HEADERS); | |
1527 STATE_CASE(STATE_READ_HEADERS_COMPLETE); | |
1528 STATE_CASE(STATE_READ_BODY); | |
1529 STATE_CASE(STATE_READ_BODY_COMPLETE); | |
1530 STATE_CASE(STATE_DRAIN_BODY_FOR_AUTH_RESTART); | |
1531 STATE_CASE(STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE); | |
1532 STATE_CASE(STATE_NONE); | |
1533 default: | |
1534 description = base::StringPrintf("Unknown state 0x%08X (%u)", state, | |
1535 state); | |
1536 break; | |
1537 } | |
1538 return description; | |
1539 } | |
1540 | |
1541 #undef STATE_CASE | |
1542 | |
1543 } // namespace net | |
OLD | NEW |