Like in synchronous programming, in makes sense to start an inactivity timer only when the caller
does a "recv" call and cancel the timer as soon as data is received from the socket.
This avoids plenty of connection inactivity timeouts. From a logical point of view,
the inactivity timeout should be reset not only only data is received from the socket
but also when the client asks for more data.
Currently ibrowse defined the nodelay socket option to true, not allowing the caller
to supply its own value, which would also make the sndbuf option useless if the caller
supplied it as well.
When sending large bodies, setting nodelay to false with a custom sndbuf can improve
network throughput very significantly. For e.g., custom tests reduced an upload from
16 minutes to about 12 minutes.
Allow chunks to be IO lists. These lists will get flattened by the ERTS in
a much more efficient way than converting them to raw binaries in Erlang code.
When reusing the same connection (ibrowse worker) for multiple requests, the current
inactivity timeout must be cleared before sending a request body. When the sending of the
body takes more than inactivity_timeout milliseconds, the client will get
a req_timedout error. Currenty inactivity_timer is cleared only after sending the whole body.
1) Set Content-Length to 0 for empty PUT and POST requests (necessary for some proxies);
2) Use iolist_size/1 instead of size/1 or length/1 because the body can be an iolist
being deleted which led to the node not being able to create
any more ETS tables if queries were made to many number of
webservers. ibrowse now deletes the ETS table it creates once the
last connection to a webserver is dropped.
Reported by Seth Falcon.
* Spurious data being returned at end of body in certain cases of
chunked encoded responses from the server.
Reported by Chris Newcombe.