On this page
  1. tecs.io.http
  2. Module contents
    1. Constructors
    2. Types
    3. Functions
  3. Constructors
    1. newClient
  4. Types
    1. Client
    2. ClientOptions
    3. plugin
    4. Request
    5. Response
  5. Functions
    1. getOpenClientCount

tecs.io.http

Asynchronous HTTP and HTTPS.

local endpoint <const> = tecs.io.URI.new(
    "https://example.com/manifest.json"
)
tecs.io.http.newClient({userAgent = "mygame/1.0"})
    :send({url = endpoint})
    :map(function(response: tecs.io.http.Response): string
        local body <const> = response.body
        if body is tecs.io.ReadableStream then
            return body:readAll()
        end
        error("the response destination is not readable")
    end)
    :onSettle(function(manifest: tecs.Future<string>)
        print(manifest.value)
    end)

The process runtime turns every open client once per iteration, so requests advance without game code pumping them.

An HTTP error status still produces a ready response. A failed future means that DNS, connection, TLS, timeout, or streaming produced no response.

Call Client:close when you no longer need its connection pool. Losing the last Lua reference does not cancel its requests. A headless tool calls tecs.runtime.poll; Application calls it once per frame.

Module contents

Constructors

Constructor Description
newClient Builds a client.

Types

Type Kind Description
Client interface A Client owns one connection pool and the futures using it.
ClientOptions record Settings copied when an HTTP client is built.
plugin record Read-only. plugin exposes requests and responses as ECS components.
Request record Request describes one request and requires only url.
Response record Response describes what a completed transfer settles to regardless of status code.

Functions

Function Kind Description
getOpenClientCount Static Returns the open-client count.

Constructors

tecs.io.http.newClient Static

Builds a client.

function tecs.io.http.newClient(options: ClientOptions): Client

Arguments

Name Type Description
options ClientOptions The caller supplies client defaults or omits this record to use every default. Each insecureHosts entry logs a warning.

Returns

Type Description
Client Returns an open client that remains active until close.

Examples

local http <const> = tecs.io.http
local endpoint, reason = tecs.io.URI.new("https://example.com/status")
if endpoint == nil then
    error(reason)
end
local client <const> = http.newClient({
    userAgent = "mygame/1.0",
    timeoutMs = 10000,
    maxBytes = 1024 * 1024,
})
local response <const> = client:send({url = endpoint}).value
print(response.status, response.url:host())
response.body:close()
client:close()

Types

tecs.io.http.Client interface

A Client owns one connection pool and the futures using it.

Closing the client cancels every pending request, releases the pool, and remains safe to repeat. A client also drives its futures as their source, but an application or tecs.runtime.poll normally performs that work rather than game code calling poll or advance directly.

interface tecs.io.http.Client is Closeable
    sliceMs: number
    defaultWaitMs: number

    advance: function(self, ms: number): integer
    cancel: function(self, future: Future<any>)
    pending: function(self): integer
    poll: function(self): integer
    pump: function(self): integer
    send: function(self, request: Request): Future<Response>
end

Interfaces

Interface
Closeable

tecs.io.http.Client.sliceMs field

Engine-owned. Sets the maximum duration of one blocking future wait slice. Ordinary game code should ignore it.

tecs.io.http.Client.sliceMs: number

tecs.io.http.Client.defaultWaitMs field

Engine-owned. Sets the timeout used when Future:wait receives no explicit timeout. Ordinary game code should ignore it.

tecs.io.http.Client.defaultWaitMs: number

tecs.io.http.Client:advance Instance

Waits briefly for an event and drains the events then ready.

Future:wait calls this through its source. Application code normally does not call it directly.

function tecs.io.http.Client.advance(self, ms: number): integer
Arguments
Name Type Description
self Client The open client to advance.
ms number The caller supplies the maximum milliseconds to wait.
Returns
Type Description
integer Returns the number of response events processed.

tecs.io.http.Client:cancel Instance

Cancels the request belonging to a future.

A settled future or a future from another source changes nothing.

function tecs.io.http.Client.cancel(self, future: Future<any>)
Arguments
Name Type Description
self Client The client that owns the request.
future Future<any> The caller supplies the request future to cancel.
Returns

None.

tecs.io.http.Client:pending Instance

Returns the number of unsettled requests.

function tecs.io.http.Client.pending(self): integer
Arguments
Name Type Description
self Client The client to inspect.
Returns
Type Description
integer Returns zero after every request settles or is canceled.

