dont leak when protocol agreement probs
authorAndy Green <andy.green@linaro.org>
Sat, 9 Mar 2013 03:52:18 +0000 (11:52 +0800)
committerAndy Green <andy.green@linaro.org>
Sat, 9 Mar 2013 03:52:18 +0000 (11:52 +0800)
Signed-off-by: Andy Green <andy.green@linaro.org>
lib/handshake.c
lib/libwebsockets.c
lib/private-libwebsockets.h

index 50138dd..bfcad65 100644 (file)
@@ -96,7 +96,7 @@ libwebsocket_read(struct libwebsocket_context *context,
                for (n = 0; n < len; n++)
                        if (libwebsocket_parse(wsi, *buf++)) {
                                lwsl_info("libwebsocket_parse failed\n");
-                               goto bail;
+                               goto bail_nuke_ah;
                        }
 
                if (wsi->u.hdr.parser_state != WSI_PARSING_COMPLETE)
@@ -104,6 +104,8 @@ libwebsocket_read(struct libwebsocket_context *context,
 
                lwsl_parser("libwebsocket_parse sees parsing complete\n");
 
+               wsi->mode = LWS_CONNMODE_PRE_WS_SERVING_ACCEPT;
+
                /* is this websocket protocol or normal http 1.0? */
 
                if (!lws_hdr_total_length(wsi, WSI_TOKEN_UPGRADE) ||
@@ -113,21 +115,14 @@ libwebsocket_read(struct libwebsocket_context *context,
 
                        if (!lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI)) {
                                lwsl_warn("Missing URI in HTTP request\n");
-                               /* drop the header info */
-                               if (wsi->u.hdr.ah)
-                                       free(wsi->u.hdr.ah);
-                               goto bail;
+                               goto bail_nuke_ah;
                        }
 
                        lwsl_info("HTTP request for '%s'\n",
                                lws_hdr_simple_ptr(wsi, WSI_TOKEN_GET_URI));
 
-                       if (libwebsocket_ensure_user_space(wsi)) {
-                               /* drop the header info */
-                               if (wsi->u.hdr.ah)
-                                       free(wsi->u.hdr.ah);
-                               goto bail;
-                       }
+                       if (libwebsocket_ensure_user_space(wsi))
+                               goto bail_nuke_ah;
 
                        /*
                         * Hm we still need the headers so the
@@ -143,6 +138,7 @@ libwebsocket_read(struct libwebsocket_context *context,
                        /* union transition */
                        memset(&wsi->u, 0, sizeof(wsi->u));
 
+                       wsi->mode = LWS_CONNMODE_HTTP_SERVING;
                        wsi->state = WSI_STATE_HTTP;
                        n = 0;
                        if (wsi->protocol->callback)
@@ -196,7 +192,7 @@ libwebsocket_read(struct libwebsocket_context *context,
                        } else {
                                lwsl_err("Req protocol %s not supported\n",
                                   lws_hdr_simple_ptr(wsi, WSI_TOKEN_PROTOCOL));
-                               goto bail;
+                               goto bail_nuke_ah;
                        }
                }
 
@@ -299,6 +295,11 @@ libwebsocket_read(struct libwebsocket_context *context,
 
        return 0;
 
+bail_nuke_ah:
+       /* drop the header info */
+       if (wsi->u.hdr.ah)
+               free(wsi->u.hdr.ah);
+
 bail:
        lwsl_info("closing connection at libwebsocket_read bail:\n");
 
index 0c85f0a..c361527 100644 (file)
@@ -207,6 +207,7 @@ libwebsocket_close_and_free_session(struct libwebsocket_context *context,
        wsi->u.ws.close_reason = reason;
 
        if (wsi->mode == LWS_CONNMODE_HTTP_SERVING && wsi->u.http.fd) {
+               lwsl_notice("closing http fd %d\n", wsi->u.http.fd);
                close(wsi->u.http.fd);
                wsi->u.http.fd = 0;
        }
index f1ff5c8..eecdd3d 100644 (file)
@@ -208,6 +208,7 @@ enum lws_rx_parse_state {
 
 enum connection_mode {
        LWS_CONNMODE_HTTP_SERVING,
+       LWS_CONNMODE_PRE_WS_SERVING_ACCEPT,
 
        LWS_CONNMODE_WS_SERVING,
        LWS_CONNMODE_WS_CLIENT,