allow message processing from onopen browser context
authorYonathan Yusim <yonathan@boxee.tv>
Sun, 8 Apr 2012 22:42:39 +0000 (06:42 +0800)
committerAndy Green <andy.green@linaro.org>
Sun, 8 Apr 2012 22:42:39 +0000 (06:42 +0800)
Found an issue in libwebsockets - if a server sends a message within its "onopen" context then the message is getting swallowed and not passed to calling client (means LWS_CALLBACK_CLIENT_RECEIVE is never getting called).
I've fixed the bug - pls find attached patch.

Signed-off-by: Yonathan Yusim <yonathan@boxee.tv>
Signed-off-by: Andy Green <andy@warmcat.com>
lib/libwebsockets.c

index 94f0a94..1feb728 100644 (file)
@@ -1458,6 +1458,7 @@ libwebsocket_service_fd(struct libwebsocket_context *context,
        int more = 1;
        struct lws_tokens eff_buf;
        int opt = 1;
+       char c;
 
 #ifdef LWS_OPENSSL_SUPPORT
        char ssl_err_buf[512];
@@ -1877,25 +1878,28 @@ libwebsocket_service_fd(struct libwebsocket_context *context,
                 *  Sec-WebSocket-Protocol: chat
                 */
 
-       #ifdef LWS_OPENSSL_SUPPORT
-               if (wsi->use_ssl)
-                       len = SSL_read(wsi->ssl, pkt, sizeof pkt);
-               else
-       #endif
-                       len = recv(wsi->sock, pkt, sizeof pkt, 0);
+               /*
+                * we have to take some care here to only take from the
+                * socket bytewise.  The browser may (and has been seen to
+                * in the case that onopen() performs websocket traffic)
+                * coalesce both handshake response and websocket traffic
+                * in one packet, since at that point the connection is
+                * definitively ready from browser pov.
+                */
 
-               if (len < 0) {
-                       fprintf(stderr,
-                                 "libwebsocket_client_handshake read error\n");
-                       goto bail3;
-               }
+               while (wsi->parser_state != WSI_PARSING_COMPLETE && len > 0) {
+#ifdef LWS_OPENSSL_SUPPORT
+                       if (wsi->use_ssl)
+                               len = SSL_read(wsi->ssl, &c, 1);
+                        else
+#endif
+                               len = recv(wsi->sock, &c, 1, 0);
 
-               p = pkt;
-               for (n = 0; n < len; n++)
-                       libwebsocket_parse(wsi, *p++);
+                       libwebsocket_parse(wsi, c);
+               }
 
                /*
-                * may be coming in multiple packets, there is a 5-second
+                * hs may also be coming in multiple packets, there is a 5-second
                 * libwebsocket timeout still active here too, so if parsing did
                 * not complete just wait for next packet coming in this state
                 */
@@ -1903,6 +1907,12 @@ libwebsocket_service_fd(struct libwebsocket_context *context,
                if (wsi->parser_state != WSI_PARSING_COMPLETE)
                        break;
 
+               /*
+                * otherwise deal with the handshake.  If there's any
+                * packet traffic already arrived we'll trigger poll() again
+                * right away and deal with it that way
+                */
+
                return lws_client_interpret_server_handshake(context, wsi);
 
 bail3: