Net API

The Net API provides:

  • HTTP(S) helpers

    • net_http_get(url, timeout_ms?)

    • net_http_post(url, content_type, body, timeout_ms?)

  • WebSocket client using WinHTTP’s WebSocket support

    • ws_connect(url, timeout_ms?) -> websocket userdata

    • WebSocket methods: send_text, send_binary, send_json, recv, poll, is_open, close

Supported URL schemes:

  • HTTP: http://, https://

  • WebSocket: ws://, wss:// (internally mapped to http:// / https:// for WinHTTP)

  • Works with hostnames and IP addresses, with or without custom ports.

⚠ These are low-level primitives intended for advanced users. Higher-level helpers/wrappers can be built on top, but are not part of this page.


HTTP API

net_http_get

ok, status_code, body = net_http_get(url, timeout_ms?)

Performs a synchronous HTTP/HTTPS GET.

Parameters

  • url : string

    • Full URL:

      • "https://example.com/api/test"

      • "http://127.0.0.1:8080/status"

  • timeout_ms : number (optional)

    • Total timeout (ms) applied to resolve, connect, send, receive.

    • 0 or nil = default WinHTTP timeouts.

Returns

  • ok : boolean

    • true if the HTTP request succeeded at the transport level (WinHTTP OK).

    • false if there was a network/protocol error.

  • status_code : integer

    • HTTP status code (200, 404, 500, ...)

    • 0 if the request failed before a response was received.

  • body : string

    • Response body as raw bytes (Lua string).

Example


net_http_post

Performs a synchronous HTTP/HTTPS POST with a request body.

Parameters

  • url : string

    • Full URL, same as net_http_get.

  • content_type : string

    • MIME type, e.g.:

      • "application/json"

      • "application/x-www-form-urlencoded"

      • "text/plain; charset=utf-8"

  • body : string

    • Request body as a Lua string (raw bytes).

  • timeout_ms : number (optional)

    • Same semantics as net_http_get.

Returns

  • ok : boolean

  • status_code : integer

  • body : string (Same meaning as net_http_get.)

Example – POST JSON


WebSocket API

The WebSocket API exposes:

  • A global constructor: ws_connect(url, timeout_ms?)

  • A userdata type net_ws with methods:

    • send_text, send_binary, send_json

    • recv, poll

    • is_open, close

Internally, the implementation uses WinHTTP:

  • ws:// → internally mapped to http://

  • wss:// → internally mapped to https://

  • A background receive thread continuously reads frames and pushes complete messages into a queue.

  • Lua sees messages via ws:recv() (blocking) or ws:poll() (non-blocking).

Global: ws_connect

Opens a client WebSocket connection.

Parameters

  • url : string

    • WebSocket URL, e.g.:

      • "wss://ws.postman-echo.com/raw"

      • "ws://127.0.0.1:9001/echo"

  • timeout_ms : number (optional)

    • WinHTTP timeouts (resolve, connect, send, receive).

Returns

  • On success:

    • ws : userdata (type net_ws)

      • A WebSocket object with methods described below.

  • On failure:

    • nil, "error string"

Example


WebSocket Object (net_ws)

Once connected, you have a userdata with metatable "net_ws", exposing these methods:

  • ws:send_text(message)

  • ws:send_binary(data)

  • ws:send_json(value)

  • ws:recv()

  • ws:poll()

  • ws:is_open()

  • ws:close(code?)

And metamethods:

  • __gc – automatic cleanup

  • __tostring"websocket(open)" or "websocket(closed)"


ws:send_text

Sends a UTF-8 text message.

Parameters

  • message : string – Lua string, treated as UTF-8.

Returns

  • ok : booleantrue if the send call succeeded; false otherwise.

Example


ws:send_binary

Sends a binary WebSocket frame.

Parameters

  • data : string – raw bytes (Lua string).

⚠ Some public echo servers (e.g. Postman’s) close the connection when they receive binary frames. That’s a server behavior, not a bug in the API.

Returns

  • ok : boolean

Example


ws:send_json

Sends a JSON text message. Supports:

  • value = string: sent directly as UTF-8.

  • value = table: encoded via global Lua function json_encode.

Parameters

  • value : string | table

    • string – assumed to already be valid JSON.

    • table – will call json_encode(value) to produce JSON.

Requirements

  • For table:

    • A global function json_encode must exist:

    • If json_encode is missing or throws, ws:send_json raises a Lua error.

Returns

  • ok : boolean

Example – string

Example – table


ws:recv (blocking)

Blocking receive that waits for a complete WebSocket message to be available in the queue.

  • Uses the internal message queue (filled by a background thread).

  • Does not block WinHTTP directly; it loops until:

    • A message is dequeued, or

    • The socket is closed and the queue is empty.

Returns

  • On message:

    • msg : string – message payload (text or binary).

    • is_text : boolean

      • true for text frames

      • false for binary frames

  • On closed and empty:

    • nil

⚠ This is a blocking loop with a small sleep (Sleep(1)). Best used in worker scripts or one-shot tests, not every frame in the UI thread.

Example


ws:poll (non-blocking)

Non-blocking receive from the internal message queue.

You get three possible outcomes:

  1. Message available

    • msg : string – message payload

    • is_text_or_closed : booleantrue = text, false = binary

  2. No message yet, still open

    • msg = nil

    • is_text_or_closed is nil

  3. Socket closed and queue empty

    • msg = nil

    • is_text_or_closed = false

This makes it easy to integrate in per-frame loops:

  • msg != nil → handle it

  • msg == nil and is_text_or_closed == nil → nothing yet

  • msg == nil and is_text_or_closed == false → closed

Example: per-frame polling


ws:is_open

Checks whether the socket is currently open.

  • Reflects the internal is_open flag updated by the background thread and close logic.

Returns

  • true if the socket is open.

  • false if it is closed or has encountered a fatal error.

Example


ws:close

Closes the WebSocket connection.

  • Signals the background receive thread to stop.

  • Sends a WebSocket close frame (best effort).

  • Waits for the thread to exit, then closes all WinHTTP handles.

Parameters

  • code : integer (optional)

    • WebSocket close status. Defaults to WINHTTP_WEB_SOCKET_SUCCESS_CLOSE_STATUS.

Example


Metamethods

__gc

Called automatically when the Lua userdata is garbage collected.

  • Calls ws_close_internal, deletes the critical section, frees lua_ws_t.

  • You don’t call this directly; it’s tied to object lifetime.

__tostring

Used when you do:

  • Returns "websocket(open)" or "websocket(closed)".

Example:


Summary

Global HTTP:

Global WebSocket:

WebSocket object (net_ws):

Last updated