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.
- 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
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>/.
See USE_CASES for an overview of common deployment patterns including virtual hosting and static roots.
| 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 |
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.
| 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 |
| 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.
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]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.
# 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