Send error messages to WS clients if triggered by Redis

Also mark the WS client as closing before we close the Redis connection,
to avoid its last error callback (if sent) trying to send out data while
we're in the middle of freeing the client.
master
Jessie Murray 3 years ago
parent 583f6747b3
commit 545d18d84d
No known key found for this signature in database
GPG Key ID: E7E4D57EDDA744C5

@ -46,12 +46,14 @@ format_send_error(struct cmd *cmd, short code, const char *msg) {
resp->http_version = cmd->http_version;
http_response_set_keep_alive(resp, cmd->keep_alive);
http_response_write(resp, cmd->fd);
} else if(cmd->is_websocket && !cmd->http_client->ws->close_after_events) {
ws_frame_and_send_response(cmd->http_client->ws, WS_BINARY_FRAME, msg, strlen(msg));
}
/* for pub/sub, remove command from client */
if(cmd->pub_sub_client) {
cmd->pub_sub_client->self_cmd = NULL;
} else {
} else if (!cmd->is_websocket) { /* don't free persistent cmd */
cmd_free(cmd);
}
}

@ -123,11 +123,14 @@ ws_client_new(struct http_client *http_client) {
static void
ws_client_free(struct ws_client *ws) {
/* mark WS client as closing to skip the Redis callback */
ws->close_after_events = 1;
pool_free_context(ws->ac); /* could trigger a cb via format_send_error */
struct http_client *c = ws->http_client;
c->ws = NULL; /* detach */
evbuffer_free(ws->rbuf);
evbuffer_free(ws->wbuf);
pool_free_context(ws->ac);
if(ws->cmd) {
ws->cmd->ac = NULL; /* we've just free'd it */
cmd_free(ws->cmd);
@ -526,6 +529,7 @@ ws_frame_and_send_response(struct ws_client *ws, enum ws_frame_type frame_type,
static void
ws_close_if_able(struct ws_client *ws) {
ws->close_after_events = 1; /* note that we're closing */
if(ws->scheduled_read || ws->scheduled_write) {
return; /* still waiting for these events to trigger */
}

Loading…
Cancel
Save