close add callback to get peer close reason
authorAndy Green <andy.green@linaro.org>
Sat, 26 Dec 2015 07:47:06 +0000 (15:47 +0800)
committerAndy Green <andy.green@linaro.org>
Sat, 26 Dec 2015 07:47:06 +0000 (15:47 +0800)
https://github.com/warmcat/libwebsockets/issues/196

Signed-off-by: Andy Green <andy.green@linaro.org>
changelog
lib/libwebsockets.h
lib/parsers.c
lib/service.c
test-server/test-server-dumb-increment.c
test-server/test.html

index 0588053..d66c7fa 100644 (file)
--- a/changelog
+++ b/changelog
@@ -37,6 +37,35 @@ simultaneous post-header connections as you like.  Since the http header
 processing is completed and the allocation released after ESTABLISHED or the
 HTTP callback, even with a pool of 1 many connections can be handled rapidly.
 
+2) There is a new callback that allows the user code to get acccess to the
+optional close code + aux data that may have been sent by the peer.
+
+LWS_CALLBACK_WS_PEER_INITIATED_CLOSE:
+             The peer has sent an unsolicited Close WS packet.  @in and
+             @len are the optional close code (first 2 bytes, network
+             order) and the optional additional information which is not
+             defined in the standard, and may be a string or non-human-
+             readble data.
+             If you return 0 lws will echo the close and then close the
+             connection.  If you return nonzero lws will just close the             connection.
+
+As usual not handling it does the right thing, if you're not interested in it
+just ignore it.
+
+The test server has "open and close" testing buttons at the bottom, if you
+open and close that connection, on close it will send a close code 3000 decimal
+and the string "Bye!" as the aux data.
+
+The test server dumb-increment callback handles this callback reason and prints
+
+lwsts[15714]: LWS_CALLBACK_WS_PEER_INITIATED_CLOSE: len 6
+lwsts[15714]:  0: 0x0B
+lwsts[15714]:  1: 0xB8
+lwsts[15714]:  2: 0x42
+lwsts[15714]:  3: 0x79
+lwsts[15714]:  4: 0x65
+lwsts[15714]:  5: 0x21
+
 
 User api changes
 ----------------
index 807087d..26587b6 100644 (file)
@@ -320,6 +320,7 @@ enum lws_callback_reasons {
        LWS_CALLBACK_UNLOCK_POLL                                = 36,
 
        LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY       = 37,
+       LWS_CALLBACK_WS_PEER_INITIATED_CLOSE                    = 38,
 
        /****** add new things just above ---^ ******/
 
@@ -1039,6 +1040,16 @@ struct lws_extension;
  *             len == 1 allows external threads to be synchronized against
  *             wsi lifecycle changes if it acquires the same lock for the
  *             duration of wsi dereference from the other thread context.
+ *
+ *     LWS_CALLBACK_WS_PEER_INITIATED_CLOSE:
+ *             The peer has sent an unsolicited Close WS packet.  @in and
+ *             @len are the optional close code (first 2 bytes, network
+ *             order) and the optional additional information which is not
+ *             defined in the standard, and may be a string or non-human-
+ *             readble data.
+ *             If you return 0 lws will echo the close and then close the
+ *             connection.  If you return nonzero lws will just close the
+ *             connection.
  */
 LWS_VISIBLE LWS_EXTERN int
 callback(const struct lws *wsi, enum lws_callback_reasons reason, void *user,
index ae6c1db..adcdc29 100644 (file)
@@ -982,6 +982,7 @@ spill:
 
                switch (wsi->u.ws.opcode) {
                case LWSWSOPC_CLOSE:
+
                        /* is this an acknowledgement of our close? */
                        if (wsi->state == LWSS_AWAITING_CLOSE_ACK) {
                                /*
@@ -995,6 +996,15 @@ spill:
                                /* if he sends us 2 CLOSE, kill him */
                                return -1;
 
+                       if (user_callback_handle_rxflow(
+                                       wsi->protocol->callback, wsi,
+                                       LWS_CALLBACK_WS_PEER_INITIATED_CLOSE,
+                                       wsi->user_space,
+                                       &wsi->u.ws.rx_user_buffer[
+                                               LWS_SEND_BUFFER_PRE_PADDING],
+                                       wsi->u.ws.rx_user_buffer_head))
+                               return -1;
+
                        lwsl_parser("server sees client close packet\n");
                        wsi->state = LWSS_RETURNED_CLOSE_ALREADY;
                        /* deal with the close packet contents as a PONG */
index ccb5d1d..46b924c 100644 (file)
@@ -37,7 +37,7 @@ lws_calllback_as_writeable(struct lws *wsi)
                n = LWS_CALLBACK_HTTP_WRITEABLE;
                break;
        }
-       lwsl_info("%s: %p (user=%p)\n", __func__, wsi, wsi->user_space);
+       lwsl_debug("%s: %p (user=%p)\n", __func__, wsi, wsi->user_space);
        return user_callback_handle_rxflow(wsi->protocol->callback,
                                           wsi, (enum lws_callback_reasons) n,
                                           wsi->user_space, NULL, 0);
index e83a12b..ef24d50 100644 (file)
@@ -67,6 +67,20 @@ callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason,
                /* you could return non-zero here and kill the connection */
                break;
 
+       /*
+        * this just demonstrates how to handle
+        * LWS_CALLBACK_WS_PEER_INITIATED_CLOSE and extract the peer's close
+        * code and auxiliary data.  You can just not handle it if you don't
+        * have a use for this.
+        */
+       case LWS_CALLBACK_WS_PEER_INITIATED_CLOSE:
+               lwsl_notice("LWS_CALLBACK_WS_PEER_INITIATED_CLOSE: len %d\n",
+                           len);
+               for (n = 0; n < (int)len; n++)
+                       lwsl_notice(" %d: 0x%02X\n", n,
+                                   ((unsigned char *)in)[n]);
+               break;
+
        default:
                break;
        }
index b9e4861..f773d15 100644 (file)
@@ -325,7 +325,7 @@ function ot_open() {
 }
 
 function ot_close() {
-       socket_ot.close();
+       socket_ot.close(3000, "Bye!");
 }
 
 /* lws-mirror protocol */