1
0
Fork 0
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:
Andy Green 2011-03-07 07:08:18 +00:00
parent da527dfdee
commit c44159fb3a
3 changed files with 53 additions and 1 deletions

View file

@ -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

View file

@ -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

View file

@ -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 {