Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Infinite loop when onstream func throws error before stream is read #204

Open
leafo opened this issue Nov 3, 2022 · 1 comment
Open
Labels

Comments

@leafo
Copy link
Contributor

leafo commented Nov 3, 2022

The following code will loop infinitely when you make a request to the server. onstream and onerror are called endlessly, the requesting client hangs. There doesn't appear to be a way to finalize the stream in the error handler based on what I've looked at so far.

I would expect it to terminate the request with a 503 error, as if you had triggered an error after getting headers.

My guess that is that since the stream doesn't make any progress being processed in the stream handler before error it's re-queued to be processed again, hence the infinite loop.

Note: It's necessary to provide a custom onerror function, as the default one will terminate the entire server by throwing an error.

local http_server = require "http.server"
local http_headers = require "http.headers"

local function onstream(server, stream)
	error("throwing an error before get_headers will cause infinite loop!")

	local req_headers = stream:get_headers()
	error("this is fine") -- error after get_headers will terminate request with 503 error as expected
end

local server = assert(http_server.listen {
	host = "127.0.0.1";
	port = 8080;
	onstream = onstream;
	onerror = function(myserver, context, op, err, errno)
		local msg = op .. " on " .. tostring(context) .. " failed"
		if err then
			msg = msg .. ": " .. tostring(err)
		end
		assert(io.stderr:write(msg, "\n"))
	end;
})

assert(server:loop())
@daurnimator daurnimator added the bug label Nov 4, 2022
@daurnimator
Copy link
Owner

onstream fires when there is a request ready to be handled: if not even a single byte of it is read, then onstream will fire again on the next main loop iteration.
If you haven't called get_headers, then it hasn't even started handling the request, and as such it can't terminate the request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants