fix onopen browser context patch
[profile/ivi/libwebsockets.git] / lib / libwebsockets.c
index f8522b5..b05f79e 100644 (file)
@@ -1089,8 +1089,8 @@ lws_client_interpret_server_handshake(struct libwebsocket_context *context,
                }
 
                strtolower(wsi->utf8_token[WSI_TOKEN_HTTP].token);
-               if (strcmp(wsi->utf8_token[WSI_TOKEN_HTTP].token,
-                       "101 websocket protocol handshake")) {
+               if (strncmp(wsi->utf8_token[WSI_TOKEN_HTTP].token,
+                                                           "101", 3)) {
                        fprintf(stderr, "libwebsocket_client_handshake "
                                "server sent bad HTTP response '%s'\n",
                                wsi->utf8_token[WSI_TOKEN_HTTP].token);
@@ -1145,8 +1145,7 @@ lws_client_interpret_server_handshake(struct libwebsocket_context *context,
         */
 
        strtolower(wsi->utf8_token[WSI_TOKEN_HTTP].token);
-       if (strcmp(wsi->utf8_token[WSI_TOKEN_HTTP].token,
-                                          "101 switching protocols")) {
+       if (strncmp(wsi->utf8_token[WSI_TOKEN_HTTP].token, "101", 3)) {
                fprintf(stderr, "libwebsocket_client_handshake "
                                "server sent bad HTTP response '%s'\n",
                                 wsi->utf8_token[WSI_TOKEN_HTTP].token);
@@ -1449,7 +1448,7 @@ libwebsocket_service_fd(struct libwebsocket_context *context,
        struct libwebsocket *new_wsi;
        int n;
        int m;
-       size_t len;
+       ssize_t len;
        int accept_fd;
        unsigned int clilen;
        struct sockaddr_in cli_addr;
@@ -1459,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];
@@ -1878,25 +1878,29 @@ 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;
-               }
+               len = 1;
+               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
                 */
@@ -1904,6 +1908,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:
@@ -1965,7 +1975,10 @@ bail3:
                if (eff_buf.token_len < 0) {
                        fprintf(stderr, "Socket read returned %d\n",
                                                            eff_buf.token_len);
-                       break;
+                       if (errno != EINTR)
+                               libwebsocket_close_and_free_session(context, wsi,
+                                                                LWS_CLOSE_STATUS_NOSTATUS);
+                       return 1;
                }
                if (!eff_buf.token_len) {
                        libwebsocket_close_and_free_session(context, wsi,