Introduction

Welcome to the snapbox wiki!
Documentation for bleeding-edge main branch is available here.

snapbox is a HTTP client library for Jule. It is based on (lib)curl and provides a simple interface for making HTTP requests.

See the Getting Started section for a quick how-to.

If you would like to contribute, feel free to fork the repository and submit a pull request :)

Copyright (c) 2025, Adam Perkowski. All rights reserved.

The library is distributed under the terms of the BSD 3-Clause license

See License Details

Getting Started

To get started with snapbox, you need to install the library first. You can do this by either:

Downloading the latest release package from the releases page, extracting it and placing it in your project's directory:

tar -xzf snapbox-0.1.0.tar.gz
rm snapbox-0.1.0.tar.gz

Or cloning the repository into a Git submodule:

git submodule add https://github.com/adamperkowski/snapbox.git snapbox
git submodule update --init
# you can also specify a tag to get a specific version:
cd snapbox
git checkout v0.1.0
cd ..

After you have the library installed in your project, you can start using it by including it in your code:

use "snapbox"

Usage Examples

Below are some simple examples of how to use snapbox.

Basic Requests

// get.jule
use "snapbox"
use "snapbox/header"
use "snapbox/status"

fn main() {
        let headerMap: header::HeaderMap = {
                header::ACCEPT: "application/json",
        }

        request := snapbox::GET("https://httpbin.org/get").Headers(headerMap)
        response := request.Send()

        if !status::IsSuccess(response.status) {
                println("Error: ")
                println(response.status)
        }

        print(response.body)
}

// post.jule
use "snapbox"
use "snapbox/header"
use "snapbox/status"

const DATA = "Hello, World!"

fn main() {
        let headerMap: header::HeaderMap = {
                header::ACCEPT: "application/json",
                header::CONTENT_TYPE: "text/plain",
        }

        request := snapbox::POST("https://httpbin.org/post").Data(DATA).Headers(headerMap)
        response := request.Send()

        if !status::IsSuccess(response.status) {
                println("Error: ")
                println(response.status)
        }

        print(response.body)
}

File Downloading

// download.jule
use "snapbox"

fn main() {
        snapbox::Download("https://httpbin.org/get", "output.txt") else {
                println(error)
        }
}

See the examples directory for a full list of examples.

Index

fn GET(url: str): Request
fn HEAD(url: str): Request
fn POST(url: str): DataRequest
fn PUT(url: str): DataRequest
fn DELETE(url: str): DataRequest
fn Download(url: str, path: str)!
struct Request
    fn Send(self): cpp.Response
    fn Headers(self, headers: header::HeaderMap): Request
struct DataRequest
    fn Send(self): cpp.Response
    fn Headers(self, headers: header::HeaderMap): DataRequest
    fn Data(self, data: str): DataRequest

GET

fn GET(url: str): Request

Builds a GET request object.

fn HEAD(url: str): Request

Builds a HEAD request object.

POST

fn POST(url: str): DataRequest

Builds a POST request object.

PUT

fn PUT(url: str): DataRequest

Builds a PUT request object.

DELETE

fn DELETE(url: str): DataRequest

Builds a DELETE request object.

Download

fn Download(url: str, path: str)!

Uses the internal C++ function to download a file from the given URL and save it to the given path.

Request

struct Request {
	// NOTE: contains filtered hidden or unexported fields
}

Request structure for non-data requests.

Send

fn Send(self): cpp.Response

Executes the request and returns the response.

Headers

fn Headers(self, headers: header::HeaderMap): Request

Sets headers for the request.

DataRequest

struct DataRequest {
	// NOTE: contains filtered hidden or unexported fields
}

Request structure for data requests.

Send

fn Send(self): cpp.Response

Executes the request and returns the response.

Headers

fn Headers(self, headers: header::HeaderMap): DataRequest

Sets headers for the request.

Data

fn Data(self, data: str): DataRequest

Sets data for the request.

Index

Variables
type StatusCode
fn IsInformational(code: StatusCode): bool
fn IsSuccess(code: StatusCode): bool
fn IsRedirection(code: StatusCode): bool
fn IsClientError(code: StatusCode): bool
fn IsServerError(code: StatusCode): bool

Variables

