The overall rate was incorrect when using non-default intervals. Also
simplify the code using plain nanosecond values, and fix the rate for
the last event which was based on the number of sleeps instead of the
actual time elapsed.
The implementation was waiting for the client, which leaves some hanging
even after they called close(). This mirrors the behavior for HTTP
connections in client.c where close() is called right before
http_client_free.
1. Origin and Sec-WebSocket-Origin are now optional: only return a matching
Sec-WebSocket-Origin if one of the two headers was provided.
2. Change order of headers: return Sec-WebSocket-Accept immediately
after Upgrade and Connection since some clients expect it there.
If the client closes the connection before we can even start to respond,
the event_add will fail and we need to clean up the http_response object
since this would have happened only after we've sent the whole response.
ws_handshake_reply was sending its response using a single write(2) call
without error-checking, which could well send only part of it and leave
the client hanging. This change creates an HTTP response object and
schedules it for writing using the event loop.
Tested with Valgrind, no memory is leaked.
1. Generate random WS connection key
2. Read headers returned in WS connection (upgrade) response
3. Validate Sec-WebSocket-Accept return value from webdis
Tested by introducing an artificial error in webdis, reported as
expected.
* Use pure.css for a basic grid
* Detect disconnections, update UI accordingly
* Make GET/SET commands configurable and interactive
* Add button to clear logs
* Test with current branch
The keep_alive flag is needed on http_response for websocket
connections. Without it, the server closes the connection as soon as a
reply to the first frame is sent.
Mostly adding trace logs to websocket.c, but also some in http.c and
worker.c for events relating to event loop and client requests and
responses. This is useful for debugging websocket issues.
* Add WEBDIS_TRACE log level for internal operations
* Warn when verbosity config is invalid
* Add slog_enabled to bypass buffer allocations if the level is filtered
1. Switch to evbuffer for correct handling of partial writes
2. Implement WS state machine in each worker
3. Clean up debug logging
4. Add detailed network log messages to help find WS issues
5. Switch to getopt_long
* Only process `Connection: close` header if full request was read
(#194). This likely fixes the same issue also reported in #145.
* Fix small memory leak when the `type` query string parameter is
used; the value was not being freed leading to growing memory usage
of a few bytes per request. Upgrading is recommended if you use this
feature.
* Fix invalid call to `ioctl`, which did not seem to affect Linux
systems but could have had an impact on macOS (found in #197).
The `request` parameter is unsigned long, not int. This was invalid on
macOS and caused issues when sockets were considered non-blocking. Also
adds an error log if the call fails.
Thanks @likuilin for opening an issue that led to this discovery.
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.
* Fixed compilation warnings
* Fixed code quality issues found by CodeQL
* Upgraded base image from alpine:3.12.6 to alpine:3.12.7
See CWE-125 and CVE-2021-30139). This is *not* a security issue if
you just use the webdis image to run the service, but could be if
you're building a new Docker image using webdis as a base image.