The http module provides an HTTP client (GET, POST, PUT, DELETE) and an HTTP server with request routing. The client is backed by libcurl; the server uses libmicrohttpd.
import http;
string http.get(string url)
Performs an HTTP GET and returns the response body as a string.
string body = http.get("https://api.example.com/data");
output(body, string);
string http.get_headers(string url, dict headers)
dict headers = {"Authorization": "Bearer mytoken", "Accept": "application/json"};
string body = http.get_headers("https://api.example.com/protected", headers);
output(body, string);
string http.post(string url, string body, dict headers)
dict headers = {"Content-Type": "application/json"};
string payload = "{\"name\": \"Alice\", \"age\": 30}";
string response = http.post("https://api.example.com/users", payload, headers);
output(response, string);
string http.put(string url, string body, dict headers)
dict headers = {"Content-Type": "application/json"};
string payload = "{\"age\": 31}";
string response = http.put("https://api.example.com/users/1", payload, headers);
string http.delete(string url, dict headers)
dict headers = {};
string response = http.delete("https://api.example.com/users/1", headers);
After any client request, call http.get_status_code() to get the HTTP status of the last response:
int http.get_status_code()
string response = http.get("https://api.example.com/item/999");
int status = http.get_status_code();
if (status == 404) {
output("Not found", string);
} else if (status == 200) {
output(response, string);
}
dict http.get_response_headers()
Returns all response headers from the last request as a dictionary.
string body = http.get("https://api.example.com/data");
dict resp_headers = http.get_response_headers();
string content_type = dict_get(resp_headers, "content-type");
output(content_type, string);
http.get_full() and http.post_full() return an opaque response pointer that includes the body, status code, and headers together. Free it when done:
ptr http.get_full(string url)
ptr http.post_full(string url, string body, dict headers)
void http.free_response(ptr response)
Use these when you need all three pieces atomically. For most cases, http.get() + http.get_status_code() is simpler.
An HTTP server requires a handler function that PIE passes to http.listen. The handler receives an opaque request and response pointer:
void myHandler(ptr req, ptr res) {
// read the request
string method = http.request_get_method(req);
string path = http.request_get_path(req);
string body = http.request_get_body(req);
// write the response
http.response_set_status(res, 200);
http.response_set_header(res, "Content-Type", "text/plain");
http.response_set_body(res, "Hello from PIE!");
}
Do not use dot notation on req/res directly — always use the module functions.
void http.listen(int port, ptr handler)
http.listen blocks forever, serving requests on the given port.
void main() {
output("Listening on port 8080", string);
http.listen(8080, myHandler);
}
void http.listen_ssl(int port, string cert_file, string key_file, ptr handler)
http.listen_ssl(8443, "server.crt", "server.key", myHandler);
| Function | Signature | Description |
|---|---|---|
http.request_get_method |
string(ptr req) |
"GET", "POST", etc. |
http.request_get_path |
string(ptr req) |
URL path, e.g. "/api/users" |
http.request_get_body |
string(ptr req) |
Request body (for POST/PUT) |
http.request_get_header |
string(ptr req, string name) |
Single request header by name |
http.request_get_headers |
dict(ptr req) |
All request headers as a dict |
| Function | Signature | Description |
|---|---|---|
http.response_set_status |
void(ptr res, int code) |
HTTP status code (e.g. 200, 404) |
http.response_set_body |
void(ptr res, string body) |
Response body |
http.response_set_header |
void(ptr res, string name, string value) |
Add a response header |
import http;
import json;
void handler(ptr req, ptr res) {
string method = http.request_get_method(req);
string path = http.request_get_path(req);
if (path == "/health") {
http.response_set_status(res, 200);
http.response_set_header(res, "Content-Type", "application/json");
http.response_set_body(res, "{\"status\":\"ok\"}");
return;
}
if (method == "POST" && path == "/echo") {
string body = http.request_get_body(req);
http.response_set_status(res, 200);
http.response_set_header(res, "Content-Type", "text/plain");
http.response_set_body(res, body);
return;
}
// 404 fallback
http.response_set_status(res, 404);
http.response_set_body(res, "Not Found");
}
void main() {
output("Server on port 8080", string);
http.listen(8080, handler);
}
import http;
import json;
void main() {
// GET request
string raw = http.get("https://jsonplaceholder.typicode.com/todos/1");
int status = http.get_status_code();
if (status != 200) {
output("Request failed", string);
return;
}
json.object todo = json.parse(raw);
int id = json.get_int(todo, "id");
string title = json.get_string(todo, "title");
int completed = json.get_bool(todo, "completed");
output("Todo #" + int_to_string(id) + ": " + title, string);
if (completed == 1) {
output("Status: done", string);
} else {
output("Status: pending", string);
}
}
- JSON Module — Parse and build JSON request/response bodies
- Module System — How imports work
- Standard Library — Built-in functions