lua-http - Man Page
Introduction
lua-http is an performant, capable HTTP and WebSocket library for Lua 5.1, 5.2, 5.3 and LuaJIT. Some of the features of the library include:
- Support for HTTP versions 1, 1.1 and 2 as specified by RFC 7230 (https://tools.ietf.org/html/rfc7230) and RFC 7540 (https://tools.ietf.org/html/rfc7540)
- Provides both client and server APIs
- Fully asynchronous API that does not block the current thread when executing operations that typically block
- Support for WebSockets as specified by RFC 6455 (https://tools.ietf.org/html/rfc6455) including ping/pong, binary data transfer and TLS encryption
- Transport Layer Security (TLS) - lua-http supports HTTPS and WSS via luaossl (https://github.com/wahern/luaossl).
- Easy integration into other event-loop or scripts
Why lua-http?
The lua-http library was written to fill a gap in the Lua ecosystem by providing an HTTP and WebSocket library with the following traits:
- Asynchronous and performant
- Can be used without forcing the developer to follow a specific pattern. Conversely, the library can be adapted to many common patterns.
- Can be used at a very high level without need to understand the transportation of HTTP data (other than connection addresses).
- Provides a rich low level API, if desired, for creating powerful HTTP based tools at the protocol level.
As a result of these design goals, the library is simple and unobtrusive and can accommodate tens of thousands of connections on commodity hardware.
lua-http is a flexible HTTP and WebSocket library that allows developers to concentrate on line-of-business features when building Internet enabled applications. If you are looking for a way to streamline development of an internet enabled application, enable HTTP networking in your game, create a new Internet Of Things (IoT) system, or write a performant custom web server for a specific use case, lua-http has the tools you need.
Portability
lua-http is pure Lua code with dependencies on the following external libraries:
- cqueues (http://25thandclement.com/~william/projects/cqueues.html) - Posix API library for Lua
- luaossl (http://25thandclement.com/~william/projects/luaossl.html) - Lua bindings for TLS/SSL
- lua-zlib (https://github.com/brimworks/lua-zlib) - Optional Lua bindings for zlib
lua-http can run on any operating system supported by cqueues and openssl, which at the time of writing is GNU/Linux, FreeBSD, NetBSD, OpenBSD, OSX and Solaris.
Common Use Cases
The following are two simple demonstrations of how the lua-http library can be used:
Retrieving a Document
The highest level interface for clients is http.request. By constructing a request object from a URI using new_from_uri
and immediately evaluating it, you can easily fetch an HTTP resource.
local http_request = require "http.request" local headers, stream = assert(http_request.new_from_uri("http://example.com"):go()) local body = assert(stream:get_body_as_string()) if headers:get ":status" ~= "200" then error(body) end print(body)
WebSocket Communications
To request information from a WebSocket server, use the websocket
module to create a new WebSocket client.
local websocket = require "http.websocket" local ws = websocket.new_from_uri("wss://echo.websocket.org") assert(ws:connect()) assert(ws:send("koo-eee!")) local data = assert(ws:receive()) assert(data == "koo-eee!") assert(ws:close())
Asynchronous Operation
lua-http has been written to perform asynchronously so that it can be used in your application, server or game without blocking your main loop. Asynchronous operations are achieved by utilizing cqueues, a Lua/C library that incorporates Lua yielding and kernel level APIs to reduce CPU usage. All lua-http operations including DNS lookup, TLS negotiation and read/write operations will not block the main application thread when run from inside a cqueue or cqueue enabled “container”. While sometimes it is necessary to block a routine (yield) and wait for external data, any blocking API calls take an optional timeout to ensure good behaviour of networked applications and avoid unresponsive or “dead” routines.
Asynchronous operations are one of the most powerful features of lua-http and require no effort on the developers part. For instance, an HTTP server can be instantiated within any Lua main loop and run alongside application code without adversely affecting the main application process. If other cqueue enabled components are integrated within a cqueue loop, the application is entirely event driven through kernel level polling APIs.
cqueues can be used in conjunction with lua-http to integrate other features into your lua application and create powerful, performant, web enabled applications. Some of the examples in this guide will use cqueues for simple demonstrations. For more resources about cqueues, please see:
- The cqueues website (http://25thandclement.com/~william/projects/cqueues.html) for more information about the cqueues library.
- cqueues examples can be found with the cqueues source code available through git or archives (http://www.25thandclement.com/~william/projects/cqueues.html#download) or accessed online here (https://github.com/wahern/cqueues/tree/master/examples).
- For more information on integrating cqueues with other event loop libraries please see integration with other event loops (https://github.com/wahern/cqueues/wiki/Integrations-with-other-main-loops).
- For other libraries that use cqueues such as asynchronous APIs for Redis and PostgreSQL, please see the cqueues wiki entry here (https://github.com/wahern/cqueues/wiki/Libraries-that-use-cqueues).
Conventions
The following is a list of API conventions and general reference:
HTTP
- HTTP 1 request and status line fields are passed around inside of headers objects under keys
":authority"
,":method"
,":path"
,":scheme"
and":status"
as defined in HTTP 2. As such, they are all kept in string form (important to remember for the:status
field). - Header fields should always be used with lower case keys.
Errors
- Invalid function parameters will throw a lua error (if validated).
- Errors are returned as
nil
, error, errno unless noted otherwise. - Some HTTP 2 operations return/throw special http 2 error objects.
Timeouts
All operations that may block the current thread take a timeout
argument. This argument is always the number of seconds to allow before returning nil, err_msg, ETIMEDOUT
where err_msg
is a localised error message such as "connection timed out"
.
Terminology
Much lua-http terminology is borrowed from HTTP 2.
Connection - An abstraction over an underlying TCP/IP socket. lua-http currently has two connection types: one for HTTP 1, one for HTTP 2.
Stream - A request/response on a connection object. lua-http has two stream types: one for HTTP 1 streams, and one for HTTP 2 streams. The common interfaces is described in stream.
Interfaces
lua-http has separate modules for HTTP 1 vs HTTP 2 protocols, yet the different versions share many common concepts. lua-http provides a common interface for operations that make sense for both protocol versions (as well as any future developments).
The following sections outline the interfaces exposed by the lua-http library.
connection
A connection encapsulates a socket and provides protocol specific operations. A connection may have streams which encapsulate the requests/responses happening over a conenction. Alternatively, you can ignore streams entirely and use low level protocol specific operations to read and write to the socket.
All connection types expose the following fields:
connection.type
The mode of use for the connection object. Valid values are:
"client"
: Acts as a client; this connection type is used by entities who want to make requests"server"
: Acts as a server; this conenction type is used by entities who want to respond to requests
connection.version
The HTTP version number of the connection as a number.
connection:pollfd()
connection:events()
connection:timeout()
connection:connect(timeout)
Completes the connection to the remote server using the address specified, HTTP version and any options specified in the connection.new
constructor. The connect
function will yield until the connection attempt finishes (success or failure) or until timeout
is exceeded. Connecting may include DNS lookups, TLS negotiation and HTTP2 settings exchange. Returns true
on success. On error, returns nil
, an error message and an error number.
connection:checktls()
Checks the socket for a valid Transport Layer Security connection. Returns the luaossl ssl object if the connection is secured. Returns nil
and an error message if there is no active TLS session. Please see the luaossl website (http://25thandclement.com/~william/projects/luaossl.html) for more information about the ssl object.
connection:localname()
Returns the connection information for the local socket. Returns address family, IP address and port for an external socket. For Unix domain sockets, the function returns AF_UNIX
and the path. If the connection object is not connected, returns AF_UNSPEC
(0). On error, returns nil
, an error message and an error number.
connection:peername()
Returns the connection information for the socket peer (as in, the next hop). Returns address family, IP address and port for an external socket. For unix sockets, the function returns AF_UNIX
and the path. If the connection object is not connected, returns AF_UNSPEC
(0). On error, returns nil
, an error message and an error number.
Note: If the client is using a proxy, the values returned :peername() point to the proxy, not the remote server.
connection:flush(timeout)
Flushes buffered outgoing data on the socket to the operating system. Returns true
on success. On error, returns nil
, an error message and an error number.
connection:shutdown()
Performs an orderly shutdown of the connection by closing all streams and calls :shutdown()
on the socket. The connection cannot be re-opened.
connection:close()
Closes a connection and releases operating systems resources. Note that :close()
performs a connection:shutdown()
prior to releasing resources.
connection:new_stream()
Creates and returns a new stream on the connection.
connection:get_next_incoming_stream(timeout)
Returns the next peer initiated stream on the connection. This function can be used to yield and “listen” for incoming HTTP streams.
connection:onidle(new_handler)
Provide a callback to get called when the connection becomes idle i.e. when there is no request in progress and no pipelined streams waiting. When called it will receive the connection
as the first argument. Returns the previous handler.
stream
An HTTP stream is an abstraction of a request/response within a HTTP connection. Within a stream there may be a number of “header” blocks as well as data known as the “body”.
All stream types expose the following fields and functions:
stream.connection
The underlying connection object.
stream:checktls()
Convenience wrapper equivalent to stream.connection:checktls()
stream:localname()
Convenience wrapper equivalent to stream.connection:localname()
stream:peername()
Convenience wrapper equivalent to stream.connection:peername()
stream:get_headers(timeout)
Retrieves the next complete headers object (i.e. a block of headers or trailers) from the stream.
stream:write_headers(headers, end_stream, timeout)
Write the given headers object to the stream. The function takes a flag indicating if this is the last chunk in the stream, if true
the stream will be closed. If timeout
is specified, the stream will wait for the send to complete until timeout
is exceeded.
stream:write_continue(timeout)
Sends a 100-continue header block.
stream:get_next_chunk(timeout)
Returns the next chunk of the http body from the socket, potentially yielding for up to timeout
seconds. On error, returns nil
, an error message and an error number.
stream:each_chunk()
Iterator over stream:get_next_chunk()
stream:get_body_as_string(timeout)
Reads the entire body from the stream and return it as a string. On error, returns nil
, an error message and an error number.
stream:get_body_chars(n, timeout)
Reads n
characters (bytes) of body from the stream and return them as a string. If the stream ends before n
characters are read then returns the partial result. On error, returns nil
, an error message and an error number.
stream:get_body_until(pattern, plain, include_pattern, timeout)
Reads in body data from the stream until the lua pattern (http://www.lua.org/manual/5.3/manual.html#6.4.1) pattern
is found and returns the data as a string. plain
is a boolean that indicates that pattern matching facilities should be turned off so that function does a plain “find substring” operation, with no characters in pattern being considered magic. include_patterns
specifies if the pattern itself should be included in the returned string. On error, returns nil
, an error message and an error number.
stream:save_body_to_file(file, timeout)
Reads the body from the stream and saves it to the lua file handle (http://www.lua.org/manual/5.3/manual.html#6.8) file
. On error, returns nil
, an error message and an error number.
stream:get_body_as_file(timeout)
Reads the body from the stream into a temporary file and returns a lua file handle (http://www.lua.org/manual/5.3/manual.html#6.8). On error, returns nil
, an error message and an error number.
stream:unget(str)
Places str
back on the incoming data buffer, allowing it to be returned again on a subsequent command (“un-gets” the data). Returns true
on success. On error, returns nil
, an error message and an error number.
stream:write_chunk(chunk, end_stream, timeout)
Writes the string chunk
to the stream. If end_stream
is true, the body will be finalized and the stream will be closed. write_chunk
yields indefinitely, or until timeout
is exceeded. On error, returns nil
, an error message and an error number.
stream:write_body_from_string(str, timeout)
Writes the string str
to the stream and ends the stream. On error, returns nil
, an error message and an error number.
stream:write_body_from_file(options|file, timeout)
options
is a table containing:.file
(file).count
(positive integer): number of bytes offile
to write
defaults to infinity (the whole file will be written)
Writes the contents of file file
to the stream and ends the stream. file
will not be automatically seeked, so ensure it is at the correct offset before calling. On error, returns nil
, an error message and an error number.
stream:shutdown()
Closes the stream. The resources are released and the stream can no longer be used.
Modules
http.bit
An abstraction layer over the various lua bit libraries.
Results are only consistent between underlying implementations when parameters and results are in the range of 0
to 0x7fffffff
.
band(a, b)
Bitwise And operation.
bor(a, b)
Bitwise Or operation.
bxor(a, b)
Bitwise XOr operation.
Example
local bit = require "http.bit" print(bit.band(1, 3)) --> 1
http.client
Deals with obtaining a connection to an HTTP server.
negotiate(socket, options, timeout)
Negotiates the HTTP settings with the remote server. If TLS has been specified, this function instantiates the encryption tunnel. Parameters are as follows:
socket
is a cqueues socket objectoptions
is a table containing:.tls
(boolean, optional): Should TLS be used?
defaults to
false
.ctx
(userdata, optional): theSSL_CTX*
to use if.tls
istrue
.
If
.ctx
isnil
then a default context will be used..sendname
(string|boolean, optional): the TLS SNI (https://en.wikipedia.org/wiki/Server_Name_Indication) host to send.
defaults to
true
connect(options, timeout)
This function returns a new connection to an HTTP server. Once a connection has been opened, a stream can be created to start a request/response exchange. Please see h1_stream.new_stream
and h2_stream.new_stream
for more information about creating streams.
options
is a table containing the options tohttp.client.negotiate
, plus the following:family
(integer, optional): socket family to use.
defaults to
AF_INET
host
(string): host to connect to.
may be either a hostname or an IP address
port
(string|integer): port to connect to in numeric form
e.g.
"80"
or80
path
(string): path to connect to (UNIX sockets)v6only
(boolean, optional): if theIPV6_V6ONLY
flag should be set on the underlying socket.bind
(string, optional): the local outgoing address and optionally port to bind in the form of"address[:port]"
, IPv6 addresses may be specified via square bracket notation. e.g."127.0.0.1"
,"127.0.0.1:50000"
,"[::1]:30000"
.
timeout
(optional) is the maximum amount of time (in seconds) to allow for connection to be established.
This includes time for DNS lookup, connection, TLS negotiation (if TLS enabled) and in the case of HTTP 2: settings exchange.
Example
Connect to a local HTTP server running on port 8000
local http_client = require "http.client" local myconnection = http_client.connect { host = "localhost"; port = 8000; tls = false; }
bake(name, value, expiry_time, domain, path, secure_only, http_only, same_site)
Returns a string suitable for use in a Set-Cookie
header with the passed parameters.
new_store()
Creates a new cookie store.
Cookies are unique for a tuple of domain, path and name; although multiple cookies with the same name may exist in a request due to overlapping paths or domains.
store.psl
A lua-psl (https://github.com/daurnimator/lua-psl) object to use for checking against the Public Suffix List. Set the field to false
to skip checking the suffix list.
Defaults to the latest (https://rockdaboot.github.io/libpsl/libpsl-Public-Suffix-List-functions.html#psl-latest) PSL on the system. If lua-psl is not installed then it will be nil
.
store.time()
A function used by the store
to get the current time for expiries and such.
Defaults to a function based on os.time
(https://www.lua.org/manual/5.3/manual.html#pdf-os.time).
store:get(domain, path, name)
Returns the cookie value for the cookie stored for the passed domain
, path
and name
.
store:remove(domain, path, name)
Deletes the cookie stored for the passed domain
, path
and name
.
If name
is nil
or not passed then all cookies for the domain
and path
are removed.
If path
is nil
or not passed (in addition to name
) then all cookies for the domain
are removed.
store:clean_due()
Returns the number of seconds until the next cookie in the store
expires.
store:clean()
Remove all expired cookies from the store
.
store:load_from_file(file)
Loads cookie data from the file object file
into store
. The file should be in the Netscape Cookiejar format. Invalid lines in the file are ignored.
Returns true
on success or passes along nil, err, errno
if a :read
call fails.
store:save_to_file(file)
Writes the cookie data from store
into the file object file
in the Netscape Cookiejar format. file
is not seek
-ed or truncated before writing.
Returns true
on success or passes along nil, err, errno
if a :write
call fails.
http.h1_connection
The h1_connection module adheres to the connection interface and provides HTTP 1 and 1.1 specific operations.
new(socket, conn_type, version)
Constructor for a new connection. Takes a cqueues socket object, a connection type string and a numeric HTTP version number. Valid values for the connection type are "client"
and "server"
. Valid values for the version number are 1
and 1.1
. Returns the newly initialized connection object.
h1_connection.version
Specifies the HTTP version used for the connection handshake. Valid values are:
1.0
1.1
See connection.version
h1_connection:pollfd()
See connection:pollfd()
h1_connection:events()
See connection:events()
h1_connection:timeout()
See connection:timeout()
h1_connection:connect(timeout)
See connection:connect(timeout)
h1_connection:checktls()
See connection:checktls()
h1_connection:localname()
See connection:localname()
h1_connection:peername()
See connection:peername()
h1_connection:flush(timeout)
See connection:flush(timeout)
h1_connection:shutdown(dir)
Shut down is as graceful as possible: pipelined streams are shutdown, then the underlying socket is shut down in the appropriate direction(s).
dir
is a string representing the direction of communication to shut down communication in. If it contains "r"
it will shut down reading, if it contains "w"
it will shut down writing. The default is "rw"
, i.e. to shutdown communication in both directions.
See connection:shutdown()
h1_connection:close()
See connection:close()
h1_connection:new_stream()
In HTTP 1, only a client may initiate new streams with this function.
See connection:new_stream()
for more information.
h1_connection:get_next_incoming_stream(timeout)
See connection:get_next_incoming_stream(timeout)
h1_connection:onidle(new_handler)
See connection:onidle(new_handler)
h1_connection:setmaxline(read_length)
Sets the maximum read buffer size (in bytes) to read_length
. i.e. sets the maximum length lines (such as headers).
The default comes from the underlying socket, which gets the (changable) cqueues default at time of construction. The default cqueues default is 4096 bytes.
h1_connection:clearerr(...)
Clears errors to allow for further read or write operations on the connection. Returns the error number of existing errors. This function is used to recover from known errors.
h1_connection:error(...)
Returns the error number of existing errors.
h1_connection:take_socket()
Used to hand the reference of the connection socket to another object. Resets the socket to defaults and returns the single existing reference of the socket to the calling routine. This function can be used for connection upgrades such as upgrading from HTTP 1 to a WebSocket.
h1_connection:read_request_line(timeout)
Reads a request line from the socket. Returns the request method, requested path and HTTP version for an incoming request. :read_request_line()
yields until a "\r\n"
terminated chunk is received, or timeout
is exceeded. If the incoming chunk is not a valid HTTP request line, nil
is returned. On error, returns nil
, an error message and an error number.
h1_connection:read_status_line(timeout)
Reads a line of input from the socket. If the input is a valid status line, the HTTP version (1 or 1.1), status code and reason description (if applicable) is returned. :read_status_line()
yields until a "\r\n"
terminated chunk is received, or timeout
is exceeded. If the socket could not be read, returns nil
, an error message and an error number.
h1_connection:read_header(timeout)
Reads a CRLF terminated HTTP header from the socket and returns the header key and value. This function will yield until a MIME compliant header item is received or until timeout
is exceeded. If the header could not be read, the function returns nil
an error and an error message.
h1_connection:read_headers_done(timeout)
Checks for an empty line, which indicates the end of the HTTP headers. Returns true
if an empty line is received. Any other value is pushed back on the socket receive buffer (unget) and the function returns false
. This function will yield waiting for input from the socket or until timeout
is exceeded. Returns nil
, an error and an error message if the socket cannot be read.
h1_connection:read_body_by_length(len, timeout)
Get len
number of bytes from the socket. Use a negative number for up to that number of bytes. This function will yield and wait on the socket if length of the buffered body is less than len
. Asserts if len is not a number.
h1_connection:read_body_till_close(timeout)
Reads the entire request body. This function will yield until the body is complete or timeout
is expired. If the read fails the function returns nil
, an error message and an error number.
h1_connection:read_body_chunk(timeout)
Reads the next available line of data from the request and returns the chunk and any chunk extensions. This function will yield until chunk size is received or timeout
is exceeded. If the chunk size is indicated as 0
then false
and any chunk extensions are returned. Returns nil
, an error message and an error number if there was an error reading reading the chunk header or the socket.
h1_connection:write_request_line(method, path, httpversion, timeout)
Writes the opening HTTP 1.x request line for a new request to the socket buffer. Yields until success or timeout
. If the write fails, returns nil
, an error message and an error number.
Note the request line will not be flushed to the remote server until write_headers_done
is called.
h1_connection:write_status_line(httpversion, status_code, reason_phrase, timeout)
Writes an HTTP status line to the socket buffer. Yields until success or timeout
. If the write fails, the function returns nil
, an error message and an error number.
Note the status line will not be flushed to the remote server until write_headers_done
is called.
h1_connection:write_header(k, v, timeout)
Writes a header item to the socket buffer as a key:value
string. Yields until success or timeout
. Returns nil
, an error message and an error if the write fails.
Note the header item will not be flushed to the remote server until write_headers_done
is called.
h1_connection:write_headers_done(timeout)
Terminates a header block by writing a blank line ("\r\n"
) to the socket. This function will flush all outstanding data in the socket output buffer. Yields until success or timeout
. Returns nil
, an error message and an error if the write fails.
h1_connection:write_body_chunk(chunk, chunk_ext, timeout)
Writes a chunk of data to the socket. chunk_ext
must be nil
as chunk extensions are not supported. Will yield until complete or timeout
is exceeded. Returns true on success. Returns nil
, an error message and an error number if the write fails.
h1_connection:write_body_last_chunk(chunk_ext, timeout)
Writes the chunked body terminator "0\r\n"
to the socket. chunk_ext
must be nil
as chunk extensions are not supported. Will yield until complete or timeout
is exceeded. Returns nil
, an error message and an error number if the write fails.
Note that the connection will not be immediately flushed to the remote server; normally this will occur when trailers are written.
h1_connection:write_body_plain(body, timeout)
Writes the contents of body
to the socket and flushes the socket output buffer immediately. Yields until success or timeout
is exceeded. Returns nil
, an error message and an error number if the write fails.
http.h1_reason_phrases
A table mapping from status codes (as strings) to reason phrases for HTTP 1. Any unknown status codes return "Unassigned"
Example
local reason_phrases = require "http.h1_reason_phrases" print(reason_phrases["200"]) --> "OK" print(reason_phrases["342"]) --> "Unassigned"
http.h1_stream
The h1_stream module adheres to the stream interface and provides HTTP 1.x specific operations.
The gzip transfer encoding is supported transparently.
h1_stream.connection
See stream.connection
h1_stream.max_header_lines
The maximum number of header lines to read. Default is 100
.
h1_stream:checktls()
See stream:checktls()
h1_stream:localname()
See stream:localname()
h1_stream:peername()
See stream:peername()
h1_stream:get_headers(timeout)
See stream:get_headers(timeout)
h1_stream:write_headers(headers, end_stream, timeout)
See stream:write_headers(headers, end_stream, timeout)
h1_stream:write_continue(timeout)
See stream:write_continue(timeout)
h1_stream:get_next_chunk(timeout)
See stream:get_next_chunk(timeout)
h1_stream:each_chunk()
See stream:each_chunk()
h1_stream:get_body_as_string(timeout)
See stream:get_body_as_string(timeout)
h1_stream:get_body_chars(n, timeout)
See stream:get_body_chars(n, timeout)
h1_stream:get_body_until(pattern, plain, include_pattern, timeout)
See stream:get_body_until(pattern, plain, include_pattern, timeout)
h1_stream:save_body_to_file(file, timeout)
See stream:save_body_to_file(file, timeout)
h1_stream:get_body_as_file(timeout)
See stream:get_body_as_file(timeout)
h1_stream:unget(str)
See stream:unget(str)
h1_stream:write_chunk(chunk, end_stream, timeout)
See stream:write_chunk(chunk, end_stream, timeout)
h1_stream:write_body_from_string(str, timeout)
See stream:write_body_from_string(str, timeout)
h1_stream:write_body_from_file(options|file, timeout)
See stream:write_body_from_file(options|file, timeout)
h1_stream:shutdown()
See stream:shutdown()
h1_stream:set_state(new)
Sets the state of the stream to new
. new
must be one of the following valid states:
"open"
: have sent or received headers; haven’t sent body yet"half closed (local)"
: have sent whole body"half closed (remote)"
: have received whole body"closed"
: complete
Not all state transitions are allowed.
h1_stream:read_headers(timeout)
Reads and returns a header block from the underlying connection. Does not take into account buffered header blocks. On error, returns nil
, an error message and an error number.
This function should rarely be used, you’re probably looking for :get_headers()
.
h1_stream:read_next_chunk(timeout)
Reads and returns the next chunk as a string from the underlying connection. Does not take into account buffered chunks. On error, returns nil
, an error message and an error number.
This function should rarely be used, you’re probably looking for :get_next_chunk()
.
http.h2_connection
The h2_connection module adheres to the connection interface and provides HTTP 2 specific operations. An HTTP 2 connection can have multiple streams actively transmitting data at once, hence an http.h2_connection acts much like a scheduler.
new(socket, conn_type, settings)
Constructor for a new connection. Takes a cqueues socket object, a connection type string and an optional table of HTTP 2 settings. Returns the newly initialized connection object in a non-connected state.
h2_connection.version
Contains the HTTP connection version. Currently this will always be 2
.
See connection.version
h2_connection:pollfd()
See connection:pollfd()
h2_connection:events()
See connection:events()
h2_connection:timeout()
See connection:timeout()
h2_connection:empty()
h2_connection:step(timeout)
h2_connection:loop(timeout)
h2_connection:connect(timeout)
See connection:connect(timeout)
h2_connection:checktls()
See connection:checktls()
h2_connection:localname()
See connection:localname()
h2_connection:peername()
See connection:peername()
h2_connection:flush(timeout)
See connection:flush(timeout)
h2_connection:shutdown()
See connection:shutdown()
h2_connection:close()
See connection:close()
h2_connection:new_stream(id)
Create and return a new h2_stream. id
(optional) is the stream id to assign the new stream, if not specified for client initiated streams this will be the next free odd numbered stream, for server initiated streams this will be the next free even numbered stream.
See connection:new_stream()
for more information.
h2_connection:get_next_incoming_stream(timeout)
See connection:get_next_incoming_stream(timeout)
h2_connection:onidle(new_handler)
See connection:onidle(new_handler)
h2_connection:read_http2_frame(timeout)
h2_connection:write_http2_frame(typ, flags, streamid, payload, timeout, flush)
h2_connection:ping(timeout)
h2_connection:write_window_update(inc, timeout)
h2_connection:write_goaway_frame(last_stream_id, err_code, debug_msg, timeout)
h2_connection:set_peer_settings(peer_settings)
h2_connection:ack_settings()
h2_connection:settings(tbl, timeout)
http.h2_error
A type of error object that encapsulates HTTP 2 error information. An http.h2_error
object has fields:
name
: The error name: a short identifier for this errorcode
: The error codedescription
: The description of the error codemessage
: An error messagetraceback
: A traceback taken at the point the error was thrownstream_error
: A boolean that indicates if this is a stream level or protocol level error
errors
A table containing errors as defined by the HTTP 2 specification (https://http2.github.io/http2-spec/#iana-errors). It can be indexed by error name (e.g. errors.PROTOCOL_ERROR
) or numeric code (e.g. errors[0x1]
).
is(ob)
Returns a boolean indicating if the object ob
is an http.h2_error
object
h2_error:new(ob)
Creates a new error object from the passed table. The table should have the form of an error object i.e. with fields name
, code
, message
, traceback
, etc.
Fields name
, code
and description
are inherited from the parent h2_error
object if not specified.
stream_error
defaults to false
.
h2_error:new_traceback(message, stream_error, lvl)
Creates a new error object, recording a traceback from the current thread.
h2_error:error(message, stream_error, lvl)
Creates and throws a new error.
h2_error:assert(cond, ...)
If cond
is truthy, returns cond, ...
If cond
is falsy (i.e. false
or nil
), throws an error with the first element of ...
as the message
.
http.h2_stream
An h2_stream represents an HTTP 2 stream. The module follows the stream interface as well as HTTP 2 specific functions.
h2_stream.connection
See stream.connection
h2_stream:checktls()
See stream:checktls()
h2_stream:localname()
See stream:localname()
h2_stream:peername()
See stream:peername()
h2_stream:get_headers(timeout)
See stream:get_headers(timeout)
h2_stream:write_headers(headers, end_stream, timeout)
See stream:write_headers(headers, end_stream, timeout)
h2_stream:write_continue(timeout)
See stream:write_continue(timeout)
h2_stream:get_next_chunk(timeout)
See stream:get_next_chunk(timeout)
h2_stream:each_chunk()
See stream:each_chunk()
h2_stream:get_body_as_string(timeout)
See stream:get_body_as_string(timeout)
h2_stream:get_body_chars(n, timeout)
See stream:get_body_chars(n, timeout)
h2_stream:get_body_until(pattern, plain, include_pattern, timeout)
See stream:get_body_until(pattern, plain, include_pattern, timeout)
h2_stream:save_body_to_file(file, timeout)
See stream:save_body_to_file(file, timeout)
h2_stream:get_body_as_file(timeout)
See stream:get_body_as_file(timeout)
h2_stream:unget(str)
See stream:unget(str)
h2_stream:write_chunk(chunk, end_stream, timeout)
See stream:write_chunk(chunk, end_stream, timeout)
h2_stream:write_body_from_string(str, timeout)
See stream:write_body_from_string(str, timeout)
h2_stream:write_body_from_file(options|file, timeout)
See stream:write_body_from_file(options|file, timeout)
h2_stream:shutdown()
See stream:shutdown()
h2_stream:pick_id(id)
h2_stream:set_state(new)
h2_stream:reprioritise(child, exclusive)
h2_stream:write_http2_frame(typ, flags, payload, timeout, flush)
Writes a frame with h2_stream
’s stream id.
See h2_connection:write_http2_frame(typ, flags, streamid, payload, timeout, flush)
h2_stream:write_data_frame(payload, end_stream, padded, timeout, flush)
h2_stream:write_headers_frame(payload, end_stream, end_headers, padded, exclusive, stream_dep, weight, timeout, flush)
h2_stream:write_priority_frame(exclusive, stream_dep, weight, timeout, flush)
h2_stream:write_rst_stream_frame(err_code, timeout, flush)
h2_stream:rst_stream(err, timeout)
h2_stream:write_settings_frame(ACK, settings, timeout, flush)
h2_stream:write_push_promise_frame(promised_stream_id, payload, end_headers, padded, timeout, flush)
h2_stream:push_promise(headers, timeout)
Pushes a new promise to the client.
Returns the new stream as a h2_stream.
h2_stream:write_ping_frame(ACK, payload, timeout, flush)
h2_stream:write_goaway_frame(last_streamid, err_code, debug_msg, timeout, flush)
h2_stream:write_window_update_frame(inc, timeout, flush)
h2_stream:write_window_update(inc, timeout)
h2_stream:write_continuation_frame(payload, end_headers, timeout, flush)
http.headers
An ordered list of header fields. Each field has a name, a value and a never_index flag that indicates if the header field is potentially sensitive data.
Each headers object has an index by field name to efficiently retrieve values by key. Keep in mind that there can be multiple values for a given field name. (e.g. an HTTP server may send two Set-Cookie
headers).
As noted in the Conventions section, HTTP 1 request and status line fields are passed around inside of headers objects under keys ":authority"
, ":method"
, ":path"
, ":scheme"
and ":status"
as defined in HTTP 2. As such, they are all kept in string form (important to remember for the ":status"
field).
new()
Creates and returns a new headers object.
headers:len()
Returns the number of headers.
Also available as #headers
in Lua 5.2+.
headers:clone()
Creates and returns a clone of the headers object.
headers:append(name, value, never_index)
Append a header.
name
is the header field name. Lower case is the convention. It will not be validated at this time.value
is the header field value. It will not be validated at this time.never_index
is an optional boolean that indicates if thevalue
should be considered secret. Defaults to true for header fields: authorization, proxy-authorization, cookie and set-cookie.
headers:each()
An iterator over all headers that emits name, value, never_index
.
Example
local http_headers = require "http.headers" local myheaders = http_headers.new() myheaders:append(":status", "200") myheaders:append("set-cookie", "foo=bar") myheaders:append("connection", "close") myheaders:append("set-cookie", "baz=qux") for name, value, never_index in myheaders:each() do print(name, value, never_index) end --[[ prints: ":status", "200", false "set-cookie", "foo=bar", true "connection", "close", false "set-cookie", "baz=qux", true ]]
headers:has(name)
Returns a boolean indicating if the headers object has a field with the given name
.
headers:delete(name)
Removes all occurrences of a field name from the headers object.
headers:geti(i)
Return the i
-th header as name, value, never_index
headers:get_as_sequence(name)
Returns all headers with the given name in a table. The table will contain a field .n
with the number of elements.
Example
local http_headers = require "http.headers" local myheaders = http_headers.new() myheaders:append(":status", "200") myheaders:append("set-cookie", "foo=bar") myheaders:append("connection", "close") myheaders:append("set-cookie", "baz=qux") local mysequence = myheaders:get_as_sequence("set-cookie") --[[ mysequence will be: {n = 2; "foo=bar"; "baz=qux"} ]]
headers:get(name)
Returns all headers with the given name as multiple return values.
headers:get_comma_separated(name)
Returns all headers with the given name as items in a comma separated string.
headers:modifyi(i, value, never_index)
Change the i
-th’s header to a new value
and never_index
.
headers:upsert(name, value, never_index)
If a header with the given name
already exists, replace it. If not, append
it to the list of headers.
Cannot be used when a header name
already has multiple values.
headers:sort()
Sort the list of headers by their field name, ordering those starting with :
first. If name
s are equal then sort by value
, then by never_index
.
headers:dump(file, prefix)
Print the headers list to the given file, one per line. If file
is not given, then print to stderr
. prefix
is prefixed to each line.
http.hpack
new(SETTINGS_HEADER_TABLE_SIZE)
hpack_context:append_data(val)
hpack_context:render_data()
hpack_context:clear_data()
hpack_context:evict_from_dynamic_table()
hpack_context:dynamic_table_tostring()
hpack_context:set_max_dynamic_table_size(SETTINGS_HEADER_TABLE_SIZE)
hpack_context:encode_max_size(val)
hpack_context:resize_dynamic_table(new_size)
hpack_context:add_to_dynamic_table(name, value, k)
hpack_context:dynamic_table_id_to_index(id)
hpack_context:lookup_pair_index(k)
hpack_context:lookup_name_index(name)
hpack_context:lookup_index(index)
hpack_context:add_header_indexed(name, value, huffman)
hpack_context:add_header_never_indexed(name, value, huffman)
hpack_context:encode_headers(headers)
hpack_context:decode_headers(payload, header_list, pos)
http.hsts
Data structures useful for HSTS (HTTP Strict Transport Security)
new_store()
Creates and returns a new HSTS store.
hsts_store.max_items
The maximum number of items allowed in the store. Decreasing this value will only prevent new items from being added, it will not remove old items.
Defaults to infinity (any number of items is allowed).
hsts_store:clone()
Creates and returns a copy of a store.
hsts_store:store(host, directives)
Add new directives to the store about the given host
. directives
should be a table of directives, which must include the key "max-age"
.
Returns a boolean indicating if the item was accepted.
hsts_store:remove(host)
Removes the entry for host
from the store (if it exists).
hsts_store:check(host)
Returns a boolean indicating if the given host
is a known HSTS host.
hsts_store:clean_due()
Returns the number of seconds until the next item in the store expires.
hsts_store:clean()
Removes expired entries from the store.
http.proxies
new()
Returns an empty `proxies' object
proxies:update(getenv)
getenv
defaults to os.getenv
(http://www.lua.org/manual/5.3/manual.html#pdf-os.getenv)
Reads environmental variables that are used to control if requests go through a proxy.
http_proxy
(orCGI_HTTP_PROXY
if running in a program withGATEWAY_INTERFACE
set): the proxy to use for normal HTTP connectionshttps_proxy
orHTTPS_PROXY
: the proxy to use for HTTPS connectionsall_proxy
orALL_PROXY
: the proxy to use for all connections, overridden by other optionsno_proxy
orNO_PROXY
: a list of hosts to not use a proxy for
Returns proxies
.
proxies:choose(scheme, host)
Returns the proxy to use for the given scheme
and host
as a URI.
http.request
The http.request module encapsulates all the functionality required to retrieve an HTTP document from a server.
new_from_uri(uri)
Creates a new http.request
object from the given URI.
request.host
The host this request should be sent to.
request.port
The port this request should be sent to.
request.bind
The local outgoing address and optionally port to bind in the form of "address[:port]"
. Default is to allow the kernel to choose an address+port.
IPv6 addresses may be specified via square bracket notation. e.g. "127.0.0.1"
, "127.0.0.1:50000"
, "[::1]:30000"
.
This option is rarely needed. Supplying an address can be used to manually select the network interface to make the request from, while supplying a port is only really used to interoperate with firewalls or devices that demand use of a certain port.
request.tls
A boolean indicating if TLS should be used.
request.ctx
An alternative SSL_CTX*
to use. If not specified, uses the default TLS settings (see http.tls for information).
request.sendname
The TLS SNI host name used.
request.version
The HTTP version to use; leave as nil
to auto-select.
request.proxy
Specifies the a proxy that the request will be made through. The value should be a URI or false
to turn off proxying for the request.
request.headers
A http.headers object of headers that will be sent in the request.
request.hsts
The http.hsts store that will be used to enforce HTTP strict transport security. An attempt will be made to add strict transport headers from a response to the store.
Defaults to a shared store.
request.proxies
The http.proxies object used to select a proxy for the request. Only consulted if request.proxy
is nil
.
request.is_top_level
A boolean flag indicating if this request is a “top level” request (See RFC 6265bis-02 Section 5.2 (https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-02#section-5.2))
Defaults to true
request.follow_redirects
Boolean indicating if :go()
should follow redirects. Defaults to true
.
request.expect_100_timeout
Number of seconds to wait for a 100 Continue response before proceeding to send a request body. Defaults to 1
.
request.max_redirects
Maximum number of redirects to follow before giving up. Defaults to 5
. Set to math.huge
to not give up.
request.post301
Respect RFC 2616 Section 10.3.2 and don’t convert POST requests into body-less GET requests when following a 301 redirect. The non-RFC behaviour is ubiquitous in web browsers and assumed by servers. Modern HTTP endpoints send status code 308 to indicate that they don’t want the method to be changed. Defaults to false
.
request.post302
Respect RFC 2616 Section 10.3.3 and don’t convert POST requests into body-less GET requests when following a 302 redirect. The non-RFC behaviour is ubiquitous in web browsers and assumed by servers. Modern HTTP endpoints send status code 307 to indicate that they don’t want the method to be changed. Defaults to false
.
request:clone()
Creates and returns a clone of the request.
The clone has its own deep copies of the .headers
and .h2_settings
fields.
The .tls
and .body
fields are shallow copied from the original request.
request:handle_redirect(headers)
Process a redirect.
headers
should be response headers for a redirect.
Returns a new request
object that will fetch from new location.
request:to_uri(with_userinfo)
Returns a URI for the request.
If with_userinfo
is true
and the request has an authorization
header (or proxy-authorization
for a CONNECT request), the returned URI will contain a userinfo component.
request:set_body(body)
Allows setting a request body. body
may be a string, function or lua file object.
- If
body
is a string it will be sent as given. - If
body
is a function, it will be called repeatedly like an iterator. It should return chunks of the request body as a string ornil
if done. - If
body
is a lua file object, it will be:seek
’d (http://www.lua.org/manual/5.3/manual.html#pdf-file:seek) to the start, then sent as a body. Any errors encountered during file operations will be thrown.
request:go(timeout)
Performs the request.
The request object is not invalidated; and can be reused for a new request. On success, returns the response headers and a stream.
http.server
http.server objects are used to encapsulate the accept()
and dispatch of http clients. Each new client request will invoke the onstream
callback in a new cqueues managed coroutine. In addition to constructing and returning a HTTP response, an onstream
handler may decide to take ownership of the connection for other purposes, e.g. upgrade from a HTTP 1.1 connection to a WebSocket connection.
For examples of how to use the server library, please see the examples directory (https://github.com/daurnimator/lua-http/tree/master/examples) in the source tree.
new(options)
Creates a new instance of an HTTP server listening on the given socket.
.socket
(cqueues.socket): the socket thataccept()
will be called on.onerror
(function): Function that will be called when an error occurs (default handler throws an error). See server:onerror().onstream
(function): Callback function for handling a new client request. The function receives the server and the new stream as parameters. If the callback throws an error it will be reported from:step()
or:loop()
.tls
(boolean): Specifies if the system should use Transport Layer Security. Values are:nil
: Allow both tls and non-tls connectionstrue
: Allows tls connections onlyfalse
: Allows non-tls connections only
.ctx
(context object): Anopenssl.ssl.context
object to use for tls connections. Ifnil
is passed, a self-signed context will be generated..connection_setup_timeout
(number): Timeout (in seconds) to wait for client to send first bytes and/or complete TLS handshake. Default is 10 seconds..intra_stream_timeout
(number): Timeout (in seconds) to wait for a new stream on an idle connection before giving up and closing the connection.version
(number): The http version to allow to connect (default: any).cq
(cqueue): A cqueues controller to use as a main loop. The default is a new controller for the server..max_concurrent
(number): Maximum number of connections to allow live at a time. Default is infinity.
listen(options)
Creates a new socket and returns an HTTP server that will accept() from it. Parameters are the same as new(options)
except instead of .socket
you provide the following:
.host
(string): Local IP address in dotted decimal or IPV6 notation. This value is required if.path
is not specified..port
(number): IP port for the local socket. Specify 0 for automatic port selection. Ports 1-1024 require the application has root privilege to run. Maximum value is 65535. If.tls == nil
then this value is required. Otherwise, the defaults are:80
if.tls == false
443
if.tls == true
.path
(string): Path to UNIX a socket. This value is required if.host
is not specified..family
(string): Protocol family. Default is"AF_INET"
.v6only
(boolean): Specifytrue
to limit all connections to ipv6 only (no ipv4-mapped-ipv6). Default isfalse
..mode
(string):fchmod
orchmod
socket after creating UNIX domain socket..mask
(boolean): Set and restore umask when binding UNIX domain socket..unlink
(boolean):true
means unlink socket path before binding..reuseaddr
(boolean): Turn onSO_REUSEADDR
flag..reuseport
(boolean): Turn onSO_REUSEPORT
flag.
server:onerror(new_handler)
If called with parameters, the function replaces the current error handler function with new_handler
and returns a reference to the old function. Calling the function with no parameters returns the current error handler. The default handler throws an error. The onerror
function for the server can be set during instantiation through the options
table passed to the server.listen(options)
function.
server:listen(timeout)
Initializes the server socket and if required, resolves DNS. server:listen()
is required if localname is called before step or loop. On error, returns nil
, an error message and an error number.
server:localname()
Returns the connection information for the local socket. Returns address family, IP address and port for an external socket. For Unix domain sockets, the function returns AF_UNIX and the path. If the connection object is not connected, returns AF_UNSPEC (0). On error, returns nil
, an error message and an error number.
server:pause()
Cause the server loop to stop processing new clients until resume is called. Existing client connections will run until closed.
server:resume()
Resumes a paused server
and processes new client requests.
server:close()
Shutdown the server and close the socket. A closed server cannot be reused.
server:pollfd()
Returns a file descriptor (as an integer) or nil
.
The file descriptor can be passed to a system API like select
or kqueue
to wait on anything this server object wants to do. This method is used for integrating with other main loops, and should be used in combination with :events()
and :timeout()
.
server:events()
Returns a string indicating the type of events the object is waiting on: the string will contain "r"
if it wants to be steped when the file descriptor returned by pollfd()
has had POLLIN indicated; "w"
for POLLOUT or "p"
for POLLPRI.
This method is used for integrating with other main loops, and should be used in combination with :pollfd()
and :timeout()
.
server:timeout()
The maximum time (in seconds) to wait before calling server:step()
.
This method is used for integrating with other main loops, and should be used in combination with :pollfd()
and :events()
.
server:empty()
Returns true
if the master socket and all client connection have been closed, false
otherwise.
server:step(timeout)
Step once through server’s main loop: any waiting clients will be accept()
-ed, any pending streams will start getting processed, and each onstream
handler will get be run at most once. This method will block for up to timeout
seconds. On error, returns nil
, an error message and an error number.
This can be used for integration with external main loops.
server:loop(timeout)
Run the server as a blocking loop for up to timeout
seconds. The server will continue to listen and accept client requests until either :pause()
or :close()
is called, or an error is experienced.
server:add_socket(socket)
Add a new connection socket to the server for processing. The server will use the current onstream
request handler and all options
currently specified through the server.listen(options)
constructor. add_socket
can be used to process connection sockets obtained from an external source such as:
- Another cqueues thread with some other master socket.
- From inetd for start on demand daemons.
- A Unix socket with
SCM_RIGHTS
.
server:add_stream(stream)
Add an existing stream to the server for processing.
http.socks
Implements a subset of the SOCKS proxy protocol.
connect(uri)
uri
is a string with the address of the SOCKS server. A scheme of "socks5"
will resolve hosts locally, a scheme of "socks5h"
will resolve hosts on the SOCKS server. If the URI has a userinfo component it will be sent to the SOCKS server as a username and password.
Returns a http.socks object.
fdopen(socket)
This function takes an existing cqueues.socket as a parameter and returns a http.socks object with socket
as its base.
socks.needs_resolve
Specifies if the destination host should be resolved locally.
socks:clone()
Make a clone of a given socks object.
socks:add_username_password_auth(username, password)
Add username + password authorisation to the set of allowed authorisation methods with the given credentials.
socks:negotiate(host, port, timeout)
Complete the SOCKS connection.
Negotiates a socks connection. host
is a required string passed to the SOCKS server as the host address. The address will be resolved locally if .needs_resolve
is true
. port
is a required number to pass to the SOCKS server as the connection port. On error, returns nil
, an error message and an error number.
socks:close()
socks:take_socket()
Take possession of the socket object managed by the http.socks object. Returns the socket (or nil
if not available).
http.tls
has_alpn
Boolean indicating if ALPN is available in the current environment.
It may be disabled if OpenSSL was compiled without ALPN support, or is an old version.
has_hostname_validation
Boolean indicating if hostname validation (https://wiki.openssl.org/index.php/Hostname_validation) is available in the current environment.
It may be disabled if OpenSSL is an old version.
modern_cipher_list
The Mozilla “Modern” cipher list (https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility) as a colon separated list, ready to pass to OpenSSL
intermediate_cipher_list
The Mozilla “Intermediate” cipher list (https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28default.29) as a colon separated list, ready to pass to OpenSSL
old_cipher_list
The Mozilla “Old” cipher list (https://wiki.mozilla.org/Security/Server_Side_TLS#Old_backward_compatibility) as a colon separated list, ready to pass to OpenSSL
banned_ciphers
A set (table with string keys and values of true
) of the ciphers banned in HTTP 2 (https://http2.github.io/http2-spec/#BadCipherSuites) where the keys are OpenSSL cipher names.
Ciphers not known by OpenSSL are missing from the set.
new_client_context()
Create and return a new luaossl SSL context useful for HTTP client connections.
new_server_context()
Create and return a new luaossl SSL context useful for HTTP server connections.
http.util
encodeURI(str)
encodeURIComponent(str)
decodeURI(str)
decodeURIComponent(str)
query_args(str)
Returns an iterator over the pairs in str
Example
local http_util = require "http.util" for name, value in http_util.query_args("foo=bar&baz=qux") do print(name, value) end --[[ prints: "foo", "bar" "baz", "qux" ]]
dict_to_query(dict)
Converts a dictionary (table with string keys) with string values to an encoded query string.
Example
local http_util = require "http.util" print(http_util.dict_to_query({foo = "bar"; baz = "qux"})) --> "baz=qux&foo=bar"
resolve_relative_path(orig_path, relative_path)
is_safe_method(method)
Returns a boolean indicating if the passed string method
is a “safe” method. See RFC 7231 section 4.2.1 (https://tools.ietf.org/html/rfc7231#section-4.2.1) for more information.
is_ip(str)
Returns a boolean indicating if the passed string str
is a valid IP.
scheme_to_port
Map from schemes (as strings) to default ports (as integers).
Example
local http_util = require "http.util" print(http_util.split_authority("localhost:8000", "http")) --> "localhost", 8000 print(http_util.split_authority("example.com", "https")) --> "localhost", 443
imf_date(time)
Returns the time in HTTP preferred date format (See RFC 7231 section 7.1.1.1 (https://tools.ietf.org/html/rfc7231#section-7.1.1.1))
time
defaults to the current time
maybe_quote(str)
- If
str
is a validtoken
, return it as-is. - If
str
would be valid as aquoted-string
, return the quoted version - Otherwise, returns
nil
http.version
name
"lua-http"
version
Current version of lua-http as a string.
http.websocket
new_from_uri(uri, protocols)
Creates a new http.websocket
object of type "client"
from the given URI.
protocols
(optional) should be a lua table containing a sequence of protocols to send to the server
new_from_stream(stream, headers)
Attempts to create a new http.websocket
object of type "server"
from the given request headers and stream.
stream
should be a live HTTP 1 stream of the"server"
type.headers
should be headers of a suspected websocket upgrade request from an HTTP 1 client.
This function does not have side effects, and is hence okay to use tentatively.
websocket.close_timeout
Amount of time (in seconds) to wait between sending a close frame and actually closing the connection. Defaults to 3
seconds.
websocket:accept(options, timeout)
Completes negotiation with a websocket client.
options
is a table containing:headers
(optional) a headers object to use as a prototype for the response headersprotocols
(optional) should be a lua table containing a sequence of protocols to allow from the client
Usually called after a successful new_from_stream
websocket:connect(timeout)
Connect to a websocket server.
Usually called after a successful new_from_uri
websocket:receive(timeout)
Reads and returns the next data frame plus its opcode. Any ping frames received while reading will be responded to.
The opcode 0x1
will be returned as "text"
and 0x2
will be returned as "binary"
.
websocket:each()
Iterator over websocket:receive()
.
websocket:send_frame(frame, timeout)
Low level function to send a raw frame.
websocket:send(data, opcode, timeout)
Send the given data
as a data frame.
data
should be a stringopcode
can be a numeric opcode,"text"
or"binary"
. Ifnil
, defaults to a text frame. Note thisopcode
is the websocket frame opcode, not an application specific opcode. The opcode should be one from the IANA registry (https://www.iana.org/assignments/websocket/websocket.xhtml#opcode).
websocket:send_ping(data, timeout)
Sends a ping frame.
data
is optional
websocket:send_pong(data, timeout)
Sends a pong frame. Works as a unidirectional keep-alive.
data
is optional
websocket:close(code, reason, timeout)
Closes the websocket connection.
code
defaults to1000
reason
is an optional string
http.zlib
An abstraction layer over the various lua zlib libraries.
engine
Currently either "lua-zlib"
(https://github.com/brimworks/lua-zlib) or "lzlib"
(https://github.com/LuaDist/lzlib)
inflate()
Returns a closure that inflates (uncompresses) a zlib stream.
The closure takes a string of compressed data and an end of stream flag (boolean
) as parameters and returns the inflated output as a string. The function will throw an error if the input is not a valid zlib stream.
deflate()
Returns a closure that deflates (compresses) a zlib stream.
The closure takes a string of uncompressed data and an end of stream flag (boolean
) as parameters and returns the deflated output as a string.
Example
local zlib = require "http.zlib" local original = "the racecar raced around the racecar track" local deflater = zlib.deflate() local compressed = deflater(original, true) print(#original, #compressed) -- compressed should be smaller local inflater = zlib.inflate() local uncompressed = inflater(compressed, true) assert(original == uncompressed)
http.compat.prosody
Provides usage similar to prosody’s net.http (https://prosody.im/doc/developers/net/http)
request(url, ex, callback)
A few key differences to the prosody net.http.request
:
- must be called from within a running cqueue
- The callback may be called from a different thread in the cqueue
The returned object will be a http.request object
- This object is passed to the callback on errors and as the fourth argument on success
- The default user-agent will be from lua-http (rather than
"Prosody XMPP Server"
) - lua-http features (such as HTTP2) will be used where possible
Example
local prosody_http = require "http.compat.prosody" local cqueues = require "cqueues" local cq = cqueues.new() cq:wrap(function() prosody_http.request("http://httpbin.org/ip", {}, function(b, c, r) print(c) --> 200 print(b) --> {"origin": "123.123.123.123"} end) end) assert(cq:loop())
http.compat.socket
Provides compatibility with luasocket’s http.request module (http://w3.impa.br/~diego/software/luasocket/http.html).
Differences:
- Will automatically be non-blocking when run inside a cqueues managed coroutine
- lua-http features (such as HTTP2) will be used where possible
Example
Using the `simple' interface as part of a normal script:
local socket_http = require "http.compat.socket" local body, code = assert(socket_http.request("http://lua.org")) print(code, #body) --> 200, 2514
Links
- Github (https://github.com/daurnimator/lua-http)
- Issue tracker (https://github.com/daurnimator/lua-http/issues)
Authors
Daurnimator <quae@daurnimator.com>.