# HG changeset patch # User jbe # Date 1434672198 -7200 # Node ID f0dc143f510adc629fae7e16265185acdfbb1122 # Parent 31820816f55431bc59676d767c74c6670d4434ce Some code cleanup / fixes in HTTP module diff -r 31820816f554 -r f0dc143f510a moonbridge_http.lua --- a/moonbridge_http.lua Fri Jun 19 00:44:01 2015 +0200 +++ b/moonbridge_http.lua Fri Jun 19 02:03:18 2015 +0200 @@ -354,30 +354,32 @@ 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 - -- functions to assert proper output/closing: - local function assert_output(...) - local retval, errmsg = ... - if retval then return ... end - state = "faulty" - socket:reset() - error("Could not send data to client: " .. errmsg) - end - local function assert_close(...) - local retval, errmsg = ... - if retval then return ... end - state = "faulty" - error("Could not finish sending data to client: " .. errmsg) - end -- function to assert non-faulty handle: local function assert_not_faulty() assert(state ~= "faulty", "Tried to use faulty request handle") end -- functions to send data to the browser: local function send(...) - assert_output(socket:write_call(unblock, ...)) + local old_state, state = state, "faulty" + if not socket:write_call(unblock, ...) then + socket:reset() + error("Could not send data to client: " .. errmsg) + end + state = old_state end local function send_flush(...) - assert_output(socket:flush_call(unblock, ...)) + local old_state, state = state, "faulty" + if not socket:flush_call(unblock, ...) then + socket:reset() + error("Could not send data to client: " .. errmsg) + end + state = old_state + end + -- function to assert proper finish/close/reset: + local function assert_close(retval, errmsg) + if not retval then + error("Could not finish sending data to client: " .. errmsg) + end end -- function to finish request: local function finish() @@ -387,26 +389,29 @@ -- close output stream: send_flush() assert_close(socket:finish()) - -- wait for EOF of peer to avoid immediate TCP RST condition: + -- wait for EOF from peer to avoid immediate TCP RST condition: consume_all() -- fully close socket: assert_close(socket:close()) else + -- flush outgoing data: send_flush() - process_body_chunk = nil + -- consume incoming data: consume_all() end end -- function that writes out buffered chunks (without flushing the socket): function send_chunk() if chunk_bytes > 0 then - assert_output(socket:write(string.format("%x\r\n", chunk_bytes))) - for i = 1, #chunk_parts do -- TODO: evaluated only once? + local old_state, state = state, "faulty" + send(string.format("%x\r\n", chunk_bytes)) + for i = 1, #chunk_parts do send(chunk_parts[i]) chunk_parts[i] = nil end chunk_bytes = 0 send("\r\n") + state = old_state end end -- function to report an error: @@ -431,7 +436,11 @@ request:finish() end) if not error_response_status then - error("Unexpected error while sending error response: " .. errmsg2) + if text then + error("Error while sending error response (" .. status .. " / " .. text .. "): " .. errmsg2) + else + error("Error while sending error response (" .. status .. "): " .. errmsg2) + end end elseif state ~= "faulty" then state = "faulty" @@ -788,7 +797,7 @@ end end end - assert_output(socket:write(key, ": ", value, "\r\n")) + send(socket:write(key, ": ", value, "\r\n")) end -- function to terminate header section in response, optionally flushing: -- (may be called multiple times unless response is finished) @@ -802,6 +811,7 @@ if close_requested and not close_responded then request:send_header("Connection", "close") end + state = "faulty" send("\r\n") finish() state = "finished" @@ -812,6 +822,7 @@ if close_requested and not close_responded then request:send_header("Connection", "close") end + state = "faulty" send("\r\n") if request.method == "HEAD" then finish()