Skip to content

Repository files navigation

HOSTTHIS(1)

NAME

hostthis - pipe a rendered file in, get a public URL out

SYNOPSIS

cat <file>      | ssh -T hostthis.dev
cat <file>      | ssh -T hostthis.dev <slug>
tar czf - <dir> | ssh -T hostthis.dev [<slug>]
ssh hostthis.dev <command> [<args>]

-T is for piped uploads only: it disables the ssh client's pseudo-terminal request so the client stops printing Pseudo-terminal will not be allocated because stdin is not a terminal.. It changes nothing on the server. Verb commands (list, get, …) pass a command argument and never trigger the warning.

DESCRIPTION

Publishes HTML, Markdown, a unified diff, a Mermaid diagram, a PDF, a CSV or JSON document, a profile as an interactive flame graph, structured logs, or plain text with linkable lines, for a configurable window (30 days by default; the operator can change or disable it) at a random subdomain. One ssh pipe, no signup, no install. Identity is your ssh public key: anyone with a different key can read the URL but cannot update, rename, pin, or delete the paste.

A Markdown paste renders in the browser; so does a diff (line-by-line or side-by-side, with syntax highlighting). Append ?raw to any rendered paste's URL for the raw source.

COMMANDS

cat file | ssh -T hostthis.dev
upload a paste. The URL prints on stdout; a QR code of it prints on stderr (drop it with 2>/dev/null). To set a label or force the content type, pass --name "label" or --type html|markdown|diff|mermaid|pdf|csv|json|flamegraph|log|text after a literal --. ssh otherwise parses a leading --name as one of its own options.
cat file | ssh -T hostthis.dev slug
replace slug's content; the URL stays the same
ssh hostthis.dev list [-o json]
your pastes, most recently updated first
ssh hostthis.dev get slug
print content to stdout
ssh hostthis.dev url slug
re-show just the URL for any existing paste or site (no ownership check; not found on an unknown slug)
ssh hostthis.dev qr slug
re-show the URL (stdout) and a QR code (stderr) for any existing paste or site
ssh hostthis.dev rename slug [label]
set the owner label from the remaining words; omit them to clear it
ssh hostthis.dev versions slug [-o json]
list versions
ssh hostthis.dev pin slug ver
stick the URL to ver; survives future updates
ssh hostthis.dev unpin slug
clear the pin; URL serves the latest version
ssh hostthis.dev delete slug
wipe the entire paste; permanent
ssh hostthis.dev delete slug ver
free one version's bytes; keeps the history row as a tombstone
ssh hostthis.dev whoami [-o json]
identity, active count, and quota usage

STATIC SITES

Pipe a gzip-tar instead of a single file to deploy a multi-file static site.

tar czf - site/ | ssh -T hostthis.dev            # deploy, get a URL
tar czf - site/ | ssh -T hostthis.dev abc12345   # re-deploy in place

Served at <slug>.hostthis.dev/<path>, with content type by file extension. A request that matches no file serves index.html, so single-page apps route client-side. A single leading directory is flattened, so tar czf - site/ serves at the root. macOS sidecar files ._*, .DS_Store, and __MACOSX/ are skipped. Delete a site with delete <slug>, the same as a paste.

ROOMS API

A deployed site or paste can store and sync state in a room, with no backend of your own. The room's UUID is the only key. The API is served on the app's own origin.

Durable key-value over HTTP:

POST   /api/rooms                -> {"id":"<uuid>"}    mint a room
GET    /api/rooms/<uuid>         -> {key: value, ...}  read the whole room
GET    /api/rooms/<uuid>/<key>   -> value              read one key
PUT    /api/rooms/<uuid>/<key>     write one key, body is the value
DELETE /api/rooms/<uuid>/<key>     delete one key

Realtime over WebSocket, on the same origin:

GET /api/rooms/<uuid>/ws

On connect you receive a snapshot of the room, then a live stream: every durable PUT/DELETE is mirrored to all clients as {"type":"put"|"delete", ...}. Frames you send are broadcast verbatim to other clients and never stored, for ephemeral motion.

