mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
flush extensions when closing
Extensions might be caching stuff that we should spill before a controlled close. It's not allowed to send anything on the wire after the close request, so we need to make the extensions spill just before. Signed-off-by: Andy Green <andy@warmcat.com>
This commit is contained in:
parent
da527dfdee
commit
c44159fb3a
3 changed files with 53 additions and 1 deletions
|
@ -91,6 +91,7 @@ int lws_extension_callback_deflate_stream(
|
|||
|
||||
return 0;
|
||||
|
||||
case LWS_EXT_CALLBACK_FLUSH_PENDING_TX:
|
||||
case LWS_EXT_CALLBACK_PACKET_TX_PRESEND:
|
||||
|
||||
/*
|
||||
|
@ -103,7 +104,11 @@ int lws_extension_callback_deflate_stream(
|
|||
conn->zs_out.next_out = conn->buf;
|
||||
conn->zs_out.avail_out = sizeof(conn->buf);
|
||||
|
||||
n = deflate(&conn->zs_out, Z_PARTIAL_FLUSH);
|
||||
n = Z_PARTIAL_FLUSH;
|
||||
if (reason == LWS_EXT_CALLBACK_FLUSH_PENDING_TX)
|
||||
n = Z_FULL_FLUSH;
|
||||
|
||||
n = deflate(&conn->zs_out, n);
|
||||
if (n == Z_STREAM_ERROR) {
|
||||
/*
|
||||
* screwed.. close the connection... we will get a
|
||||
|
|
|
@ -149,6 +149,9 @@ libwebsocket_close_and_free_session(struct libwebsocket_context *context,
|
|||
int old_state;
|
||||
unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 2 +
|
||||
LWS_SEND_BUFFER_POST_PADDING];
|
||||
int ret;
|
||||
int m;
|
||||
struct lws_tokens eff_buf;
|
||||
|
||||
if (!wsi)
|
||||
return;
|
||||
|
@ -160,6 +163,48 @@ libwebsocket_close_and_free_session(struct libwebsocket_context *context,
|
|||
|
||||
wsi->close_reason = reason;
|
||||
|
||||
/*
|
||||
* flush any tx pending from extensions, since we may send close packet
|
||||
* if there are problems with send, just nuke the connection
|
||||
*/
|
||||
|
||||
ret = 1;
|
||||
while (ret == 1) {
|
||||
|
||||
/* default to nobody has more to spill */
|
||||
|
||||
ret = 0;
|
||||
eff_buf.token = NULL;
|
||||
eff_buf.token_len = 0;
|
||||
|
||||
/* show every extension the new incoming data */
|
||||
|
||||
for (n = 0; n < wsi->count_active_extensions; n++) {
|
||||
m = wsi->active_extensions[n]->callback(
|
||||
wsi->protocol->owning_server, wsi,
|
||||
LWS_EXT_CALLBACK_FLUSH_PENDING_TX,
|
||||
wsi->active_extensions_user[n], &eff_buf, 0);
|
||||
if (m < 0) {
|
||||
fprintf(stderr, "Extension reports "
|
||||
"fatal error\n");
|
||||
goto just_kill_connection;
|
||||
}
|
||||
if (m)
|
||||
/*
|
||||
* at least one extension told us he has more
|
||||
* to spill, so we will go around again after
|
||||
*/
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
/* assuming they left us something to send, send it */
|
||||
|
||||
if (eff_buf.token_len)
|
||||
if (lws_issue_raw(wsi, (unsigned char *)eff_buf.token,
|
||||
eff_buf.token_len))
|
||||
goto just_kill_connection;
|
||||
}
|
||||
|
||||
/*
|
||||
* signal we are closing, libsocket_write will
|
||||
* add any necessary version-specific stuff. If the write fails,
|
||||
|
@ -197,6 +242,7 @@ libwebsocket_close_and_free_session(struct libwebsocket_context *context,
|
|||
/* else, the send failed and we should just hang up */
|
||||
}
|
||||
|
||||
just_kill_connection:
|
||||
/*
|
||||
* we won't be servicing or receiving anything further from this guy
|
||||
* remove this fd from wsi mapping hashtable
|
||||
|
|
|
@ -78,6 +78,7 @@ enum libwebsocket_extension_callback_reasons {
|
|||
LWS_EXT_CALLBACK_DESTROY,
|
||||
LWS_EXT_CALLBACK_PACKET_RX_PREPARSE,
|
||||
LWS_EXT_CALLBACK_PACKET_TX_PRESEND,
|
||||
LWS_EXT_CALLBACK_FLUSH_PENDING_TX,
|
||||
};
|
||||
|
||||
enum libwebsocket_write_protocol {
|
||||
|
|
Loading…
Add table
Reference in a new issue