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>
diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c
index fdfaa46..6e36ff1 100644
--- a/lib/libwebsockets.c
+++ b/lib/libwebsockets.c
@@ -149,6 +149,9 @@
 	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;
@@ -161,6 +164,48 @@
 	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,
 	 * no worries we are closing anyway.  If we didn't initiate this
@@ -197,6 +242,7 @@
 		/* 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