1 // Copyright (c) 2006-2009 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 "base/format_macros.h" 8 #include "base/scoped_ptr.h" 9 #include "base/compiler_specific.h" 10 #include "base/field_trial.h" 11 #include "base/histogram.h" 12 #include "base/stats_counters.h" 13 #include "base/string_util.h" 14 #include "base/trace_event.h" 15 #include "build/build_config.h" 16 #include "net/base/connection_type_histograms.h" 17 #include "net/base/io_buffer.h" 18 #include "net/base/load_flags.h" 19 #include "net/base/net_errors.h" 20 #include "net/base/net_util.h" 21 #include "net/base/ssl_cert_request_info.h" 22 #include "net/base/upload_data_stream.h" 23 #include "net/flip/flip_session.h" 24 #include "net/flip/flip_session_pool.h" 25 #include "net/flip/flip_stream.h" 26 #include "net/http/http_auth.h" 27 #include "net/http/http_auth_handler.h" 28 #include "net/http/http_basic_stream.h" 29 #include "net/http/http_chunked_decoder.h" 30 #include "net/http/http_network_session.h" 31 #include "net/http/http_request_info.h" 32 #include "net/http/http_response_headers.h" 33 #include "net/http/http_response_info.h" 34 #include "net/http/http_util.h" 35 #include "net/socket/client_socket_factory.h" 36 #include "net/socket/socks5_client_socket.h" 37 #include "net/socket/socks_client_socket.h" 38 #include "net/socket/ssl_client_socket.h" 39 40 using base::Time; 41 42 namespace net { 43 44 namespace { 45 46 void BuildRequestHeaders(const HttpRequestInfo* request_info, 47 const std::string& authorization_headers, 48 const UploadDataStream* upload_data_stream, 49 bool using_proxy, 50 std::string* request_headers) { 51 const std::string path = using_proxy ? 52 HttpUtil::SpecForRequest(request_info->url) : 53 HttpUtil::PathForRequest(request_info->url); 54 *request_headers = 55 StringPrintf("%s %s HTTP/1.1\r\nHost: %s\r\n", 56 request_info->method.c_str(), path.c_str(), 57 GetHostAndOptionalPort(request_info->url).c_str()); 58 59 // For compat with HTTP/1.0 servers and proxies: 60 if (using_proxy) 61 *request_headers += "Proxy-"; 62 *request_headers += "Connection: keep-alive\r\n"; 63 64 if (!request_info->user_agent.empty()) { 65 StringAppendF(request_headers, "User-Agent: %s\r\n", 66 request_info->user_agent.c_str()); 67 } 68 69 // Our consumer should have made sure that this is a safe referrer. See for 70 // instance WebCore::FrameLoader::HideReferrer. 71 if (request_info->referrer.is_valid()) 72 StringAppendF(request_headers, "Referer: %s\r\n", 73 request_info->referrer.spec().c_str()); 74 75 // Add a content length header? 76 if (upload_data_stream) { 77 StringAppendF(request_headers, "Content-Length: %" PRIu64 "\r\n", 78 upload_data_stream->size()); 79 } else if (request_info->method == "POST" || request_info->method == "PUT" || 80 request_info->method == "HEAD") { 81 // An empty POST/PUT request still needs a content length. As for HEAD, 82 // IE and Safari also add a content length header. Presumably it is to 83 // support sending a HEAD request to an URL that only expects to be sent a 84 // POST or some other method that normally would have a message body. 85 *request_headers += "Content-Length: 0\r\n"; 86 } 87 88 // Honor load flags that impact proxy caches. 89 if (request_info->load_flags & LOAD_BYPASS_CACHE) { 90 *request_headers += "Pragma: no-cache\r\nCache-Control: no-cache\r\n"; 91 } else if (request_info->load_flags & LOAD_VALIDATE_CACHE) { 92 *request_headers += "Cache-Control: max-age=0\r\n"; 93 } 94 95 if (!authorization_headers.empty()) { 96 *request_headers += authorization_headers; 97 } 98 99 // TODO(darin): Need to prune out duplicate headers. 100 101 *request_headers += request_info->extra_headers; 102 *request_headers += "\r\n"; 103 } 104 105 // The HTTP CONNECT method for establishing a tunnel connection is documented 106 // in draft-luotonen-web-proxy-tunneling-01.txt and RFC 2817, Sections 5.2 and 107 // 5.3. 108 void BuildTunnelRequest(const HttpRequestInfo* request_info, 109 const std::string& authorization_headers, 110 std::string* request_headers) { 111 // RFC 2616 Section 9 says the Host request-header field MUST accompany all 112 // HTTP/1.1 requests. Add "Proxy-Connection: keep-alive" for compat with 113 // HTTP/1.0 proxies such as Squid (required for NTLM authentication). 114 *request_headers = StringPrintf( 115 "CONNECT %s HTTP/1.1\r\nHost: %s\r\nProxy-Connection: keep-alive\r\n", 116 GetHostAndPort(request_info->url).c_str(), 117 GetHostAndOptionalPort(request_info->url).c_str()); 118 119 if (!request_info->user_agent.empty()) 120 StringAppendF(request_headers, "User-Agent: %s\r\n", 121 request_info->user_agent.c_str()); 122 123 if (!authorization_headers.empty()) { 124 *request_headers += authorization_headers; 125 } 126 127 *request_headers += "\r\n"; 128 } 129 130 } // namespace 131 132 //----------------------------------------------------------------------------- 133 134 std::string* HttpNetworkTransaction::g_next_protos = NULL; 135 136 HttpNetworkTransaction::HttpNetworkTransaction(HttpNetworkSession* session) 137 : pending_auth_target_(HttpAuth::AUTH_NONE), 138 ALLOW_THIS_IN_INITIALIZER_LIST( 139 io_callback_(this, &HttpNetworkTransaction::OnIOComplete)), 140 user_callback_(NULL), 141 session_(session), 142 request_(NULL), 143 pac_request_(NULL), 144 connection_(new ClientSocketHandle), 145 reused_socket_(false), 146 headers_valid_(false), 147 logged_response_time(false), 148 using_ssl_(false), 149 proxy_mode_(kDirectConnection), 150 establishing_tunnel_(false), 151 embedded_identity_used_(false), 152 read_buf_len_(0), 153 next_state_(STATE_NONE) { 154 session->ssl_config_service()->GetSSLConfig(&ssl_config_); 155 if (g_next_protos) 156 ssl_config_.next_protos = *g_next_protos; 157 } 158 159 // static 160 void HttpNetworkTransaction::SetNextProtos(const std::string& next_protos) { 161 delete g_next_protos; 162 g_next_protos = new std::string(next_protos); 163 } 164 165 int HttpNetworkTransaction::Start(const HttpRequestInfo* request_info, 166 CompletionCallback* callback, 167 LoadLog* load_log) { 168 SIMPLE_STATS_COUNTER("HttpNetworkTransaction.Count"); 169 170 load_log_ = load_log; 171 request_ = request_info; 172 start_time_ = base::Time::Now(); 173 174 next_state_ = STATE_RESOLVE_PROXY; 175 int rv = DoLoop(OK); 176 if (rv == ERR_IO_PENDING) 177 user_callback_ = callback; 178 return rv; 179 } 180 181 int HttpNetworkTransaction::RestartIgnoringLastError( 182 CompletionCallback* callback) { 183 if (connection_->socket()->IsConnectedAndIdle()) { 184 next_state_ = STATE_SEND_REQUEST; 185 } else { 186 connection_->socket()->Disconnect(); 187 connection_->Reset(); 188 next_state_ = STATE_INIT_CONNECTION; 189 } 190 int rv = DoLoop(OK); 191 if (rv == ERR_IO_PENDING) 192 user_callback_ = callback; 193 return rv; 194 } 195 196 int HttpNetworkTransaction::RestartWithCertificate( 197 X509Certificate* client_cert, 198 CompletionCallback* callback) { 199 ssl_config_.client_cert = client_cert; 200 if (client_cert) { 201 session_->ssl_client_auth_cache()->Add(GetHostAndPort(request_->url), 202 client_cert); 203 } 204 ssl_config_.send_client_cert = true; 205 next_state_ = STATE_INIT_CONNECTION; 206 // Reset the other member variables. 207 // Note: this is necessary only with SSL renegotiation. 208 ResetStateForRestart(); 209 int rv = DoLoop(OK); 210 if (rv == ERR_IO_PENDING) 211 user_callback_ = callback; 212 return rv; 213 } 214 215 int HttpNetworkTransaction::RestartWithAuth( 216 const std::wstring& username, 217 const std::wstring& password, 218 CompletionCallback* callback) { 219 HttpAuth::Target target = pending_auth_target_; 220 if (target == HttpAuth::AUTH_NONE) { 221 NOTREACHED(); 222 return ERR_UNEXPECTED; 223 } 224 225 pending_auth_target_ = HttpAuth::AUTH_NONE; 226 227 DCHECK(auth_identity_[target].invalid || 228 (username.empty() && password.empty())); 229 230 if (auth_identity_[target].invalid) { 231 // Update the username/password. 232 auth_identity_[target].source = HttpAuth::IDENT_SRC_EXTERNAL; 233 auth_identity_[target].invalid = false; 234 auth_identity_[target].username = username; 235 auth_identity_[target].password = password; 236 } 237 238 PrepareForAuthRestart(target); 239 240 DCHECK(user_callback_ == NULL); 241 int rv = DoLoop(OK); 242 if (rv == ERR_IO_PENDING) 243 user_callback_ = callback; 244 245 return rv; 246 } 247 248 void HttpNetworkTransaction::PrepareForAuthRestart(HttpAuth::Target target) { 249 DCHECK(HaveAuth(target)); 250 DCHECK(auth_identity_[target].source != HttpAuth::IDENT_SRC_PATH_LOOKUP); 251 252 // Add the auth entry to the cache before restarting. We don't know whether 253 // the identity is valid yet, but if it is valid we want other transactions 254 // to know about it. If an entry for (origin, handler->realm()) already 255 // exists, we update it. 256 // 257 // If auth_identity_[target].source is HttpAuth::IDENT_SRC_NONE, 258 // auth_identity_[target] contains no identity because identity is not 259 // required yet. 260 // 261 // TODO(wtc): For NTLM_SSPI, we add the same auth entry to the cache in 262 // round 1 and round 2, which is redundant but correct. It would be nice 263 // to add an auth entry to the cache only once, preferrably in round 1. 264 // See http://crbug.com/21015. 265 bool has_auth_identity = 266 auth_identity_[target].source != HttpAuth::IDENT_SRC_NONE; 267 if (has_auth_identity) { 268 session_->auth_cache()->Add(AuthOrigin(target), auth_handler_[target], 269 auth_identity_[target].username, auth_identity_[target].password, 270 AuthPath(target)); 271 } 272 273 bool keep_alive = false; 274 // Even if the server says the connection is keep-alive, we have to be 275 // able to find the end of each response in order to reuse the connection. 276 if (GetResponseHeaders()->IsKeepAlive() && 277 http_stream_->CanFindEndOfResponse()) { 278 // If the response body hasn't been completely read, we need to drain 279 // it first. 280 if (!http_stream_->IsResponseBodyComplete()) { 281 next_state_ = STATE_DRAIN_BODY_FOR_AUTH_RESTART; 282 read_buf_ = new IOBuffer(kDrainBodyBufferSize); // A bit bucket. 283 read_buf_len_ = kDrainBodyBufferSize; 284 return; 285 } 286 keep_alive = true; 287 } 288 289 // We don't need to drain the response body, so we act as if we had drained 290 // the response body. 291 DidDrainBodyForAuthRestart(keep_alive); 292 } 293 294 void HttpNetworkTransaction::DidDrainBodyForAuthRestart(bool keep_alive) { 295 if (keep_alive && connection_->socket()->IsConnectedAndIdle()) { 296 // We should call connection_->set_idle_time(), but this doesn't occur 297 // often enough to be worth the trouble. 298 next_state_ = STATE_SEND_REQUEST; 299 connection_->set_is_reused(true); 300 reused_socket_ = true; 301 } else { 302 next_state_ = STATE_INIT_CONNECTION; 303 connection_->socket()->Disconnect(); 304 connection_->Reset(); 305 } 306 307 // Reset the other member variables. 308 ResetStateForRestart(); 309 } 310 311 int HttpNetworkTransaction::Read(IOBuffer* buf, int buf_len, 312 CompletionCallback* callback) { 313 DCHECK(buf); 314 DCHECK_LT(0, buf_len); 315 316 State next_state = STATE_NONE; 317 318 // Are we using SPDY or HTTP? 319 if (spdy_stream_.get()) { 320 DCHECK(!http_stream_.get()); 321 DCHECK(spdy_stream_->GetResponseInfo()->headers); 322 next_state = STATE_SPDY_READ_BODY; 323 } else { 324 scoped_refptr<HttpResponseHeaders> headers = GetResponseHeaders(); 325 DCHECK(headers.get()); 326 next_state = STATE_READ_BODY; 327 328 if (!connection_->is_initialized()) 329 return 0; // connection_->has been reset. Treat like EOF. 330 331 if (establishing_tunnel_) { 332 // We're trying to read the body of the response but we're still trying 333 // to establish an SSL tunnel through the proxy. We can't read these 334 // bytes when establishing a tunnel because they might be controlled by 335 // an active network attacker. We don't worry about this for HTTP 336 // because an active network attacker can already control HTTP sessions. 337 // We reach this case when the user cancels a 407 proxy auth prompt. 338 // See http://crbug.com/8473. 339 DCHECK_EQ(407, headers->response_code()); 340 LogBlockedTunnelResponse(headers->response_code()); 341 return ERR_TUNNEL_CONNECTION_FAILED; 342 } 343 } 344 345 read_buf_ = buf; 346 read_buf_len_ = buf_len; 347 348 next_state_ = next_state; 349 int rv = DoLoop(OK); 350 if (rv == ERR_IO_PENDING) 351 user_callback_ = callback; 352 return rv; 353 } 354 355 const HttpResponseInfo* HttpNetworkTransaction::GetResponseInfo() const { 356 return ((headers_valid_ && response_.headers) || response_.ssl_info.cert || 357 response_.cert_request_info) ? &response_ : NULL; 358 } 359 360 LoadState HttpNetworkTransaction::GetLoadState() const { 361 // TODO(wtc): Define a new LoadState value for the 362 // STATE_INIT_CONNECTION_COMPLETE state, which delays the HTTP request. 363 switch (next_state_) { 364 case STATE_RESOLVE_PROXY_COMPLETE: 365 return LOAD_STATE_RESOLVING_PROXY_FOR_URL; 366 case STATE_INIT_CONNECTION_COMPLETE: 367 return connection_->GetLoadState(); 368 case STATE_SEND_REQUEST_COMPLETE: 369 return LOAD_STATE_SENDING_REQUEST; 370 case STATE_READ_HEADERS_COMPLETE: 371 return LOAD_STATE_WAITING_FOR_RESPONSE; 372 case STATE_READ_BODY_COMPLETE: 373 return LOAD_STATE_READING_RESPONSE; 374 default: 375 return LOAD_STATE_IDLE; 376 } 377 } 378 379 uint64 HttpNetworkTransaction::GetUploadProgress() const { 380 if (!http_stream_.get()) 381 return 0; 382 383 return http_stream_->GetUploadProgress(); 384 } 385 386 HttpNetworkTransaction::~HttpNetworkTransaction() { 387 // If we still have an open socket, then make sure to disconnect it so it 388 // won't call us back and we don't try to reuse it later on. 389 if (connection_.get() && connection_->is_initialized()) 390 connection_->socket()->Disconnect(); 391 392 if (pac_request_) 393 session_->proxy_service()->CancelPacRequest(pac_request_); 394 395 if (spdy_stream_.get()) 396 spdy_stream_->Cancel(); 397 } 398 399 void HttpNetworkTransaction::DoCallback(int rv) { 400 DCHECK(rv != ERR_IO_PENDING); 401 DCHECK(user_callback_); 402 403 // Since Run may result in Read being called, clear user_callback_ up front. 404 CompletionCallback* c = user_callback_; 405 user_callback_ = NULL; 406 c->Run(rv); 407 } 408 409 void HttpNetworkTransaction::OnIOComplete(int result) { 410 int rv = DoLoop(result); 411 if (rv != ERR_IO_PENDING) 412 DoCallback(rv); 413 } 414 415 int HttpNetworkTransaction::DoLoop(int result) { 416 DCHECK(next_state_ != STATE_NONE); 417 418 int rv = result; 419 do { 420 State state = next_state_; 421 next_state_ = STATE_NONE; 422 switch (state) { 423 case STATE_RESOLVE_PROXY: 424 DCHECK_EQ(OK, rv); 425 TRACE_EVENT_BEGIN("http.resolve_proxy", request_, request_->url.spec()); 426 rv = DoResolveProxy(); 427 break; 428 case STATE_RESOLVE_PROXY_COMPLETE: 429 rv = DoResolveProxyComplete(rv); 430 TRACE_EVENT_END("http.resolve_proxy", request_, request_->url.spec()); 431 break; 432 case STATE_INIT_CONNECTION: 433 DCHECK_EQ(OK, rv); 434 TRACE_EVENT_BEGIN("http.init_conn", request_, request_->url.spec()); 435 rv = DoInitConnection(); 436 break; 437 case STATE_INIT_CONNECTION_COMPLETE: 438 rv = DoInitConnectionComplete(rv); 439 TRACE_EVENT_END("http.init_conn", request_, request_->url.spec()); 440 break; 441 case STATE_SOCKS_CONNECT: 442 DCHECK_EQ(OK, rv); 443 TRACE_EVENT_BEGIN("http.socks_connect", request_, request_->url.spec()); 444 rv = DoSOCKSConnect(); 445 break; 446 case STATE_SOCKS_CONNECT_COMPLETE: 447 rv = DoSOCKSConnectComplete(rv); 448 TRACE_EVENT_END("http.socks_connect", request_, request_->url.spec()); 449 break; 450 case STATE_SSL_CONNECT: 451 DCHECK_EQ(OK, rv); 452 TRACE_EVENT_BEGIN("http.ssl_connect", request_, request_->url.spec()); 453 rv = DoSSLConnect(); 454 break; 455 case STATE_SSL_CONNECT_COMPLETE: 456 rv = DoSSLConnectComplete(rv); 457 TRACE_EVENT_END("http.ssl_connect", request_, request_->url.spec()); 458 break; 459 case STATE_SEND_REQUEST: 460 DCHECK_EQ(OK, rv); 461 TRACE_EVENT_BEGIN("http.send_request", request_, request_->url.spec()); 462 LoadLog::BeginEvent(load_log_, 463 LoadLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST); 464 rv = DoSendRequest(); 465 break; 466 case STATE_SEND_REQUEST_COMPLETE: 467 rv = DoSendRequestComplete(rv); 468 TRACE_EVENT_END("http.send_request", request_, request_->url.spec()); 469 LoadLog::EndEvent(load_log_, 470 LoadLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST); 471 break; 472 case STATE_READ_HEADERS: 473 DCHECK_EQ(OK, rv); 474 TRACE_EVENT_BEGIN("http.read_headers", request_, request_->url.spec()); 475 LoadLog::BeginEvent(load_log_, 476 LoadLog::TYPE_HTTP_TRANSACTION_READ_HEADERS); 477 rv = DoReadHeaders(); 478 break; 479 case STATE_READ_HEADERS_COMPLETE: 480 rv = DoReadHeadersComplete(rv); 481 TRACE_EVENT_END("http.read_headers", request_, request_->url.spec()); 482 LoadLog::EndEvent(load_log_, 483 LoadLog::TYPE_HTTP_TRANSACTION_READ_HEADERS); 484 break; 485 case STATE_READ_BODY: 486 DCHECK_EQ(OK, rv); 487 TRACE_EVENT_BEGIN("http.read_body", request_, request_->url.spec()); 488 LoadLog::BeginEvent(load_log_, 489 LoadLog::TYPE_HTTP_TRANSACTION_READ_BODY); 490 rv = DoReadBody(); 491 break; 492 case STATE_READ_BODY_COMPLETE: 493 rv = DoReadBodyComplete(rv); 494 TRACE_EVENT_END("http.read_body", request_, request_->url.spec()); 495 LoadLog::EndEvent(load_log_, 496 LoadLog::TYPE_HTTP_TRANSACTION_READ_BODY); 497 break; 498 case STATE_DRAIN_BODY_FOR_AUTH_RESTART: 499 DCHECK_EQ(OK, rv); 500 TRACE_EVENT_BEGIN("http.drain_body_for_auth_restart", 501 request_, request_->url.spec()); 502 LoadLog::BeginEvent( 503 load_log_, 504 LoadLog::TYPE_HTTP_TRANSACTION_DRAIN_BODY_FOR_AUTH_RESTART); 505 rv = DoDrainBodyForAuthRestart(); 506 break; 507 case STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE: 508 rv = DoDrainBodyForAuthRestartComplete(rv); 509 TRACE_EVENT_END("http.drain_body_for_auth_restart", 510 request_, request_->url.spec()); 511 LoadLog::EndEvent( 512 load_log_, 513 LoadLog::TYPE_HTTP_TRANSACTION_DRAIN_BODY_FOR_AUTH_RESTART); 514 break; 515 case STATE_SPDY_SEND_REQUEST: 516 DCHECK_EQ(OK, rv); 517 TRACE_EVENT_BEGIN("http.send_request", request_, request_->url.spec()); 518 LoadLog::BeginEvent(load_log_, 519 LoadLog::TYPE_FLIP_TRANSACTION_SEND_REQUEST); 520 rv = DoSpdySendRequest(); 521 break; 522 case STATE_SPDY_SEND_REQUEST_COMPLETE: 523 rv = DoSpdySendRequestComplete(rv); 524 TRACE_EVENT_END("http.send_request", request_, request_->url.spec()); 525 LoadLog::EndEvent(load_log_, 526 LoadLog::TYPE_FLIP_TRANSACTION_SEND_REQUEST); 527 break; 528 case STATE_SPDY_READ_HEADERS: 529 DCHECK_EQ(OK, rv); 530 TRACE_EVENT_BEGIN("http.read_headers", request_, request_->url.spec()); 531 LoadLog::BeginEvent(load_log_, 532 LoadLog::TYPE_FLIP_TRANSACTION_READ_HEADERS); 533 rv = DoSpdyReadHeaders(); 534 break; 535 case STATE_SPDY_READ_HEADERS_COMPLETE: 536 rv = DoSpdyReadHeadersComplete(rv); 537 TRACE_EVENT_END("http.read_headers", request_, request_->url.spec()); 538 LoadLog::EndEvent(load_log_, 539 LoadLog::TYPE_FLIP_TRANSACTION_READ_HEADERS); 540 break; 541 case STATE_SPDY_READ_BODY: 542 DCHECK_EQ(OK, rv); 543 TRACE_EVENT_BEGIN("http.read_body", request_, request_->url.spec()); 544 LoadLog::BeginEvent(load_log_, 545 LoadLog::TYPE_FLIP_TRANSACTION_READ_BODY); 546 rv = DoSpdyReadBody(); 547 break; 548 case STATE_SPDY_READ_BODY_COMPLETE: 549 rv = DoSpdyReadBodyComplete(rv); 550 TRACE_EVENT_END("http.read_body", request_, request_->url.spec()); 551 LoadLog::EndEvent(load_log_, 552 LoadLog::TYPE_FLIP_TRANSACTION_READ_BODY); 553 break; 554 default: 555 NOTREACHED() << "bad state"; 556 rv = ERR_FAILED; 557 break; 558 } 559 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); 560 561 return rv; 562 } 563 564 int HttpNetworkTransaction::DoResolveProxy() { 565 DCHECK(!pac_request_); 566 567 next_state_ = STATE_RESOLVE_PROXY_COMPLETE; 568 569 if (request_->load_flags & LOAD_BYPASS_PROXY) { 570 proxy_info_.UseDirect(); 571 return OK; 572 } 573 574 return session_->proxy_service()->ResolveProxy( 575 request_->url, &proxy_info_, &io_callback_, &pac_request_, load_log_); 576 } 577 578 int HttpNetworkTransaction::DoResolveProxyComplete(int result) { 579 580 pac_request_ = NULL; 581 582 if (result != OK) { 583 DLOG(ERROR) << "Failed to resolve proxy: " << result; 584 // Fall-back to direct when there were runtime errors in the PAC script, 585 // or some other failure with the settings. 586 proxy_info_.UseDirect(); 587 } 588 589 // Remove unsupported proxies from the list. 590 proxy_info_.RemoveProxiesWithoutScheme( 591 ProxyServer::SCHEME_DIRECT | ProxyServer::SCHEME_HTTP | 592 ProxyServer::SCHEME_SOCKS4 | ProxyServer::SCHEME_SOCKS5); 593 594 // There are four possible outcomes of having run the ProxyService: 595 // (1) The ProxyService decided we should connect through a proxy. 596 // (2) The ProxyService decided we should direct-connect. 597 // (3) The ProxyService decided we should give up, as there are no more 598 // proxies to try (this is more likely to happen during 599 // ReconsiderProxyAfterError()). 600 // (4) The ProxyService failed (which can happen if the PAC script 601 // we were configured with threw a runtime exception). 602 // 603 // It is important that we fail the connection in case (3) rather than 604 // falling-back to a direct connection, since sending traffic through 605 // a proxy may be integral to the user's privacy/security model. 606 // 607 // For example if a user had configured traffic to go through the TOR 608 // anonymizing proxy to protect their privacy, it would be bad if we 609 // silently fell-back to direct connect if the proxy server were to 610 // become unreachable. 611 // 612 // In case (4) it is less obvious what the right thing to do is. On the 613 // one hand, for consistency it would be natural to hard-fail as well. 614 // However, both Firefox 3.5 and Internet Explorer 8 will silently fall-back 615 // to DIRECT in this case, so we will do the same for compatibility. 616 // 617 // For more information, see: 618 // http://www.chromium.org/developers/design-documents/proxy-settings-fallback 619 620 if (proxy_info_.is_empty()) { 621 // No proxies/direct to choose from. This happens when we don't support any 622 // of the proxies in the returned list. 623 return ERR_NO_SUPPORTED_PROXIES; 624 } 625 626 next_state_ = STATE_INIT_CONNECTION; 627 return OK; 628 } 629 630 int HttpNetworkTransaction::DoInitConnection() { 631 DCHECK(!connection_->is_initialized()); 632 DCHECK(proxy_info_.proxy_server().is_valid()); 633 634 next_state_ = STATE_INIT_CONNECTION_COMPLETE; 635 636 using_ssl_ = request_->url.SchemeIs("https"); 637 638 if (proxy_info_.is_direct()) 639 proxy_mode_ = kDirectConnection; 640 else if (proxy_info_.proxy_server().is_socks()) 641 proxy_mode_ = kSOCKSProxy; 642 else if (using_ssl_) 643 proxy_mode_ = kHTTPProxyUsingTunnel; 644 else 645 proxy_mode_ = kHTTPProxy; 646 647 // Build the string used to uniquely identify connections of this type. 648 // Determine the host and port to connect to. 649 std::string connection_group; 650 std::string host; 651 int port; 652 if (proxy_mode_ != kDirectConnection) { 653 ProxyServer proxy_server = proxy_info_.proxy_server(); 654 connection_group = "proxy/" + proxy_server.ToURI() + "/"; 655 host = proxy_server.HostNoBrackets(); 656 port = proxy_server.port(); 657 } else { 658 host = request_->url.HostNoBrackets(); 659 port = request_->url.EffectiveIntPort(); 660 } 661 662 // Use the fixed testing ports if they've been provided. 663 if (using_ssl_) { 664 if (session_->fixed_https_port() != 0) 665 port = session_->fixed_https_port(); 666 } else if (session_->fixed_http_port() != 0) { 667 port = session_->fixed_http_port(); 668 } 669 670 // For a connection via HTTP proxy not using CONNECT, the connection 671 // is to the proxy server only. For all other cases 672 // (direct, HTTP proxy CONNECT, SOCKS), the connection is upto the 673 // url endpoint. Hence we append the url data into the connection_group. 674 if (proxy_mode_ != kHTTPProxy) 675 connection_group.append(request_->url.GetOrigin().spec()); 676 677 DCHECK(!connection_group.empty()); 678 679 HostResolver::RequestInfo resolve_info(host, port); 680 resolve_info.set_priority(request_->priority); 681 682 // The referrer is used by the DNS prefetch system to correlate resolutions 683 // with the page that triggered them. It doesn't impact the actual addresses 684 // that we resolve to. 685 resolve_info.set_referrer(request_->referrer); 686 687 // If the user is refreshing the page, bypass the host cache. 688 if (request_->load_flags & LOAD_BYPASS_CACHE || 689 request_->load_flags & LOAD_DISABLE_CACHE) { 690 resolve_info.set_allow_cached_response(false); 691 } 692 693 // Check first if we have a flip session for this group. If so, then go 694 // straight to using that. 695 if (session_->flip_session_pool()->HasSession(resolve_info)) 696 return OK; 697 698 int rv = connection_->Init(connection_group, resolve_info, request_->priority, 699 &io_callback_, session_->tcp_socket_pool(), 700 load_log_); 701 return rv; 702 } 703 704 int HttpNetworkTransaction::DoInitConnectionComplete(int result) { 705 if (result < 0) { 706 UpdateConnectionTypeHistograms(CONNECTION_HTTP, false); 707 return ReconsiderProxyAfterError(result); 708 } 709 710 DCHECK_EQ(OK, result); 711 712 // If we don't have an initialized connection, that means we have a flip 713 // connection waiting for us. 714 if (!connection_->is_initialized()) { 715 next_state_ = STATE_SPDY_SEND_REQUEST; 716 return OK; 717 } 718 719 LogTCPConnectedMetrics(*connection_); 720 721 // Set the reused_socket_ flag to indicate that we are using a keep-alive 722 // connection. This flag is used to handle errors that occur while we are 723 // trying to reuse a keep-alive connection. 724 reused_socket_ = connection_->is_reused(); 725 if (reused_socket_) { 726 next_state_ = STATE_SEND_REQUEST; 727 } else { 728 // Now we have a TCP connected socket. Perform other connection setup as 729 // needed. 730 UpdateConnectionTypeHistograms(CONNECTION_HTTP, true); 731 if (proxy_mode_ == kSOCKSProxy) 732 next_state_ = STATE_SOCKS_CONNECT; 733 else if (using_ssl_ && proxy_mode_ == kDirectConnection) { 734 next_state_ = STATE_SSL_CONNECT; 735 } else { 736 next_state_ = STATE_SEND_REQUEST; 737 if (proxy_mode_ == kHTTPProxyUsingTunnel) 738 establishing_tunnel_ = true; 739 } 740 } 741 742 return OK; 743 } 744 745 int HttpNetworkTransaction::DoSOCKSConnect() { 746 DCHECK_EQ(kSOCKSProxy, proxy_mode_); 747 748 next_state_ = STATE_SOCKS_CONNECT_COMPLETE; 749 750 // Add a SOCKS connection on top of our existing transport socket. 751 ClientSocket* s = connection_->release_socket(); 752 HostResolver::RequestInfo req_info(request_->url.HostNoBrackets(), 753 request_->url.EffectiveIntPort()); 754 req_info.set_referrer(request_->referrer); 755 req_info.set_priority(request_->priority); 756 757 if (proxy_info_.proxy_server().scheme() == ProxyServer::SCHEME_SOCKS5) 758 s = new SOCKS5ClientSocket(s, req_info); 759 else 760 s = new SOCKSClientSocket(s, req_info, session_->host_resolver()); 761 connection_->set_socket(s); 762 return connection_->socket()->Connect(&io_callback_, load_log_); 763 } 764 765 int HttpNetworkTransaction::DoSOCKSConnectComplete(int result) { 766 DCHECK_EQ(kSOCKSProxy, proxy_mode_); 767 768 if (result == OK) { 769 if (using_ssl_) { 770 next_state_ = STATE_SSL_CONNECT; 771 } else { 772 next_state_ = STATE_SEND_REQUEST; 773 } 774 } else { 775 result = ReconsiderProxyAfterError(result); 776 } 777 return result; 778 } 779 780 int HttpNetworkTransaction::DoSSLConnect() { 781 next_state_ = STATE_SSL_CONNECT_COMPLETE; 782 783 if (request_->load_flags & LOAD_VERIFY_EV_CERT) 784 ssl_config_.verify_ev_cert = true; 785 786 ssl_connect_start_time_ = base::TimeTicks::Now(); 787 788 // Add a SSL socket on top of our existing transport socket. 789 ClientSocket* s = connection_->release_socket(); 790 s = session_->socket_factory()->CreateSSLClientSocket( 791 s, request_->url.HostNoBrackets(), ssl_config_); 792 connection_->set_socket(s); 793 return connection_->socket()->Connect(&io_callback_, load_log_); 794 } 795 796 int HttpNetworkTransaction::DoSSLConnectComplete(int result) { 797 SSLClientSocket* ssl_socket = 798 reinterpret_cast<SSLClientSocket*>(connection_->socket()); 799 800 SSLClientSocket::NextProtoStatus status = 801 SSLClientSocket::kNextProtoUnsupported; 802 std::string proto; 803 // GetNextProto will fail and and trigger a NOTREACHED if we pass in a socket 804 // that hasn't had SSL_ImportFD called on it. If we get a certificate error 805 // here, then we know that we called SSL_ImportFD. 806 if (result == OK || IsCertificateError(result)) 807 status = ssl_socket->GetNextProto(&proto); 808 static const char kSpdyProto[] = "spdy"; 809 const bool use_spdy = (status == SSLClientSocket::kNextProtoNegotiated && 810 proto == kSpdyProto); 811 812 if (IsCertificateError(result)) { 813 if (use_spdy) { 814 // TODO(agl/willchan/wtc): We currently ignore certificate errors for 815 // spdy but we shouldn't. http://crbug.com/32020 816 result = OK; 817 } else { 818 result = HandleCertificateError(result); 819 } 820 } 821 822 if (result == OK) { 823 DCHECK(ssl_connect_start_time_ != base::TimeTicks()); 824 base::TimeDelta connect_duration = 825 base::TimeTicks::Now() - ssl_connect_start_time_; 826 827 if (use_spdy) { 828 UMA_HISTOGRAM_CUSTOM_TIMES("Net.SpdyConnectionLatency", 829 connect_duration, 830 base::TimeDelta::FromMilliseconds(1), 831 base::TimeDelta::FromMinutes(10), 832 100); 833 834 UpdateConnectionTypeHistograms(CONNECTION_SPDY, true); 835 next_state_ = STATE_SPDY_SEND_REQUEST; 836 } else { 837 UMA_HISTOGRAM_CUSTOM_TIMES("Net.SSL_Connection_Latency", 838 connect_duration, 839 base::TimeDelta::FromMilliseconds(1), 840 base::TimeDelta::FromMinutes(10), 841 100); 842 843 next_state_ = STATE_SEND_REQUEST; 844 } 845 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { 846 result = HandleCertificateRequest(result); 847 } else { 848 result = HandleSSLHandshakeError(result); 849 } 850 return result; 851 } 852 853 int HttpNetworkTransaction::DoSendRequest() { 854 next_state_ = STATE_SEND_REQUEST_COMPLETE; 855 856 UploadDataStream* request_body = NULL; 857 if (!establishing_tunnel_ && request_->upload_data) 858 request_body = new UploadDataStream(request_->upload_data); 859 860 // This is constructed lazily (instead of within our Start method), so that 861 // we have proxy info available. 862 if (request_headers_.empty()) { 863 // Figure out if we can/should add Proxy-Authentication & Authentication 864 // headers. 865 bool have_proxy_auth = 866 ShouldApplyProxyAuth() && 867 (HaveAuth(HttpAuth::AUTH_PROXY) || 868 SelectPreemptiveAuth(HttpAuth::AUTH_PROXY)); 869 bool have_server_auth = 870 ShouldApplyServerAuth() && 871 (HaveAuth(HttpAuth::AUTH_SERVER) || 872 SelectPreemptiveAuth(HttpAuth::AUTH_SERVER)); 873 874 std::string authorization_headers; 875 876 // TODO(wtc): If BuildAuthorizationHeader fails (returns an authorization 877 // header with no credentials), we should return an error to prevent 878 // entering an infinite auth restart loop. See http://crbug.com/21050. 879 if (have_proxy_auth) 880 authorization_headers.append( 881 BuildAuthorizationHeader(HttpAuth::AUTH_PROXY)); 882 if (have_server_auth) 883 authorization_headers.append( 884 BuildAuthorizationHeader(HttpAuth::AUTH_SERVER)); 885 886 if (establishing_tunnel_) { 887 BuildTunnelRequest(request_, authorization_headers, &request_headers_); 888 } else { 889 BuildRequestHeaders(request_, authorization_headers, request_body, 890 proxy_mode_ == kHTTPProxy, &request_headers_); 891 } 892 } 893 894 headers_valid_ = false; 895 http_stream_.reset(new HttpBasicStream(connection_.get(), load_log_)); 896 897 return http_stream_->SendRequest(request_, request_headers_, 898 request_body, &response_, &io_callback_); 899 } 900 901 int HttpNetworkTransaction::DoSendRequestComplete(int result) { 902 if (result < 0) 903 return HandleIOError(result); 904 905 next_state_ = STATE_READ_HEADERS; 906 907 return OK; 908 } 909 910 int HttpNetworkTransaction::DoReadHeaders() { 911 next_state_ = STATE_READ_HEADERS_COMPLETE; 912 913 return http_stream_->ReadResponseHeaders(&io_callback_); 914 } 915 916 int HttpNetworkTransaction::HandleConnectionClosedBeforeEndOfHeaders() { 917 if (establishing_tunnel_) { 918 // The connection was closed before the tunnel could be established. 919 return ERR_TUNNEL_CONNECTION_FAILED; 920 } 921 922 if (!response_.headers) { 923 // The connection was closed before any data was sent. Likely an error 924 // rather than empty HTTP/0.9 response. 925 return ERR_EMPTY_RESPONSE; 926 } 927 928 return OK; 929 } 930 931 int HttpNetworkTransaction::DoReadHeadersComplete(int result) { 932 // We can get a certificate error or ERR_SSL_CLIENT_AUTH_CERT_NEEDED here 933 // due to SSL renegotiation. 934 if (using_ssl_) { 935 if (IsCertificateError(result)) { 936 // We don't handle a certificate error during SSL renegotiation, so we 937 // have to return an error that's not in the certificate error range 938 // (-2xx). 939 LOG(ERROR) << "Got a server certificate with error " << result 940 << " during SSL renegotiation"; 941 result = ERR_CERT_ERROR_IN_SSL_RENEGOTIATION; 942 } else if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { 943 result = HandleCertificateRequest(result); 944 if (result == OK) 945 return result; 946 } 947 } 948 949 if (result < 0 && result != ERR_CONNECTION_CLOSED) 950 return HandleIOError(result); 951 952 if (result == ERR_CONNECTION_CLOSED && ShouldResendRequest(result)) { 953 ResetConnectionAndRequestForResend(); 954 return OK; 955 } 956 957 // After we call RestartWithAuth a new response_time will be recorded, and 958 // we need to be cautious about incorrectly logging the duration across the 959 // authentication activity. 960 if (!logged_response_time) { 961 LogTransactionConnectedMetrics(); 962 logged_response_time = true; 963 } 964 965 if (result == ERR_CONNECTION_CLOSED) { 966 int rv = HandleConnectionClosedBeforeEndOfHeaders(); 967 if (rv != OK) 968 return rv; 969 // TODO(wtc): Traditionally this code has returned 0 when reading a closed 970 // socket. That is partially corrected in classes that we call, but 971 // callers need to be updated. 972 result = 0; 973 } 974 975 if (response_.headers->GetParsedHttpVersion() < HttpVersion(1, 0)) { 976 // Require the "HTTP/1.x" status line for SSL CONNECT. 977 if (establishing_tunnel_) 978 return ERR_TUNNEL_CONNECTION_FAILED; 979 980 // HTTP/0.9 doesn't support the PUT method, so lack of response headers 981 // indicates a buggy server. See: 982 // https://bugzilla.mozilla.org/show_bug.cgi?id=193921 983 if (request_->method == "PUT") 984 return ERR_METHOD_NOT_SUPPORTED; 985 } 986 987 if (establishing_tunnel_) { 988 switch (response_.headers->response_code()) { 989 case 200: // OK 990 if (http_stream_->IsMoreDataBuffered()) { 991 // The proxy sent extraneous data after the headers. 992 return ERR_TUNNEL_CONNECTION_FAILED; 993 } 994 next_state_ = STATE_SSL_CONNECT; 995 // Reset for the real request and response headers. 996 request_headers_.clear(); 997 http_stream_.reset(new HttpBasicStream(connection_.get(), load_log_)); 998 headers_valid_ = false; 999 establishing_tunnel_ = false; 1000 return OK; 1001 1002 // We aren't able to CONNECT to the remote host through the proxy. We 1003 // need to be very suspicious about the response because an active network 1004 // attacker can force us into this state by masquerading as the proxy. 1005 // The only safe thing to do here is to fail the connection because our 1006 // client is expecting an SSL protected response. 1007 // See http://crbug.com/7338. 1008 case 407: // Proxy Authentication Required 1009 // We need this status code to allow proxy authentication. Our 1010 // authentication code is smart enough to avoid being tricked by an 1011 // active network attacker. 1012 break; 1013 default: 1014 // For all other status codes, we conservatively fail the CONNECT 1015 // request. 1016 // We lose something by doing this. We have seen proxy 403, 404, and 1017 // 501 response bodies that contain a useful error message. For 1018 // example, Squid uses a 404 response to report the DNS error: "The 1019 // domain name does not exist." 1020 LogBlockedTunnelResponse(response_.headers->response_code()); 1021 return ERR_TUNNEL_CONNECTION_FAILED; 1022 } 1023 } 1024 1025 // Check for an intermediate 100 Continue response. An origin server is 1026 // allowed to send this response even if we didn't ask for it, so we just 1027 // need to skip over it. 1028 // We treat any other 1xx in this same way (although in practice getting 1029 // a 1xx that isn't a 100 is rare). 1030 if (response_.headers->response_code() / 100 == 1) { 1031 response_.headers = new HttpResponseHeaders(""); 1032 next_state_ = STATE_READ_HEADERS; 1033 return OK; 1034 } 1035 1036 int rv = HandleAuthChallenge(); 1037 if (rv != OK) 1038 return rv; 1039 1040 if (using_ssl_ && !establishing_tunnel_) { 1041 SSLClientSocket* ssl_socket = 1042 reinterpret_cast<SSLClientSocket*>(connection_->socket()); 1043 ssl_socket->GetSSLInfo(&response_.ssl_info); 1044 } 1045 1046 headers_valid_ = true; 1047 return OK; 1048 } 1049 1050 int HttpNetworkTransaction::DoReadBody() { 1051 DCHECK(read_buf_); 1052 DCHECK_GT(read_buf_len_, 0); 1053 DCHECK(connection_->is_initialized()); 1054 1055 next_state_ = STATE_READ_BODY_COMPLETE; 1056 return http_stream_->ReadResponseBody(read_buf_, read_buf_len_, 1057 &io_callback_); 1058 } 1059 1060 int HttpNetworkTransaction::DoReadBodyComplete(int result) { 1061 // We are done with the Read call. 1062 DCHECK(!establishing_tunnel_) << 1063 "We should never read a response body of a tunnel."; 1064 1065 bool done = false, keep_alive = false; 1066 if (result < 0) { 1067 // Error or closed connection while reading the socket. 1068 done = true; 1069 // TODO(wtc): Traditionally this code has returned 0 when reading a closed 1070 // socket. That is partially corrected in classes that we call, but 1071 // callers need to be updated. 1072 if (result == ERR_CONNECTION_CLOSED) 1073 result = 0; 1074 } else if (http_stream_->IsResponseBodyComplete()) { 1075 done = true; 1076 keep_alive = GetResponseHeaders()->IsKeepAlive(); 1077 } 1078 1079 // Clean up connection_->if we are done. 1080 if (done) { 1081 LogTransactionMetrics(); 1082 if (!keep_alive) 1083 connection_->socket()->Disconnect(); 1084 connection_->Reset(); 1085 // The next Read call will return 0 (EOF). 1086 } 1087 1088 // Clear these to avoid leaving around old state. 1089 read_buf_ = NULL; 1090 read_buf_len_ = 0; 1091 1092 return result; 1093 } 1094 1095 int HttpNetworkTransaction::DoDrainBodyForAuthRestart() { 1096 // This method differs from DoReadBody only in the next_state_. So we just 1097 // call DoReadBody and override the next_state_. Perhaps there is a more 1098 // elegant way for these two methods to share code. 1099 int rv = DoReadBody(); 1100 DCHECK(next_state_ == STATE_READ_BODY_COMPLETE); 1101 next_state_ = STATE_DRAIN_BODY_FOR_AUTH_RESTART_COMPLETE; 1102 return rv; 1103 } 1104 1105 // TODO(wtc): This method and the DoReadBodyComplete method are almost 1106 // the same. Figure out a good way for these two methods to share code. 1107 int HttpNetworkTransaction::DoDrainBodyForAuthRestartComplete(int result) { 1108 // keep_alive defaults to true because the very reason we're draining the 1109 // response body is to reuse the connection for auth restart. 1110 bool done = false, keep_alive = true; 1111 if (result < 0) { 1112 // Error or closed connection while reading the socket. 1113 done = true; 1114 keep_alive = false; 1115 } else if (http_stream_->IsResponseBodyComplete()) { 1116 done = true; 1117 } 1118 1119 if (done) { 1120 DidDrainBodyForAuthRestart(keep_alive); 1121 } else { 1122 // Keep draining. 1123 next_state_ = STATE_DRAIN_BODY_FOR_AUTH_RESTART; 1124 } 1125 1126 return OK; 1127 } 1128 1129 int HttpNetworkTransaction::DoSpdySendRequest() { 1130 next_state_ = STATE_SPDY_SEND_REQUEST_COMPLETE; 1131 CHECK(!spdy_stream_.get()); 1132 1133 // First we get a SPDY session. Theoretically, we've just negotiated one, but 1134 // if one already exists, then screw it, use the existing one! Otherwise, 1135 // use the existing TCP socket. 1136 1137 HostResolver::RequestInfo req_info(request_->url.HostNoBrackets(), 1138 request_->url.EffectiveIntPort()); 1139 req_info.set_priority(request_->priority); 1140 const scoped_refptr<FlipSessionPool> spdy_pool = 1141 session_->flip_session_pool(); 1142 scoped_refptr<FlipSession> spdy_session; 1143 1144 if (spdy_pool->HasSession(req_info)) { 1145 spdy_session = spdy_pool->Get(req_info, session_); 1146 } else { 1147 spdy_session = spdy_pool->GetFlipSessionFromSocket( 1148 req_info, session_, connection_.release()); 1149 } 1150 1151 CHECK(spdy_session.get()); 1152 1153 UploadDataStream* upload_data = request_->upload_data ? 1154 new UploadDataStream(request_->upload_data) : NULL; 1155 headers_valid_ = false; 1156 spdy_stream_ = spdy_session->GetOrCreateStream( 1157 *request_, upload_data, load_log_); 1158 return spdy_stream_->SendRequest(upload_data, &response_, &io_callback_); 1159 } 1160 1161 int HttpNetworkTransaction::DoSpdySendRequestComplete(int result) { 1162 if (result < 0) 1163 return result; 1164 1165 next_state_ = STATE_SPDY_READ_HEADERS; 1166 return OK; 1167 } 1168 1169 int HttpNetworkTransaction::DoSpdyReadHeaders() { 1170 next_state_ = STATE_SPDY_READ_HEADERS_COMPLETE; 1171 return spdy_stream_->ReadResponseHeaders(&io_callback_); 1172 } 1173 1174 int HttpNetworkTransaction::DoSpdyReadHeadersComplete(int result) { 1175 // TODO(willchan): Flesh out the support for HTTP authentication here. 1176 if (result == OK) 1177 headers_valid_ = true; 1178 return result; 1179 } 1180 1181 int HttpNetworkTransaction::DoSpdyReadBody() { 1182 next_state_ = STATE_SPDY_READ_BODY_COMPLETE; 1183 1184 return spdy_stream_->ReadResponseBody( 1185 read_buf_, read_buf_len_, &io_callback_); 1186 } 1187 1188 int HttpNetworkTransaction::DoSpdyReadBodyComplete(int result) { 1189 read_buf_ = NULL; 1190 read_buf_len_ = 0; 1191 1192 if (result <= 0) 1193 spdy_stream_ = NULL; 1194 1195 return result; 1196 } 1197 1198 void HttpNetworkTransaction::LogTCPConnectedMetrics( 1199 const ClientSocketHandle& handle) { 1200 const base::TimeDelta time_to_obtain_connected_socket = 1201 base::TimeTicks::Now() - handle.init_time(); 1202 1203 static const bool use_late_binding_histogram = 1204 !FieldTrial::MakeName("", "SocketLateBinding").empty(); 1205 1206 if (handle.reuse_type() == ClientSocketHandle::UNUSED) { 1207 UMA_HISTOGRAM_CUSTOM_TIMES( 1208 "Net.HttpConnectionLatency", 1209 time_to_obtain_connected_socket, 1210 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10), 1211 100); 1212 } 1213 1214 UMA_HISTOGRAM_ENUMERATION("Net.TCPSocketType", handle.reuse_type(), 1215 ClientSocketHandle::NUM_TYPES); 1216 1217 if (use_late_binding_histogram) { 1218 UMA_HISTOGRAM_ENUMERATION( 1219 FieldTrial::MakeName("Net.TCPSocketType", "SocketLateBinding"), 1220 handle.reuse_type(), ClientSocketHandle::NUM_TYPES); 1221 } 1222 1223 UMA_HISTOGRAM_CLIPPED_TIMES( 1224 "Net.TransportSocketRequestTime", 1225 time_to_obtain_connected_socket, 1226 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10), 1227 100); 1228 1229 if (use_late_binding_histogram) { 1230 UMA_HISTOGRAM_CUSTOM_TIMES( 1231 FieldTrial::MakeName("Net.TransportSocketRequestTime", 1232 "SocketLateBinding").data(), 1233 time_to_obtain_connected_socket, 1234 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10), 1235 100); 1236 } 1237 1238 switch (handle.reuse_type()) { 1239 case ClientSocketHandle::UNUSED: 1240 break; 1241 case ClientSocketHandle::UNUSED_IDLE: 1242 UMA_HISTOGRAM_CUSTOM_TIMES( 1243 "Net.SocketIdleTimeBeforeNextUse_UnusedSocket", 1244 handle.idle_time(), base::TimeDelta::FromMilliseconds(1), 1245 base::TimeDelta::FromMinutes(6), 100); 1246 if (use_late_binding_histogram) { 1247 UMA_HISTOGRAM_CUSTOM_TIMES( 1248 FieldTrial::MakeName("Net.SocketIdleTimeBeforeNextUse_UnusedSocket", 1249 "SocketLateBinding").data(), 1250 handle.idle_time(), base::TimeDelta::FromMilliseconds(1), 1251 base::TimeDelta::FromMinutes(6), 100); 1252 } 1253 break; 1254 case ClientSocketHandle::REUSED_IDLE: 1255 UMA_HISTOGRAM_CUSTOM_TIMES( 1256 "Net.SocketIdleTimeBeforeNextUse_ReusedSocket", 1257 handle.idle_time(), base::TimeDelta::FromMilliseconds(1), 1258 base::TimeDelta::FromMinutes(6), 100); 1259 if (use_late_binding_histogram) { 1260 UMA_HISTOGRAM_CUSTOM_TIMES( 1261 FieldTrial::MakeName("Net.SocketIdleTimeBeforeNextUse_ReusedSocket", 1262 "SocketLateBinding").data(), 1263 handle.idle_time(), base::TimeDelta::FromMilliseconds(1), 1264 base::TimeDelta::FromMinutes(6), 100); 1265 } 1266 break; 1267 default: 1268 NOTREACHED(); 1269 break; 1270 } 1271 } 1272 1273 void HttpNetworkTransaction::LogIOErrorMetrics( 1274 const ClientSocketHandle& handle) { 1275 static const bool use_late_binding_histogram = 1276 !FieldTrial::MakeName("", "SocketLateBinding").empty(); 1277 1278 UMA_HISTOGRAM_ENUMERATION("Net.IOError_SocketReuseType", 1279 handle.reuse_type(), ClientSocketHandle::NUM_TYPES); 1280 1281 if (use_late_binding_histogram) { 1282 UMA_HISTOGRAM_ENUMERATION( 1283 FieldTrial::MakeName("Net.IOError_SocketReuseType", 1284 "SocketLateBinding"), 1285 handle.reuse_type(), ClientSocketHandle::NUM_TYPES); 1286 } 1287 1288 switch (handle.reuse_type()) { 1289 case ClientSocketHandle::UNUSED: 1290 break; 1291 case ClientSocketHandle::UNUSED_IDLE: 1292 UMA_HISTOGRAM_CUSTOM_TIMES( 1293 "Net.SocketIdleTimeOnIOError2_UnusedSocket", 1294 handle.idle_time(), base::TimeDelta::FromMilliseconds(1), 1295 base::TimeDelta::FromMinutes(6), 100); 1296 if (use_late_binding_histogram) { 1297 UMA_HISTOGRAM_CUSTOM_TIMES( 1298 FieldTrial::MakeName("Net.SocketIdleTimeOnIOError2_UnusedSocket", 1299 "SocketLateBinding").data(), 1300 handle.idle_time(), base::TimeDelta::FromMilliseconds(1), 1301 base::TimeDelta::FromMinutes(6), 100); 1302 } 1303 break; 1304 case ClientSocketHandle::REUSED_IDLE: 1305 UMA_HISTOGRAM_CUSTOM_TIMES( 1306 "Net.SocketIdleTimeOnIOError2_ReusedSocket", 1307 handle.idle_time(), base::TimeDelta::FromMilliseconds(1), 1308 base::TimeDelta::FromMinutes(6), 100); 1309 if (use_late_binding_histogram) { 1310 UMA_HISTOGRAM_CUSTOM_TIMES( 1311 FieldTrial::MakeName("Net.SocketIdleTimeOnIOError2_ReusedSocket", 1312 "SocketLateBinding").data(), 1313 handle.idle_time(), base::TimeDelta::FromMilliseconds(1), 1314 base::TimeDelta::FromMinutes(6), 100); 1315 } 1316 break; 1317 default: 1318 NOTREACHED(); 1319 break; 1320 } 1321 } 1322 1323 void HttpNetworkTransaction::LogTransactionConnectedMetrics() const { 1324 base::TimeDelta total_duration = response_.response_time - start_time_; 1325 1326 UMA_HISTOGRAM_CLIPPED_TIMES( 1327 "Net.Transaction_Connected_Under_10", 1328 total_duration, 1329 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10), 1330 100); 1331 1332 static const bool use_late_binding_histogram = 1333 !FieldTrial::MakeName("", "SocketLateBinding").empty(); 1334 1335 if (use_late_binding_histogram) { 1336 UMA_HISTOGRAM_CUSTOM_TIMES( 1337 FieldTrial::MakeName("Net.Transaction_Connected_Under_10", 1338 "SocketLateBinding").data(), 1339 total_duration, 1340 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10), 1341 100); 1342 } 1343 1344 if (!reused_socket_) { 1345 UMA_HISTOGRAM_CLIPPED_TIMES( 1346 "Net.Transaction_Connected_New", 1347 total_duration, 1348 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10), 1349 100); 1350 } 1351 1352 // Currently, non-zero priority requests are frame or sub-frame resource 1353 // types. This will change when we also prioritize certain subresources like 1354 // css, js, etc. 1355 if (request_->priority) { 1356 UMA_HISTOGRAM_CLIPPED_TIMES( 1357 "Net.Priority_High_Latency", 1358 total_duration, 1359 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10), 1360 100); 1361 } else { 1362 UMA_HISTOGRAM_CLIPPED_TIMES( 1363 "Net.Priority_Low_Latency", 1364 total_duration, 1365 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10), 1366 100); 1367 } 1368 } 1369 1370 void HttpNetworkTransaction::LogTransactionMetrics() const { 1371 base::TimeDelta duration = base::Time::Now() - 1372 response_.request_time; 1373 if (60 < duration.InMinutes()) 1374 return; 1375 1376 base::TimeDelta total_duration = base::Time::Now() - start_time_; 1377 1378 UMA_HISTOGRAM_LONG_TIMES("Net.Transaction_Latency", duration); 1379 UMA_HISTOGRAM_CLIPPED_TIMES("Net.Transaction_Latency_Under_10", duration, 1380 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(10), 1381 100); 1382 UMA_HISTOGRAM_CLIPPED_TIMES("Net.Transaction_Latency_Total_Under_10", 1383 total_duration, base::TimeDelta::FromMilliseconds(1), 1384 base::TimeDelta::FromMinutes(10), 100); 1385 if (!reused_socket_) { 1386 UMA_HISTOGRAM_CLIPPED_TIMES( 1387 "Net.Transaction_Latency_Total_New_Connection_Under_10", 1388 total_duration, base::TimeDelta::FromMilliseconds(1), 1389 base::TimeDelta::FromMinutes(10), 100); 1390 } 1391 } 1392 1393 void HttpNetworkTransaction::LogBlockedTunnelResponse( 1394 int response_code) const { 1395 LOG(WARNING) << "Blocked proxy response with status " << response_code 1396 << " to CONNECT request for " 1397 << GetHostAndPort(request_->url) << "."; 1398 } 1399 1400 int HttpNetworkTransaction::HandleCertificateError(int error) { 1401 DCHECK(using_ssl_); 1402 1403 const int kCertFlags = LOAD_IGNORE_CERT_COMMON_NAME_INVALID | 1404 LOAD_IGNORE_CERT_DATE_INVALID | 1405 LOAD_IGNORE_CERT_AUTHORITY_INVALID | 1406 LOAD_IGNORE_CERT_WRONG_USAGE; 1407 if (request_->load_flags & kCertFlags) { 1408 switch (error) { 1409 case ERR_CERT_COMMON_NAME_INVALID: 1410 if (request_->load_flags & LOAD_IGNORE_CERT_COMMON_NAME_INVALID) 1411 error = OK; 1412 break; 1413 case ERR_CERT_DATE_INVALID: 1414 if (request_->load_flags & LOAD_IGNORE_CERT_DATE_INVALID) 1415 error = OK; 1416 break; 1417 case ERR_CERT_AUTHORITY_INVALID: 1418 if (request_->load_flags & LOAD_IGNORE_CERT_AUTHORITY_INVALID) 1419 error = OK; 1420 break; 1421 } 1422 } 1423 1424 if (error != OK) { 1425 SSLClientSocket* ssl_socket = 1426 reinterpret_cast<SSLClientSocket*>(connection_->socket()); 1427 ssl_socket->GetSSLInfo(&response_.ssl_info); 1428 1429 // Add the bad certificate to the set of allowed certificates in the 1430 // SSL info object. This data structure will be consulted after calling 1431 // RestartIgnoringLastError(). And the user will be asked interactively 1432 // before RestartIgnoringLastError() is ever called. 1433 SSLConfig::CertAndStatus bad_cert; 1434 bad_cert.cert = response_.ssl_info.cert; 1435 bad_cert.cert_status = response_.ssl_info.cert_status; 1436 ssl_config_.allowed_bad_certs.push_back(bad_cert); 1437 } 1438 return error; 1439 } 1440 1441 int HttpNetworkTransaction::HandleCertificateRequest(int error) { 1442 // Assert that the socket did not send a client certificate. 1443 // Note: If we got a reused socket, it was created with some other 1444 // transaction's ssl_config_, so we need to disable this assertion. We can 1445 // get a certificate request on a reused socket when the server requested 1446 // renegotiation (rehandshake). 1447 // TODO(wtc): add a GetSSLParams method to SSLClientSocket so we can query 1448 // the SSL parameters it was created with and get rid of the reused_socket_ 1449 // test. 1450 DCHECK(reused_socket_ || !ssl_config_.send_client_cert); 1451 1452 response_.cert_request_info = new SSLCertRequestInfo; 1453 SSLClientSocket* ssl_socket = 1454 reinterpret_cast<SSLClientSocket*>(connection_->socket()); 1455 ssl_socket->GetSSLCertRequestInfo(response_.cert_request_info); 1456 1457 // Close the connection while the user is selecting a certificate to send 1458 // to the server. 1459 connection_->socket()->Disconnect(); 1460 connection_->Reset(); 1461 1462 // If the user selected one of the certificate in client_certs for this 1463 // server before, use it automatically. 1464 X509Certificate* client_cert = session_->ssl_client_auth_cache()-> 1465 Lookup(GetHostAndPort(request_->url)); 1466 if (client_cert) { 1467 const std::vector<scoped_refptr<X509Certificate> >& client_certs = 1468 response_.cert_request_info->client_certs; 1469 for (size_t i = 0; i < client_certs.size(); ++i) { 1470 if (client_cert->fingerprint().Equals(client_certs[i]->fingerprint())) { 1471 ssl_config_.client_cert = client_cert; 1472 ssl_config_.send_client_cert = true; 1473 next_state_ = STATE_INIT_CONNECTION; 1474 // Reset the other member variables. 1475 // Note: this is necessary only with SSL renegotiation. 1476 ResetStateForRestart(); 1477 return OK; 1478 } 1479 } 1480 } 1481 return error; 1482 } 1483 1484 int HttpNetworkTransaction::HandleSSLHandshakeError(int error) { 1485 if (ssl_config_.send_client_cert && 1486 (error == ERR_SSL_PROTOCOL_ERROR || 1487 error == ERR_BAD_SSL_CLIENT_AUTH_CERT)) { 1488 session_->ssl_client_auth_cache()->Remove(GetHostAndPort(request_->url)); 1489 } 1490 1491 switch (error) { 1492 case ERR_SSL_PROTOCOL_ERROR: 1493 case ERR_SSL_VERSION_OR_CIPHER_MISMATCH: 1494 if (ssl_config_.tls1_enabled) { 1495 // This could be a TLS-intolerant server or an SSL 3.0 server that 1496 // chose a TLS-only cipher suite. Turn off TLS 1.0 and retry. 1497 ssl_config_.tls1_enabled = false; 1498 connection_->socket()->Disconnect(); 1499 connection_->Reset(); 1500 next_state_ = STATE_INIT_CONNECTION; 1501 error = OK; 1502 } 1503 break; 1504 } 1505 return error; 1506 } 1507 1508 // This method determines whether it is safe to resend the request after an 1509 // IO error. It can only be called in response to request header or body 1510 // write errors or response header read errors. It should not be used in 1511 // other cases, such as a Connect error. 1512 int HttpNetworkTransaction::HandleIOError(int error) { 1513 switch (error) { 1514 // If we try to reuse a connection that the server is in the process of 1515 // closing, we may end up successfully writing out our request (or a 1516 // portion of our request) only to find a connection error when we try to 1517 // read from (or finish writing to) the socket. 1518 case ERR_CONNECTION_RESET: 1519 case ERR_CONNECTION_CLOSED: 1520 case ERR_CONNECTION_ABORTED: 1521 LogIOErrorMetrics(*connection_); 1522 if (ShouldResendRequest(error)) { 1523 ResetConnectionAndRequestForResend(); 1524 error = OK; 1525 } 1526 break; 1527 } 1528 return error; 1529 } 1530 1531 void HttpNetworkTransaction::ResetStateForRestart() { 1532 pending_auth_target_ = HttpAuth::AUTH_NONE; 1533 read_buf_ = NULL; 1534 read_buf_len_ = 0; 1535 http_stream_.reset(); 1536 headers_valid_ = false; 1537 request_headers_.clear(); 1538 response_ = HttpResponseInfo(); 1539 } 1540 1541 HttpResponseHeaders* HttpNetworkTransaction::GetResponseHeaders() const { 1542 return response_.headers; 1543 } 1544 1545 bool HttpNetworkTransaction::ShouldResendRequest(int error) const { 1546 // NOTE: we resend a request only if we reused a keep-alive connection. 1547 // This automatically prevents an infinite resend loop because we'll run 1548 // out of the cached keep-alive connections eventually. 1549 if (establishing_tunnel_ || 1550 !connection_->ShouldResendFailedRequest(error) || 1551 GetResponseHeaders()) { // We have received some response headers. 1552 return false; 1553 } 1554 return true; 1555 } 1556 1557 void HttpNetworkTransaction::ResetConnectionAndRequestForResend() { 1558 connection_->socket()->Disconnect(); 1559 connection_->Reset(); 1560 // We need to clear request_headers_ because it contains the real request 1561 // headers, but we may need to resend the CONNECT request first to recreate 1562 // the SSL tunnel. 1563 request_headers_.clear(); 1564 next_state_ = STATE_INIT_CONNECTION; // Resend the request. 1565 } 1566 1567 int HttpNetworkTransaction::ReconsiderProxyAfterError(int error) { 1568 DCHECK(!pac_request_); 1569 1570 // A failure to resolve the hostname or any error related to establishing a 1571 // TCP connection could be grounds for trying a new proxy configuration. 1572 // 1573 // Why do this when a hostname cannot be resolved? Some URLs only make sense 1574 // to proxy servers. The hostname in those URLs might fail to resolve if we 1575 // are still using a non-proxy config. We need to check if a proxy config 1576 // now exists that corresponds to a proxy server that could load the URL. 1577 // 1578 switch (error) { 1579 case ERR_NAME_NOT_RESOLVED: 1580 case ERR_INTERNET_DISCONNECTED: 1581 case ERR_ADDRESS_UNREACHABLE: 1582 case ERR_CONNECTION_CLOSED: 1583 case ERR_CONNECTION_RESET: 1584 case ERR_CONNECTION_REFUSED: 1585 case ERR_CONNECTION_ABORTED: 1586 case ERR_TIMED_OUT: 1587 case ERR_TUNNEL_CONNECTION_FAILED: 1588 break; 1589 default: 1590 return error; 1591 } 1592 1593 if (request_->load_flags & LOAD_BYPASS_PROXY) { 1594 return error; 1595 } 1596 1597 int rv = session_->proxy_service()->ReconsiderProxyAfterError( 1598 request_->url, &proxy_info_, &io_callback_, &pac_request_, load_log_); 1599 if (rv == OK || rv == ERR_IO_PENDING) { 1600 // If the error was during connection setup, there is no socket to 1601 // disconnect. 1602 if (connection_->socket()) 1603 connection_->socket()->Disconnect(); 1604 connection_->Reset(); 1605 next_state_ = STATE_RESOLVE_PROXY_COMPLETE; 1606 } else { 1607 // If ReconsiderProxyAfterError() failed synchronously, it means 1608 // there was nothing left to fall-back to, so fail the transaction 1609 // with the last connection error we got. 1610 // TODO(eroman): This is a confusing contract, make it more obvious. 1611 rv = error; 1612 } 1613 1614 return rv; 1615 } 1616 1617 bool HttpNetworkTransaction::ShouldApplyProxyAuth() const { 1618 return (proxy_mode_ == kHTTPProxy) || establishing_tunnel_; 1619 } 1620 1621 bool HttpNetworkTransaction::ShouldApplyServerAuth() const { 1622 return !establishing_tunnel_ && 1623 !(request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA); 1624 } 1625 1626 std::string HttpNetworkTransaction::BuildAuthorizationHeader( 1627 HttpAuth::Target target) const { 1628 DCHECK(HaveAuth(target)); 1629 1630 // Add a Authorization/Proxy-Authorization header line. 1631 std::string credentials = auth_handler_[target]->GenerateCredentials( 1632 auth_identity_[target].username, 1633 auth_identity_[target].password, 1634 request_, 1635 &proxy_info_); 1636 1637 return HttpAuth::GetAuthorizationHeaderName(target) + 1638 ": " + credentials + "\r\n"; 1639 } 1640 1641 GURL HttpNetworkTransaction::AuthOrigin(HttpAuth::Target target) const { 1642 return target == HttpAuth::AUTH_PROXY ? 1643 GURL("http://" + proxy_info_.proxy_server().host_and_port()) : 1644 request_->url.GetOrigin(); 1645 } 1646 1647 std::string HttpNetworkTransaction::AuthPath(HttpAuth::Target target) 1648 const { 1649 // Proxy authentication realms apply to all paths. So we will use 1650 // empty string in place of an absolute path. 1651 return target == HttpAuth::AUTH_PROXY ? 1652 std::string() : request_->url.path(); 1653 } 1654 1655 // static 1656 std::string HttpNetworkTransaction::AuthTargetString( 1657 HttpAuth::Target target) { 1658 return target == HttpAuth::AUTH_PROXY ? "proxy" : "server"; 1659 } 1660 1661 void HttpNetworkTransaction::InvalidateRejectedAuthFromCache( 1662 HttpAuth::Target target, 1663 const GURL& auth_origin) { 1664 DCHECK(HaveAuth(target)); 1665 1666 // TODO(eroman): this short-circuit can be relaxed. If the realm of 1667 // the preemptively used auth entry matches the realm of the subsequent 1668 // challenge, then we can invalidate the preemptively used entry. 1669 // Otherwise as-is we may send the failed credentials one extra time. 1670 if (auth_identity_[target].source == HttpAuth::IDENT_SRC_PATH_LOOKUP) 1671 return; 1672 1673 // Clear the cache entry for the identity we just failed on. 1674 // Note: we require the username/password to match before invalidating 1675 // since the entry in the cache may be newer than what we used last time. 1676 session_->auth_cache()->Remove(auth_origin, 1677 auth_handler_[target]->realm(), 1678 auth_identity_[target].username, 1679 auth_identity_[target].password); 1680 } 1681 1682 bool HttpNetworkTransaction::SelectPreemptiveAuth(HttpAuth::Target target) { 1683 DCHECK(!HaveAuth(target)); 1684 1685 // Don't do preemptive authorization if the URL contains a username/password, 1686 // since we must first be challenged in order to use the URL's identity. 1687 if (request_->url.has_username()) 1688 return false; 1689 1690 // SelectPreemptiveAuth() is on the critical path for each request, so it 1691 // is expected to be fast. LookupByPath() is fast in the common case, since 1692 // the number of http auth cache entries is expected to be very small. 1693 // (For most users in fact, it will be 0.) 1694 1695 HttpAuthCache::Entry* entry = session_->auth_cache()->LookupByPath( 1696 AuthOrigin(target), AuthPath(target)); 1697 1698 // We don't support preemptive authentication for connection-based 1699 // authentication schemes because they can't reuse entry->handler(). 1700 // Hopefully we can remove this limitation in the future. 1701 if (entry && !entry->handler()->is_connection_based()) { 1702 auth_identity_[target].source = HttpAuth::IDENT_SRC_PATH_LOOKUP; 1703 auth_identity_[target].invalid = false; 1704 auth_identity_[target].username = entry->username(); 1705 auth_identity_[target].password = entry->password(); 1706 auth_handler_[target] = entry->handler(); 1707 return true; 1708 } 1709 return false; 1710 } 1711 1712 bool HttpNetworkTransaction::SelectNextAuthIdentityToTry( 1713 HttpAuth::Target target, 1714 const GURL& auth_origin) { 1715 DCHECK(auth_handler_[target]); 1716 DCHECK(auth_identity_[target].invalid); 1717 1718 // Try to use the username/password encoded into the URL first. 1719 if (target == HttpAuth::AUTH_SERVER && request_->url.has_username() && 1720 !embedded_identity_used_) { 1721 auth_identity_[target].source = HttpAuth::IDENT_SRC_URL; 1722 auth_identity_[target].invalid = false; 1723 // Extract the username:password from the URL. 1724 GetIdentityFromURL(request_->url, 1725 &auth_identity_[target].username, 1726 &auth_identity_[target].password); 1727 embedded_identity_used_ = true; 1728 // TODO(eroman): If the password is blank, should we also try combining 1729 // with a password from the cache? 1730 return true; 1731 } 1732 1733 // Check the auth cache for a realm entry. 1734 HttpAuthCache::Entry* entry = session_->auth_cache()->LookupByRealm( 1735 auth_origin, auth_handler_[target]->realm()); 1736 1737 if (entry) { 1738 // Disallow re-using of identity if the scheme of the originating challenge 1739 // does not match. This protects against the following situation: 1740 // 1. Browser prompts user to sign into DIGEST realm="Foo". 1741 // 2. Since the auth-scheme is not BASIC, the user is reasured that it 1742 // will not be sent over the wire in clear text. So they use their 1743 // most trusted password. 1744 // 3. Next, the browser receives a challenge for BASIC realm="Foo". This 1745 // is the same realm that we have a cached identity for. However if 1746 // we use that identity, it would get sent over the wire in 1747 // clear text (which isn't what the user agreed to when entering it). 1748 if (entry->handler()->scheme() != auth_handler_[target]->scheme()) { 1749 LOG(WARNING) << "The scheme of realm " << auth_handler_[target]->realm() 1750 << " has changed from " << entry->handler()->scheme() 1751 << " to " << auth_handler_[target]->scheme(); 1752 return false; 1753 } 1754 1755 auth_identity_[target].source = HttpAuth::IDENT_SRC_REALM_LOOKUP; 1756 auth_identity_[target].invalid = false; 1757 auth_identity_[target].username = entry->username(); 1758 auth_identity_[target].password = entry->password(); 1759 return true; 1760 } 1761 return false; 1762 } 1763 1764 std::string HttpNetworkTransaction::AuthChallengeLogMessage() const { 1765 std::string msg; 1766 std::string header_val; 1767 void* iter = NULL; 1768 scoped_refptr<HttpResponseHeaders> headers = GetResponseHeaders(); 1769 while (headers->EnumerateHeader(&iter, "proxy-authenticate", &header_val)) { 1770 msg.append("\n Has header Proxy-Authenticate: "); 1771 msg.append(header_val); 1772 } 1773 1774 iter = NULL; 1775 while (headers->EnumerateHeader(&iter, "www-authenticate", &header_val)) { 1776 msg.append("\n Has header WWW-Authenticate: "); 1777 msg.append(header_val); 1778 } 1779 1780 // RFC 4559 requires that a proxy indicate its support of NTLM/Negotiate 1781 // authentication with a "Proxy-Support: Session-Based-Authentication" 1782 // response header. 1783 iter = NULL; 1784 while (headers->EnumerateHeader(&iter, "proxy-support", &header_val)) { 1785 msg.append("\n Has header Proxy-Support: "); 1786 msg.append(header_val); 1787 } 1788 1789 return msg; 1790 } 1791 1792 int HttpNetworkTransaction::HandleAuthChallenge() { 1793 scoped_refptr<HttpResponseHeaders> headers = GetResponseHeaders(); 1794 DCHECK(headers); 1795 1796 int status = headers->response_code(); 1797 if (status != 401 && status != 407) 1798 return OK; 1799 HttpAuth::Target target = status == 407 ? 1800 HttpAuth::AUTH_PROXY : HttpAuth::AUTH_SERVER; 1801 GURL auth_origin = AuthOrigin(target); 1802 1803 LOG(INFO) << "The " << AuthTargetString(target) << " " 1804 << auth_origin << " requested auth" 1805 << AuthChallengeLogMessage(); 1806 1807 if (target == HttpAuth::AUTH_PROXY && proxy_info_.is_direct()) 1808 return ERR_UNEXPECTED_PROXY_AUTH; 1809 1810 // The auth we tried just failed, hence it can't be valid. Remove it from 1811 // the cache so it won't be used again. 1812 // TODO(wtc): IsFinalRound is not the right condition. In a multi-round 1813 // auth sequence, the server may fail the auth in round 1 if our first 1814 // authorization header is broken. We should inspect response_.headers to 1815 // determine if the server already failed the auth or wants us to continue. 1816 // See http://crbug.com/21015. 1817 if (HaveAuth(target) && auth_handler_[target]->IsFinalRound()) { 1818 InvalidateRejectedAuthFromCache(target, auth_origin); 1819 auth_handler_[target] = NULL; 1820 auth_identity_[target] = HttpAuth::Identity(); 1821 } 1822 1823 auth_identity_[target].invalid = true; 1824 1825 if (target != HttpAuth::AUTH_SERVER || 1826 !(request_->load_flags & LOAD_DO_NOT_SEND_AUTH_DATA)) { 1827 // Find the best authentication challenge that we support. 1828 HttpAuth::ChooseBestChallenge(headers, target, auth_origin, 1829 &auth_handler_[target]); 1830 } 1831 1832 if (!auth_handler_[target]) { 1833 if (establishing_tunnel_) { 1834 LOG(ERROR) << "Can't perform auth to the " << AuthTargetString(target) 1835 << " " << auth_origin << " when establishing a tunnel" 1836 << AuthChallengeLogMessage(); 1837 1838 // We are establishing a tunnel, we can't show the error page because an 1839 // active network attacker could control its contents. Instead, we just 1840 // fail to establish the tunnel. 1841 DCHECK(target == HttpAuth::AUTH_PROXY); 1842 return ERR_PROXY_AUTH_REQUESTED; 1843 } 1844 // We found no supported challenge -- let the transaction continue 1845 // so we end up displaying the error page. 1846 return OK; 1847 } 1848 1849 if (auth_handler_[target]->NeedsIdentity()) { 1850 // Pick a new auth identity to try, by looking to the URL and auth cache. 1851 // If an identity to try is found, it is saved to auth_identity_[target]. 1852 SelectNextAuthIdentityToTry(target, auth_origin); 1853 } else { 1854 // Proceed with the existing identity or a null identity. 1855 // 1856 // TODO(wtc): Add a safeguard against infinite transaction restarts, if 1857 // the server keeps returning "NTLM". 1858 auth_identity_[target].invalid = false; 1859 } 1860 1861 // Make a note that we are waiting for auth. This variable is inspected 1862 // when the client calls RestartWithAuth() to pick up where we left off. 1863 pending_auth_target_ = target; 1864 1865 if (auth_identity_[target].invalid) { 1866 // We have exhausted all identity possibilities, all we can do now is 1867 // pass the challenge information back to the client. 1868 PopulateAuthChallenge(target, auth_origin); 1869 } 1870 return OK; 1871 } 1872 1873 void HttpNetworkTransaction::PopulateAuthChallenge(HttpAuth::Target target, 1874 const GURL& auth_origin) { 1875 // Populates response_.auth_challenge with the authentication challenge info. 1876 // This info is consumed by URLRequestHttpJob::GetAuthChallengeInfo(). 1877 1878 AuthChallengeInfo* auth_info = new AuthChallengeInfo; 1879 auth_info->is_proxy = target == HttpAuth::AUTH_PROXY; 1880 auth_info->host_and_port = ASCIIToWide(GetHostAndPort(auth_origin)); 1881 auth_info->scheme = ASCIIToWide(auth_handler_[target]->scheme()); 1882 // TODO(eroman): decode realm according to RFC 2047. 1883 auth_info->realm = ASCIIToWide(auth_handler_[target]->realm()); 1884 response_.auth_challenge = auth_info; 1885 } 1886 1887 } // namespace net 1888