lua-buffet
Socket-like buffer objects for Lua
$ opm get un-def/lua-buffet
lua-buffet
[!Luarocks](https://luarocks.org/modules/undef/lua-buffet) [!OPM](https://opm.openresty.org/package/un-def/lua-buffet/) [!Build Status](https://travis-ci.org/un-def/lua-buffet) [!License][license]
Socket-like buffer objects for Lua
Name
The word “buffet” is a portmanteau of “buffer” and “socket”.
Description
A buffet is an object that has the same interface as socket objects in the popular Lua libraries LuaSocket and Lua Nginx Module but doesn't do any real network communication. Instead the network stack the buffet receives data from an arbitrary source. The data source can be a string, a table of strings or an iterator function producing strings.
The buffet works in a streaming fashion. That is, the buffet doesn't try to read and store internally the whole source data at once but reads as little as possible and only when necessary. That means that the buffet can be efficiently used as a proxy for sources of unlimited amounts of data such as real sockets or file I/O readers.
Another possible use is unit testing where the buffet can be used as a mock object instead of the real socket object.
Basic usage
local buffet = require('buffet')
local buffet_resty = require('buffet.resty')
-- Input data is a string.
-- Read data in chunks of 3 bytes.
do
local bf = buffet_resty.new('data string')
print(buffet.is_closed(bf)) -- false
repeat
local data, err, partial = bf:receive(3)
print(data, err, partial)
until err
print(buffet.is_closed(bf)) -- true
end
-- Input data is a table containing data chunks.
-- Read data line by line.
do
local bf = buffet_resty.new({'line 1\nline', ' 2\nli', 'ne 3\n'})
repeat
local data, err, partial = bf:receive('*l')
print(data, err, partial)
until err
end
-- Input data is a function producing data chunks.
-- Read data splitted by the specified pattern, up to 4 bytes at once.
do
local iterator = coroutine.wrap(function()
coroutine.yield('first-==-se')
coroutine.yield('cond-==')
coroutine.yield('-thi')
coroutine.yield('rd')
coroutine.yield(nil, 'some error')
coroutine.yield('unreachable')
end)
local bf = buffet_resty.new(iterator)
local reader = bf:receiveuntil('-==-')
print(buffet.get_iterator_error(bf)) -- nil
repeat
local data, err, partial = reader(4)
print(data, err, partial)
until err
print(buffet.get_iterator_error(bf)) -- some error
end
-- Send data.
do
local bf = buffet_resty.new()
for i = 1, 5 do
local char = string.char(0x40 + i)
bf:send(string.rep(char, i))
end
local send_buffer = buffet.get_send_buffer(bf)
print(#send_buffer) -- 5
for _, chunk in ipairs(send_buffer) do
print(chunk)
end
print(buffet.get_sent_data(bf)) -- ABBCCCDDDDEEEEE
end
For more advanded usage see the examples directory.
Documentation
Documentation is available at https://undef.im/lua-buffet/.
Changelog
For detailed changelog see CHANGELOG.md.
TODO
OpenResty
ngx.socket.tcp
[x] constructor (
ngx.socket.tcp
~buffet.resty.new
)[x]
:connect
(noop)[x]
:sslhandshake
(noop)[x]
:send
[x]
:receive
[x]
:receive()
[x]
:receive('*l')
[x]
:receive('*a')
[x]
:receive(size)
[x]
:receiveany
[x]
:receiveuntil
[x]
iterator()
[x]
iterator(size)
[x]
inclusive
option
[x]
:close
[x]
:settimeout
(noop)[x]
:settimeouts
(noop)[x]
:setoption
(noop)[x]
:setkeepalive
(equivalent to:close
)[x]
:getreusedtimes
(noop)
ngx.socket.udp
...
LuaSocket
...
License
The [MIT License][license].
[license]: https://github.com/un-def/lua-buffet/blob/master/LICENSE
Authors
un.def
License
mit
Versions
-
un-def/lua-buffet 0.2.0Socket-like buffer objects for Lua 2020-07-05 10:54:05
-
un-def/lua-buffet 0.1.0Socket-like buffer objects for Lua 2020-06-17 13:30:50