tecs.io.http.Client:poll Instance

Polls this client as a future source without blocking.

Application code normally lets the process runtime call this.

function tecs.io.http.Client.poll(self): integer
Arguments
Name Type Description
self Client The open client to poll.
Returns
Type Description
integer Returns the number of response events processed.

tecs.io.http.Client:pump Instance

Drains every response event currently ready without blocking.

Application code normally lets the process runtime call this.

function tecs.io.http.Client.pump(self): integer
Arguments
Name Type Description
self Client The open client to advance.
Returns
Type Description
integer Returns the number of response events processed.

tecs.io.http.Client:send Instance

Starts one HTTP transfer and returns immediately.

A transport failure settles the future as failed. An HTTP error status settles it as ready with that status in the response.

function tecs.io.http.Client.send(
    self, request: Request
): Future<Response>
Arguments
Name Type Description
self Client The open client that owns the request.
request Request The caller supplies the URL and optional method, headers, body, destination, timeouts, and byte limit.
Returns
Type Description
Future<Response> Returns a future settled by the process runtime.

tecs.io.http.ClientOptions record

Settings copied when an HTTP client is built.

userAgent and headers set request defaults. timeoutMs defaults to 30000, connectTimeoutMs to 10000, and stallTimeoutMs to zero, which disables the no-progress timeout. maxRedirects defaults to five, maxConnections to 16, and maxConnectionsPerHost to six. maxBytes defaults to zero for no response limit. compressed defaults to true.

insecureHosts disables certificate verification for named hosts and logs a warning for each. proxy accepts the textual spelling of an absolute URI, follows environment variables when nil, and forces a direct connection when empty. noProxy uses Reqwest's exclusion syntax, and proxyCredentials uses user:password.

record tecs.io.http.ClientOptions
    userAgent: string
    headers: {string: string}
    timeoutMs: number
    connectTimeoutMs: number
    stallTimeoutMs: number
    maxRedirects: integer
    maxConnections: integer
    maxConnectionsPerHost: integer
    maxBytes: integer
    compressed: boolean
    insecureHosts: {string}
    proxy: string
    noProxy: string
    proxyCredentials: string
end

tecs.io.http.ClientOptions.userAgent field

Caller-writable. Sets User-Agent on every request.

tecs.io.http.ClientOptions.userAgent: string

tecs.io.http.ClientOptions.headers field

Caller-writable. Sets headers sent on every request. Per-request headers override these without regard to case.

tecs.io.http.ClientOptions.headers: {string: string}

tecs.io.http.ClientOptions.timeoutMs field

Caller-writable. Sets milliseconds allowed for a whole transfer. Defaults to 30000.

tecs.io.http.ClientOptions.timeoutMs: number

tecs.io.http.ClientOptions.connectTimeoutMs field

Caller-writable. Sets milliseconds allowed to establish a connection. Defaults to 10000.

tecs.io.http.ClientOptions.connectTimeoutMs: number

tecs.io.http.ClientOptions.stallTimeoutMs field

Caller-writable. Sets milliseconds a response may make no progress. Zero disables this timeout.

tecs.io.http.ClientOptions.stallTimeoutMs: number

tecs.io.http.ClientOptions.maxRedirects field

Caller-writable. Sets redirects followed. Defaults to five; zero follows none.

tecs.io.http.ClientOptions.maxRedirects: integer

tecs.io.http.ClientOptions.maxConnections field

Caller-writable. Sets requests allowed to use sockets at once. Defaults to 16.

tecs.io.http.ClientOptions.maxConnections: integer

tecs.io.http.ClientOptions.maxConnectionsPerHost field

Caller-writable. Sets requests allowed to use sockets to one host. Defaults to six.

tecs.io.http.ClientOptions.maxConnectionsPerHost: integer

tecs.io.http.ClientOptions.maxBytes field

Caller-writable. Sets maximum response-body bytes. Zero is unbounded.

tecs.io.http.ClientOptions.maxBytes: integer

tecs.io.http.ClientOptions.compressed field

Caller-writable. Accepts gzip and deflate response compression when true. Defaults to true.

tecs.io.http.ClientOptions.compressed: boolean

tecs.io.http.ClientOptions.insecureHosts field

Caller-writable. Lists host names whose TLS certificates are not verified.

