# HG changeset patch # User jbe # Date 1434847347 -7200 # Node ID a1907691f740b402aebae72150c16bd39deb2c35 # Parent 2ed3d94a0eb785658423cb7fb8a6784f4996b467 Fixes to timeout system in HTTP module diff -r 2ed3d94a0eb7 -r a1907691f740 moonbridge_http.lua --- a/moonbridge_http.lua Sun Jun 21 02:05:24 2015 +0200 +++ b/moonbridge_http.lua Sun Jun 21 02:42:27 2015 +0200 @@ -231,21 +231,6 @@ end end end - -- function that enforces consumption of all input: - local function consume_all(timeout) - local starttime = timeout and moonbridge_io.timeref() - while consume do - if timeout then - if not poll(socket_set, nil, timeout-moonbridge_io.timeref(starttime)) then - return false - end - else - poll(socket_set, nil) - end - consume() - return true - end - end -- handle requests in a loop: repeat -- table for caching nil values: @@ -375,6 +360,60 @@ local chunk_bytes = 0 -- sum of lengths of chunks to send local streamed_post_params = {} -- mapping from POST field name to stream function local streamed_post_param_patterns = {} -- list of POST field pattern and stream function pairs + -- function to report an error: + local function request_error(throw_error, status, text) + if + state == "init" or + state == "no_status_sent" or + state == "info_status_sent" + then + local error_response_status, errmsg = pcall(function() + request:monologue() + request:send_status(status) + request:send_header("Content-Type", "text/plain") + request:send_data(status, "\n") + if text then + request:send_data("\n", text, "\n") + end + request:finish() + end) + if not error_response_status then + if text then + error("Error while sending error response (" .. status .. " / " .. text .. "): " .. errmsg) + else + error("Error while sending error response (" .. status .. "): " .. errmsg) + end + end + end + if throw_error then + local errmsg = "Error while reading request from client. Error response: " .. status + if text then + errmsg = errmsg .. " (" .. text .. ")" + end + error(errmsg) + else + return survive + end + end + -- function that enforces consumption of all input: + local function consume_all(timeout) + local starttime = timeout and moonbridge_io.timeref() + while consume do + if timeout then + -- passed timeout does not get reset but refers to starttime + if not poll(socket_set, nil, timeout-moonbridge_io.timeref(starttime)) then + return false + end + else + -- stall_timeout gets reset for every poll + if not poll(socket_set, nil, stall_timeout) then + request_error(true, "408 Request Timeout", "Timeout while waiting for request body") + end + end + consume() + end + return true + end -- function to assert non-faulty handle: local function assert_not_faulty() assert(state ~= "faulty", "Tried to use faulty request handle") @@ -439,41 +478,6 @@ state = old_state end end - -- function to report an error: - local function request_error(throw_error, status, text) - if - state == "init" or - state == "no_status_sent" or - state == "info_status_sent" - then - local error_response_status, errmsg = pcall(function() - request:monologue() - request:send_status(status) - request:send_header("Content-Type", "text/plain") - request:send_data(status, "\n") - if text then - request:send_data("\n", text, "\n") - end - request:finish() - end) - if not error_response_status then - if text then - error("Error while sending error response (" .. status .. " / " .. text .. "): " .. errmsg) - else - error("Error while sending error response (" .. status .. "): " .. errmsg) - end - end - end - if throw_error then - local errmsg = "Error while reading request from client. Error response: " .. status - if text then - errmsg = errmsg .. " (" .. text .. ")" - end - error(errmsg) - else - return survive - end - end -- read functions local function read(...) local data, status = socket:read_yield(...)