Skip to content
Paul Manias edited this page May 12, 2026 · 4 revisions

Tuku is a command-line HTTP/HTTPS client for Tiri workflows. It provides a curl-like feature set using Origo-style name=value arguments, built on the Kotuku HTTP class. Tuku is designed for scripting, automation, and quick manual requests from the terminal.

origo apps/tuku.tiri url=https://example.com

Table of Contents

Quick Start

Options Reference

Defaults and Implicit Behaviour

Exit Behaviour

Examples

Structured Error Output

Verbose Summary Format

Quick Start

Tuku is executed through Origo like any Tiri application. The minimal invocation fetches a URL and prints the response body to standard output:

origo apps/tuku.tiri url=https://example.com

To save the response body to a file:

origo apps/tuku.tiri url=https://example.com output=page.html

To send a POST request with a JSON body:

origo apps/tuku.tiri url=https://api.example.com/items method=post json='{"name":"Ada"}'

To check only the HTTP status code:

origo apps/tuku.tiri url=https://example.com status

Run origo apps/tuku.tiri help to see the full option table with descriptions.

Options Reference

Core

Option Type Description
url string Target HTTP or HTTPS URL. Required unless version or help is used.
method enum HTTP method: get, head, delete, options, post, put, or patch. Default: get.
version flag Print the Tuku version and exit.
help flag Print usage information and exit.

Output

Option Type Description
output file Save the response body to a file instead of standard output.
status flag Print the numeric HTTP status code to standard output.
headers flag Print all response headers as tuku: header key=value lines.
include flag Print response headers before the response body. Alias: with-headers.
silent flag Suppress non-body output.
verbose flag Print a structured transfer summary after the request completes.
fail flag Treat HTTP 4xx and 5xx statuses as failures, raising ERR_Failed.

Request Body

Only one body option may be used per request. Providing any body option implies method=post unless method is set explicitly.

Option Type Description
data string Send a string as the request body.
datafile file Read the request body from a file.
json string Send a JSON string as the request body. Implies contenttype=application/json.
form array Send form fields as name=value entries. Implies contenttype=application/x-www-form-urlencoded.
multipart array Send multipart form fields as name=value or file fields as name=@path. Implies a multipart/form-data content type with a generated boundary.
contenttype string Explicitly set the Content-Type request header, overriding implicit defaults.

Request Headers

Option Type Description
header array Custom request headers in Name: Value form.
useragent string User-Agent request header. Default: Tuku/1.0 Kotuku.
user string Authentication credentials as username:password.

Connection

Option Type Default Description
timeout number 30 Overall transfer timeout in seconds.
connect-timeout number 10 Initial connection timeout in seconds.
data-timeout number 30 Send/receive data timeout in seconds.
proxy string Proxy server as host:port.
insecure flag Disable SSL server certificate verification.

Transfer Controls

Option Type Description
resume flag Resume a partial download. Requires output and method=get.
raw flag Disable HTTP chunk handling.
no-head flag Do not send a HEAD probe before upload methods.
follow flag Follow HTTP redirects.
max-redirects integer Maximum redirects to follow when follow is set. Default: 10.
debug-socket flag Log request socket headers and data.

Defaults and Implicit Behaviour

Tuku applies the following defaults when options are not explicitly set:

  • method defaults to get.
  • When any body option (data, datafile, json, form, or multipart) is present, method defaults to post.
  • json sets contenttype to application/json unless contenttype is provided.
  • form sets contenttype to application/x-www-form-urlencoded unless contenttype is provided.
  • multipart sets contenttype to multipart/form-data with a generated boundary unless contenttype is provided.
  • useragent defaults to Tuku/1.0 Kotuku.
  • timeout defaults to 30, connect-timeout to 10, and data-timeout to 30.
  • max-redirects defaults to 10 and must be at least 1.
  • All timeout values must be greater than zero.

Exit Behaviour

Tuku follows curl-like conventions for exit status:

  • Success: Tuku exits with code 0 when the HTTP transfer completes, regardless of the HTTP status code.
  • Transport errors (DNS failure, connection refused, timeouts): Tuku prints a structured error line and raises ERR_Failed.
  • HTTP 4xx/5xx: By default these do not cause a failure. Use fail to map HTTP error statuses to ERR_Failed.
  • Argument errors: Invalid or incompatible options are reported with a structured error line and a non-zero exit code.

When status is set, the numeric HTTP status code is always printed to standard output, even when fail causes a non-zero exit.

