Bug 1579049 - P1: Map Http error response codes to gecko error codes r=mayhemer,valentin

Differential Revision: https://phabricator.services.mozilla.com/D49903

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Kershaw Chang 2019-11-21 14:24:36 +00:00
Родитель c8984db985
Коммит 60f6486027
9 изменённых файлов: 207 добавлений и 92 удалений

Просмотреть файл

@ -4000,7 +4000,7 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI* aURI,
break; break;
case NS_ERROR_PROXY_CONNECTION_REFUSED: case NS_ERROR_PROXY_CONNECTION_REFUSED:
case NS_ERROR_PROXY_AUTHENTICATION_FAILED: case NS_ERROR_PROXY_AUTHENTICATION_FAILED:
case NS_ERROR_TOO_MANY_REQUESTS: case NS_ERROR_PROXY_TOO_MANY_REQUESTS:
// Proxy connection was refused. // Proxy connection was refused.
error = "proxyConnectFailure"; error = "proxyConnectFailure";
break; break;
@ -6563,7 +6563,7 @@ nsresult nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
aStatus == NS_ERROR_UNKNOWN_PROXY_HOST || aStatus == NS_ERROR_UNKNOWN_PROXY_HOST ||
aStatus == NS_ERROR_PROXY_CONNECTION_REFUSED || aStatus == NS_ERROR_PROXY_CONNECTION_REFUSED ||
aStatus == NS_ERROR_PROXY_AUTHENTICATION_FAILED || aStatus == NS_ERROR_PROXY_AUTHENTICATION_FAILED ||
aStatus == NS_ERROR_TOO_MANY_REQUESTS || aStatus == NS_ERROR_PROXY_TOO_MANY_REQUESTS ||
aStatus == NS_ERROR_BLOCKED_BY_POLICY) && aStatus == NS_ERROR_BLOCKED_BY_POLICY) &&
(isTopFrame || UseErrorPages())) { (isTopFrame || UseErrorPages())) {
DisplayLoadError(aStatus, url, nullptr, aChannel); DisplayLoadError(aStatus, url, nullptr, aChannel);

Просмотреть файл

@ -148,7 +148,7 @@ XPC_MSG_DEF(NS_ERROR_PROXY_CONNECTION_REFUSED , "The connection to the pro
XPC_MSG_DEF(NS_ERROR_PROXY_AUTHENTICATION_FAILED , "The proxy requires authentication") XPC_MSG_DEF(NS_ERROR_PROXY_AUTHENTICATION_FAILED , "The proxy requires authentication")
XPC_MSG_DEF(NS_ERROR_PROXY_BAD_GATEWAY , "The request failed on the proxy") XPC_MSG_DEF(NS_ERROR_PROXY_BAD_GATEWAY , "The request failed on the proxy")
XPC_MSG_DEF(NS_ERROR_PROXY_GATEWAY_TIMEOUT , "The request timed out on the proxy") XPC_MSG_DEF(NS_ERROR_PROXY_GATEWAY_TIMEOUT , "The request timed out on the proxy")
XPC_MSG_DEF(NS_ERROR_TOO_MANY_REQUESTS , "Sending too many requests to a proxy") XPC_MSG_DEF(NS_ERROR_PROXY_TOO_MANY_REQUESTS , "Sending too many requests to a proxy")
XPC_MSG_DEF(NS_ERROR_NET_TIMEOUT , "The connection has timed out") XPC_MSG_DEF(NS_ERROR_NET_TIMEOUT , "The connection has timed out")
XPC_MSG_DEF(NS_ERROR_OFFLINE , "The requested action could not be completed in the offline state") XPC_MSG_DEF(NS_ERROR_OFFLINE , "The requested action could not be completed in the offline state")
XPC_MSG_DEF(NS_ERROR_PORT_ACCESS_NOT_ALLOWED , "Establishing a connection to an unsafe or otherwise banned port was prohibited") XPC_MSG_DEF(NS_ERROR_PORT_ACCESS_NOT_ALLOWED , "Establishing a connection to an unsafe or otherwise banned port was prohibited")

Просмотреть файл

@ -1168,24 +1168,11 @@ void SpdyConnectTransaction::MapStreamToHttpConnection(
mTunnelStreamOut = new OutputStreamShim(this, mIsWebsocket); mTunnelStreamOut = new OutputStreamShim(this, mIsWebsocket);
mTunneledConn = new nsHttpConnection(); mTunneledConn = new nsHttpConnection();
switch (httpResponseCode) { if (httpResponseCode != 200) {
case 404: nsresult err = HttpProxyResponseToErrorCode(httpResponseCode);
CreateShimError(NS_ERROR_UNKNOWN_HOST); if (NS_FAILED(err)) {
break; CreateShimError(err);
case 407: }
CreateShimError(NS_ERROR_PROXY_AUTHENTICATION_FAILED);
break;
case 429:
CreateShimError(NS_ERROR_TOO_MANY_REQUESTS);
break;
case 502:
CreateShimError(NS_ERROR_PROXY_BAD_GATEWAY);
break;
case 504:
CreateShimError(NS_ERROR_PROXY_GATEWAY_TIMEOUT);
break;
default:
break;
} }
// this new http connection has a specific hashkey (i.e. to a particular // this new http connection has a specific hashkey (i.e. to a particular

Просмотреть файл

@ -841,5 +841,141 @@ void LogHeaders(const char* lineStart) {
} }
} }
nsresult HttpProxyResponseToErrorCode(uint32_t aStatusCode) {
MOZ_ASSERT(aStatusCode >= 300,
"Call HttpProxyResponseToErrorCode with successful status code!");
nsresult rv;
switch (aStatusCode) {
case 300:
case 301:
case 302:
case 303:
case 307:
case 308:
// Bad redirect: not top-level, or it's a POST, bad/missing Location,
// or ProcessRedirect() failed for some other reason. Legal
// redirects that fail because site not available, etc., are handled
// elsewhere, in the regular codepath.
rv = NS_ERROR_CONNECTION_REFUSED;
break;
// Squid sends 404 if DNS fails (regular 404 from target is tunneled)
case 404: // HTTP/1.1: "Not Found"
// RFC 2616: "some deployed proxies are known to return 400 or
// 500 when DNS lookups time out." (Squid uses 500 if it runs
// out of sockets: so we have a conflict here).
case 400: // HTTP/1.1 "Bad Request"
case 500: // HTTP/1.1: "Internal Server Error"
rv = NS_ERROR_UNKNOWN_HOST;
break;
case 401:
rv = NS_ERROR_PROXY_UNAUTHORIZED;
break;
case 402:
rv = NS_ERROR_PROXY_PAYMENT_REQUIRED;
break;
case 403:
rv = NS_ERROR_PROXY_FORBIDDEN;
break;
case 405:
rv = NS_ERROR_PROXY_METHOD_NOT_ALLOWED;
break;
case 406:
rv = NS_ERROR_PROXY_NOT_ACCEPTABLE;
break;
case 407: // ProcessAuthentication() failed (e.g. no header)
rv = NS_ERROR_PROXY_AUTHENTICATION_FAILED;
break;
case 408:
rv = NS_ERROR_PROXY_REQUEST_TIMEOUT;
break;
case 409:
rv = NS_ERROR_PROXY_CONFLICT;
break;
case 410:
rv = NS_ERROR_PROXY_GONE;
break;
case 411:
rv = NS_ERROR_PROXY_LENGTH_REQUIRED;
break;
case 412:
rv = NS_ERROR_PROXY_PRECONDITION_FAILED;
break;
case 413:
rv = NS_ERROR_PROXY_REQUEST_ENTITY_TOO_LARGE;
break;
case 414:
rv = NS_ERROR_PROXY_REQUEST_URI_TOO_LONG;
break;
case 415:
rv = NS_ERROR_PROXY_UNSUPPORTED_MEDIA_TYPE;
break;
case 416:
rv = NS_ERROR_PROXY_REQUESTED_RANGE_NOT_SATISFIABLE;
break;
case 417:
rv = NS_ERROR_PROXY_EXPECTATION_FAILED;
break;
case 421:
rv = NS_ERROR_PROXY_MISDIRECTED_REQUEST;
break;
case 425:
rv = NS_ERROR_PROXY_TOO_EARLY;
break;
case 426:
rv = NS_ERROR_PROXY_UPGRADE_REQUIRED;
break;
case 428:
rv = NS_ERROR_PROXY_PRECONDITION_REQUIRED;
break;
case 429:
rv = NS_ERROR_PROXY_TOO_MANY_REQUESTS;
break;
case 431:
rv = NS_ERROR_PROXY_REQUEST_HEADER_FIELDS_TOO_LARGE;
break;
case 451:
rv = NS_ERROR_PROXY_UNAVAILABLE_FOR_LEGAL_REASONS;
break;
case 501:
rv = NS_ERROR_PROXY_NOT_IMPLEMENTED;
break;
case 502:
rv = NS_ERROR_PROXY_BAD_GATEWAY;
break;
case 503:
// Squid returns 503 if target request fails for anything but DNS.
/* User sees: "Failed to Connect:
* Firefox can't establish a connection to the server at
* www.foo.com. Though the site seems valid, the browser
* was unable to establish a connection."
*/
rv = NS_ERROR_CONNECTION_REFUSED;
break;
// RFC 2616 uses 504 for both DNS and target timeout, so not clear what to
// do here: picking target timeout, as DNS covered by 400/404/500
case 504:
rv = NS_ERROR_PROXY_GATEWAY_TIMEOUT;
break;
case 505:
rv = NS_ERROR_PROXY_VERSION_NOT_SUPPORTED;
break;
case 506:
rv = NS_ERROR_PROXY_VARIANT_ALSO_NEGOTIATES;
break;
case 510:
rv = NS_ERROR_PROXY_NOT_EXTENDED;
break;
case 511:
rv = NS_ERROR_PROXY_NETWORK_AUTHENTICATION_REQUIRED;
break;
default:
rv = NS_ERROR_PROXY_CONNECTION_REFUSED;
break;
}
return rv;
}
} // namespace net } // namespace net
} // namespace mozilla } // namespace mozilla

