Networking

Functions for HTTP requests, sockets, and Base64 encoding.

net.send_request

Signature: net.send_request(url, headers, post_fields)

Description: Sends an HTTP request with optional headers and POST data. The response will be delivered asynchronously to a callback registered with engine.register_on_network_callback().

Parameters:

  • url (string): The URL to send the request to.

  • headers (string, optional): HTTP headers to include with the request.

  • post_fields (string, optional): Data to send in a POST request. If not provided, a GET request will be sent.

Returns: None

Example:

-- Register a callback to handle responses
function handle_network_response(response_data, url)
    -- Read the response data from the buffer
    local response_text = memory.read_string(response_data, 0)
    
    engine.log("Received response from: " .. url, 0, 255, 0, 255)
    engine.log("Response length: " .. string.len(response_text) .. " characters", 255, 255, 255, 255)
    
    -- You can also save the response to a file
    fs.write_to_file_from_buffer("response.txt", response_data)
    
    -- If response is JSON, try to parse it
    if string.match(url, "%.json") then
        local success, parsed = pcall(json.decode, response_text)
        if success and parsed then
            engine.log("Successfully parsed JSON response", 0, 255, 0, 255)
            process_json_data(parsed, url)
        else
            engine.log("Failed to parse JSON response", 255, 0, 0, 255)
        end
    end
end

-- Process JSON data based on the URL
function process_json_data(data, url)
    -- Example: Process bank holidays JSON
    if string.match(url, "bank%-holidays%.json") then
        -- Current date for comparison (YYYY-MM-DD format)
        local today = os.date("%Y-%m-%d")
        
        -- Access the 'england-and-wales' holidays section
        local region = data["england-and-wales"]
        local events = region and region["events"]
        
        if not events then
            engine.log("No events found for 'england-and-wales'", 255, 0, 0, 255)
            return
        end
        
        -- Find the next upcoming event
        local next_holiday = nil
        for _, event in ipairs(events) do
            if event.date > today then
                next_holiday = event
                break
            end
        end
        
        -- Output the result
        if next_holiday then
            engine.log("Next Bank Holiday: " .. next_holiday.title, 0, 255, 200, 255)
            engine.log("Date: " .. next_holiday.date, 0, 200, 255, 255)
        else
            engine.log("No upcoming holidays found.", 255, 255, 0, 255)
        end
    end
end

-- Register the network callback
engine.register_callback("network", handle_network_response)

-- Send a GET request
function send_get_request()
    local url = "https://example.com/api/data"
    local headers = "User-Agent: MyLuaScript/1.0"
    
    networking.http_get(url, headers)
    engine.log("GET request sent to: " .. url, 255, 255, 255, 255)
end

-- Send a POST request
function send_post_request()
    local url = "https://example.com/api/submit"
    local headers = "User-Agent: MyLuaScript/1.0\r\nContent-Type: application/x-www-form-urlencoded"
    local post_data = "param1=value1&param2=value2"
    
    networking.http_post(url, headers, post_data)
    engine.log("POST request sent to: " .. url, 255, 255, 255, 255)
end

-- Get UK bank holidays
function get_bank_holidays()
    local url = "https://www.gov.uk/bank-holidays.json"
    networking.http_get(url)
    engine.log("Requesting UK bank holidays...", 255, 255, 0, 255)
end

-- Execute the request functions
-- Uncomment the ones you want to use
-- send_get_request()
-- send_post_request()
get_bank_holidays()

net.resolve

Signature: net.resolve(hostname)

Description: Looks up the first IPv4 or IPv6 address for a hostname.

Parameters:

  • hostname (string): The hostname to resolve (e.g., "google.com").

Returns:

  • string: The resolved IP address, or nil if resolution failed.

Example:

function resolve_hostname(hostname)
    local ip = net.resolve(hostname)
    
    if ip then
        engine.log("Resolved " .. hostname .. " to " .. ip, 0, 255, 0, 255)
        return ip
    else
        engine.log("Failed to resolve " .. hostname, 255, 0, 0, 255)
        return nil
    end
end

-- Usage example
local google_ip = resolve_hostname("google.com")
local nonexistent_ip = resolve_hostname("this-does-not-exist.example")

net.create_socket

Signature: net.create_socket(ip, port)

Description: Opens a TCP connection to the specified IP address and port, returning a socket object.

Parameters:

  • ip (string): The IP address to connect to.

  • port (number): The port number to connect to.

Returns:

  • socket (table): A socket object with methods for sending and receiving data, or nil if connection failed.

  • error (string): An error message if the connection failed.

Example:

function connect_to_server(hostname, port)
    -- First resolve the hostname to an IP address
    local ip = net.resolve(hostname)
    if not ip then
        engine.log("Failed to resolve hostname: " .. hostname, 255, 0, 0, 255)
        return nil
    end
    
    -- Connect to the server
    local socket, error = net.create_socket(ip, port)
    if not socket then
        engine.log("Failed to connect: " .. error, 255, 0, 0, 255)
        return nil
    end
    
    engine.log("Connected to " .. hostname .. " (" .. ip .. ":" .. port .. ")", 0, 255, 0, 255)
    return socket
end

-- Usage example: Connect to a web server
local socket = connect_to_server("example.com", 80)

