moonbridge
diff moonbridge_http.lua @ 115:7014436d88ea
Added helper function moonbridge_io.timeref(...); HTTP module sends 408 Request Timeout
author | jbe |
---|---|
date | Fri Apr 10 00:33:07 2015 +0200 (2015-04-10) |
parents | fca51922b708 |
children | 831f2d4b2d73 8ab33bfb47e7 |
line diff
1.1 --- a/moonbridge_http.lua Thu Apr 09 20:02:43 2015 +0200 1.2 +++ b/moonbridge_http.lua Fri Apr 10 00:33:07 2015 +0200 1.3 @@ -180,13 +180,16 @@ 1.4 end 1.5 local input_chunk_size = options.maximum_input_chunk_size or options.chunk_size or 16384 1.6 local output_chunk_size = options.minimum_output_chunk_size or options.chunk_size or 1024 1.7 - local request_header_timeout, response_timeout 1.8 + local request_idle_timeout, request_header_timeout, response_timeout 1.9 + if options.request_idle_timeout ~= nil then 1.10 + request_idle_timeout = options.request_idle_timeout or 0 1.11 + else 1.12 + request_idle_timeout = 330 1.13 + end 1.14 if options.request_header_timeout ~= nil then 1.15 - request_header_timeout = options.request_header_timeout 1.16 - elseif options.timeout ~= nil then 1.17 - request_header_timeout = options.timeout or 0 1.18 + request_header_timeout = options.request_header_timeout or 0 1.19 else 1.20 - request_header_timeout = 360 1.21 + request_header_timeout = 30 1.22 end 1.23 if options.timeout ~= nil then 1.24 response_timeout = options.timeout or 0 1.25 @@ -195,10 +198,9 @@ 1.26 end 1.27 -- return connect handler: 1.28 return function(socket) 1.29 + local socket_set = {[socket] = true} -- used for moonbridge_io.poll(...) 1.30 local survive = true -- set to false if process shall be terminated later 1.31 repeat 1.32 - -- (re)set timeout: 1.33 - timeout(request_header_timeout or 0) 1.34 -- process named arguments "request_header_size_limit" and "request_body_size_limit": 1.35 local remaining_header_size_limit = options.request_header_size_limit or 1024*1024 1.36 local remaining_body_size_limit = options.request_body_size_limit or 64*1024*1024 1.37 @@ -311,9 +313,13 @@ 1.38 -- close output stream: 1.39 assert_output(socket:finish()) 1.40 -- wait for EOF of peer to avoid immediate TCP RST condition: 1.41 - timeout(2, function() 1.42 - socket:drain() 1.43 - end) 1.44 + do 1.45 + local start_time = moonbridge_io.timeref() 1.46 + repeat 1.47 + socket:drain_nb() 1.48 + local time_left = 2 - moonbridge_io.timeref(start_time) 1.49 + until time_left <= 0 or not moonbridge_io.poll(socket_set, nil, time_left) 1.50 + end 1.51 -- fully close socket: 1.52 socket_closed = true -- avoid double close on error 1.53 assert_output(socket:close()) 1.54 @@ -893,6 +899,12 @@ 1.55 end 1.56 end 1.57 }) 1.58 + -- wait for input: 1.59 + if not moonbridge_io.poll({[socket] = true}, nil, request_idle_timeout) then 1.60 + return request_error(false, "408 Request Timeout") 1.61 + end 1.62 + -- set timeout for request header processing: 1.63 + timeout(request_header_timeout) 1.64 -- read and parse request line: 1.65 local line = socket:read(remaining_header_size_limit, "\n") 1.66 if not line then return survive end 1.67 @@ -991,12 +1003,14 @@ 1.68 request.cookies[decode_uri(rawkey)] = decode_uri(rawvalue) 1.69 end 1.70 end 1.71 - -- (re)set timeout: 1.72 + -- (re)set timeout for handler: 1.73 timeout(response_timeout or 0) 1.74 -- call underlying handler and remember boolean result: 1.75 if handler(request) ~= true then survive = false end 1.76 -- finish request (unless already done by underlying handler): 1.77 request:finish() 1.78 + -- stop timeout timer: 1.79 + timeout(0) 1.80 until connection_close_responded 1.81 return survive 1.82 end