spork-https  Table of Contents

  1. Overview
    1. Features
  2. Status
  3. Dependencies
  4. Quick Start
    1. Installation
    2. Basic Usage
  5. API Reference
    1. https/get
      1. Parameters
      2. Returns
      3. Example
    2. https/post
      1. Parameters
      2. Example
    3. https/put
    4. https/patch
    5. https/delete
    6. https/head
    7. https/request
    8. https/open-stream
      1. Example
    9. https/download
      1. Example
    10. https/server
      1. Parameters
      2. Example
  6. TLS Options
    1. Security Options
  7. Testing
  8. Examples
    1. Simple GET Request
    2. POST with JSON
    3. Using spork/http Directly
  9. Development
    1. Code Formatting
    2. Documentation Generation
  10. Architecture
  11. Related Projects
  12. License
  13. Contributing
  14. Changelog

Overview

spork-https provides HTTPS support for spork's HTTP client using jsec for TLS encryption. It is a thin wrapper that demonstrates the stream-factory pattern in spork, enabling HTTPS requests through pluggable transport mechanisms.

Features

  • Simple HTTPS client API (https/get, https/post, etc.)
  • Streaming HTTPS responses via https/open-stream
  • Constant-memory downloads to files or sinks via https/download
  • Adaptive socket factory enabling seamless HTTP/HTTPS redirects
  • HTTPS server support with TLS encryption
  • Full TLS support via jsec
  • Certificate verification
  • Custom TLS options (ciphers, versions, client certificates, mTLS)
  • Compatible with spork's HTTP API
  • Works with Janet's with macro for automatic cleanup

Status

Functional - The library works for basic HTTPS client/server use cases.

Dependencies

  • Janet >= 1.35.0
  • spork (modified version with stream-factory support)
  • jsec >= 1.0.0

Quick Start

Installation

jpm install spork-https

Basic Usage

(import spork-https :as https)

# Simple HTTPS GET
(let [response (https/get "https://example.com/")]
  (pp (:status response))
  (pp (length (:body response))))

# HTTPS POST with body
(https/post "https://api.example.com/data"
            :body "{\"key\": \"value\"}"
            :headers {"Content-Type" "application/json"})

API Reference

https/get

(https/get url &keys opts)

Make an HTTPS GET request.

