Home

Awesome

lua-resty-socket

Module Version Build Status

cosocket/LuaSocket automatic compatibility module for lua-resty modules wanting to be compatible with plain Lua or OpenResty's init context.

The use case for this library is: you are developing a lua-resty module relying on cosockets, but you want it to also be usable in OpenResty's init context or even in plain Lua. This module aims at always providing your library with sockets that will be compatible in the current context, saving you time and effort, and extending LuaSocket's API to match that of cosockets, allowing you to always write your code as if you were in a cosocket-compatible OpenResty context.

Table of Contents

Features

Back to TOC

Motivation

The aim of this module is to provide an automatic fallback to LuaSocket when ngx_lua's cosockets are not available. That is:

When falling back to LuaSocket, it provides you with shims for cosocket-only functions such as getreusedtimes, setkeepalive etc...

It comes handy when one is developing a module/library that aims at being either compatible with both ngx_lua and plain Lua, or in ngx_lua contexts such as init.

Back to TOC

Libraries using it

Here are some concrete examples uses of this module. You can see how we only write code as if we were constantly in an cosocket-compatible OpenResty context, which greatly simplifies our work and provides out of the box plain Lua compatibility.

Back to TOC

Important note

The use of LuaSocket inside ngx_lua is very strongly discouraged due to its blocking nature. However, it is fine to use it in the init context where blocking is not considered harmful.

In the future, only the init phase will allow falling back to LuaSocket.

It currently only support TCP sockets.

Back to TOC

Usage

All of the available functions follow the same prototype as the cosocket API, allowing this example to run in any ngx_lua context or outside ngx_lua altogether:

local socket = require 'resty.socket'
local sock = socket.tcp()

getmetatable(sock) == socket.luasocket_mt ---> true/false depending on underlying socket

sock:settimeout(1000) ---> 1000ms translated to 1s if LuaSocket

sock:getreusedtimes(...) ---> 0 if LuaSocket

sock:setkeepalive(...) ---> calls close() if LuaSocket

sock:sslhandshake(...) ---> LuaSec dependency if LuaSocket

As such, one can write a module relying on TCP sockets such as:

local socket = require 'resty.socket'

local _M = {}

function _M.new()
  local sock = socket.tcp() -- similar to ngx.socket.tcp()

  return setmetatable({
    sock = sock
  }, {__index = _M})
end

function _M:connect(host, port)
  local ok, err = self.sock:connect(host, port)
  if not ok then
    return nil, err
  end

  local times, err = self.sock:getreusedtimes() -- cosocket API
  if not times then
    return nil, err
  elseif times == 0 then
    -- handle connection
  end
end

return _M

The user of such a module could use it in contexts with cosocket support, or in the init phase of ngx_lua, with little effort from the developer.

Back to TOC

Requirements

As long as sockets are created in contexts with support for cosockets, this module will never require LuaSocket nor LuaSec.

Back to TOC

Installation

This module can either be copied in a lua-resty library, allowing one to modify the list of contexts allowing fallback.

It can also be installed via LuaRocks:

$ luarocks install lua-resty-socket

Back to TOC

License

Work licensed under the MIT License.

Back to TOC