mod_adhoc: Add support for commands only executable by global administrators
[prosody.git] / util / httpstream.lua
index 1aad0d916413b775c4b8b04584d65b1a19c2a69a..bdc3fce776c45827ffdf7cd533d7df69dc1a4cdc 100644 (file)
@@ -46,7 +46,7 @@ local function parser(success_cb, parser_type, options_cb)
                        local status_line = readline();
                        local method, path, httpversion = status_line:match("^(%S+)%s+(%S+)%s+HTTP/(%S+)$");
                        if not method then coroutine.yield("invalid-status-line"); end
-                       -- TODO parse url
+                       path = path:gsub("^//+", "/"); -- TODO parse url more
                        local headers = readheaders();
                        
                        -- read body
@@ -67,7 +67,8 @@ local function parser(success_cb, parser_type, options_cb)
                        -- read status line
                        local status_line = readline();
                        local httpversion, status_code, reason_phrase = status_line:match("^HTTP/(%S+)%s+(%d%d%d)%s+(.*)$");
-                       if not httpversion then coroutine.yield("invalid-status-line"); end
+                       status_code = tonumber(status_code);
+                       if not status_code then coroutine.yield("invalid-status-line"); end
                        local headers = readheaders();
                        
                        -- read body
@@ -79,7 +80,18 @@ local function parser(success_cb, parser_type, options_cb)
                        local body;
                        if have_body then
                                local len = tonumber(headers["content-length"]);
-                               if len then -- TODO check for invalid len
+                               if headers["transfer-encoding"] == "chunked" then
+                                       body = "";
+                                       while true do
+                                               local chunk_size = readline():match("^%x+");
+                                               if not chunk_size then coroutine.yield("invalid-chunk-size"); end
+                                               chunk_size = tonumber(chunk_size, 16)
+                                               if chunk_size == 0 then break; end
+                                               body = body..readlength(chunk_size);
+                                               if readline() ~= "" then coroutine.yield("invalid-chunk-ending"); end
+                                       end
+                                       local trailers = readheaders();
+                               elseif len then -- TODO check for invalid len
                                        body = readlength(len);
                                else -- read to end
                                        repeat
@@ -92,9 +104,12 @@ local function parser(success_cb, parser_type, options_cb)
                        
                        success_cb({
                                code = status_code;
+                               httpversion = httpversion;
+                               headers = headers;
+                               body = body;
+                               -- COMPAT the properties below are deprecated
                                responseversion = httpversion;
                                responseheaders = headers;
-                               body = body;
                        });
                end
        else coroutine.yield("unknown-parser-type"); end