web Network Access
web is Alia's standard library network module, providing URL parsing, an HTTP client/server, MIME type lookup, and more.
Importing the Module
import 'web' as web ~ import as a variable
import 'web' ~ import into scope
URL Utilities
urlParse
Parses a URL string into a structured object.
| Parameter | Type | Required | Description |
|---|---|---|---|
| First positional argument | String | Yes | The URL string to parse |
Returned object properties:
| Property | Type | Description |
|---|---|---|
protocol | String | Protocol, e.g. 'https' |
host | String | Hostname + port, e.g. 'example.com:8080' |
hostname | String | Hostname, e.g. 'example.com' |
port | Number? | Port number, null if absent |
pathname | String | Path, e.g. '/path' |
search | String? | Query string, null if absent |
hash | String? | Anchor, null if absent |
href | String | Full URL |
const parsed = web.urlParse 'https://example.com:8080/path?key=value#anchor'
parsed.protocol ~ 'https'
parsed.hostname ~ 'example.com'
parsed.port ~ 8080
parsed.pathname ~ '/path'
parsed.search ~ '?key=value'
parsed.hash ~ '#anchor'
urlBuild
Builds a URL string from a structured object. urlBuild is the inverse of urlParse.
| Parameter | Type | Required | Description |
|---|---|---|---|
| First positional argument | Object | Yes | Object containing the URL components |
const url = call web.urlBuild *[
protocol: 'https',
hostname: 'example.com',
port: 8080,
pathname: '/api',
search: '?q=alia'
]
~ 'https://example.com:8080/api?q=alia'
urlEncode / urlDecode
Encodes/decodes an entire URL (preserving URL reserved characters such as ://, ?, #).
web.urlEncode 'https://example.com/路径'
~ 'https://example.com/%E8%B7%AF%E5%BE%84'
web.urlDecode 'https://example.com/%E8%B7%AF%E5%BE%84'
~ 'https://example.com/路径'
urlEncodeComponent / urlDecodeComponent
Encodes/decodes a URI component (encodes all special characters).
web.urlEncodeComponent 'hello world'
~ 'hello%20world'
web.urlDecodeComponent 'hello%20world'
~ 'hello world'
MIME Types
mimeGet
Gets the MIME type for a file extension.
| Parameter | Type | Required | Description |
|---|---|---|---|
| First positional argument | String | Yes | File extension (with or without the . prefix) |
web.mimeGet 'json' ~ 'application/json'
web.mimeGet '.html' ~ 'text/html'
web.mimeGet 'png' ~ 'image/png'
web.mimeGet 'xyz' ~ 'application/octet-stream' ~ default for unknown types
Built-in MIME mapping table:
| Extension | MIME Type |
|---|---|
html, htm | text/html |
css | text/css |
js, mjs | application/javascript |
json | application/json |
xml | application/xml |
txt | text/plain |
csv | text/csv |
png | image/png |
jpg, jpeg | image/jpeg |
gif | image/gif |
svg | image/svg+xml |
ico | image/x-icon |
webp | image/webp |
mp3 | audio/mpeg |
wav | audio/wav |
ogg | audio/ogg |
mp4 | video/mp4 |
webm | video/webm |
pdf | application/pdf |
zip | application/zip |
gz | application/gzip |
tar | application/x-tar |
wasm | application/wasm |
ttf | font/ttf |
woff | font/woff |
woff2 | font/woff2 |
yaml, yml | application/x-yaml |
md | text/markdown |
mimeGetExtension
Gets the preferred file extension for a MIME type.
| Parameter | Type | Required | Description |
|---|---|---|---|
| First positional argument | String | Yes | MIME type string |
web.mimeGetExtension 'text/html' ~ 'html'
web.mimeGetExtension 'application/json' ~ 'json'
web.mimeGetExtension 'application/x-unknown' ~ null
HTTP Client
httpRequest
Initiates an asynchronous HTTP request.
| Parameter | Type | Required | Description |
|---|---|---|---|
| First positional argument | Object | Yes | Request options object |
Request options object properties:
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
url | String | Yes | - | Request URL |
method | String | No | 'GET' | HTTP method |
headers | Object | No | {} | Request headers |
body | String | No | null | Request body |
timeout | Number | No | 30000 | Timeout (milliseconds) |
Returns a Stack (asynchronous request object, to be consumed with await):
After the request is initiated, an awaitable Stack conforming to Alia's asynchronous model is returned. The request runs on a background thread; await waits for the result, and the response object can be accessed via task.response.
| Property | Type | Description |
|---|---|---|
status | Number | HTTP status code |
statusText | String | Status text |
headers | Object | Response headers |
body | String | Response body |
ok | Boolean | true when the status code is 200-299 |
const opts = *[
method: 'GET',
url: 'https://api.example.com/data'
]
const resp = await web.httpRequest opts
if (resp.ok as Boolean) {
print resp.body as String
}
await accepts an expression returning a Stack, so the response can be obtained in a single step; alternatively, hold the task handle first and then await it, in order to access isRunning/isDone/detach:
const task = web.httpRequest opts
await task
if (task.response.ok as Boolean) {
print task.response.body as String
}
Online Detection
It is recommended to determine online status using the https://alia.0832.ink/externalAccess static probe: this file is deployed on the documentation site and its content is true.
import 'web' as web
const opts = *[url: 'https://alia.0832.ink/externalAccess', timeout: 10000]
const task = web.httpRequest opts
await task
assert (Ok task.response.body) error 'externalAccess should return body'
assert (call task.response.body.trim) == 'true' error 'externalAccess should be true'
assert task.response.status == 200 error 'externalAccess should return 200'
When offline, the request fails or falls back to HTML, which is not true.
serverCreate
Creates an HTTP server instance.
const server = call web.serverCreate
Methods of the returned Server object:
server.addRoute
Registers a route handler.
| Parameter | Type | Required | Description |
|---|---|---|---|
| First positional argument | String | Yes | HTTP method (GET, POST, etc.), or * to match all |
| Second positional argument | String | Yes | Path pattern, supporting :param dynamic parameters |
| Third positional argument | Alias | Yes | Request handler (req, res) -> { ... } |
server.addRoute 'GET' '/hello' (alias -> <Object req> and <Object res> {
res.send 'Hello, World!'
})
server.addRoute 'GET' '/users/:id' (alias -> <Object req> and <Object res> {
call res.json *[userId: (req.params as Object)['id']]
})
server.addRoute 'POST' '/api/data' (alias -> <Object req> and <Object res> {
~ req.body contains the request body
call res.json *[received: true]
})
Request object (req) properties:
| Property | Type | Description |
|---|---|---|
method | String | HTTP method |
url | String | Original URL |
path | String | Path portion |
query | Object | Query parameters |
headers | Object | Request headers |
body | String? | Request body |
params | Object? | Path parameters |
Response object (res) methods:
| Method | Description |
|---|---|
res.setStatus code | Sets the status code, defaults to 200 |
res.setHeader name value | Sets a response header |
res.send bodyText | Sends a text response |
res.json data | Sends a JSON response (sets Content-Type automatically) |
res.end | Ends the response |
server.listen
Starts the server listening on the specified port.
| Parameter | Type | Required | Description |
|---|---|---|---|
| First positional argument | Number | Yes | Port number to listen on |
callback | Alias | No | Callback invoked after a successful startup |
server.listen 3000 (alias -> {
io.print 'Server running on http://localhost:3000'
})
server.close
Closes the server (initiating and non-blocking: the call merely initiates the shutdown, and port resources are released asynchronously).
server.close
Complete Example
import 'web' as web
import 'io' as io
~ URL parsing
const parsed = web.urlParse 'https://example.com/search?q=alia'
print 'Host: ' .. parsed.hostname
print 'Path: ' .. parsed.pathname
~ HTTP client (asynchronous)
const opts = *[
url: 'https://api.github.com'
]
const task = web.httpRequest opts
await task
print 'Status code: ' .. (task.response.status as Number)
~ HTTP server
const server = call web.serverCreate
server.addRoute 'GET' '/api/hello' (alias -> <Object req> and <Object res> {
call res.json *[greeting: 'Hello from Alia!']
})
server.listen 3000
io.print 'Server started, visit http://localhost:3000/api/hello'