diff --git a/src/formats/common.c b/src/formats/common.c index 94f88e6..50e4780 100644 --- a/src/formats/common.c +++ b/src/formats/common.c @@ -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); } } diff --git a/src/websocket.c b/src/websocket.c index af31577..27358ea 100644 --- a/src/websocket.c +++ b/src/websocket.c @@ -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 */ }