test server align rxbuf with permessage deflate rx buf size
authorAndy Green <andy@warmcat.com>
Fri, 1 Apr 2016 01:30:09 +0000 (09:30 +0800)
committerAndy Green <andy@warmcat.com>
Fri, 1 Apr 2016 01:30:09 +0000 (09:30 +0800)
Add a test html button that will send 9KB of junk to confirm it

https://github.com/warmcat/libwebsockets/issues/480

permessage-deflate now checks the protocol rx buffer size for being
>=128, if not, permessage-deflate is disabled on that connection.

If it is >=128 but less than the zlib decompress buffer size, the
zlib decompress buffer size for that connection is reduced to the
nearest power of two of the protocol rx buf size.

To test this, dumb_increment is left violating the >= 128 rx buffer
size and permessage-deflte can be seen to be disabled on his
connections in the test html.

Signed-off-by: Andy Green <andy@warmcat.com>
lib/client.c
lib/extension-permessage-deflate.c
lib/server-handshake.c
test-server/test-server.c
test-server/test.html

index 1ba809b9fdf4fcdbe7de37f134a383c3f14d8c4b..b4cd336172eea063aa462a7ab142fd0c763a9eab 100644 (file)
@@ -707,10 +707,14 @@ check_extensions:
 
                        /* allow him to construct his ext instance */
 
-                       ext->callback(lws_get_context(wsi), ext, wsi,
+                       if (ext->callback(lws_get_context(wsi), ext, wsi,
                                      LWS_EXT_CB_CLIENT_CONSTRUCT,
                                      (void *)&wsi->act_ext_user[wsi->count_act_ext],
-                                     (void *)&opts, 0);
+                                     (void *)&opts, 0)) {
+                               lwsl_notice(" ext %s failed construction\n", ext_name);
+                               ext++;
+                               continue;
+                       }
 
                        /*
                         * allow the user code to override ext defaults if it
index 6ae348a6e3ee2cdf2e9cb8025277536bca35d1aa..439120af1c3b465929307b9c781bc110ecbeb376 100644 (file)
@@ -75,6 +75,17 @@ lws_extension_callback_pm_deflate(struct lws_context *context,
 
        case LWS_EXT_CB_CLIENT_CONSTRUCT:
        case LWS_EXT_CB_CONSTRUCT:
+
+               n = LWS_MAX_SOCKET_IO_BUF;
+               if (wsi->protocol->rx_buffer_size)
+                       n =  wsi->protocol->rx_buffer_size;
+
+               if (n < 128) {
+                       lwsl_err(" permessage-deflate requires the protocol (%s) to have an RX buffer >= 128\n",
+                                       wsi->protocol->name);
+                       return -1;
+               }
+
                /* fill in **user */
                priv = lws_zalloc(sizeof(*priv));
                *((void **)user) = priv;