tecs.io.http.ClientOptions.insecureHosts: {string}

tecs.io.http.ClientOptions.proxy field

Caller-writable. Sets the textual spelling of an absolute proxy URI. Nil follows the environment; an empty string forces a direct connection. This option accepts a string, not a URI object.

tecs.io.http.ClientOptions.proxy: string

tecs.io.http.ClientOptions.noProxy field

Caller-writable. Lists hosts excluded from an explicitly configured proxy.

tecs.io.http.ClientOptions.noProxy: string

tecs.io.http.ClientOptions.proxyCredentials field

Caller-writable. Sets proxy credentials in user:password form.

tecs.io.http.ClientOptions.proxyCredentials: string

tecs.io.http.plugin record

Read-only. plugin exposes requests and responses as ECS components.

record tecs.io.http.plugin
    record Request is Component
        url: URI
        method: string
        headers: {string: string}
        body: string | ReadableStream
        into: string | WritableStream
        timeoutMs: number
        stallTimeoutMs: number
        maxBytes: integer
    end

    record Response is Component
        status: integer
        headers: {string: string}
        body: Stream
        url: URI
        error: string
    end

    record Pending is Component
    end

    clientOf: function(World): Client
    close: function(World)
    install: function(World, Options)
end

tecs.io.http.plugin.Request record

What a game spawns to make a request. The fields of a Request, because there is no second vocabulary for the same thing.

record tecs.io.http.plugin.Request is Component
    url: URI
    method: string
    headers: {string: string}
    body: string | ReadableStream
    into: string | WritableStream
    timeoutMs: number
    stallTimeoutMs: number
    maxBytes: integer
end
Interfaces
Interface
Component

tecs.io.http.plugin.Request.url field

Caller-writable. Sets an absolute HTTP or HTTPS URI.

tecs.io.http.plugin.Request.url: URI

tecs.io.http.plugin.Request.method field

Caller-writable. Sets the method. Defaults to "GET".

tecs.io.http.plugin.Request.method: string

tecs.io.http.plugin.Request.headers field

Caller-writable. Sets headers merged over the client's defaults without regard to case. A Content-Length must contain decimal digits and must match a body whose length is known.

tecs.io.http.plugin.Request.headers: {string: string}

tecs.io.http.plugin.Request.body field

Caller-writable. Sets what to send. A snapshot rejects a tecs.io.newHandleStream here because its live handle cannot be reconstructed.

tecs.io.http.plugin.Request.body: string | ReadableStream

tecs.io.http.plugin.Request.into field

Caller-writable. Sets where the body goes. Left out, the response carries a replayable in-memory Stream. A snapshot rejects a tecs.io.newHandleStream here because its live handle cannot be reconstructed.

tecs.io.http.plugin.Request.into: string | WritableStream

tecs.io.http.plugin.Request.timeoutMs field

Caller-writable. Sets milliseconds for this transfer, overriding the client's value.

tecs.io.http.plugin.Request.timeoutMs: number

tecs.io.http.plugin.Request.stallTimeoutMs field

Caller-writable. Sets tolerated milliseconds without progress, overriding the client's value.

tecs.io.http.plugin.Request.stallTimeoutMs: number

tecs.io.http.plugin.Request.maxBytes field

Caller-writable. Sets the body byte limit, overriding the client's value.

tecs.io.http.plugin.Request.maxBytes: integer

tecs.io.http.plugin.Response record

What replaces a Request once the transfer settles.

Present whatever happened, because "the request finished" is the event a system waits for and a failure is one of the ways it can finish. error is what says which.

record tecs.io.http.plugin.Response is Component
    status: integer
    headers: {string: string}
    body: Stream
    url: URI
    error: string
end
Interfaces
Interface
Component

tecs.io.http.plugin.Response.status field

Engine-owned. Reports the HTTP status code, or zero when the transfer never received one.

tecs.io.http.plugin.Response.status: integer

tecs.io.http.plugin.Response.headers field

Engine-owned. Reports response headers with lower-cased names.

tecs.io.http.plugin.Response.headers: {string: string}

tecs.io.http.plugin.Response.body field

Engine-owned. Provides the body wherever it went.

tecs.io.http.plugin.Response.body: Stream

tecs.io.http.plugin.Response.url field

Engine-owned. Reports the URI that actually answered, or nil when the request failed before it supplied a valid URI.

tecs.io.http.plugin.Response.url: URI

