o
odinpkg.dev
packages / library / Volt

Volt

26a1ea4library

simple, fast, standalone intermediate HTTP Client alternative to curl, entirely in Odin.

MIT · updated 1 month ago

volt

Fast minimal HTTP client built in Odin.

It started as a small http client and then got out of hand kinda

Versions before 0.3.0 were mostly development testing. 0.4.0 is where the built in HTTP server became real instead of just sitting there for no reason


install dependencies

linux general

Install a C toolchain, Odin, and curl development libraries.

You need libcurl available at build and runtime.

gentoo / exherbo-ish

For Gentoo:

sudo emerge dev-lang/odin net-misc/curl dev-libs/mbedtls

For Exherbo, install Odin and curl through your cave. Exact package names may differ depending on your repositories. Sorry for the lack of info here, carry on (i recommend brew for odin on exherbo)

arch

sudo pacman -S base-devel clang curl mbedtls

debian ubuntu

sudo apt install build-essential clang libcurl4-openssl-dev libmbedtls-dev

fedora

sudo dnf install clang gcc make libcurl-devel mbedtls-devel

solus

sudo eopkg it -c system.devel curl-devel mbedtls-devel llvm-clang-devel

Build Odin from source on Solus if the packaged version is missing or too old.

git clone https://github.com/odin-lang/Odin.git
cd Odin
make release-native

Set environment if needed.

export ODIN_ROOT="$PWD"

Optional install.

sudo cp odin /usr/local/bin/odin

build

From the project directory:

odin build volt.odin -file -out:volt -extra-linker-flags:"-lcurl"

Or if building as a package/directory:

odin build . -out:volt -extra-linker-flags:"-lcurl"

On some weird systems with custom dynamic linker paths, you may need something like:

odin build volt.odin -file -out:volt -extra-linker-flags:"-Wl,--dynamic-linker=/usr/x86_64-pc-linux-gnu/lib64/ld-linux-x86-64.so.2"

If Odin cannot find base, core, or vendor, set ODIN_ROOT.

export ODIN_ROOT="/path/to/Odin"

If the linker complains about curl, make sure the curl development package is installed.

If the compiler picks a weird clang, check:

which clang

Usually you want the system one.


usage

Basic GET:

volt https://example.com

HEAD request:

volt -I https://example.com

POST JSON:

volt -j -d '{"name":"volt"}' https://httpbin.org/post

Send a file as the request body:

volt -X PUT -d @file.bin https://example.com/upload

Read request body from stdin:

cat data.json | volt -j -d @- https://httpbin.org/post

Clean output for scripts:

volt --clean https://example.com/file.txt > file.txt

If you pipe internet scripts into a shell, that is between you and whatever demon lives in /bin/sh.

Save with remote filename:

volt -O https://example.com/file.tar.xz

Save to a specific file:

volt -o output.bin https://example.com/file.bin

Resume a download:

volt -O -C https://example.com/file.tar.xz

Include response headers:

volt -i https://example.com

Dump headers to a file:

volt -D headers.txt https://example.com

Pretty-print JSON:

volt --json-pretty https://httpbin.org/json

Debug timing:

volt --debug https://example.com

Fail on HTTP errors:

volt -f https://httpbin.org/status/404

Cookies:

volt -c cookies.txt https://httpbin.org/cookies/set/test/value
volt -b cookies.txt https://httpbin.org/cookies

Benchmark:

volt --bench 50 https://example.com

Batch requests from a file:

volt --batch urls.txt -P 8

urls.txt can look like this:

https://example.com
https://httpbin.org/get
https://kernel.org

Blank lines and lines starting with # are ignored.


server mode

--serve is real now.

Start a local static file server:

volt --serve 8080 --serve-dir .

Serve on all interfaces:

volt --serve 8080 --serve-dir public --bind 0.0.0.0

Use another port if 8080 is already busy:

volt --serve 9090 --serve-dir .

Health check:

volt http://127.0.0.1:8080/__volt/health --json-pretty

Directory manifest:

volt http://127.0.0.1:8080/__volt/manifest --json-pretty

Echo endpoint:

volt http://127.0.0.1:8080/__volt/echo --json-pretty

SPA fallback:

volt --serve 8080 --serve-dir . --spa

If index.html exists, missing paths fall back to it.

volt http://127.0.0.1:8080/some/fake/path

Disable generated directory listings:

volt --serve 8080 --serve-dir . --no-dir-list

Allow uploads:

volt --serve 8080 --serve-dir . --allow-upload --upload-dir drops

Upload a file:

volt -X PUT -d @test.txt http://127.0.0.1:8080/__volt/upload/test.txt --json-pretty

Then check it:

cat drops/test.txt

Change max request size:

volt --serve 8080 --max-request 67108864

That example allows requests up to 64 MB.


server notes

The server is meant for local development, quick file sharing, test uploads, and poking HTTP clients.

It is not trying to be nginx.

Be careful with:

volt --serve 8080 --serve-dir . --bind 0.0.0.0

That exposes the served directory to your network.

If your project has .git, secrets, build artifacts, or random cursed files, do not serve the whole repo on a public or untrusted network.

Upload mode is off by default for a reason.


features

Client side:

  • GET, POST, PUT, PATCH, DELETE, HEAD, and custom methods
  • request bodies from strings, files, or stdin
  • custom headers
  • JSON mode
  • pretty JSON output
  • response headers in output
  • dump headers to file
  • file downloads
  • remote filename saving
  • resume downloads
  • cookies
  • redirects
  • no-redirect mode
  • timeout and connect timeout
  • retry support
  • rate limiting
  • fail-on-HTTP-error mode
  • benchmark mode
  • real parallel batch mode through libcurl multi
  • debug timing breakdown

Server side:

  • static file serving
  • generated directory listings
  • optional directory listing disable
  • SPA fallback to index.html
  • health endpoint
  • manifest endpoint
  • echo endpoint
  • upload endpoint
  • configurable bind address
  • configurable max request size

notes

Uses libcurl for the client side networking.

Uses Odin core:net for the built-in server.

Requires Odin base/core/vendor folders to be available.

If you see errors about base or core not being found, set ODIN_ROOT.

If build fails, check curl development libraries first. It is almost always curl, linker flags, or the wrong compiler being picked.


status

Working HTTP client.

Working tiny HTTP server.

Not pretending to replace curl.

Not pretending to replace nginx.

Just a fast little Odin network tool that does useful stuff without acting like a whole cloud platform.

More features can be added later if they actually earn their keep.


inspired by

rfetch by Moritisimor

This is Volt by RobertFlexx