@@ -102,6 +113,23 @@ lws_extension_callback_pm_deflate(struct lws_context *context,
                priv->args[PMD_TX_BUF_PWR2] = 10; /* ie, 1024 */
                priv->args[PMD_COMP_LEVEL] = 1;
                priv->args[PMD_MEM_LEVEL] = 8;
+
+               /* cap the RX buf at the nearest power of 2 to protocol rx buf */
+
+               n = LWS_MAX_SOCKET_IO_BUF;
+               if (wsi->protocol->rx_buffer_size)
+                       n =  wsi->protocol->rx_buffer_size;
+
+               extra = 7;
+               while (n >= 1 << (extra + 1))
+                       extra++;
+
+               if (extra < priv->args[PMD_RX_BUF_PWR2]) {
+                       priv->args[PMD_RX_BUF_PWR2] = extra;
+                       lwsl_err(" Capping pmd rx to %d\n", 1 << extra);
+               }
+               lwsl_err("   ok\n");
+
                break;
 
        case LWS_EXT_CB_DESTROY:
index 5f52585256928208d3e5566e4aefec1280494b6b..fd126a7596c53899f8aa6619d6f84d5d8a4a5b41 100644 (file)
@@ -123,11 +123,6 @@ lws_extension_server_handshake(struct lws *wsi, char **p)
 
                        /* apply it */
 
-                       if (ext_count)
-                               *(*p)++ = ',';
-                       else
-                               LWS_CPYAPP(*p, "\x0d\x0aSec-WebSocket-Extensions: ");
-                       *p += sprintf(*p, "%s", ext_name);
                        ext_count++;
 
                        /* instantiate the extension on this conn */
@@ -136,10 +131,21 @@ lws_extension_server_handshake(struct lws *wsi, char **p)
 
                        /* allow him to construct his context */
 
-                       ext->callback(lws_get_context(wsi), ext, wsi,
+                       if (ext->callback(lws_get_context(wsi), ext, wsi,
                                      LWS_EXT_CB_CONSTRUCT,
                                      (void *)&wsi->act_ext_user[wsi->count_act_ext],
-                                     NULL, 0);
+                                     NULL, 0)) {
+                               lwsl_notice("ext %s failed construction\n", ext_name);
+                               ext_count--;
+                               ext++;
+                               continue;
+                       }
+
+                       if (ext_count > 1)
+                               *(*p)++ = ',';
+                       else
+                               LWS_CPYAPP(*p, "\x0d\x0aSec-WebSocket-Extensions: ");
+                       *p += sprintf(*p, "%s", ext_name);
 
                        wsi->count_act_ext++;
                        lwsl_parser("count_act_ext <- %d\n", wsi->count_act_ext);
index 09f7046472fc8ce8dfa6936cab054f652d1f5c23..8fabc8254fac1b64b05f7655d85f61f2d75525a3 100644 (file)
@@ -89,25 +89,25 @@ static struct lws_protocols protocols[] = {
                "dumb-increment-protocol",
                callback_dumb_increment,
                sizeof(struct per_session_data__dumb_increment),
-               10,
+               10, /* rx buf size must be >= permessage-deflate rx size */
        },
        {
                "lws-mirror-protocol",
                callback_lws_mirror,
                sizeof(struct per_session_data__lws_mirror),
-               128,
+               128, /* rx buf size must be >= permessage-deflate rx size */
        },
        {
                "lws-echogen",
                callback_lws_echogen,
                sizeof(struct per_session_data__echogen),
-               128,
+               128, /* rx buf size must be >= permessage-deflate rx size */
        },
        {
                "lws-status",
                callback_lws_status,
                sizeof(struct per_session_data__lws_status),
-               128,
+               128, /* rx buf size must be >= permessage-deflate rx size */
        },
        { NULL, NULL, 0, 0 } /* terminator */
 };
index eff2ba19d15a7c9075b1600e3ca6a1b89779607c..450a296b46f100ff97038ac37c64b302d2c479ff 100644 (file)
@@ -127,6 +127,7 @@ to zero just this connection's number.
            <td align=center><div id=number style="font-size:120%;"> </div></td>
            <td align=center>
             <input type=button id=offset value="Reset counter" onclick="reset();" >
+            <input type=button id=junk value="Send junk" onclick="junk();" >
            </td>
            </tr>
         </table>
@@ -477,7 +478,7 @@ document.getElementById("number").textContent = get_appropriate_ws_url();
                        document.getElementById("s_statustd").style.backgroundColor = "#40ff40";
                        document.getElementById("s_status").innerHTML =
                                " <b>websocket connection opened</b><br>" +
-                               san(socket_di.extensions);
+                               san(socket_status.extensions);
                } 
 
                socket_status.onmessage =function got_packet(msg) {
@@ -514,6 +515,12 @@ function reset() {
        socket_di.send("reset\n");
 }
 
+
+function junk() {
+       for(var word = ''; word.length < 9000; word += 'a'){}
+       socket_di.send(word);
+}
+
 var socket_ot;
 
 function ot_open() {
@@ -579,7 +586,7 @@ function ot_req_close() {
                        document.getElementById("wslm_statustd").style.backgroundColor = "#40ff40";
                        document.getElementById("wslm_status").innerHTML =
                                " <b>websocket connection opened</b><br>" +
-                               san(socket_di.extensions);
+                               san(socket_lm.extensions);
                } 
 
                socket_lm.onmessage =function got_packet(msg) {