socket:send


Signature: socket:send(data)

Description: Sends data on a socket created with net.create_socket().

Parameters:

  • data (string): The raw string data to send on the socket.

Returns:

  • bytes_sent (number): The number of bytes sent, or nil if the send operation failed.

  • error (string): An error message if the send operation failed.

Example:

function send_http_request(hostname, path)
    local socket = connect_to_server(hostname, 80)
    if not socket then
        return false
    end
    
    -- Build a simple HTTP request
    local request = table.concat({
        "GET " .. path .. " HTTP/1.1",
        "Host: " .. hostname,
        "Connection: close",
        "User-Agent: Lua Socket Client",
        "",
        ""
    }, "\r\n")
    
    -- Send the request
    local bytes_sent, error = socket:send(request)
    if not bytes_sent then
        engine.log("Failed to send data: " .. error, 255, 0, 0, 255)
        socket:close()
        return false
    end
    
    engine.log("Sent " .. bytes_sent .. " bytes", 0, 255, 0, 255)
    return socket
end

-- Usage example
local socket = send_http_request("example.com", "/")

socket:receive

Signature: socket:receive(maxlen)

Description: Reads up to maxlen bytes from a socket.

Parameters:

  • maxlen (number): The maximum number of bytes to read.

Returns:

  • data (string): The received data as a string, or nil if the receive operation failed.

  • error (string): An error message if the receive operation failed.

Example:

function receive_http_response(socket, max_size)
    local response, error = socket:receive(max_size or 4096)
    
    if not response then
        engine.log("Failed to receive data: " .. error, 255, 0, 0, 255)
        return nil
    end
    
    engine.log("Received " .. #response .. " bytes", 0, 255, 0, 255)
    
    -- For HTTP responses, we might just want to show a preview
    local preview = response:sub(1, 200) .. (response:len() > 200 and "..." or "")
    engine.log("Response preview: \n" .. preview, 255, 255, 255, 255)
    
    return response
end

-- Usage example: Send a request and receive the response
local socket = send_http_request("example.com", "/")
if socket then
    local response = receive_http_response(socket, 8192)
    socket:close()
end

socket:close

Signature: socket:close()

Description: Immediately closes a socket connection.

Parameters: None

Returns: None

Example:

function http_get(hostname, path)
    local socket = connect_to_server(hostname, 80)
    if not socket then
        return nil
    end
    
    -- Send HTTP GET request
    local request = "GET " .. path .. " HTTP/1.1\r\nHost: " .. hostname .. "\r\nConnection: close\r\n\r\n"
    local sent, serr = socket:send(request)
    
    if not sent then
        engine.log("Send failed: " .. serr, 255, 0, 0, 255)
        socket:close()
        return nil
    end
    
    -- Receive response
    local response = ""
    local chunk_size = 4096
    
    while true do
        local chunk, rerr = socket:receive(chunk_size)
        
        if chunk then
            response = response .. chunk
            -- If we received less than chunk_size, we're likely done
            if #chunk < chunk_size then
                break
            end
        else
            -- Check if error is just "closed" which means the server closed connection
            if rerr ~= "closed" then
                engine.log("Receive error: " .. rerr, 255, 0, 0, 255)
            end
            break
        end
    end
    
    -- Close the socket
    socket:close()
    engine.log("Socket closed", 255, 255, 255, 255)
    
    return response
end

-- Usage example
local response = http_get("example.com", "/")
if response then
    -- Process the response...
    engine.log("Response received with " .. #response .. " bytes", 0, 255, 0, 255)
end

net.base64_encode

Signature: net.base64_encode(string)

Description: Encodes a string using Base64 encoding.

Parameters:

  • string (string): The string data to encode.

Returns:

  • string: The Base64-encoded string.

Example:

function encode_base64(text)
    local encoded = net.base64_encode(text)
    engine.log("Original: " .. text, 255, 255, 255, 255)
    engine.log("Base64 encoded: " .. encoded, 0, 255, 0, 255)
    return encoded
end

-- Usage example
local username = "user123"
local password = "secr3t"
local credentials = username .. ":" .. password
local encoded_credentials = encode_base64(credentials)

-- Construct a Basic Auth header
local auth_header = "Authorization: Basic " .. encoded_credentials

net.base64_decode

Signature: net.base64_decode(string)

Description: Decodes a Base64-encoded string.

Parameters:

  • string (string): The Base64-encoded string to decode.

Returns:

  • string: The decoded string.

Example:

function decode_base64(encoded_text)
    local decoded = net.base64_decode(encoded_text)
    engine.log("Base64 encoded: " .. encoded_text, 255, 255, 255, 255)
    engine.log("Decoded: " .. decoded, 0, 255, 0, 255)
    return decoded
end

-- Usage example
local encoded = "SGVsbG8sIHdvcmxkIQ=="
local decoded = decode_base64(encoded)  -- Should output "Hello, world!"

-- Example with an auth header
local auth_header = "Basic dXNlcjEyMzpzZWNyM3Q="
local encoded_part = auth_header:sub(7)  -- Remove "Basic " prefix
local credentials = decode_base64(encoded_part)  -- Should output "user123:secr3t"

Last updated

Was this helpful?