rasler
v0.2.0
Published
RASLer — RASL protocol node implementation with content-addressed storage and MASL support
Maintainers
Readme
RASLer
RASLer is a HTTP server that implements RASL's /.well-known/rasl/ endpoint, backed by content-addressed storage, MASL metadata support, and a full-featured operator API.
Features
- Storage — content blobs are stored by CID on disk, backed by a SQLite database that enables capacity management and a pluggable eviction policy
- DASL & MASL CIDs — content serving by simple DASL CIDs, or via MASL CIDs with path-based resolution for both single files and website bundles as per the proposed specification (see "RASL Path Resolution via MASL")
- Static roots — serve files from local directories by CID without copying them into the blob store
- Mount points - use human-friendly URLs with virtual hosts and MASL paths
- Operator API — upload raw files or CARs, pin/unpin, and evict; manage mount points; status, etc.
- Server factory — compose your own server including RASL functionality
Quick start
npm install
cp .env.example .env
# edit .env and set API_SECRET
cp rasler.config.example.json rasler.config.json # optional — configure static roots, mount points, CORS
npm start
# open http://localhost:3000/api-docs in a browserFrom the API docs UI, you can:
- Enter
API_SECRETto authenticate - Upload one or more files (or CARs with MASL metadata, see Utilities for help building) and record their MASL CIDs
Once uploaded, you can access the files at http://localhost:3000/.well-known/rasl/<cid>/.
Slow start
See USE_CASES for an overview of common deployment patterns including virtual hosting and static roots.
Configuration
Environment variables (.env)
| Variable | Required | Default | Description |
|---|---|---|---|
| ORIGIN | No | http://localhost:<PORT> | This node's public origin, protocol included (e.g. https://node1.example.com). Used in Link: rel="duplicate" headers. A bare hostname without protocol is accepted and defaults to https://. |
| API_SECRET | Yes | — | Pre-shared secret to send as x-rasl-operator-secret header |
| PORT | No | 3000 | HTTP listen port |
| DATA_DIR | No | ./data | Directory for the SQLite database and content blobs |
| TOTAL_CAPACITY | No | 1G | Storage budget (200M, 1G, 2GB, plain bytes) |
| OPERATOR_API_PATH_PREFIX | No | — | Mount operator API under a path prefix (e.g. /admin) |
| SWAGGER_UI | No | true | Set false to disable the interactive API docs at <operator-api-path-prefix>/api-docs |
rasler.config.json
Static roots, mount points, and CORS origins are configured in an optional rasler.config.json file in the working directory. Copy rasler.config.example.json to get started.
{
"staticRoots": [
{ "path": "/var/www/assets", "watch": true, "ignore": ["**/*.log", ".DS_Store"] }
],
"mountPoints": [
{ "hostname": "example.com", "directory": "/var/www/html" },
{ "hostname": "example.com", "prefix": "/docs", "directory": "/var/www/docs" }
],
"operatorCorsOrigins": ["http://localhost:5173", "https://admin.example.com"]
}| Key | Description |
|---|---|
| staticRoots | Directories to serve as static RASL roots. String entries use defaults; object entries add watch (re-index on change) and ignore (glob patterns to skip). See STATIC_ROOTS. |
| staticMaxHistory | Maximum pinned MASL versions per static root; older versions are unpinned for LRU eviction. Omit for unlimited. |
| mountPoints | Virtual host mappings: { hostname, prefix?, directory }. See MOUNT_POINTS. |
| operatorCorsOrigins | Origins allowed to call the Operator API cross-origin. |
Implicit ./public mount — if a ./public directory exists and no root-level mount point is configured for the origin domain, RASLer automatically serves it at the document root with Link: rel="duplicate" headers.
API
RASL retrieval (public)
| Method | Path | Description |
|---|---|---|
| GET | /.well-known/rasl/:cid | Retrieve raw content by CID |
| HEAD | /.well-known/rasl/:cid | Same as GET, no body |
| GET | /.well-known/rasl/:cid/* | Retrieve content via MASL document CID; path suffix resolved against MASL resources |
| HEAD | /.well-known/rasl/:cid/* | Same as GET, no body |
Operator API (requires x-rasl-operator-secret header)
| Method | Path | Description |
|---|---|---|
| GET | /status | Show server status (including storage usage) |
| POST | /upload | Upload files (multipart or CAR) |
| POST | /pin | Pin CIDs |
| DELETE | /pin/:cid | Unpin a CID |
| GET | /content | List held content |
| GET | /content/:cid | Get content metadata |
| DELETE | /content/:cid | Evict a CID |
| GET | /static-roots | List configured static roots and their current MASL CIDs |
| GET | /mount-points | List all mount points (static and runtime) with their MASL CIDs |
| PUT | /mount-points/:hostname[/:prefix] | Map a hostname (with optional path prefix) to a held bundle MASL CID (runtime, persisted) |
| DELETE | /mount-points/:hostname[/:prefix] | Remove a runtime mount point mapping |
The Operator API can be relocated via the OPERATOR_API_PATH_PREFIX environment option.
Full request/response details are in openapi.json and can be viewed and used interactively if SWAGGER_UI=true.
Utilities
The following utility script is included.
# Build a CAR file (with MASL bundle header) from a static website directory tree
npm run get-in-the-car <input-dir> [output.car]Development
Contributions are welcome! Please use GitHub Issues to discuss or propose improvements or file bugs.
See ARCHITECTURE for a code walkthrough as well as details on using RASLer as a library.
Pull requests that make changes to the API should include updated JSDoc and a freshly generated openapi.json.
Scripts
# Run the node
npm start
# Run tests (includes lint)
npm test
# Lint only
npm run lint
# Regenerate openapi.json from JSDoc in src/routes/operator.js
npm run generate:openapi
# Generate HTML docs from *.md files into ./public
npm run generate:docs