Shaser is a SHA256-indexed file cache and HTTP server. It keeps a local database that maps a SHA256 hash to an absolute file path, can download missing files from peer servers, and can register uploaded files into the server cache.
The index layout is compatible with iaito's samples database.
makeThe default cache root is platform-specific and can be overridden with
-root or SHASER_ROOT:
macOS: ~/Library/Application Support/shaser/samples
Linux: ${XDG_DATA_HOME:-~/.local/share}/shaser/samples
Windows: %LOCALAPPDATA%\shaser\samples
Install system-wide or for the current user:
make install PREFIX=/usr/local
make user-install
make uninstall PREFIX=/usr/local
make user-uninstalluser-install and user-uninstall are intended for r2pm. They install the
binary into $(r2pm -H R2PM_BINDIR) and the library/header under
$(r2pm -H R2PM_PREFIX).
DESTDIR is supported for package managers:
make install PREFIX=/usr DESTDIR="$pkgdir"
make user-install DESTDIR="$pkgdir"Index bucket files use the iaito layout:
<root>/<first2>/<next2>/<first4>
Each bucket line is:
<sha256> <absolute-path>
This gives 65,536 buckets and keeps lookups cheap: resolving one hash reads one small bucket file. Downloaded or uploaded blob content is stored beside the bucket using the full hash:
<root>/<first2>/<next2>/<full-sha256>
Those names cannot collide because bucket files are 4 hex chars and blobs are
64 hex chars. Access metadata for quota cleanup lives under <root>/meta/.
Inspect defaults:
./shaser config
./shaser config -jsonCompute a SHA256:
./shaser hash /path/to/fileRegister files:
./shaser cache register -root ./samples /path/to/file
./shaser cache scan -root ./samples /path/to/treeResolve and list:
./shaser cache lookup -root ./samples <sha256>
./shaser cache list -root ./samples
./shaser cache stats -root ./samples -large 104857600 -older 720hRemove entries:
./shaser cache remove -root ./samples <sha256>
./shaser cache remove-path -root ./samples /path/prefixConfigure peers:
./shaser peer add http://127.0.0.1:8080
./shaser peer add -token READ_TOKEN https://peer.example
./shaser peer listDownload from local cache or peers. Successful downloads are registered into the local cache and the command prints the local absolute path:
./shaser cache get -root ./samples <sha256>Run the server:
./shaser server -root ./samples -listen 127.0.0.1:8080Endpoints:
GET /
GET /?sha256=<sha256>
GET /sha256/<sha256>
HEAD /sha256/<sha256>
GET /<first2>/<next2>/<full-sha256>
POST /sha256
PUT /sha256/<sha256>
The root page serves a small HTML form for pasting a SHA256. Submitting it checks the local cache and configured peers, redirects to the download when the hash is available, or shows an error page when it is not.
Downloads are always sent with Content-Encoding: gzip. Direct hash paths make
it possible to expose the cache root with a generic static HTTP server too.
Useful server flags:
-peers FILE JSON peer list
-auth-file FILE JSON auth config
-auth require read bearer tokens
-read-token TOKEN comma-separated read tokens
-upload-token TOKEN comma-separated upload tokens
-bandwidth BYTES per-response bandwidth limit
-tls-cert FILE enable HTTPS with this cert
-tls-key FILE HTTPS key
Reads are public unless read auth is enabled. Uploads always require an upload token.
Generate and manage bearer tokens:
./shaser auth gen -kind upload -name alice
./shaser auth add -kind read -name bob READ_TOKEN
./shaser auth add -kind upload -name ci UPLOAD_TOKEN
./shaser auth require-read on
./shaser auth listNamed tokens are stored with their creation time, so auth list shows who each
token was issued for and when it was added.
Upload to a peer:
./shaser upload -peer http://127.0.0.1:8080 -token UPLOAD_TOKEN /path/to/fileThe C API is opt-in and uses radare2's RMuta for local SHA256 computation.
Normal Go builds do not require radare2 headers or libraries.
Build a shared library:
go build -tags capi -buildmode=c-shared -o libshaser.dylib ./capiOn Linux, use libshaser.so as the output name. The build expects
pkg-config --cflags --libs r_muta to work.
Public functions are declared in capi/shaser.h:
char *shaser_sha256_file(const char *path);
char *shaser_register_file(const char *root, const char *path);
char *shaser_lookup(const char *root, const char *sha256);
char *shaser_get(const char *root, const char *peer_file, const char *sha256);
char *shaser_upload_file(const char *base_url, const char *token, const char *path);
char *shaser_last_error(void);
void shaser_free(char *s);All returned strings must be released with shaser_free(). NULL means failure;
call shaser_last_error() for a diagnostic string.
SHASER_ROOT default cache root
SHASER_CONFIG default config JSON file
SHASER_PEERS default peer JSON file
SHASER_AUTH default auth JSON file
go test ./...
go vet ./...
go test -tags capi ./capi
go build -tags capi -buildmode=c-shared -o /tmp/libshaser.dylib ./capi