tecs.io.http.plugin.Response.error field

Engine-owned. Reports why the transfer did not complete, or nil when it did. A 404 is not one of these: it is a status of 404 and no error.

tecs.io.http.plugin.Response.error: string

tecs.io.http.plugin.Pending record

On an entity whose request is in flight. Internal, and the reason a request is sent once rather than every frame.

A marker, and the future it stands for is not a field on it: a future holds listeners and the source that settles them, so nothing a save writes can carry one. Transient for the same reason, which is what makes a save taken mid-request coherent: the Request survives, this does not, and the load sends it again.

record tecs.io.http.plugin.Pending is Component
end
Interfaces
Interface
Component

tecs.io.http.plugin.clientOf Static

The world's client, or nil when the plugin is not installed.

function tecs.io.http.plugin.clientOf(World): Client
Arguments
Name Type Description
#1 World
Returns
Type Description
Client

tecs.io.http.plugin.close Static

Closes the world's client and forgets it.

function tecs.io.http.plugin.close(World)
Arguments
Name Type Description
#1 World
Returns

None.

tecs.io.http.plugin.install Static

Installs the plugin: world:addPlugin(tecs.io.http.plugin.install).

Takes options because the plugin builds the world's client, and a game that wants a userAgent on it has nowhere else to say so: world:addPlugin(function(w) http.plugin.install(w, {...}) end).

function tecs.io.http.plugin.install(World, Options)
Arguments
Name Type Description
#1 World
#2 Options
Returns

None.

tecs.io.http.Request record

Request describes one request and requires only url.

record tecs.io.http.Request
    url: URI
    method: string
    headers: {string: string}
    body: string | iotypes.ReadableStream
    into: string | iotypes.WritableStream
    timeoutMs: number
    stallTimeoutMs: number
    maxBytes: integer
end

tecs.io.http.Request.url field

Caller-writable. Sets an absolute URL with an http or https scheme.

tecs.io.http.Request.url: URI

tecs.io.http.Request.method field

Caller-writable. Sets the method. Defaults to GET.

tecs.io.http.Request.method: string

tecs.io.http.Request.headers field

Caller-writable. Sets headers merged over the client's defaults. A Content-Length must contain decimal digits and must match a body whose length is known.

tecs.io.http.Request.headers: {string: string}

tecs.io.http.Request.body field

Caller-writable. Sets bytes to send. A stream opens one reader when this request begins and feeds it through a bounded upload queue.

tecs.io.http.Request.body: string | iotypes.ReadableStream

tecs.io.http.Request.into field

Caller-writable. Sets where response chunks are written. A string is a file path.

tecs.io.http.Request.into: string | iotypes.WritableStream

tecs.io.http.Request.timeoutMs field

Caller-writable. Overrides the client's whole-transfer timeout.

tecs.io.http.Request.timeoutMs: number

tecs.io.http.Request.stallTimeoutMs field

Caller-writable. Overrides the client's no-progress timeout.

tecs.io.http.Request.stallTimeoutMs: number

tecs.io.http.Request.maxBytes field

Caller-writable. Overrides the client's body limit. Zero is unbounded.

tecs.io.http.Request.maxBytes: integer

tecs.io.http.Response record

Response describes what a completed transfer settles to regardless of status code.

record tecs.io.http.Response
    status: integer
    headers: {string: string}
    body: iotypes.Stream
    url: URI

    ok: function(self): boolean
end

tecs.io.http.Response.status field

Read-only. Reports the status after redirects.

tecs.io.http.Response.status: integer

tecs.io.http.Response.headers field

Read-only. Reports final response headers with lower-cased names.

tecs.io.http.Response.headers: {string: string}

tecs.io.http.Response.body field

Read-only. Provides response bytes in memory or in the requested destination.

tecs.io.http.Response.body: iotypes.Stream

tecs.io.http.Response.url field

Read-only. Reports the effective URL after redirects.

tecs.io.http.Response.url: URI

tecs.io.http.Response:ok Instance

Whether the status is in the 2xx range.

function tecs.io.http.Response.ok(self): boolean
Arguments
Name Type Description
self Response
Returns
Type Description
boolean

Functions

tecs.io.http.getOpenClientCount Static

Returns the open-client count.

function tecs.io.http.getOpenClientCount(): integer

Arguments

None.

Returns

Type Description
integer Returns the process-wide count of clients not yet closed.