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