aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Wild <mwild1@gmail.com>2023-02-09 22:57:32 +0000
committerMatthew Wild <mwild1@gmail.com>2023-02-09 22:57:32 +0000
commit0fd88a07a4951d6e06e20f7c3dcc5c115cd78ace (patch)
treeeccb53440d4a7c55e6490e08aa97381db3100588
parent28e3b19ca114cc499d02c32bd470670b349c09bf (diff)
downloadprosody-0fd88a07a4951d6e06e20f7c3dcc5c115cd78ace.tar.gz
prosody-0fd88a07a4951d6e06e20f7c3dcc5c115cd78ace.zip
net.http.parser: Improve handling of responses without content-length
This ensures that we support responses without a content-length header, and allow streaming them through the streaming handler interface. An example of such a response would be Server-Sent Events streams.
-rw-r--r--net/http/parser.lua17
-rw-r--r--spec/net_http_parser_spec.lua6
2 files changed, 14 insertions, 9 deletions
diff --git a/net/http/parser.lua b/net/http/parser.lua
index 7fbade4c..b95d9017 100644
--- a/net/http/parser.lua
+++ b/net/http/parser.lua
@@ -130,10 +130,13 @@ function httpstream.new(success_cb, error_cb, parser_type, options_cb)
partial = true;
};
end
- if len and len > bodylimit then
+ if not len or len > bodylimit then
-- Early notification, for redirection
success_cb(packet);
- if not packet.body_sink then error = true; return error_cb("content-length-limit-exceeded"); end
+ if not packet.body_sink and (len and len > bodylimit) then
+ error = true;
+ return error_cb("content-length-limit-exceeded");
+ end
end
if chunked and not packet.body_sink then
success_cb(packet);
@@ -174,9 +177,11 @@ function httpstream.new(success_cb, error_cb, parser_type, options_cb)
end
elseif packet.body_sink then
local chunk = buffer:read_chunk(len);
- while chunk and len > 0 do
+ while chunk and (not len or len > 0) do
if packet.body_sink:write(chunk) then
- len = len - #chunk;
+ if len then
+ len = len - #chunk;
+ end
chunk = buffer:read_chunk(len);
else
error = true;
@@ -188,9 +193,9 @@ function httpstream.new(success_cb, error_cb, parser_type, options_cb)
packet.partial = nil;
success_cb(packet);
end
- elseif buffer:length() >= len then
+ elseif not len or buffer:length() >= len then -- or not len
assert(not chunked)
- packet.body = buffer:read(len) or "";
+ packet.body = len and buffer:read(len) or buffer:read_chunk() or "";
state = nil;
packet.partial = nil;
success_cb(packet);
diff --git a/spec/net_http_parser_spec.lua b/spec/net_http_parser_spec.lua
index f71cad20..ed70c431 100644
--- a/spec/net_http_parser_spec.lua
+++ b/spec/net_http_parser_spec.lua
@@ -87,7 +87,7 @@ o
]],
{
- body = "Hello", count = 2;
+ body = "Hello", count = 3;
}
);
end);
@@ -116,7 +116,7 @@ o
]],
{
- body = "Hello", count = 3;
+ body = "Hello", count = 4;
}
);
end);
@@ -129,7 +129,7 @@ o
assert.equal("25930f021785ae14053a322c2dbc1897c3769720", sha1(data, true), "test data malformed");
test_stream(data, {
- body = string.rep("~", 11085), count = 2;
+ body = string.rep("~", 11085), count = 3;
});
end);
end);