socket: Automatic LuaSocket/cosockets compatibility module
Installation
If you haven't set up RPM repository subscription, sign up. Then you can proceed with the following steps.
CentOS/RHEL 7 or Amazon Linux 2
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install lua-resty-socket
CentOS/RHEL 8+, Fedora Linux, Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-socket
To use this Lua library with NGINX, ensure that nginx-module-lua is installed.
This document describes lua-resty-socket v1.0.0 released on Jan 18 2019.
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.
Features
- Allows your lua-resty modules to automatically use cosockets/LuaSocket
- Provides
sslhandshake
proxy when using LuaSocket, with a dependency on LuaSec - Does not get blocked to using LuaSocket in further contexts if loaded in the
ngx_lua
init
(easy mistake to make) - Memoizes underlying socket methods for performance
- Outputs a warning log for your users when spawning a socket using LuaSocket while in OpenResty
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 not used in ngx_lua
- In ngx_lua contexts where cosockets are not supported (init
, init_worker
,
etc...)
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
.
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.
- lua-cassandra: see how the cassandra module is compatible in both OpenResty and plain Lua with no efforts or special code paths distinguishing cosockets and LuaSocket.
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.
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.
GitHub
You may find additional configuration tips and documentation for this module in the GitHub repository for nginx-module-socket.