• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Chromium Authors
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/proxy_fallback.h"
6 
7 #include "net/base/net_errors.h"
8 #include "net/base/proxy_server.h"
9 
10 namespace net {
11 
CanFalloverToNextProxy(const ProxyServer & proxy,int error,int * final_error)12 NET_EXPORT bool CanFalloverToNextProxy(const ProxyServer& proxy,
13                                        int error,
14                                        int* final_error) {
15   *final_error = error;
16 
17   if (proxy.is_quic()) {
18     switch (error) {
19       case ERR_QUIC_PROTOCOL_ERROR:
20       case ERR_QUIC_HANDSHAKE_FAILED:
21       case ERR_MSG_TOO_BIG:
22         return true;
23     }
24   }
25 
26   // TODO(eroman): Split up these error codes across the relevant proxy types.
27   //
28   // A failure to resolve the hostname or any error related to establishing a
29   // TCP connection could be grounds for trying a new proxy configuration.
30   //
31   // Why do this when a hostname cannot be resolved?  Some URLs only make sense
32   // to proxy servers.  The hostname in those URLs might fail to resolve if we
33   // are still using a non-proxy config.  We need to check if a proxy config
34   // now exists that corresponds to a proxy server that could load the URL.
35   //
36   // A failure while establishing a tunnel to the proxy
37   // (ERR_TUNNEL_CONNECTION_FAILED) is NOT considered grounds for fallback.
38   // Other browsers similarly don't fallback, and some client's PAC
39   // configurations rely on this for some degree of content blocking.
40   // See https://crbug.com/680837 for details.
41   switch (error) {
42     case ERR_PROXY_CONNECTION_FAILED:
43     case ERR_NAME_NOT_RESOLVED:
44     case ERR_INTERNET_DISCONNECTED:
45     case ERR_ADDRESS_UNREACHABLE:
46     case ERR_CONNECTION_CLOSED:
47     case ERR_CONNECTION_TIMED_OUT:
48     case ERR_CONNECTION_RESET:
49     case ERR_CONNECTION_REFUSED:
50     case ERR_CONNECTION_ABORTED:
51     case ERR_TIMED_OUT:
52     case ERR_SOCKS_CONNECTION_FAILED:
53     // ERR_PROXY_CERTIFICATE_INVALID can happen in the case of trying to talk to
54     // a proxy using SSL, and ending up talking to a captive portal that
55     // supports SSL instead.
56     case ERR_PROXY_CERTIFICATE_INVALID:
57     // ERR_SSL_PROTOCOL_ERROR can happen when trying to talk SSL to a non-SSL
58     // server (like a captive portal).
59     case ERR_SSL_PROTOCOL_ERROR:
60       return true;
61 
62     case ERR_SOCKS_CONNECTION_HOST_UNREACHABLE:
63       // Remap the SOCKS-specific "host unreachable" error to a more
64       // generic error code (this way consumers like the link doctor
65       // know to substitute their error page).
66       //
67       // Note that if the host resolving was done by the SOCKS5 proxy, we can't
68       // differentiate between a proxy-side "host not found" versus a proxy-side
69       // "address unreachable" error, and will report both of these failures as
70       // ERR_ADDRESS_UNREACHABLE.
71       *final_error = ERR_ADDRESS_UNREACHABLE;
72       return false;
73   }
74   return false;
75 }
76 
77 }  // namespace net
78