1. Introduce ws_client struct
2. Handle all communications from websocket.c for WS clients
3. Always use a dedicated Redis connection for WS clients
4. Add rbuf & wbuf evbuffers for incoming & outgoing WS data
5. Use event_base_once to control R/W events
6. WS test: make sure to read complete HTTP response
For WS clients, reuse a persistent cmd struct attached to the
http_client object: take the cmd built from the WS frame, and copy it to
the persistent cmd.
1. Only HTTP-based pub-sub clients were re-using a cmd object, but
WS clients were not. This led to the commands sent by a WS client
to be processed out of order, just queued to Redis but with no
guarantee that they would be de-queued from the event loop in the
same order. This change attaches a permanent cmd object (with its
associated Redis context) to WS clients just like pub-sub clients
do.
2. WS responses are also no longer sent out of order, but added to a
write buffer that is scheduled for writing as long as there is still
some data left to send. This replaces the use of http_response which
contained extra fields (headers, HTTP response) that were duplicated
without ever being sent out.
Passing `?type=foo/bar` in the query string makes Webdis return the
response with a `Content-Type: foo/bar` header (this is useful to serve
files from Webdis, e.g. web page or their dependencies such as CSS,
images, etc). I discovered with Valgrind that the *value* of this query
string parameter was leaked and never freed, which would likely not
cause a huge issue but would still gradually grow the memory usage.
There were 2 different functions taking care of this parameter, the
first calling strdup(3) on it and the second *transferring* pointer
ownership into it (meaning overwriting the just-strdup'd value).
This is now fixed, Webdis no longer leaks this small string, and an
allocation was avoided.