HTTP server connection management - http

I've been playing around with an http server I'm creating using boost::asio (hence the c++ tag).
With HTTP/1.1 the default is to keep the clients connection open for more than 1 request/response.
My question is:
How long should I keep a client connection open? Should I use a deadline_timer which closes the connection after some arbitrary amount of time?
Or, should I just wait for the underlying socket receive timeout to expire? At which point my receive handler will be invoked with an EOF error prompting me to remove the client connection from my list of connections.
Furthermore, if this is specified in an RFC document, which one?

Related

How to check http(s) request connection status?

Story: In a client-server system I use a long time connection(an http(s) request from client to server with a long time timeout) in order to use notify client to do some actions(Most of data transfer is from client to server but some commands send to client in response of this http(s) request).
Problem: If client cancel the connection server can understand that but if internet connection of client loses(e.g, unplug the LAN cable or it loses the WLAN/GPRS antenna) neither client nor server understand this. Connection still remains until (some time spends and) somebody writes something in it which is too late.
PS: 0) I googled with AKC/NACK, Keep-alive, ping-pong and heartbeat key words for http(s) request and could not find a protocol which it periodically check the status of request.
1) In this you can find an argument for curl command which sets a time interval to send a props(also I monitored this with wireshark). But if still if you unplug the cable neither curl command nor server can understand the connection lost.
curl -k --keepalive-time 5 https://exampel.com/v1/v/f9a64e73/notification
2) Also here explains that there is an http header which is used to use a connection multiple time.
In server side and with nginx web-server we can enable TCP keep-alive probe with so_keepalive=on as listen input argument. Find more information in this link.

When does a http2 TCP connection close?

I understand that http2 uses one tcp connection to serve multiple requests, for example, if I request index.html which contains a.css and a.js, these three requests will be done in one tcp connection.
What happens if user clicks index2.html? does this request still use the same previous tcp connection? If so, will the browser keep the connection open until user closes the browser? And on the server side, does the server keep many connections open all the time?
When using HTTP/2, browsers typically open only one connection per domain.
In your example, index2.html will be sent on the same TCP connection that was used for index.html, a.css and a.js.
In HTTP/2 requests are multiplexed on the same TCP connection, so that the browser can send them concurrently, without waiting for a previous request to be responded to.
Both browsers and servers have an idle timeout for TCP connections.
If the connection is idle for long enough, it will be closed by either party - the one that has the shorter idle timeout, to save resources.
For example, you may open a connection to a wikipedia.org, perform a few requests, and then leave that tab and work on something else.
After a while (typically 30 seconds) the browser will close the TCP connection to wikipedia.org.
On the server side, the server will keep the connections from various clients open, until they are either closed by the client or until the server-side idle timeout fires, at which point it's the server that initiated the close of the TCP connection.
With HTTP/2, the number of connections that a server has to maintain is vastly less than it was with HTTP/1.1.
With HTTP/2, a server has to maintain just 1 TCP connection per client; with HTTP/1.1, the server had to maintain typically 2-8 TCP connections per client.
What happens if user clicks index2.html? does this request still use the same previous tcp connection?
Yes. On top of that, multiple browser tabs/windows also share a single HTTP/2 connection.
If so, will the browser keep the connection open until user closes the browser?
Below from RFC - connection management
For best performance, it is expected that clients will not close
connections until it is determined that no further communication with
a server is necessary (for example, when a user navigates away from a
particular web page) or until the server closes the connection.
Clients SHOULD NOT open more than one HTTP/2 connection to a given
host and port pair.
And on the server side, does the server keep many connections open all the time?
Servers are encouraged to maintain open connections for as long as
possible but are permitted to terminate idle connections if necessary.
When either endpoint chooses to close the transport-layer TCP
connection, the terminating endpoint SHOULD first send a GOAWAY
(Section 6.8) frame so that both endpoints can reliably determine
whether previously sent frames have been processed and gracefully
complete or terminate any necessary remaining tasks.
More info on connection error below.
RFC connection-error-handling
A connection error is any error that prevents further processing of
the frame layer or corrupts any connection state. An endpoint that
encounters a connection error SHOULD first send a GOAWAY frame with
the stream identifier of the last stream that it successfully received
from its peer. The GOAWAY frame includes an error code that indicates
why the connection is terminating. After sending the GOAWAY frame for
an error condition, the endpoint MUST close the TCP connection. It is
possible that the GOAWAY will not be reliably received by the
receiving endpoint. In the event of a connection error, GOAWAY only
provides a best-effort attempt to communicate with the peer about why
the connection is being terminated.
An endpoint can end a connection at any time. In particular, an
endpoint MAY choose to treat a stream error as a connection error.
Endpoints SHOULD send a GOAWAY frame when ending a connection,
providing that circumstances permit it.

Websocket - Should client send ping frames?

As the title suggests, should Ping Frames only be sent from a server or it is better to have both endpoints send them? As mentioned in the Websocket RFC:
NOTE: A Ping frame may serve either as a keepalive...
So by by having one endpoint sending a ping request it should keep the connection open, right?
The second part of above line is this:
or as a means to verify that the remote endpoint is still responsive.
I'm new to the concept of websockets but if the connection closes from the server won't the client be notified?
Consider the case where the server just goes away, maybe it crashes. Who or what will notify the client of this? Or say a network link close to the server is down for so long that by the time it comes back up, the server has totally forgotten about this client. Who or what would tell the client?
There are three possibilities:
The client does not need to detect loss of the connection. In this case, there's nothing special you need to do.
The client has some way to detect loss of the connection already. For example, if the connection is idle for some period of time, the client could send an application-level query and timeout if it gets no response or if the query fails.
The client needs to detect loss of the connection but has no existing way to do this. In this case, using pings makes sense.
In a typical query/response protocol, the client usually doesn't need to ping the server because there's some query it can send that has the same effect. Unless the protocol layered above websocket supports some way for the server to query the client, the server often has only two choices: use pings to detect lost connections or disconnect idle clients.
Both variants has ways of implementation. For example in case if server sends ping to client, then client can get information that server disconnected by have a loop with deadline timer which is reset every time when ping is received. If the timer reaches dealine, then it's mean that server disconnected.

IBrowse and persistent connection per client process

I need to operate with a SOAP service from Erlang. SOAP implementation is not a subject, I have a problem with HTTP requests at a client side.
I use IBrowse as a HTTP client. This SOAP service uses a specific authorization mechanism, which relates an opened session to a client connection (socket). So, the client should use only one persistent connection to server (socket), and if it try to send a request via another socket (e.g., connection from pool) - authorization will fail.
I use IBrowse in this way:
Spawn connection process to server (ibrowse:spawn_worker_process/1)
Send request to server via spawned process with {max_sessions, 1} and {max_pipeline_size, 0}.
If I understand the docs right, this should use one socket for server connection with disabled pipelining, also, I use Connection: Keep-Alive header and HTTP version explicitly set to 1.0. But my connection is always closed after the response is received.
How can I use IBrowse (or another http-client) the way I described above?
I think you could that with hackney by reusing a connection.
Also gun is quite nice http client, easy to use, keeping connection, but with little less connection control.

http 1.1 persistent connection

Http 1.1 uses persistent connections as it has advantage of sending multiple http request using same connection. My concern is with the below guideline:
You must call the Close method to close the stream and release the connection. Failure to do so may cause your application to run out of connections.
Why should I close the stream or connection after receiving response, if same connection is used for multiple httprequest? I am triggering multiple httprequests for same internet resource so why should I close connection/stream/response each time I receive a response?

Resources