Просмотреть файл

@ -336,6 +336,11 @@ class ParsedHeaderValueListList {
void LogHeaders(const char* lineStart); void LogHeaders(const char* lineStart);
// Convert HTTP response codes returned by a proxy to nsresult.
// This function should be only used when we get a failed response to the
// CONNECT method.
nsresult HttpProxyResponseToErrorCode(uint32_t aStatusCode);
} // namespace net } // namespace net
} // namespace mozilla } // namespace mozilla

Просмотреть файл

@ -1938,67 +1938,7 @@ nsresult nsHttpChannel::ProcessFailedProxyConnect(uint32_t httpStatus) {
MOZ_ASSERT(mConnectionInfo->UsingConnect(), MOZ_ASSERT(mConnectionInfo->UsingConnect(),
"proxy connect failed but not using CONNECT?"); "proxy connect failed but not using CONNECT?");
nsresult rv; nsresult rv = HttpProxyResponseToErrorCode(httpStatus);
switch (httpStatus) {
case 300:
case 301:
case 302:
case 303:
case 307:
case 308:
// Bad redirect: not top-level, or it's a POST, bad/missing Location,
// or ProcessRedirect() failed for some other reason. Legal
// redirects that fail because site not available, etc., are handled
// elsewhere, in the regular codepath.
rv = NS_ERROR_CONNECTION_REFUSED;
break;
case 403: // HTTP/1.1: "Forbidden"
case 501: // HTTP/1.1: "Not Implemented"
// user sees boilerplate Mozilla "Proxy Refused Connection" page.
rv = NS_ERROR_PROXY_CONNECTION_REFUSED;
break;
case 407: // ProcessAuthentication() failed (e.g. no header)
rv = NS_ERROR_PROXY_AUTHENTICATION_FAILED;
break;
case 429:
rv = NS_ERROR_TOO_MANY_REQUESTS;
break;
// Squid sends 404 if DNS fails (regular 404 from target is tunneled)
case 404: // HTTP/1.1: "Not Found"
// RFC 2616: "some deployed proxies are known to return 400 or
// 500 when DNS lookups time out." (Squid uses 500 if it runs
// out of sockets: so we have a conflict here).
case 400: // HTTP/1.1 "Bad Request"
case 500: // HTTP/1.1: "Internal Server Error"
/* User sees: "Address Not Found: Firefox can't find the server at
* www.foo.com."
*/
rv = NS_ERROR_UNKNOWN_HOST;
break;
case 502: // HTTP/1.1: "Bad Gateway" (invalid resp from target server)
rv = NS_ERROR_PROXY_BAD_GATEWAY;
break;
case 503: // HTTP/1.1: "Service Unavailable"
// Squid returns 503 if target request fails for anything but DNS.
/* User sees: "Failed to Connect:
* Firefox can't establish a connection to the server at
* www.foo.com. Though the site seems valid, the browser
* was unable to establish a connection."
*/
rv = NS_ERROR_CONNECTION_REFUSED;
break;
// RFC 2616 uses 504 for both DNS and target timeout, so not clear what to
// do here: picking target timeout, as DNS covered by 400/404/500
case 504: // HTTP/1.1: "Gateway Timeout"
// user sees: "Network Timeout: The server at www.foo.com
// is taking too long to respond."
rv = NS_ERROR_PROXY_GATEWAY_TIMEOUT;
break;
// Confused proxy server or malicious response
default:
rv = NS_ERROR_PROXY_CONNECTION_REFUSED;
break;
}
LOG(("Cancelling failed proxy CONNECT [this=%p httpStatus=%u]\n", this, LOG(("Cancelling failed proxy CONNECT [this=%p httpStatus=%u]\n", this,
httpStatus)); httpStatus));

Просмотреть файл

@ -206,7 +206,7 @@ add_task(async function proxy_too_many_requests_failure() {
CL_EXPECT_FAILURE CL_EXPECT_FAILURE
); );
Assert.equal(status, Cr.NS_ERROR_TOO_MANY_REQUESTS); Assert.equal(status, Cr.NS_ERROR_PROXY_TOO_MANY_REQUESTS);
Assert.equal(http_code, undefined); Assert.equal(http_code, undefined);
}); });