const CONTINUE: StatusCode = 100
const SWITCHING_PROTOCOLS: StatusCode = 101
const PROCESSING: StatusCode = 102
const OK: StatusCode = 200
const CREATED: StatusCode = 201
const ACCEPTED: StatusCode = 202
const NON_AUTHORITATIVE_INFORMATION: StatusCode = 203
const NO_CONTENT: StatusCode = 204
const RESET_CONTENT: StatusCode = 205
const PARTIAL_CONTENT: StatusCode = 206
const MULTI_STATUS: StatusCode = 207
const ALREADY_REPORTED: StatusCode = 208
const IM_USED: StatusCode = 226
const MULTIPLE_CHOICES: StatusCode = 300
const MOVED_PERMANENTLY: StatusCode = 301
const FOUND: StatusCode = 302
const SEE_OTHER: StatusCode = 303
const NOT_MODIFIED: StatusCode = 304
const USE_PROXY: StatusCode = 305
const TEMPORARY_REDIRECT: StatusCode = 307
const PERMANENT_REDIRECT: StatusCode = 308
const BAD_REQUEST: StatusCode = 400
const UNAUTHORIZED: StatusCode = 401
const PAYMENT_REQUIRED: StatusCode = 402
const FORBIDDEN: StatusCode = 403
const NOT_FOUND: StatusCode = 404
const METHOD_NOT_ALLOWED: StatusCode = 405
const NOT_ACCEPTABLE: StatusCode = 406
const PROXY_AUTHENTICATION_REQUIRED: StatusCode = 407
const REQUEST_TIMEOUT: StatusCode = 408
const CONFLICT: StatusCode = 409
const GONE: StatusCode = 410
const LENGTH_REQUIRED: StatusCode = 411
const PRECONDITION_FAILED: StatusCode = 412
const PAYLOAD_TOO_LARGE: StatusCode = 413
const URI_TOO_LONG: StatusCode = 414
const UNSUPPORTED_MEDIA_TYPE: StatusCode = 415
const RANGE_NOT_SATISFIABLE: StatusCode = 416
const EXPECTATION_FAILED: StatusCode = 417
const IM_A_TEAPOT: StatusCode = 418
const MISDIRECTED_REQUEST: StatusCode = 421
const UNPROCESSABLE_ENTITY: StatusCode = 422
const LOCKED: StatusCode = 423
const FAILED_DEPENDENCY: StatusCode = 424
const UPGRADE_REQUIRED: StatusCode = 426
const PRECONDITION_REQUIRED: StatusCode = 428
const TOO_MANY_REQUESTS: StatusCode = 429
const REQUEST_HEADER_FIELDS_TOO_LARGE: StatusCode = 431
const UNAVAILABLE_FOR_LEGAL_REASONS: StatusCode = 451
const INTERNAL_SERVER_ERROR: StatusCode = 500
const NOT_IMPLEMENTED: StatusCode = 501
const BAD_GATEWAY: StatusCode = 502
const SERVICE_UNAVAILABLE: StatusCode = 503
const GATEWAY_TIMEOUT: StatusCode = 504
const HTTP_VERSION_NOT_SUPPORTED: StatusCode = 505
const VARIANT_ALSO_NEGOTIATES: StatusCode = 506
const INSUFFICIENT_STORAGE: StatusCode = 507
const LOOP_DETECTED: StatusCode = 508
const NOT_EXTENDED: StatusCode = 510
const NETWORK_AUTHENTICATION_REQUIRED: StatusCode = 511

StatusCode

type StatusCode = int

The status code type used for responses.

IsInformational

fn IsInformational(code: StatusCode): bool

Checks if a status code is informational. (1xx)

IsSuccess

fn IsSuccess(code: StatusCode): bool

Checks if a status code is a success. (2xx)

IsRedirection

fn IsRedirection(code: StatusCode): bool

Checks if a status code is a redirection. (3xx)

IsClientError

fn IsClientError(code: StatusCode): bool

Checks if a status code is a client error. (4xx)

IsServerError

fn IsServerError(code: StatusCode): bool

Checks if a status code is a server error. (5xx)

Index

Variables
type HeaderMap
fn Slice(headers: HeaderMap): []str

Variables

