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)12NET_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