Просмотреть файл

@ -446,7 +446,7 @@ add_task(async function proxy_too_many_requests_failure() {
CL_EXPECT_FAILURE CL_EXPECT_FAILURE
); );
Assert.equal(status, Cr.NS_ERROR_TOO_MANY_REQUESTS); Assert.equal(status, Cr.NS_ERROR_PROXY_TOO_MANY_REQUESTS);
Assert.equal(http_code, undefined); Assert.equal(http_code, undefined);
Assert.equal( Assert.equal(
await proxy_session_counter(), await proxy_session_counter(),

Просмотреть файл

@ -330,14 +330,6 @@ with modules["NETWORK"]:
errors["NS_ERROR_NET_INTERRUPT"] = FAILURE(71) errors["NS_ERROR_NET_INTERRUPT"] = FAILURE(71)
# The connection attempt to a proxy failed. # The connection attempt to a proxy failed.
errors["NS_ERROR_PROXY_CONNECTION_REFUSED"] = FAILURE(72) errors["NS_ERROR_PROXY_CONNECTION_REFUSED"] = FAILURE(72)
# The proxy requires authentication; used when we can't easily propagate 407s.
errors["NS_ERROR_PROXY_AUTHENTICATION_FAILED"] = FAILURE(407)
# Indicates that we have sent too many requests in a given amount of time.
errors["NS_ERROR_TOO_MANY_REQUESTS"] = FAILURE(429)
# The proxy failed to connect the remote server.
errors["NS_ERROR_PROXY_BAD_GATEWAY"] = FAILURE(502)
# The proxy did get any response from the remote server in time.
errors["NS_ERROR_PROXY_GATEWAY_TIMEOUT"] = FAILURE(504)
# A transfer was only partially done when it completed. # A transfer was only partially done when it completed.
errors["NS_ERROR_NET_PARTIAL_TRANSFER"] = FAILURE(76) errors["NS_ERROR_NET_PARTIAL_TRANSFER"] = FAILURE(76)
# HTTP/2 detected invalid TLS configuration # HTTP/2 detected invalid TLS configuration
@ -460,6 +452,61 @@ with modules["NETWORK"]:
# Generic error for non-specific failures during service worker interception # Generic error for non-specific failures during service worker interception
errors["NS_ERROR_INTERCEPTION_FAILED"] = FAILURE(100) errors["NS_ERROR_INTERCEPTION_FAILED"] = FAILURE(100)
# All Http proxy CONNECT response codes
errors["NS_ERROR_PROXY_CODE_BASE"] = FAILURE(1000)
# Redirection 3xx
errors["NS_ERROR_PROXY_MULTIPLE_CHOICES"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 300
errors["NS_ERROR_PROXY_MOVED_PERMANENTLY"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 301
errors["NS_ERROR_PROXY_FOUND"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 302
errors["NS_ERROR_PROXY_SEE_OTHER"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 303
errors["NS_ERROR_PROXY_NOT_MODIFIED"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 304
errors["NS_ERROR_PROXY_TEMPORARY_REDIRECT"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 307
errors["NS_ERROR_PROXY_PERMANENT_REDIRECT"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 308
# Client error 4xx
errors["NS_ERROR_PROXY_BAD_REQUEST"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 400
errors["NS_ERROR_PROXY_UNAUTHORIZED"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 401
errors["NS_ERROR_PROXY_PAYMENT_REQUIRED"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 402
errors["NS_ERROR_PROXY_FORBIDDEN"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 403
errors["NS_ERROR_PROXY_NOT_FOUND"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 404
errors["NS_ERROR_PROXY_METHOD_NOT_ALLOWED"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 405
errors["NS_ERROR_PROXY_NOT_ACCEPTABLE"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 406
# The proxy requires authentication; used when we can't easily propagate 407s.
errors["NS_ERROR_PROXY_AUTHENTICATION_FAILED"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 407
errors["NS_ERROR_PROXY_REQUEST_TIMEOUT"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 408
errors["NS_ERROR_PROXY_CONFLICT"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 409
errors["NS_ERROR_PROXY_GONE"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 410
errors["NS_ERROR_PROXY_LENGTH_REQUIRED"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 411
errors["NS_ERROR_PROXY_PRECONDITION_FAILED"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 412
errors["NS_ERROR_PROXY_REQUEST_ENTITY_TOO_LARGE"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 413
errors["NS_ERROR_PROXY_REQUEST_URI_TOO_LONG"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 414
errors["NS_ERROR_PROXY_UNSUPPORTED_MEDIA_TYPE"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 415
errors["NS_ERROR_PROXY_REQUESTED_RANGE_NOT_SATISFIABLE"] = \
errors["NS_ERROR_PROXY_CODE_BASE"] + 416
errors["NS_ERROR_PROXY_EXPECTATION_FAILED"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 417
errors["NS_ERROR_PROXY_MISDIRECTED_REQUEST"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 421
errors["NS_ERROR_PROXY_TOO_EARLY"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 425
errors["NS_ERROR_PROXY_UPGRADE_REQUIRED"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 426
errors["NS_ERROR_PROXY_PRECONDITION_REQUIRED"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 428
# Indicates that we have sent too many requests in a given amount of time.
errors["NS_ERROR_PROXY_TOO_MANY_REQUESTS"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 429
errors["NS_ERROR_PROXY_REQUEST_HEADER_FIELDS_TOO_LARGE"] = \
errors["NS_ERROR_PROXY_CODE_BASE"] + 431
errors["NS_ERROR_PROXY_UNAVAILABLE_FOR_LEGAL_REASONS"] = \
errors["NS_ERROR_PROXY_CODE_BASE"] + 451
# Server error 5xx
errors["NS_ERROR_PROXY_INTERNAL_SERVER_ERROR"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 500
errors["NS_ERROR_PROXY_NOT_IMPLEMENTED"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 501
errors["NS_ERROR_PROXY_BAD_GATEWAY"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 502
errors["NS_ERROR_PROXY_SERVICE_UNAVAILABLE"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 503
# The proxy did get any response from the remote server in time.
errors["NS_ERROR_PROXY_GATEWAY_TIMEOUT"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 504
errors["NS_ERROR_PROXY_VERSION_NOT_SUPPORTED"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 505
errors["NS_ERROR_PROXY_VARIANT_ALSO_NEGOTIATES"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 506
errors["NS_ERROR_PROXY_NOT_EXTENDED"] = errors["NS_ERROR_PROXY_CODE_BASE"] + 510
errors["NS_ERROR_PROXY_NETWORK_AUTHENTICATION_REQUIRED"] = \
errors["NS_ERROR_PROXY_CODE_BASE"] + 511
# ======================================================================= # =======================================================================
# 7: NS_ERROR_MODULE_PLUGINS # 7: NS_ERROR_MODULE_PLUGINS