5.5 KiB
noxy is a nostr proxy
noxy proxies URL preview metadata, images and other media files. the idea is to run such proxies to reduce IP address leaks and client fingerprinting.
to limit noxy abuse, it works only with URLs linked to from nostr events. the following nostr event kinds are currently supported:
- 0:
set_metadata
;picture
URL - 1:
text_note
; any URL in thecontent
- 40: create channel;
picture
URL - 41: set channel metadata;
picture
URL - 42: channel message; any URL in the
content
API
over HTTP, noxy exposes two endpoints: one for meta info of URL preview, and the other one for file (data) transfer.
/meta
the request has the following form. all parameter values are expected to be url-encoded.
GET /meta?id=<nostr-event-id>&relay=<relay-uri>&url=<original-url>
the parameters are:
id
: nostr event id as described in NIP-01relay
: a URL of a nostr relay where the event was posted tourl
: any URL found in the event text note or thepicture
for structured messages
noxy fetches HTML at url
, looks for OGP metadata
and responds with a JSON object containing the following keys:
{
"type": "<OGP type>",
"title": "<OGP title>",
"descr": "<OGP description>",
"images": ["<URL>", ...]
}
where image URLs are taken from og:image:secure_url
or og:image
; the former
is preferred. other fields are copied verbatim from og:type
, og:title
and og:description
, respectively. future versions may also employ
oEmbed and other metadata formats parsing.
the web page at url
must be served with text/html
content type. if the page
contains no or empty OGP metadata, noxy response with 200 OK and blank fields.
otherwise, the response is a 4xx status code.
/data
data endpoint request is of the following form. all parameter values are expected to be url-encoded.
GET /data?id=<nostr-event-id>&relay=<relay-uri>&url=<file-url>
the parameters are:
id
: a nostr event idrelay
: a URL of a nostr relay where the event was posted tourl
: any URL found either in the event text note,picture
field for structured messages, or animages
array element of a/meta
endpoint response produced from the same event id.
the data endpoint simply streams contents at the url
to the client
with the same content-type
as the original. content-length
may or may
not be present. in the latter case, the response is chunked.
example: fetch a pubkey profile picture, event kind 0
$ eventid=e01ac1cfc5cb68b54183f878261b21ef30a65f5e06a24356cfe3ecdacce14bae
$ relay=wss://relay.nostr.info
$ url=https://git.qcode.ch/avatars/5a8071777eba7ebf178143fa650c8012?size=870
$ curl -o /tmp/img "https://noxy.nostr.ch/data?id=$eventid&relay=$relay&url=$url"
$ file /tmp/img
/tmp/img: PNG image data, 290 x 290, 16-bit/color RGB, non-interlaced
example: fetch images from a text note, event kind 1
$ eventid=d822fdd220d8a74d2f025f331840eec8a640a663f1d3ca3de9f6a74ff0cc61fa
$ relay=wss://relay.damus.io
$ url=https://res.cloudinary.com/eskema/image/upload/v1668636521/osso_vt7qh7.png
$ curl -o /tmp/img "https://noxy.nostr.ch/data?id=$eventid&relay=$relay&url=$url"
$ file /tmp/img
/tmp/img: PNG image data, 800 x 800, 8-bit/color RGB, non-interlaced
example: fetch link preview from a text note, event kind 1
$ EVENTID=af30dac1d800acc25b87d0d6d0dd33bddf49e7f356556540a6c7722e3cb363fe
$ RELAY=wss://nostr.x1ddos.ch/
$ URL=https://github.com/fiatjaf/noscl/pull/24
$ curl "https://noxy.nostr.ch/meta?id=$EVENTID&relay=$RELAY&url=$URL"
response:
{
"type": "object",
"title": "publish,message: accept content from stdin by x1ddos · Pull Request #24 · fiatjaf/noscl",
"descr": "if the arg to publish or message command is '-', it is read from stdin.\ncloses #19",
"images": [
"https://opengraph.githubassets.com/dc27bad9f4d71ea7803c4bd07a9991c0bcb798bbdc451aebc42d222e5d7692c8/fiatjaf/noscl/pull/24"
]
}
now, fetch the preview image. note the change from /meta
to /data
endpoint:
$ URL=https://opengraph.githubassets.com/dc27bad9f4d71ea7803c4bd07a9991c0bcb798bbdc451aebc42d222e5d7692c8/fiatjaf/noscl/pull/24
$ curl -o /tmp/img "https://noxy.nostr.ch/data?id=$EVENTID&relay=$RELAY&url=$URL"
$ file /tmp/img
/tmp/img: PNG image data, 1200 x 600, 8-bit/color RGBA, non-interlaced
development
the binary's entry point is cmd/noxy/main.go.
it imports packages in the root of the repo. the actual proxy is implemented
by Noxer
in noxy.go.
running the server locally:
mkdir cache
go run ./cmd/noxy -cachedir $PWD/cache
before sending a patch, make sure the code is passing tests:
go test -race
files are formatted:
go fmt ./...
and the go module file is updated:
go mod tidy
release
a release binary is built using the following script.
it produces noxy
executable in the root of the repo.
./tools/release.sh
before making a new release, you'll probably want to create a new git tag.
the tag is used as the noxy version, also printed when -V
flag is specified.