A value is opaque bytes. The whole-room read and the snapshot/put frames embed each value as JSON when it parses as JSON - a value you PUT as a JSON object comes back as a nested object, not a quoted string - and as a JSON string otherwise. Reading a single key returns the raw bytes.

Limits: 256 KiB and 256 keys per room; 64 MiB per app. Deployments without a room store return 404.

LIMITS

100 MiB per identity, counting post-compression bytes across every active version of every active paste. Text compresses 5-10x under zstd, so the real raw-payload ceiling is typically 50-100 MiB.

Pastes are HTML, Markdown, a unified diff, a Mermaid diagram, a PDF, a CSV or JSON document, folded stacks as a flame graph, NDJSON logs, or plain text; sites are a gzip-tar archive. Pastes and sites persist indefinitely.

EXIT STATUS

0   success
1   generic failure
2   usage error: bad arguments or unknown verb
3   identity required: no ssh key presented
4   not found, or not yours
6   refused by the per-subnet rate limit

ENVIRONMENT

NO_COLOR    set to any value to disable color output
TERM=dumb   also disables color output

Read from the environment your ssh client forwards.

EXAMPLES

# upload, get a URL on stdout (and a QR code on stderr)
cat index.html | ssh -T hostthis.dev

# capture just the URL; 2>/dev/null drops the QR + narration
url=$(cat index.html | ssh -T hostthis.dev 2>/dev/null)

# upload with a label; --name and --type follow a literal --
cat notes.md | ssh -T hostthis.dev -- --name "alpha notes"

# update an existing paste; same URL, bumps to v2, v3, ...
cat v2.html | ssh -T hostthis.dev abc12345

# force content type when sniffing gets it wrong
cat tricky.html | ssh -T hostthis.dev -- --type html

# render a unified diff (auto-detected, or force it with --type diff)
git diff | ssh -T hostthis.dev
cat review.patch | ssh -T hostthis.dev -- --type diff

# a mermaid diagram, a pdf, a csv, a json document - all auto-detected
cat architecture.mmd | ssh -T hostthis.dev
cat q3-review.pdf    | ssh -T hostthis.dev
cat sales.csv        | ssh -T hostthis.dev
cat events.json      | ssh -T hostthis.dev

# a profile renders as an interactive flame graph. The accepted format is
# folded stacks ("a;b;c 123" per line), which every profiler can emit:
# perf via stackcollapse-perf.pl, Go pprof, py-spy --format raw, async-profiler
cat cpu.folded | ssh -T hostthis.dev

# NDJSON logs get levels, filtering and per-line links. This is the shape
# Loki and OpenSearch both work in; their stream and bulk wrappers unwrap.
cat app.ndjson | ssh -T hostthis.dev

# anything else textual renders with a line gutter and citable ranges
cat nginx.conf | ssh -T hostthis.dev

# link to a place INSIDE a paste
#   <url>#some-heading   markdown heading
#   <url>#page=3         pdf page
#   <url>#row=42         csv row
#   <url>#F1L42-L48      diff lines of file 1 (shift-click, or tap, for a range)
#   <url>#focus=main;serve  flame graph: zoom to that stack
#   <url>#q=malloc          flame graph: highlight matching frames

# read your content back
ssh hostthis.dev get abc12345

# re-show the link for an existing paste (URL only, or URL + QR)
ssh hostthis.dev url abc12345
ssh hostthis.dev qr abc12345

# set the owner label from the words, or omit it to clear
ssh hostthis.dev rename abc12345 design notes v2
ssh hostthis.dev rename abc12345

# stick the URL on v1 even though v3 is the latest
ssh hostthis.dev pin abc12345 1
ssh hostthis.dev unpin abc12345

# free one version's bytes; leaves a tombstone row
ssh hostthis.dev delete abc12345 2

# deploy a static site
tar czf - site/ | ssh -T hostthis.dev

SEE ALSO

Source: github.com/Zamua/hostthis

LICENSE

MIT - see LICENSE.

About

Pipe HTML or Markdown to ssh, get a URL.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages