In HTTP 502, what is meant by an invalid response? - http

I'm trying to test a server to see if it behaves according to the definition below and for that, I need to construct and send an invalid response to the gateway server, from the upstream server. The HTTP spec says the following regarding the status code 502 - Bad Gateway.
The 502 (Bad Gateway) status code indicates that the server, while
acting as a gateway or proxy, received an invalid response from an
inbound server it accessed while attempting to fulfill the request.
But what exactly constitute an invalid response? Does a non-standard response code (say, some random number like 6789) count as an invalid response? Or a response with an invalid HTTP version?
Came across this: 502 HTTP Status Code, which says incomplete headers and response bodies can cause 502 errors. How does a server determine if the headers or the body is incomplete? And more importantly, is it possible to create such a response programmatically (I'm using Java)?

I managed to find the following in the HTTP spec (RFC7230 section 3.3.3).
If a message is received without Transfer-Encoding and with
either multiple Content-Length header fields having differing
field-values or a single Content-Length header field having an
invalid value, then the message framing is invalid and the
recipient MUST treat it as an unrecoverable error. If this is a
request message, the server MUST respond with a 400 (Bad Request)
status code and then close the connection. If this is a response
message received by a proxy, the proxy MUST close the connection
to the server, discard the received response, and send a 502 (Bad Gateway) response to the client. If this is a response message
received by a user agent, the user agent MUST close the
connection to the server and discard the received response.
Apart from this, I've also noticed that Nginx returns a 502 when acting as a reverse proxy/load balancer, when the upstream server is down.

Related

Clarification required about internal error

I am using calculate route API to calculate distance and time from origin to destination. Wanted to validate some error codes that I have observed in error code documentation.
One of which is 500 Internal error.
Description for this says "There is a server configuration issue" can I get a clear reason for cause of this error! What does server configuration Issue mean?!
Response status codes beginning with the digit "5" indicate cases in which the server is aware that it has erred or is incapable of performing the request.
500 Internal Server Error
The server encountered an unexpected condition which prevented it from fulfilling the request.
501 Not Implemented
The server does not support the functionality required to fulfill the request. This is the appropriate response when the server does not recognize the request method and is not capable of supporting it for any resource.
502 Bad Gateway
The server, while acting as a gateway or proxy, received an invalid response from the upstream server it accessed in attempting to fulfill the request.
503 Service Unavailable
The server is currently unable to handle the request due to a temporary overloading or maintenance of the server. The implication is that this is a temporary condition which will be alleviated after some delay. If known, the length of the delay MAY be indicated in a Retry-After header. If no Retry-After is given, the client SHOULD handle the response as it would for a 500 response.
504 Gateway Timeout
The server, while acting as a gateway or proxy, did not receive a timely response from the upstream server specified by the URI (e.g. HTTP, FTP, LDAP) or some other auxiliary server (e.g. DNS) it needed to access in attempting to complete the request.
505 HTTP Version Not Supported
The server does not support, or refuses to support, the HTTP protocol version that was used in the request message. The server is indicating that it is unable or unwilling to complete the request using the same major version as the client, as described in section 3.1, other than with this error message. The response SHOULD contain an entity describing why that version is not supported and what other protocols are supported by that server.

How does proxy or gateway deal with upstream status code?

Right now we are writing a gateway server, it receives a request from client, modify it and send the modified request to upstream, then copy response back to client.
Here we come out a problem that, what if upstream returns HTTP status code 500, should we return 500 to client? If so, how do we distinguish whether gateway failed or upstream failed?
Similar issues also apply to HTTP status code 404, 429 etc...
So, question is:
1. Should gateway return HTTP status code as whatever upstream returns?
In this case, how do we distinguish which server failed exactly
(consider that in a monitor system)
2. Is it a good practice that gateway map upstream status codes to some
fixed range of status codes? e.g. upstream 5xx -> client 502

What's the most appropriate HTTP status code to return when a client specifies HTTP/1.0 in a websocket opening handshake?

According to the WebSocket RFC (RFC6455#section-4.2.1):
If the server, while reading the handshake, finds that the client did not send a handshake that matches the description below [...], the server MUST stop processing the client's handshake and return an HTTP response with an appropriate error code (such as 400 Bad Request).
An HTTP/1.1 or higher GET request, including a "Request-URI" [RFC2616] that should be interpreted as a /resource name/ defined in Section 3 (or an absolute HTTP/HTTPS URI containing the /resource name/).
[etc...]
When the client's handshake message instead specifies HTTP/1.0 (or perhaps an even lower version number?), I'm not sure if responding with HTTP/1.1 400 \r\n\r\n is appropriate given its definition (RFC7231#section-6.5.1):
The 400 (Bad Request) status code indicates that the server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).
I suppose that whether or not the HTTP version number being too low is to be considered a client error depends on how to interpret a client handshake message:
Either...
A client handshake message is a plain HTTP1.1 message (which can cause a future upgrade to WebSocket if it includes a certain set of HTTP headers).
...or...
A client handshake message is actually not an HTTP1.1 message but actually a message that is part of the WebSocket standard and which merely masquerades as an HTTP1.1 message.
If the latter, a status code of 400 makes sense, because the client is in clear violation of the WebSocket standard.
If the former, a status code of 400 doesn't make sense, because the message is valid as an HTTP message; and a status code of 505 might be preferable: (RFC7231#section-6.6.6)
The 505 (HTTP Version Not Supported) status code indicates that the server does not support, or refuses to support, the major version of HTTP that was used in the request message. The server is indicating that it is unable or unwilling to complete the request using the same major version as the client, as described in Section 2.6 of [RFC7230], other than with this error message. The server SHOULD generate a representation for the 505 response that describes why that version is not supported and what other protocols are supported by that server.
Then again, I don't like the idea of returning a 5XX class status code, because it more or less suggests that the server is at fault for throwing the error...
EDIT: As I mention in a comment below, most of the ambiguity probably arises from the fact that I don't check whether the client even meant to upgrade to WebSocket at all.

Is it correct to return a 502 status code when it's my proxy that has an internal error?

I've written a small proxy, and I'm wondering if it's correct for me to return a 502 Bad Gateway error when the proxy server itself has an internal error. The RFC seem to say that this is something you only do if the server on the other end gives a bad response.
The server, while acting as a gateway or proxy, received an invalid response from the upstream server it accessed in attempting to fulfill the request.
I take this to mean that if for example the upstream server is setting a content-length header that is different from the response body length, we should set a 502 error i.e. when the response is invalid.
Am I misinterpreting the RFC?
An invalid Content-Length could just as well be handled as an invalid response (502 error). 503 should only be used when the condition is temporary, i.e., the same request can be served at a later time.
The common practice is to use 500 AFAIK. This is in a way wrong, as there's no distinction between the origin server and the proxy. I've also observed servers returning 504, but I consider this behavior wrong.

Should a 502 HTTP status code be used if a proxy receives no response at all?

According to the RFC:
10.5.3 502 Bad Gateway
The server, while acting as a gateway or proxy, received an invalid response from the upstream server it accessed in attempting to fulfill the request.
Can invalid response also mean no response at all (e.g. connection refused)?
Yes. Empty or incomplete headers or response body typically caused by broken connections or server side crash can cause 502 errors if accessed via a gateway or proxy.
For more information about the network errors
https://en.wikipedia.org/wiki/List_of_HTTP_status_codes

Resources