Examples

Fetching a Page

Print the response body of a URL to standard output:

origo apps/tuku.tiri url=https://example.com

Saving to a File

Download the response body to a local file:

origo apps/tuku.tiri url=https://example.com/report.pdf output=report.pdf

Posting Data

Send a plain text body with an explicit content type:

origo apps/tuku.tiri url=https://httpbin.org/post data="hello world" contenttype=text/plain

JSON API Requests

Post a JSON payload. The content type is set automatically:

origo apps/tuku.tiri url=https://api.example.com/items json='{"name":"Ada","role":"Engineer"}'

Form Submission

Submit URL-encoded form fields:

origo apps/tuku.tiri url=https://example.com/login form={username=ada,password=secret}

Multiple values use Origo array syntax:

origo apps/tuku.tiri url=https://example.com/login form={"username=ada","password=secret"}

Multipart Uploads

Send multipart text fields:

origo apps/tuku.tiri url=https://example.com/profile multipart={name=Ada,role=Engineer}

Upload a file by prefixing the field value with @:

origo apps/tuku.tiri url=https://example.com/upload multipart={doc=@report.pdf}

Custom Headers

Set one or more custom request headers:

origo apps/tuku.tiri url=https://api.example.com header={"Accept: application/json","X-Token: my-secret"}

Inspecting Status

Print only the HTTP status code:

origo apps/tuku.tiri url=https://example.com status

This prints a single line to standard output, e.g. 200.

Verbose Transfer Summary

Print a structured summary after the transfer:

origo apps/tuku.tiri url=https://example.com output=page.html verbose

See Verbose Summary Format for the output structure.

Response Headers

Print all response headers without verbose mode:

origo apps/tuku.tiri url=https://example.com headers status

Each header is printed as tuku: header key=value, one per line. When combined with verbose, response headers are included in the verbose summary instead.

Print response headers before the response body:

origo apps/tuku.tiri url=https://example.com include

When output is set, include prints headers to standard output and writes the response body to the file.

Following Redirects

Follow HTTP redirects:

origo apps/tuku.tiri url=https://example.com/old-path follow

Tuku follows 301, 302, 303, 307, and 308 redirects when follow is set. 301, 302, and 303 redirects switch the next request to GET; 307 and 308 preserve the current method and body. Use max-redirects=N to limit redirect chains.

Resuming Downloads

Resume a partially downloaded file. Tuku reads the existing file size and issues a Range header:

origo apps/tuku.tiri url=https://example.com/large.zip output=large.zip resume

Resume requires output to be set and method to be get (the default).

Using a Proxy

Route the request through an HTTP proxy:

origo apps/tuku.tiri url=https://example.com proxy=proxy.local:8080

The proxy value must be in host:port format with a port between 1 and 65535.

Authentication

Provide HTTP credentials:

origo apps/tuku.tiri url=https://api.example.com user=admin:password123

Automation with fail

In scripts, use fail to treat HTTP error statuses as non-zero exits:

origo apps/tuku.tiri url=https://api.example.com/health fail

If the server returns a 4xx or 5xx status, Tuku prints a structured error line and exits with a non-zero code. Without fail, the same request would exit successfully.

Structured Error Output

Tuku emits machine-readable error lines to standard output in the format:

tuku: error: type=TYPE [status=NNN] [code=NNN] message=DESCRIPTION
Field Description
type Error category: argument, transport, http, redirect, or runtime.
status HTTP status code, present for http errors.
code Internal error code, present for transport and runtime errors.
message Human-readable description of the error.

Examples:

tuku: error: type=argument message=Required parameter 'url' is missing.
tuku: error: type=http status=404 code=7 message=HTTP status 404
tuku: error: type=transport status=0 code=32 message=Connection refused

Verbose Summary Format

When verbose is set, Tuku prints a line-oriented transfer summary after the request completes. Each line is prefixed with tuku: for easy parsing:

tuku: method=GET
tuku: url=https://example.com
tuku: status=200
tuku: bytes=1256
tuku: output=page.html
tuku: transport=Okay
tuku: header content-type=text/html; charset=UTF-8
tuku: header content-length=1256
Line Description
method HTTP method used (upper-case).
url Request URL.
status HTTP status code.
bytes Number of bytes received.
output Output target: a file path or stdout.
transport Transport result: Okay on success, or an error description.
header One line per response header, in key=value format.

When output is not set and the response body is streamed to standard output, output shows stdout.

Clone this wiki locally