Parameters

  • url - HTTPS URL string (must start with https://)
  • opts - Optional keyword arguments:
    • :headers - Request headers table
    • :tls-opts - TLS options (see TLS Options)

Returns

Response table with:

  • :status - HTTP status code (integer)
  • :headers - Response headers table
  • :body - Response body (buffer)
  • :connection - TLS stream
  • :buffer - Internal buffer

Example

(import spork-https :as https)

(let [res (https/get "https://example.com/")]
  (assert (= (:status res) 200))
  (print "Body length: " (length (:body res))))

https/post

(https/post url &keys opts)

Make an HTTPS POST request.

Parameters

  • url - HTTPS URL string
  • opts - Optional keyword arguments:
    • :body - Request body (string or buffer)
    • :headers - Request headers table
    • :tls-opts - TLS options

Example

(https/post "https://api.example.com/submit"
            :body "data=value"
            :headers {"Content-Type" "application/x-www-form-urlencoded"})

https/put

(https/put url &keys opts)

Make an HTTPS PUT request. Parameters same as https/post.

https/patch

(https/patch url &keys opts)

Make an HTTPS PATCH request. Parameters same as https/post.

https/delete

(https/delete url &keys opts)

Make an HTTPS DELETE request.

https/head

(https/head url &keys opts)

Make an HTTPS HEAD request.

https/request

(https/request method url &keys opts)

Make an HTTPS request with specified method.

  • method - HTTP method string ("GET", "POST", etc.)
  • url - HTTPS URL string
  • opts - Optional keyword arguments:
    • :body - Request body content
    • :headers - Request headers table
    • :sink - Target to stream response body into (function, file, or buffer)
    • :max-redirects - Maximum number of 3xx redirects to follow (default 0)
    • :tls-opts - TLS options passed to jsec/tls/connect
    • :stream-opts - Additional stream options

https/open-stream

(https/open-stream url &keys opts)

Open a streaming HTTPS/HTTP connection to url. Returns a response stream object implementing :status, :headers, :read, :blocks, :lines, and :close. Automatically follows HTTP 3xx redirects across HTTP and HTTPS up to :max-redirects (default 10).

  • url - HTTPS/HTTP URL string
  • opts - Optional keyword arguments:
    • :method - HTTP method string (default "GET")
    • :body - Request body content
    • :headers - Request headers table
    • :max-redirects - Maximum redirects to follow (default 10)
    • :tls-opts - TLS options passed to jsec/tls/connect
    • :stream-opts - Additional stream options

Example

(import spork-https :as https)

(with [s (https/open-stream "https://example.com/stream")]
  (print "Status: " (:status s))
  (loop [block :in (:blocks s 1024)]
    (file/write stdout block)))

https/download

(https/download url dest &keys opts)

Download a resource over HTTPS/HTTP streaming directly to a file, buffer, or sink callback with constant $O(1)$ memory usage.

  • url - URL to download
  • dest - Target file path (string), file handle, buffer, or sink function ((fn [chunk]))
  • opts - Optional keyword arguments:
    • :headers - Request headers table
    • :max-redirects - Maximum redirects to follow (default 10)
    • :tls-opts - TLS options
    • :stream-opts - Additional stream options

Example

(import spork-https :as https)

# Download directly to file
(https/download "https://example.com/large-archive.tar.gz" "archive.tar.gz")

# Download with progress sink callback
(var total 0)
(https/download "https://example.com/data.bin"
                (fn [chunk]
                  (+= total (length chunk))
                  (file/write stdout ".")))

https/server

(https/server handler cert key &opt host port tls-opts)

Create an HTTPS server that handles incoming requests with TLS encryption.

Parameters

  • handler - Request handler function (same signature as spork/http)
    • Receives request table with :headers, :path, :method, :body
    • Returns response table with :status, :headers, :body
  • cert - Server certificate (PEM string or file path)
  • key - Server private key (PEM string or file path)
  • host - Host to bind to (default "0.0.0.0")
  • port - Port to bind to (default "8443")
  • tls-opts - Optional TLS configuration table (see TLS Options)

Example

(import spork-https :as https)
(import jsec/cert)

# Generate certificate and key
(let [result (cert/generate-self-signed-cert
               {:common-name "localhost"
                :organization "Test"
                :country "US"
                :days-valid 365
                :bits 2048})
      cert (result :cert)
      pkey (result :key)]

  # Create handler
  (defn handler [req]
    (case (req :method)
      "GET" {:status 200
             :headers {"Content-Type" "text/plain"}
             :body "Hello, HTTPS!"}
      {:status 405
       :headers {"Content-Type" "text/plain"}
       :body "Method Not Allowed"}))

  # Start server
  (def server (https/server handler cert pkey "0.0.0.0" "8443"))

  # Server runs until closed
  (ev/sleep 60)
  (:close server))

TLS Options

The :tls-opts table accepts the following keys:

Option Type Description
:verify boolean Verify server certificate (default: true)
:ca string Path to CA certificate file for verification
:cert string Client certificate for mTLS
:key string Client private key for mTLS
:security table Security options (TLS versions, ciphers, etc.)

Security Options

(https/get "https://example.com/"
           :tls-opts {:security {:min-version "TLS1.2"
                                 :max-version "TLS1.3"
                                 :ciphers "HIGH:!aNULL"}})

Testing

spork-https uses assay for testing.

# Run all tests
janet test/runner.janet # options like verbosity go here (ex: --verbosity 6)

# Clean build and test
jpm clean && jpm build && jpm test

The test suite covers:

  • HTTPS client tests (GET, POST, PUT, PATCH, DELETE)
  • HTTPS server tests (request handling, TLS handshake, concurrent clients)
  • Stream factory integration tests
  • Certificate generation tests

Examples

Runnable examples are in the examples/ directory:

File Description
simple-server.janet HTTPS server with self-signed cert
simple-client.janet HTTPS client requests
local-test.janet Client/server without network

Simple GET Request

(import spork-https :as https)

(let [res (https/get "https://api.github.com/users/janet-lang")]
  (when (= (:status res) 200)
    (print "Success!")
    (print (:body res))))

POST with JSON

(import spork-https :as https)
(import spork/json)

(let [payload (json/encode {:name "test" :value 42})
      res (https/post "https://api.example.com/data"
                     :body payload
                     :headers {"Content-Type" "application/json"})]
  (print "Status: " (:status res)))

Using spork/http Directly

You can use spork's http module directly with jsec as the stream factory:

(import spork/http)
(import jsec/tls :as tls)

(let [res (http/request "GET" "https://example.com/"
                       :stream-factory tls/connect)]
  (pp (:status res)))

Development

Code Formatting

jpm run format-janet   # Format Janet source files
jpm run format         # Format all code

Documentation Generation

jpm run gen-docs       # Generate markdown from org files
jpm run clean-gen      # Clean generated files

Architecture

spork-https is a thin wrapper that:

  1. Creates a TLS stream factory function with jsec
  2. Passes this factory to spork's http/request via :stream-factory
  3. Merges TLS options from :tls-opts into the factory

This design keeps spork transport-agnostic while enabling HTTPS through optional extensions.

Related Projects

  • spork - Janet utilities and HTTP client
  • jsec - TLS/SSL support for Janet via OpenSSL
  • janet-assay - Testing framework for Janet
  • Janet - The Janet programming language

License

ISC License - see LICENSE file

Contributing

Issues and pull requests welcome at https://github.com/llmII/spork-https. Tickets and patches (fossil, preferred) at https://code.amlegion.org/spork-https.

Changelog

See NEWS.org for version history.