commit: a545f27fdb504b22ee3799d58f8645ca3fb30eb8 Author: Nicolas PARLANT <nicolas.parlant <AT> parhuet <DOT> fr> AuthorDate: Fri Dec 6 00:56:47 2024 +0000 Commit: Nicolas PARLANT <ppn <AT> parhuet <DOT> fr> CommitDate: Fri Dec 6 20:45:49 2024 +0000 URL: https://gitweb.gentoo.org/repo/proj/guru.git/commit/?id=a545f27f
dev-lua/lua-http: add doc/man, version 20240908 to 0.4_p20240908 Signed-off-by: Nicolas PARLANT <nicolas.parlant <AT> parhuet.fr> dev-lua/lua-http/Manifest | 2 +- dev-lua/lua-http/files/lua-http.3 | 2119 ++++++++++++++++++++ ...240908.ebuild => lua-http-0.4_p20240908.ebuild} | 15 +- 3 files changed, 2133 insertions(+), 3 deletions(-) diff --git a/dev-lua/lua-http/Manifest b/dev-lua/lua-http/Manifest index c32ca2fbe..d83ea6b84 100644 --- a/dev-lua/lua-http/Manifest +++ b/dev-lua/lua-http/Manifest @@ -1 +1 @@ -DIST lua-http-20240908.tar.gz 142897 BLAKE2B 2c68b11ffa8e579ba2be9db08c65f8f28b1eb96079a8d1b71c245ff516a7249cee86317aca3e0635b2e612120aedfa6f4e3bbe9392919835502845567cb2100f SHA512 579db298e901c555bfabd09d375d83ec1be0b45e37c9c55a779620c720a18392fdee3dc971a2ded7b0804f1fcdfc9f69863510a5823b1a0b2637b8195a42cae1 +DIST lua-http-0.4_p20240908.tar.gz 142897 BLAKE2B 2c68b11ffa8e579ba2be9db08c65f8f28b1eb96079a8d1b71c245ff516a7249cee86317aca3e0635b2e612120aedfa6f4e3bbe9392919835502845567cb2100f SHA512 579db298e901c555bfabd09d375d83ec1be0b45e37c9c55a779620c720a18392fdee3dc971a2ded7b0804f1fcdfc9f69863510a5823b1a0b2637b8195a42cae1 diff --git a/dev-lua/lua-http/files/lua-http.3 b/dev-lua/lua-http/files/lua-http.3 new file mode 100644 index 000000000..c3cceca86 --- /dev/null +++ b/dev-lua/lua-http/files/lua-http.3 @@ -0,0 +1,2119 @@ +.\" 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 q...@daurnimator.com +.ME \c. diff --git a/dev-lua/lua-http/lua-http-20240908.ebuild b/dev-lua/lua-http/lua-http-0.4_p20240908.ebuild similarity index 81% rename from dev-lua/lua-http/lua-http-20240908.ebuild rename to dev-lua/lua-http/lua-http-0.4_p20240908.ebuild index c0e49196e..2d446bc7e 100644 --- a/dev-lua/lua-http/lua-http-20240908.ebuild +++ b/dev-lua/lua-http/lua-http-0.4_p20240908.ebuild @@ -9,6 +9,7 @@ inherit lua DESCRIPTION="HTTP Library for Lua. Supports HTTP(S) 1.0, 1.1 and 2.0; client and server." HOMEPAGE="https://daurnimator.github.io/lua-http/" +HOMEPAGE+=" https://github.com/daurnimator/lua-http" EGIT_COMMIT="ee3cf4b4992479b8ebfb39b530694af3bbd1d1eb" SRC_URI="https://github.com/daurnimator/${PN}/archive/${EGIT_COMMIT}.tar.gz -> ${P}.tar.gz" S="${WORKDIR}/${PN}-${EGIT_COMMIT}" @@ -17,12 +18,11 @@ LICENSE="MIT" SLOT="0" KEYWORDS="~amd64" +IUSE="doc" REQUIRED_USE="${LUA_REQUIRED_USE}" DEPEND=" ${LUA_DEPS} - lua_targets_luajit? ( dev-lua/compat53[lua_targets_luajit(-)] ) - lua_targets_lua5-1? ( dev-lua/compat53[lua_targets_lua5-1(-)] ) dev-lua/basexx[${LUA_USEDEP}] dev-lua/binaryheap[${LUA_USEDEP}] dev-lua/cqueues[${LUA_USEDEP}] @@ -31,11 +31,19 @@ DEPEND=" dev-lua/lpeg-patterns[${LUA_USEDEP}] dev-lua/LuaBitOp[${LUA_USEDEP}] dev-lua/luaossl[${LUA_USEDEP}] + lua_targets_luajit? ( dev-lua/compat53[lua_targets_luajit(-)] ) + lua_targets_lua5-1? ( dev-lua/compat53[lua_targets_lua5-1(-)] ) " RDEPEND="${DEPEND}" +BDEPEND="doc? ( virtual/pandoc )" lua_enable_tests busted +src_compile() { + default + use doc && emake -C doc lua-http.html +} + lua_src_install() { insinto $(lua_get_lmod_dir)/http/ doins http/*.lua http/compat/*.lua @@ -43,5 +51,8 @@ lua_src_install() { src_install() { lua_foreach_impl lua_src_install + use doc && local HTML_DOCS=( doc/lua-http.html ) + dodoc -r "examples" + doman "${FILESDIR}"/lua-http.3 einstalldocs }