Networking
This module of the core library contains functionality for communicating with remote systems over a network.
Sub Modules
Requests
The Requests submodule provides an HTTP client for sending requests to web servers and APIs.
The current HTTP client is provided by:
>@ "net/requests/http"
The http submodule uses libcurl and supports:
- HTTP and HTTPS
- GET
- POST
- PUT
- PATCH
- DELETE
- HEAD
- OPTIONS
- Custom HTTP methods
- Request headers
- Request bodies
- Query parameters
- Redirects
- TLS certificate verification
- Compressed responses
- HTTP/2 negotiation when supported by the server and installed libcurl version
The module returns HTTP responses as Hachi strings containing the response headers followed by the response body.
Import
Import the Requests HTTP client before using its functions:
>@ "net/requests/http"
Example:
>@ "net/requests/http"
response: httpGET:
"https://example.com"
print: response
Compile and run normally:
hachi main.hachi -go
The module automatically declares its libcurl dependency. A separate -cf option is not required.
Response Format
All request functions return a String.
A successful HTTP transaction returns the response headers followed by the response body:
HTTP/2 200
content-type: application/json
content-length: 27
{"message":"Hello Hachi"}
An HTTP error status, such as 404 or 503, is still returned as a normal HTTP response:
HTTP/2 404
content-type: application/json
{"error":"Not Found"}
A network or transport failure returns a string beginning with:
Hachi HTTP error:
Example:
Hachi HTTP error: Could not resolve host
HTTP status codes do not currently cause the Hachi program to exit with a nonzero status. The calling program must inspect the returned response when it needs to distinguish successful and unsuccessful HTTP status codes.
Headers
Custom request headers are provided as a newline-separated string:
headers: "Accept: application/json
Content-Type: application/json
X-Hachi-Client: example"
Each header must use the following format:
Header-Name: Header Value
A trailing newline is not required.
Request Bodies
Request bodies are supplied as Hachi strings.
Example JSON body:
body: "{
\"language\": \"Hachi\",
\"mascot\": \"wolf\",
\"working\": true
}"
Double quotes inside the body must be escaped.
Example form body:
body: "language=Hachi&mascot=wolf"
The calling program is responsible for constructing JSON, form data, query strings, and other request formats.
Functions
httpRequest
Sends a fully configurable HTTP request.
Use httpRequest when a request requires custom headers, a request body, authorization, or a custom HTTP method.
Syntax:
httpRequest:
<method>,
<url>,
<headers>,
<body>
Parameters:
| Parameter | Type | Description |
|---|---|---|
method | String | HTTP method to send |
url | String | Complete request URL |
headers | String | Newline-separated request headers |
body | String | Request body, or an empty string |
Returns:
String
Example:
>@ "net/requests/http"
headers: "Accept: application/json
Content-Type: application/json"
body: "{
\"message\": \"Hello from Hachi\"
}"
response: httpRequest:
"POST",
"https://httpbingo.org/anything",
headers,
body
print: response
A request without custom headers or a body uses empty strings:
response: httpRequest:
"GET",
"https://example.com",
"",
""
httpGET
Sends an HTTP GET request.
Syntax:
httpGET: <url>
Returns:
String
Example:
>@ "net/requests/http"
response: httpGET:
"https://example.com"
print: response
GET With Query Parameters
Query parameters are included directly in the URL:
response: httpGET:
"https://httpbingo.org/anything?language=Hachi&wolf=true"
The caller is responsible for URL-encoding query parameter names and values when necessary.
GET With Custom Headers
Use httpRequest when a GET request requires custom headers:
headers: "Accept: application/json
X-Hachi-Test: custom-get
X-Client-Version: 0.5.3"
response: httpRequest:
"GET",
"https://httpbingo.org/anything",
headers,
""
print: response
httpPOST
Sends an HTTP POST request with a request body.
Syntax:
httpPOST:
<url>,
<body>
Returns:
String
Example:
>@ "net/requests/http"
response: httpPOST:
"https://httpbingo.org/anything",
"message=Hello"
print: response
Use httpRequest when the POST request requires a content type or other custom headers.
JSON POST
headers: "Content-Type: application/json
Accept: application/json"
body: "{
\"language\": \"Hachi\",
\"mascot\": \"wolf\"
}"
response: httpRequest:
"POST",
"https://httpbingo.org/anything",
headers,
body
print: response
Form-Encoded POST
headers: "Content-Type: application/x-www-form-urlencoded
Accept: application/json"
body: "language=Hachi&mascot=wolf"
response: httpRequest:
"POST",
"https://httpbingo.org/anything",
headers,
body
print: response
httpPUT
Sends an HTTP PUT request with a request body.
Syntax:
httpPUT:
<url>,
<body>
Returns:
String
Example:
>@ "net/requests/http"
response: httpPUT:
"https://httpbingo.org/anything/resource/42",
"replacement value"
print: response
PUT With JSON
headers: "Content-Type: application/json
Accept: application/json"
body: "{
\"resource\": \"core-http-module\",
\"operation\": \"replace\",
\"enabled\": true
}"
response: httpRequest:
"PUT",
"https://httpbingo.org/anything/resource/42",
headers,
body
print: response
httpPATCH
Sends an HTTP PATCH request with a request body.
Syntax:
httpPATCH:
<url>,
<body>
Returns:
String
Example:
>@ "net/requests/http"
response: httpPATCH:
"https://httpbingo.org/anything/resource/42",
"updated value"
print: response
PATCH With JSON
headers: "Content-Type: application/json
Accept: application/json"
body: "{
\"operation\": \"partial-update\",
\"enabled\": false
}"
response: httpRequest:
"PATCH",
"https://httpbingo.org/anything/resource/42",
headers,
body
print: response
httpDELETE
Sends an HTTP DELETE request without a request body.
Syntax:
httpDELETE: <url>
Returns:
String
Example:
>@ "net/requests/http"
response: httpDELETE:
"https://httpbingo.org/anything/resource/42"
print: response
DELETE With a Body
Some APIs accept a request body with DELETE.
Use httpRequest for this case:
headers: "Content-Type: application/json
Accept: application/json"
body: "{
\"reason\": \"resource no longer required\",
\"force\": true
}"
response: httpRequest:
"DELETE",
"https://httpbingo.org/anything/resource/42",
headers,
body
print: response
Support for a DELETE request body depends on the remote server.
httpHEAD
Sends an HTTP HEAD request.
A HEAD request asks the server to return response headers without returning the normal response body.
Syntax:
httpHEAD: <url>
Returns:
String
Example:
>@ "net/requests/http"
response: httpHEAD:
"https://example.com"
print: response
httpOPTIONS
Sends an HTTP OPTIONS request.
OPTIONS can be used to inspect the methods or capabilities advertised by a server.
Syntax:
httpOPTIONS: <url>
Returns:
String
Example:
>@ "net/requests/http"
response: httpOPTIONS:
"https://httpbingo.org/anything"
print: response
The response may contain headers such as:
allow:
access-control-allow-methods:
The exact response depends on the server.
Custom HTTP Methods
httpRequest accepts methods other than the standard convenience functions.
Example using PROPFIND:
>@ "net/requests/http"
headers: "Content-Type: text/plain
X-Hachi-Test: custom-method"
response: httpRequest:
"PROPFIND",
"https://httpbingo.org/anything/custom-resource",
headers,
"Hachi custom HTTP method request body"
print: response
Other examples include:
response: httpRequest:
"REPORT",
url,
headers,
body
response: httpRequest:
"LOCK",
url,
headers,
body
response: httpRequest:
"PURGE",
url,
headers,
""
The remote server must support the requested method.
Authorization
Authorization is provided through request headers.
Bearer Token
>@ "net/requests/http"
headers: "Accept: application/json
Authorization: Bearer hachi-example-token"
response: httpRequest:
"GET",
"https://httpbingo.org/anything",
headers,
""
print: response
Basic Authorization
A preconstructed Basic authorization header can also be supplied:
headers: "Accept: application/json
Authorization: Basic <encoded-credentials>"
The module does not automatically encode credentials or retrieve tokens.
Applications should avoid storing production credentials directly in source code.
Redirects
Redirect following is enabled by default.
A redirected response may contain more than one HTTP header block:
HTTP/2 302
location: https://example.com/final
HTTP/2 200
content-type: text/html
<html>...</html>
The final header block normally describes the final response.
Compression
The module enables the response encodings supported by the installed libcurl build.
These may include:
- gzip
- deflate
- Brotli
- Zstandard
libcurl decompresses supported response bodies before they are returned to Hachi.
TLS
HTTPS certificate and hostname verification are enabled.
TLS verification failures are returned as transport errors:
Hachi HTTP error: <TLS error>
The current module does not provide a public option to disable TLS verification.
Timeouts
Requests currently use a 30-second total timeout.
A timeout returns an error similar to:
Hachi HTTP error: Operation timed out after 30000 milliseconds
The timeout is currently configured by the module and cannot be changed per request.
Default User Agent
The module sends the following default User-Agent:
Hachi-HTTP/1.0
A request can provide a different User-Agent through custom headers:
headers: "Accept: application/json
User-Agent: My-Hachi-Application/1.0"
Native Dependency
The http submodule declares its libcurl dependency internally:
nativePackage: "libcurl"
Hachi resolves the required compiler and linker flags automatically when the module is imported.
Normal usage requires only:
hachi main.hachi -go
The system must have libcurl, its development headers, and a working pkg-config package definition.
The installation can be checked with:
pkg-config --modversion libcurl
Complete Example
>@ "net/requests/http"
headers: "Content-Type: application/json
Accept: application/json
Authorization: Bearer example-token"
body: "{
\"language\": \"Hachi\",
\"mascot\": \"wolf\",
\"working\": true
}"
response: httpRequest:
"POST",
"https://httpbingo.org/anything",
headers,
body
print: response
Run:
hachi main.hachi -go
Current Limitations
The current Requests module returns one raw response string.
It does not yet provide:
- A structured response object
- A numeric status-code accessor
- Separate header and body return values
- Automatic JSON encoding or decoding
- Automatic URL encoding
- Multipart form helpers
- File upload helpers
- Streaming downloads
- Cookie or session management
- Per-request timeout configuration
- Proxy configuration through the Hachi API
- Client certificate configuration through the Hachi API
These capabilities may be added in future versions.