Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/proxy/proxy_service.h" | 5 #include "net/proxy/proxy_service.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 151 DCHECK(!was_cancelled()); | 151 DCHECK(!was_cancelled()); |
| 152 | 152 |
| 153 // Make a note in the results which configuration was in use at the | 153 // Make a note in the results which configuration was in use at the |
| 154 // time of the resolve. | 154 // time of the resolve. |
| 155 results_->config_id_ = config_id_; | 155 results_->config_id_ = config_id_; |
| 156 | 156 |
| 157 // Reset the state associated with in-progress-resolve. | 157 // Reset the state associated with in-progress-resolve. |
| 158 resolve_job_ = NULL; | 158 resolve_job_ = NULL; |
| 159 config_id_ = ProxyConfig::INVALID_ID; | 159 config_id_ = ProxyConfig::INVALID_ID; |
| 160 | 160 |
| 161 // Notify the service of the completion. | |
| 162 service_->DidCompletePacRequest(results_->config_id_, result_code); | |
| 163 | |
| 164 // Clean up the results list. | 161 // Clean up the results list. |
| 165 if (result_code == OK) | 162 if (result_code == OK) |
| 166 results_->RemoveBadProxies(service_->proxy_retry_info_); | 163 results_->RemoveBadProxies(service_->proxy_retry_info_); |
| 167 | 164 |
| 168 LoadLog::EndEvent(load_log_, LoadLog::TYPE_PROXY_SERVICE); | 165 LoadLog::EndEvent(load_log_, LoadLog::TYPE_PROXY_SERVICE); |
| 169 | 166 |
| 170 return result_code; | 167 return result_code; |
| 171 } | 168 } |
| 172 | 169 |
| 173 LoadLog* load_log() const { return load_log_; } | 170 LoadLog* load_log() const { return load_log_; } |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 204 scoped_refptr<LoadLog> load_log_; | 201 scoped_refptr<LoadLog> load_log_; |
| 205 }; | 202 }; |
| 206 | 203 |
| 207 // ProxyService --------------------------------------------------------------- | 204 // ProxyService --------------------------------------------------------------- |
| 208 | 205 |
| 209 ProxyService::ProxyService(ProxyConfigService* config_service, | 206 ProxyService::ProxyService(ProxyConfigService* config_service, |
| 210 ProxyResolver* resolver) | 207 ProxyResolver* resolver) |
| 211 : config_service_(config_service), | 208 : config_service_(config_service), |
| 212 resolver_(resolver), | 209 resolver_(resolver), |
| 213 next_config_id_(1), | 210 next_config_id_(1), |
| 214 config_is_bad_(false), | |
| 215 should_use_proxy_resolver_(false), | 211 should_use_proxy_resolver_(false), |
| 216 ALLOW_THIS_IN_INITIALIZER_LIST(init_proxy_resolver_callback_( | 212 ALLOW_THIS_IN_INITIALIZER_LIST(init_proxy_resolver_callback_( |
| 217 this, &ProxyService::OnInitProxyResolverComplete)) { | 213 this, &ProxyService::OnInitProxyResolverComplete)) { |
| 218 } | 214 } |
| 219 | 215 |
| 220 // static | 216 // static |
| 221 ProxyService* ProxyService::Create( | 217 ProxyService* ProxyService::Create( |
| 222 ProxyConfigService* proxy_config_service, | 218 ProxyConfigService* proxy_config_service, |
| 223 bool use_v8_resolver, | 219 bool use_v8_resolver, |
| 224 URLRequestContext* url_request_context, | 220 URLRequestContext* url_request_context, |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 311 *pac_request = req.get(); | 307 *pac_request = req.get(); |
| 312 return rv; // ERR_IO_PENDING | 308 return rv; // ERR_IO_PENDING |
| 313 } | 309 } |
| 314 | 310 |
| 315 int ProxyService::TryToCompleteSynchronously(const GURL& url, | 311 int ProxyService::TryToCompleteSynchronously(const GURL& url, |
| 316 ProxyInfo* result) { | 312 ProxyInfo* result) { |
| 317 result->config_id_ = config_.id(); | 313 result->config_id_ = config_.id(); |
| 318 | 314 |
| 319 DCHECK(config_.id() != ProxyConfig::INVALID_ID); | 315 DCHECK(config_.id() != ProxyConfig::INVALID_ID); |
| 320 | 316 |
| 321 // Fallback to a "direct" (no proxy) connection if the current configuration | 317 if (should_use_proxy_resolver_ || IsInitializingProxyResolver()) { |
| 322 // is known to be bad. | 318 // May need to go through ProxyResolver for this. |
| 323 if (config_is_bad_) { | 319 return ERR_IO_PENDING; |
| 324 // Reset this flag to false in case the ProxyInfo object is being | 320 } |
| 325 // re-used by the caller. | |
| 326 result->config_was_tried_ = false; | |
| 327 } else { | |
| 328 // Remember that we are trying to use the current proxy configuration. | |
| 329 result->config_was_tried_ = true; | |
| 330 | 321 |
| 331 if (should_use_proxy_resolver_ || IsInitializingProxyResolver()) { | 322 if (!config_.proxy_rules.empty()) { |
| 332 // May need to go through ProxyResolver for this. | 323 ApplyProxyRules(url, config_.proxy_rules, result); |
| 333 return ERR_IO_PENDING; | 324 return OK; |
| 334 } | |
| 335 | |
| 336 if (!config_.proxy_rules.empty()) { | |
| 337 ApplyProxyRules(url, config_.proxy_rules, result); | |
| 338 return OK; | |
| 339 } | |
| 340 } | 325 } |
| 341 | 326 |
| 342 // otherwise, we have no proxy config | 327 // otherwise, we have no proxy config |
| 343 result->UseDirect(); | 328 result->UseDirect(); |
| 344 return OK; | 329 return OK; |
| 345 } | 330 } |
| 346 | 331 |
| 347 void ProxyService::ApplyProxyRules(const GURL& url, | 332 void ProxyService::ApplyProxyRules(const GURL& url, |
| 348 const ProxyConfig::ProxyRules& proxy_rules, | 333 const ProxyConfig::ProxyRules& proxy_rules, |
| 349 ProxyInfo* result) { | 334 ProxyInfo* result) { |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 448 // Check to see if we have a new config since ResolveProxy was called. We | 433 // Check to see if we have a new config since ResolveProxy was called. We |
| 449 // want to re-run ResolveProxy in two cases: 1) we have a new config, or 2) a | 434 // want to re-run ResolveProxy in two cases: 1) we have a new config, or 2) a |
| 450 // direct connection failed and we never tried the current config. | 435 // direct connection failed and we never tried the current config. |
| 451 | 436 |
| 452 bool re_resolve = result->config_id_ != config_.id(); | 437 bool re_resolve = result->config_id_ != config_.id(); |
| 453 if (!re_resolve) { | 438 if (!re_resolve) { |
| 454 UpdateConfig(load_log); | 439 UpdateConfig(load_log); |
| 455 if (result->config_id_ != config_.id()) { | 440 if (result->config_id_ != config_.id()) { |
| 456 // A new configuration! | 441 // A new configuration! |
| 457 re_resolve = true; | 442 re_resolve = true; |
| 458 } else if (!result->config_was_tried_) { | |
| 459 // We never tried the proxy configuration since we thought it was bad, | |
| 460 // but because we failed to establish a connection, let's try the proxy | |
| 461 // configuration again to see if it will work now. | |
| 462 config_is_bad_ = false; | |
| 463 re_resolve = true; | |
| 464 } | 443 } |
| 465 } | 444 } |
| 466 if (re_resolve) { | 445 if (re_resolve) { |
| 467 // If we have a new config or the config was never tried, we delete the | 446 // If we have a new config or the config was never tried, we delete the |
| 468 // list of bad proxies and we try again. | 447 // list of bad proxies and we try again. |
| 469 proxy_retry_info_.clear(); | 448 proxy_retry_info_.clear(); |
| 470 return ResolveProxy(url, result, callback, pac_request, load_log); | 449 return ResolveProxy(url, result, callback, pac_request, load_log); |
| 471 } | 450 } |
| 472 | 451 |
| 473 // We don't have new proxy settings to try, fallback to the next proxy | 452 // We don't have new proxy settings to try, try to fallback to the next proxy |
| 474 // in the list. | 453 // in the list. |
| 475 bool was_direct = result->is_direct(); | 454 bool did_fallback = result->Fallback(&proxy_retry_info_); |
| 476 if (!was_direct && result->Fallback(&proxy_retry_info_)) | |
| 477 return OK; | |
| 478 | 455 |
| 479 // TODO(eroman): Hmm, this doesn't seem right. For starters just because | 456 // Return synchronous failure if there is nothing left to fall-back to. |
| 480 // auto_detect is true doesn't mean we are actually using it. | 457 // TODO(eroman): This is a yucky API, clean it up. |
| 481 if (!config_.auto_detect && !config_.proxy_rules.empty()) { | 458 return did_fallback ? OK : ERR_FAILED; |
|
wtc
2010/01/07 20:12:27
I wonder if this ERR_FAILED error code may leak th
eroman
2010/01/07 21:08:19
This shouldn't leak since HttpNetworkTransaction c
wtc
2010/01/07 21:22:09
I see. Now I think an async failure (with ERR_FAI
wtc
2010/01/07 21:53:56
eroman went though the async failure case with me,
| |
| 482 // If auto detect is on, then we should try a DIRECT connection | |
| 483 // as the attempt to reach the proxy failed. | |
| 484 return ERR_FAILED; | |
| 485 } | |
| 486 | |
| 487 // If we already tried a direct connection, then just give up. | |
| 488 if (was_direct) | |
| 489 return ERR_FAILED; | |
| 490 | |
| 491 // Try going direct. | |
| 492 result->UseDirect(); | |
| 493 return OK; | |
| 494 } | 459 } |
| 495 | 460 |
| 496 void ProxyService::CancelPacRequest(PacRequest* req) { | 461 void ProxyService::CancelPacRequest(PacRequest* req) { |
| 497 DCHECK(req); | 462 DCHECK(req); |
| 498 req->Cancel(); | 463 req->Cancel(); |
| 499 RemovePendingRequest(req); | 464 RemovePendingRequest(req); |
| 500 } | 465 } |
| 501 | 466 |
| 502 bool ProxyService::ContainsPendingRequest(PacRequest* req) { | 467 bool ProxyService::ContainsPendingRequest(PacRequest* req) { |
| 503 PendingRequests::iterator it = std::find( | 468 PendingRequests::iterator it = std::find( |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 537 ProxyConfigService* new_proxy_config_service) { | 502 ProxyConfigService* new_proxy_config_service) { |
| 538 config_service_.reset(new_proxy_config_service); | 503 config_service_.reset(new_proxy_config_service); |
| 539 UpdateConfig(NULL); | 504 UpdateConfig(NULL); |
| 540 } | 505 } |
| 541 | 506 |
| 542 void ProxyService::PurgeMemory() { | 507 void ProxyService::PurgeMemory() { |
| 543 if (resolver_.get()) | 508 if (resolver_.get()) |
| 544 resolver_->PurgeMemory(); | 509 resolver_->PurgeMemory(); |
| 545 } | 510 } |
| 546 | 511 |
| 547 void ProxyService::DidCompletePacRequest(int config_id, int result_code) { | |
| 548 // If we get an error that indicates a bad PAC config, then we should | |
| 549 // remember that, and not try the PAC config again for a while. | |
| 550 | |
| 551 // Our config may have already changed. | |
| 552 if (result_code == OK || config_id != config_.id()) | |
| 553 return; | |
| 554 | |
| 555 // Remember that this configuration doesn't work. | |
| 556 config_is_bad_ = true; | |
| 557 } | |
| 558 | |
| 559 // static | 512 // static |
| 560 ProxyConfigService* ProxyService::CreateSystemProxyConfigService( | 513 ProxyConfigService* ProxyService::CreateSystemProxyConfigService( |
| 561 MessageLoop* io_loop, MessageLoop* file_loop) { | 514 MessageLoop* io_loop, MessageLoop* file_loop) { |
| 562 #if defined(OS_WIN) | 515 #if defined(OS_WIN) |
| 563 return new ProxyConfigServiceWin(); | 516 return new ProxyConfigServiceWin(); |
| 564 #elif defined(OS_MACOSX) | 517 #elif defined(OS_MACOSX) |
| 565 return new ProxyConfigServiceMac(); | 518 return new ProxyConfigServiceMac(); |
| 566 #elif defined(OS_LINUX) | 519 #elif defined(OS_LINUX) |
| 567 ProxyConfigServiceLinux* linux_config_service | 520 ProxyConfigServiceLinux* linux_config_service |
| 568 = new ProxyConfigServiceLinux(); | 521 = new ProxyConfigServiceLinux(); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 631 SetConfig(latest); | 584 SetConfig(latest); |
| 632 } | 585 } |
| 633 | 586 |
| 634 void ProxyService::SetConfig(const ProxyConfig& config) { | 587 void ProxyService::SetConfig(const ProxyConfig& config) { |
| 635 config_ = config; | 588 config_ = config; |
| 636 | 589 |
| 637 // Increment the ID to reflect that the config has changed. | 590 // Increment the ID to reflect that the config has changed. |
| 638 config_.set_id(next_config_id_++); | 591 config_.set_id(next_config_id_++); |
| 639 | 592 |
| 640 // Reset state associated with latest config. | 593 // Reset state associated with latest config. |
| 641 config_is_bad_ = false; | |
| 642 proxy_retry_info_.clear(); | 594 proxy_retry_info_.clear(); |
| 643 | 595 |
| 644 // Cancel any PAC fetching / ProxyResolver::SetPacScript() which was | 596 // Cancel any PAC fetching / ProxyResolver::SetPacScript() which was |
| 645 // in progress for the previous configuration. | 597 // in progress for the previous configuration. |
| 646 init_proxy_resolver_.reset(); | 598 init_proxy_resolver_.reset(); |
| 647 should_use_proxy_resolver_ = false; | 599 should_use_proxy_resolver_ = false; |
| 648 | 600 |
| 649 // Start downloading + testing the PAC scripts for this new configuration. | 601 // Start downloading + testing the PAC scripts for this new configuration. |
| 650 if (config_.MayRequirePACResolver()) { | 602 if (config_.MayRequirePACResolver()) { |
| 651 // Since InitProxyResolver will be playing around with the proxy resolver | 603 // Since InitProxyResolver will be playing around with the proxy resolver |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 827 OnCompletion(result_); | 779 OnCompletion(result_); |
| 828 } | 780 } |
| 829 } | 781 } |
| 830 | 782 |
| 831 void SyncProxyServiceHelper::OnCompletion(int rv) { | 783 void SyncProxyServiceHelper::OnCompletion(int rv) { |
| 832 result_ = rv; | 784 result_ = rv; |
| 833 event_.Signal(); | 785 event_.Signal(); |
| 834 } | 786 } |
| 835 | 787 |
| 836 } // namespace net | 788 } // namespace net |
| OLD | NEW |