Search code examples
socketslualuasocket

lua http socket timeout


The LuaSocket HTTP module documentation says that a timeout can be set on a HTTP connection:

The following constants can be set to control the default behavior of the HTTP module:

PORT: default port used for connections; PROXY: default proxy used for connections; TIMEOUT: sets the timeout for all I/O operations; USERAGENT: default user agent reported to server. http://w3.impa.br/~diego/software/luasocket/http.htm

How do I set these constants in a lua script?


Solution

  • You can do this to set a timeout for one request instead of the entire HTTP module:

    local socket = require "socket"
    local http = require "socket.http"
    response = http.request{url=URL, create=function()
      local req_sock = socket.tcp()
      req_sock:settimeout(5)
      return req_sock
    end}
    

    Note that the default behavior of :settimeout, as well as global settings like http.TIMEOUT, sets a time limit for any individual operation within the request - in other words, it's how long the operation may go without any activity before timing out. If you wish to set an overall upper bound on an operation - a time that the overall request can't exceed, regardless of activity - you should pass a mode argument of 't' as the second parameter to :settimeout, like so:

    local socket = require "socket"
    local http = require "socket.http"
    response = http.request{url=URL, create=function()
      local req_sock = socket.tcp()
      -- note the second parameter here
      req_sock:settimeout(5, 't')
      return req_sock
    end}
    

    As an example to illustrate the distinction between the two modes, imagine that, after making your request, the server responded with a chunk of the response once a second, taking seven seconds overall to complete. With req_sock:settimeout(5, 'b') (or just req_sock:settimeout(5)) setting a 5-second block timeout, this request would proceed just fine, as none of the underlying I/O operations took longer than five seconds: however, with req_sock:settimeout(5, 't') setting a five-second total timeout, the request would fail after five seconds.

    Of course, it may make sense to set restrictions for both of these durations, having both a short inactivity timeout as well as a longer overall timeout. As such, per the documentation, you can make two separate calls to specify both:

    local socket = require "socket"
    local http = require "socket.http"
    response = http.request{url=URL, create=function()
      local req_sock = socket.tcp()
      req_sock:settimeout(5, 'b')
      req_sock:settimeout(30, 't')
      return req_sock
    end}