const ACCEPT = "Accept"
const ACCEPT_CHARSET = "Accept-Charset"
const ACCEPT_ENCODING = "Accept-Encoding"
const ACCEPT_LANGUAGE = "Accept-Language"
const ACCEPT_RANGES = "Accept-Ranges"
const ACCESS_CONTROL_ALLOW_CREDENTIALS = "Access-Control-Allow-Credentials"
const ACCESS_CONTROL_ALLOW_HEADERS = "Access-Control-Allow-Headers"
const ACCESS_CONTROL_ALLOW_METHODS = "Access-Control-Allow-Methods"
const ACCESS_CONTROL_ALLOW_ORIGIN = "Access-Control-Allow-Origin"
const ACCESS_CONTROL_EXPOSE_HEADERS = "Access-Control-Expose-Headers"
const ACCESS_CONTROL_MAX_AGE = "Access-Control-Max-Age"
const ACCESS_CONTROL_REQUEST_HEADERS = "Access-Control-Request-Headers"
const ACCESS_CONTROL_REQUEST_METHOD = "Access-Control-Request-Method"
const AGE = "Age"
const ALLOW = "Allow"
const ALT_SVC = "Alt-Svc"
const AUTHORIZATION = "Authorization"
const CACHE_CONTROL = "Cache-Control"
const CACHE_STATUS = "Cache-Status"
const CDN_CACHE_CONTROL = "CDN-Cache-Control"
const CONNECTION = "Connection"
const CONTENT_DISPOSITION = "Content-Disposition"
const CONTENT_ENCODING = "Content-Encoding"
const CONTENT_LANGUAGE = "Content-Language"
const CONTENT_LENGTH = "Content-Length"
const CONTENT_LOCATION = "Content-Location"
const CONTENT_RANGE = "Content-Range"
const CONTENT_SECURITY_POLICY = "Content-Security-Policy"
const CONTENT_SECURITY_POLICY_REPORT_ONLY = "Content-Security-Policy-Report-Only"
const CONTENT_TYPE = "Content-Type"
const COOKIE = "Cookie"
const DATE = "Date"
const DNT = "Dnt"
const ETAG = "Etag"
const EXPECT = "Expect"
const EXPIRES = "Expires"
const FORWARDED = "Forwarded"
const FROM = "From"
const HOST = "Host"
const IF_MATCH = "If-Match"
const IF_MODIFIED_SINCE = "If-Modified-Since"
const IF_NONE_MATCH = "If-None-Match"
const IF_RANGE = "If-Range"
const IF_UNMODIFIED_SINCE = "If-Unmodified-Since"
const LAST_MODIFIED = "Last-Modified"
const LINK = "Link"
const LOCATION = "Location"
const MAX_FORWARDS = "Max-Forwards"
const ORIGIN = "Origin"
const PRAGMA = "Pragma"
const PROXY_AUTHENTICATE = "Proxy-Authenticate"
const PROXY_AUTHORIZATION = "Proxy-Authorization"
const PUBLIC_KEY_PINS = "Public-Key-Pins"
const PUBLIC_KEY_PINS_REPORT_ONLY = "Public-Key-Pins-Report-Only"
const RANGE = "Range"
const REFERER = "Referer"
const REFERRER_POLICY = "Referrer-Policy"
const RETRY_AFTER = "Retry-After"
const SEC_WEBSOCKET_ACCEPT = "Sec-Websocket-Accept"
const SEC_WEBSOCKET_EXTENSIONS = "Sec-Websocket-Extensions"
const SEC_WEBSOCKET_KEY = "Sec-Websocket-Key"
const SEC_WEBSOCKET_PROTOCOL = "Sec-Websocket-Protocol"
const SEC_WEBSOCKET_VERSION = "Sec-Websocket-Version"
const SERVER = "Server"
const SET_COOKIE = "Set-Cookie"
const STRICT_TRANSPORT_SECURITY = "Strict-Transport-Security"
const TE = "Te"
const TRAILER = "Trailer"
const TRANSFER_ENCODING = "Transfer-Encoding"
const UPGRADE = "Upgrade"
const UPGRADE_INSECURE_REQUESTS = "Upgrade-Insecure-Requests"
const USER_AGENT = "User-Agent"
const VARY = "Vary"
const VIA = "Via"
const WARNING = "Warning"
const WWW_AUTHENTICATE = "Www-Authenticate"
const X_CONTENT_TYPE_OPTIONS = "X-Content-Type-Options"
const X_DNS_PREFETCH_CONTROL = "X-Dns-Prefetch-Control"
const X_FRAME_OPTIONS = "X-Frame-Options"
const X_XSS_PROTECTION = "X-Xss-Protection"

HeaderMap

type HeaderMap = map[str]str

The map of headers type used for requests.

Slice

fn Slice(headers: HeaderMap): []str

Slices a HeaderMap into a []str.