Skip to content

HTTP Client

lib/http_client.tpr is the embedded outbound HTTP library. Use it to call other APIs from inside a Tulpar program — no extra dependency, no npm install.

import "http_client";
json r = http_get("http://api.example.com/users/1");
if (r["ok"]) {
print("status=" + toString(r["status"]));
print("body=" + r["body"]);
}
HelperWraps
http_get(url)GET with empty body
http_post(url, body)POST with raw string body
http_put(url, body)PUT
http_delete(url)DELETE
http_get_json(url)GET + fromJson(body) if response 2xx
http_post_json(url, data)POST toJson(data) + parse response
http_request(method, url, body)The underlying primitive

Every helper returns the same envelope:

json r = http_get("http://api.example.com/");
if (r["ok"]) {
int status = r["status"]; // 200, 404, ...
json headers = r["headers"]; // case-sensitive header map
str body = r["body"]; // raw response body
} else {
str why = r["error"]; // "connect failed", "TLS handshake failed", ...
}

The _json variants additionally parse r["body"] and put the result in r["data"]:

json r = http_get_json("http://api.example.com/users/1");
if (r["ok"]) {
json user = r["data"];
print("hello " + user["name"]);
}

https:// URLs work when Tulpar was built with OpenSSL. Without it, the call returns {"ok": 0, "error": "TLS not compiled in (build Tulpar with OpenSSL to enable https://)"}.

To enable TLS on MSYS2:

Terminal window
pacman -S mingw-w64-x86_64-openssl
# then rebuild Tulpar
./build.sh

The CMake configuration auto-detects OpenSSL via find_package(OpenSSL) and toggles the TULPAR_HAS_TLS=1 define. SNI is set automatically, certificate verification is currently SSL_VERIFY_NONE until a configurable trust-store path lands.

Every verb has an _async twin that returns a promise instead of blocking: http_get_async, http_post_async, http_put_async, http_delete_async (wrapping the http_request_async built-in). The request runs on a worker pool while the async event loop keeps pumping other coroutines, so you can fan out to several upstreams at once and gather the results:

import "http_client";
async func dashboard() {
// Three upstreams fetched concurrently — total time ~ the slowest one.
var r = await gather(
http_get_async("http://api/users"),
http_get_async("http://api/orders"),
http_get_async("http://api/stats")
);
return r;
}
var data = await dashboard();
print(toString(data[0]["status"])); // 200

The resolved value is the same { ok, status, headers, body } envelope as the blocking client. Worker-pool size defaults to 4; override it with the TULPAR_HTTP_POOL environment variable. See the Async / Await guide for the full concurrency model, including error handling when a request rejects.

Today:

  • Plain HTTP/1.0 (no keep-alive on the client side)
  • HTTPS via OpenSSL when compiled in
  • 8 MB response cap to avoid runaway memory on misbehaving servers
  • No automatic redirect following
  • No chunked transfer-encoding support

Roadmap:

  • HTTP/1.1 keep-alive on the client (connection pool)
  • Redirect following with cycle detection
  • Chunked transfer-encoding
  • Configurable trust-store path for production TLS verification