HTTP server timeout. When should it be sent - http

I’m writing small http server and try to understand timeout issues.
RFC7230 don’t give an answer for the question what are conditions that forces server to send timeout (408 Request timeout). Should it be sent when client sends request too long? Or if nothing was sent in opened connection for some time? What the logic should be? Is there any standard or behavioral model?

The whole process would be
server wait for a request -> read request header -> read request body -> prepare response header -> prepare response body
So if the request take to long Ex: 30 seconds, then server will return a response header with code 408 Request timeout
The next case is when server can read whole request header and body and try to process that request but can not complete in an amount of time then it will return 504 Gateway Timeout or 503 Service Unavailable.
It will depend of each situation. But the rule is always use 4xx for request errors and 5xx for server errors
The short explaination for thoose http code is listed here: HTTP response status codes

Related

What status code should a client assume if an HTTP response has a payload but no status code?

I was playing around my redis server and tried to hit with the browser. Redis detected it as a Cross Protocol Scripting attack and returned an error in the response's payload. However, when I checked the window's console, it turned out that the request was returned without a status code. So, in such cases what status code should a client assume?
There is no such thing as a response without a status code. Every HTTP response has one, and if you didn't get one it means:
You weren't talking to a HTTP server.
The HTTP server did something it shouldn't.
In each case I would expect your HTTP client to throw some kind of exception but not return a Http Response object.

What is the difference between HTTP 408 and 504 errors?

These are both timeout errors, but who is timing out in a 408 vs. a 504?
From w3, 408 is defined as:
The client did not produce a request within the time that the server was prepared to wait. The client MAY repeat the request without modifications at any later time.
...And 504 is:
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.
So who is the 'client' in the 408 if not an intermediary server? If it's an actual end user, how does a server know to wait for their request before they have made it?
The client is the browser or client application. The server knows to wait for a request because it has accepted a connection, or already read part of the request, say a header or two.
Amazon documentation tells: http://docs.aws.amazon.com/en_en/elasticloadbalancing/latest/classic/ts-elb-error-message.html#ts-elb-errorcodes-http408
Indicates that the client cancelled the request or failed to send a full request
Mozilla documentation tells: https://developer.mozilla.org/en/docs/Web/HTTP/Status/408
The HTTP 408 Request Timeout response status code means that the server would like to shut down this unused connection. It is sent on an idle connection by some servers, even without any previous request by the client

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

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.

"Expect: 100-Continue" and... how a server tell the client it wish to receive the body and discard it?

HTTP Protocol: http://greenbytes.de/tech/webdav/draft-ietf-httpbis-p2-semantics-26.html#header.expect
A server that responds with a final status code before reading the entire message body SHOULD indicate in that response whether it intends to close the connection or continue reading and discarding the request message
If the server wish to close the connection it will include "Connection: close" in his response. But how can it tell the client it wish to continue reading and discarding the body ? I don't know any header to do that.
And if it receive the body and discard it, this doesnt mean that "100-Continue" is useless ? That's the whole point of "100-Continue", not sending the body if it will be rejected anyway.
When the server sends its final reply, it has finished processing the request. If the server sends that reply while the client is still sending its data, the client should stop sending, and then the presense of an HTTP keep-alive (an explicit Connection: keep-alive header in an HTTP 1.0 reply, or a missing Connection: close header in an HTTP 1.1 reply) is the server's indication that it will be discarding any remaining data that is sent, since it needs to clear the socket of pending data before it can receive a new request on the same connection.
The 100-Continue is not useless. Think of what happens when the server sends 100 to let the client start sending, then later errors and decides to stop receiving and send a final reply reporting the error. The server did not know at the start of the request that it was going to error.

Netty Client sending Keep Alive HTTP request

I am creating a Netty Client which sends HTTP request to POST data to server.To increase the performance what i did was using Keep alive Http request(i know that in HTTP 1.1 all requests are keep alive by default, so i am making sure that Connection header is not set to close while sending the Http request) so that it uses the same channel to send the Http Request. Now when i send the Http request to the correct URL,i.e. if i get HttpResponse Status OK in return from server, i am able to send the next Http Request properly but when i send the Http Request for which i get BAD REQUEST or SERVICE UNAVAILABLE or something other than OK then i am unable to send the next request that is the channel future f.success() returned after calling channel.write(request) is false. I am unable to understand why it happens. I have followed the same model of coding as done in HttpSnoopClient example given in netty,
except i have removed the connection:close header & even the client handler is the same as that given in snoop client, also i have am instantiating the bootstrap only once at the starting
I tried getting channelFuture f.cause().getMessage() but it was null it seems

Resources