8d2dcd
diff --git a/modules/lua/lua_request.c b/modules/lua/lua_request.c
8d2dcd
index ba63584..c1ba74a 100644
8d2dcd
--- a/modules/lua/lua_request.c
8d2dcd
+++ b/modules/lua/lua_request.c
8d2dcd
@@ -2193,23 +2193,20 @@ static int lua_websocket_greet(lua_State *L)
8d2dcd
     return 0;
8d2dcd
 }
8d2dcd
 
8d2dcd
-static apr_status_t lua_websocket_readbytes(conn_rec* c, char* buffer, 
8d2dcd
-        apr_off_t len) 
8d2dcd
+static apr_status_t lua_websocket_readbytes(conn_rec* c,
8d2dcd
+                                            apr_bucket_brigade *brigade,
8d2dcd
+                                            char* buffer, apr_off_t len)
8d2dcd
 {
8d2dcd
-    apr_bucket_brigade *brigade = apr_brigade_create(c->pool, c->bucket_alloc);
8d2dcd
+    apr_size_t delivered;
8d2dcd
     apr_status_t rv;
8d2dcd
+
8d2dcd
     rv = ap_get_brigade(c->input_filters, brigade, AP_MODE_READBYTES, 
8d2dcd
             APR_BLOCK_READ, len);
8d2dcd
     if (rv == APR_SUCCESS) {
8d2dcd
-        if (!APR_BRIGADE_EMPTY(brigade)) {
8d2dcd
-            apr_bucket* bucket = APR_BRIGADE_FIRST(brigade);
8d2dcd
-            const char* data = NULL;
8d2dcd
-            apr_size_t data_length = 0;
8d2dcd
-            rv = apr_bucket_read(bucket, &data, &data_length, APR_BLOCK_READ);
8d2dcd
-            if (rv == APR_SUCCESS) {
8d2dcd
-                memcpy(buffer, data, len);
8d2dcd
-            }
8d2dcd
-            apr_bucket_delete(bucket);
8d2dcd
+        delivered = len;
8d2dcd
+        rv = apr_brigade_flatten(brigade, buffer, &delivered);
8d2dcd
+        if ((rv == APR_SUCCESS) && (delivered < len)) {
8d2dcd
+            rv = APR_INCOMPLETE;
8d2dcd
         }
8d2dcd
     }
8d2dcd
     apr_brigade_cleanup(brigade);
8d2dcd
@@ -2239,35 +2236,28 @@ static int lua_websocket_peek(lua_State *L)
8d2dcd
 
8d2dcd
 static int lua_websocket_read(lua_State *L) 
8d2dcd
 {
8d2dcd
-    apr_socket_t *sock;
8d2dcd
     apr_status_t rv;
8d2dcd
     int do_read = 1;
8d2dcd
     int n = 0;
8d2dcd
-    apr_size_t len = 1;
8d2dcd
     apr_size_t plen = 0;
8d2dcd
     unsigned short payload_short = 0;
8d2dcd
     apr_uint64_t payload_long = 0;
8d2dcd
     unsigned char *mask_bytes;
8d2dcd
     char byte;
8d2dcd
-    int plaintext;
8d2dcd
-    
8d2dcd
-    
8d2dcd
+    apr_bucket_brigade *brigade;
8d2dcd
+    conn_rec* c;
8d2dcd
+
8d2dcd
     request_rec *r = ap_lua_check_request_rec(L, 1);
8d2dcd
-    plaintext = ap_lua_ssl_is_https(r->connection) ? 0 : 1;
8d2dcd
+    c = r->connection;
8d2dcd
 
8d2dcd
-    
8d2dcd
     mask_bytes = apr_pcalloc(r->pool, 4);
8d2dcd
-    sock = ap_get_conn_socket(r->connection);
8d2dcd
+
8d2dcd
+    brigade = apr_brigade_create(r->pool, c->bucket_alloc);
8d2dcd
 
8d2dcd
     while (do_read) {
8d2dcd
         do_read = 0;
8d2dcd
         /* Get opcode and FIN bit */
8d2dcd
-        if (plaintext) {
8d2dcd
-            rv = apr_socket_recv(sock, &byte, &len;;
8d2dcd
-        }
8d2dcd
-        else {
8d2dcd
-            rv = lua_websocket_readbytes(r->connection, &byte, 1);
8d2dcd
-        }
8d2dcd
+        rv = lua_websocket_readbytes(c, brigade, &byte, 1);
8d2dcd
         if (rv == APR_SUCCESS) {
8d2dcd
             unsigned char ubyte, fin, opcode, mask, payload;
8d2dcd
             ubyte = (unsigned char)byte;
8d2dcd
@@ -2277,12 +2267,7 @@ static int lua_websocket_read(lua_State *L)
8d2dcd
             opcode = ubyte & 0xf;
8d2dcd
 
8d2dcd
             /* Get the payload length and mask bit */
8d2dcd
-            if (plaintext) {
8d2dcd
-                rv = apr_socket_recv(sock, &byte, &len;;
8d2dcd
-            }
8d2dcd
-            else {
8d2dcd
-                rv = lua_websocket_readbytes(r->connection, &byte, 1);
8d2dcd
-            }
8d2dcd
+            rv = lua_websocket_readbytes(c, brigade, &byte, 1);
8d2dcd
             if (rv == APR_SUCCESS) {
8d2dcd
                 ubyte = (unsigned char)byte;
8d2dcd
                 /* Mask is the first bit */
8d2dcd
@@ -2293,40 +2278,25 @@ static int lua_websocket_read(lua_State *L)
8d2dcd
 
8d2dcd
                 /* Extended payload? */
8d2dcd
                 if (payload == 126) {
8d2dcd
-                    len = 2;
8d2dcd
-                    if (plaintext) {
8d2dcd
-                        /* XXX: apr_socket_recv does not receive len bits, only up to len bits! */
8d2dcd
-                        rv = apr_socket_recv(sock, (char*) &payload_short, &len;;
8d2dcd
-                    }
8d2dcd
-                    else {
8d2dcd
-                        rv = lua_websocket_readbytes(r->connection, 
8d2dcd
-                                (char*) &payload_short, 2);
8d2dcd
-                    }
8d2dcd
-                    payload_short = ntohs(payload_short);
8d2dcd
+                    rv = lua_websocket_readbytes(c, brigade,
8d2dcd
+                                                 (char*) &payload_short, 2);
8d2dcd
 
8d2dcd
-                    if (rv == APR_SUCCESS) {
8d2dcd
-                        plen = payload_short;
8d2dcd
-                    }
8d2dcd
-                    else {
8d2dcd
+                    if (rv != APR_SUCCESS) {
8d2dcd
                         return 0;
8d2dcd
                     }
8d2dcd
+
8d2dcd
+                    plen = ntohs(payload_short);
8d2dcd
                 }
8d2dcd
                 /* Super duper extended payload? */
8d2dcd
                 if (payload == 127) {
8d2dcd
-                    len = 8;
8d2dcd
-                    if (plaintext) {
8d2dcd
-                        rv = apr_socket_recv(sock, (char*) &payload_long, &len;;
8d2dcd
-                    }
8d2dcd
-                    else {
8d2dcd
-                        rv = lua_websocket_readbytes(r->connection, 
8d2dcd
-                                (char*) &payload_long, 8);
8d2dcd
-                    }
8d2dcd
-                    if (rv == APR_SUCCESS) {
8d2dcd
-                        plen = ap_ntoh64(&payload_long);
8d2dcd
-                    }
8d2dcd
-                    else {
8d2dcd
+                    rv = lua_websocket_readbytes(c, brigade,
8d2dcd
+                                                 (char*) &payload_long, 8);
8d2dcd
+
8d2dcd
+                    if (rv != APR_SUCCESS) {
8d2dcd
                         return 0;
8d2dcd
                     }
8d2dcd
+
8d2dcd
+                    plen = ap_ntoh64(&payload_long);
8d2dcd
                 }
8d2dcd
                 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03210)
8d2dcd
                               "Websocket: Reading %" APR_SIZE_T_FMT " (%s) bytes, masking is %s. %s", 
8d2dcd
@@ -2335,46 +2305,27 @@ static int lua_websocket_read(lua_State *L)
8d2dcd
                               mask ? "on" : "off", 
8d2dcd
                               fin ? "This is a final frame" : "more to follow");
8d2dcd
                 if (mask) {
8d2dcd
-                    len = 4;
8d2dcd
-                    if (plaintext) {
8d2dcd
-                        rv = apr_socket_recv(sock, (char*) mask_bytes, &len;;
8d2dcd
-                    }
8d2dcd
-                    else {
8d2dcd
-                        rv = lua_websocket_readbytes(r->connection, 
8d2dcd
-                                (char*) mask_bytes, 4);
8d2dcd
-                    }
8d2dcd
+                    rv = lua_websocket_readbytes(c, brigade,
8d2dcd
+                                                 (char*) mask_bytes, 4);
8d2dcd
+
8d2dcd
                     if (rv != APR_SUCCESS) {
8d2dcd
                         return 0;
8d2dcd
                     }
8d2dcd
                 }
8d2dcd
                 if (plen < (HUGE_STRING_LEN*1024) && plen > 0) {
8d2dcd
                     apr_size_t remaining = plen;
8d2dcd
-                    apr_size_t received;
8d2dcd
-                    apr_off_t at = 0;
8d2dcd
                     char *buffer = apr_palloc(r->pool, plen+1);
8d2dcd
                     buffer[plen] = 0;
8d2dcd
 
8d2dcd
-                    if (plaintext) {
8d2dcd
-                        while (remaining > 0) {
8d2dcd
-                            received = remaining;
8d2dcd
-                            rv = apr_socket_recv(sock, buffer+at, &received);
8d2dcd
-                            if (received > 0 ) {
8d2dcd
-                                remaining -= received;
8d2dcd
-                                at += received;
8d2dcd
-                            }
8d2dcd
-                        }
8d2dcd
-                        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, 
8d2dcd
-                                "Websocket: Frame contained %" APR_OFF_T_FMT " bytes, pushed to Lua stack", 
8d2dcd
-                                at);
8d2dcd
-                    }
8d2dcd
-                    else {
8d2dcd
-                        rv = lua_websocket_readbytes(r->connection, buffer, 
8d2dcd
-                                remaining);
8d2dcd
-                        ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, 
8d2dcd
-                                "Websocket: SSL Frame contained %" APR_SIZE_T_FMT " bytes, "\
8d2dcd
-                                "pushed to Lua stack", 
8d2dcd
-                                remaining);
8d2dcd
+                    rv = lua_websocket_readbytes(c, brigade, buffer, remaining);
8d2dcd
+
8d2dcd
+                    if (rv != APR_SUCCESS) {
8d2dcd
+                        return 0;
8d2dcd
                     }
8d2dcd
+
8d2dcd
+                    ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
8d2dcd
+                                  "Websocket: Frame contained %" APR_SIZE_T_FMT \
8d2dcd
+                                  " bytes, pushed to Lua stack", remaining);
8d2dcd
                     if (mask) {
8d2dcd
                         for (n = 0; n < plen; n++) {
8d2dcd
                             buffer[n] ^= mask_bytes[n%4];
8d2dcd
@@ -2386,14 +2337,25 @@ static int lua_websocket_read(lua_State *L)
8d2dcd
                     return 2;
8d2dcd
                 }
8d2dcd
 
8d2dcd
-
8d2dcd
                 /* Decide if we need to react to the opcode or not */
8d2dcd
                 if (opcode == 0x09) { /* ping */
8d2dcd
                     char frame[2];
8d2dcd
-                    plen = 2;
8d2dcd
+                    apr_bucket *b;
8d2dcd
+
8d2dcd
                     frame[0] = 0x8A;
8d2dcd
                     frame[1] = 0;
8d2dcd
-                    apr_socket_send(sock, frame, &plen); /* Pong! */
8d2dcd
+
8d2dcd
+                    /* Pong! */
8d2dcd
+                    b = apr_bucket_transient_create(frame, 2, c->bucket_alloc);
8d2dcd
+                    APR_BRIGADE_INSERT_TAIL(brigade, b);
8d2dcd
+
8d2dcd
+                    rv = ap_pass_brigade(c->output_filters, brigade);
8d2dcd
+                    apr_brigade_cleanup(brigade);
8d2dcd
+
8d2dcd
+                    if (rv != APR_SUCCESS) {
8d2dcd
+                        return 0;
8d2dcd
+                    }
8d2dcd
+
8d2dcd
                     do_read = 1;
8d2dcd
                 }
8d2dcd
             }