From 23cf77e0b7013da14877a30c14098e7fa7616fcc Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Sat, 23 Oct 2021 22:49:50 -0400 Subject: [PATCH] Rate limiting, docs --- README.md | 15 ++++-- config/config.go | 26 ++++++++-- go.mod | 1 + go.sum | 9 ++-- server/index.html | 57 ++++++++++++++++------ server/server.go | 120 +++++++++++++++++++++++++++++++++++----------- server/topic.go | 9 ++++ 7 files changed, 180 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index 45205a1..72f48b8 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,14 @@ via scripts. I run a free version of it on *[ntfy.sh](https://ntfy.sh)*. **No si ## Usage ### Subscribe to a topic -You can subscribe to a topic either in a web UI, or in your own app by subscribing to an -[SSE](https://en.wikipedia.org/wiki/Server-sent_events)/[EventSource](https://developer.mozilla.org/en-US/docs/Web/API/EventSource), +Topics are created on the fly by subscribing to them. You can create and subscribe to a topic either in a web UI, or in +your own app by subscribing to an [SSE](https://en.wikipedia.org/wiki/Server-sent_events)/[EventSource](https://developer.mozilla.org/en-US/docs/Web/API/EventSource), or a JSON or raw feed. -Here's how to see the raw/json/sse stream in `curl`. This will subscribe to the topic and wait for events. +Because there is no sign-up, **the topic is essentially a password**, so pick something that's not easily guessable. + +Here's how you can create a topic `mytopic`, subscribe to it topic and wait for events. This is using `curl`, but you +can use any library that can do HTTP GETs: ``` # Subscribe to "mytopic" and output one message per line (\n are replaced with a space) @@ -54,9 +57,11 @@ Best effort. ### Why is the web UI so ugly? I don't particularly like JS or dealing with CSS. I'll make it pretty after it's functional. +## Will you know what topics exist, can you spy on me? +If you don't trust me or your messages are sensitive, run your ntfy on your own server. That said, the logs do not +contain any topic names + ## TODO -- rate limiting / abuse protection -- release/packaging - add HTTPS ## Contributing diff --git a/config/config.go b/config/config.go index 8529791..ba91f13 100644 --- a/config/config.go +++ b/config/config.go @@ -1,18 +1,38 @@ // Package config provides the main configuration package config +import ( + "golang.org/x/time/rate" + "time" +) + +// Defines default config settings const ( - DefaultListenHTTP = ":80" + DefaultListenHTTP = ":80" + defaultManagerInterval = time.Minute +) + +// Defines the max number of requests, here: +// 50 requests bucket, replenished at a rate of 1 per second +var ( + defaultLimit = rate.Every(time.Second) + defaultLimitBurst = 50 ) // Config is the main config struct for the application. Use New to instantiate a default config struct. type Config struct { - ListenHTTP string + ListenHTTP string + Limit rate.Limit + LimitBurst int + ManagerInterval time.Duration } // New instantiates a default new config func New(listenHTTP string) *Config { return &Config{ - ListenHTTP: listenHTTP, + ListenHTTP: listenHTTP, + Limit: defaultLimit, + LimitBurst: defaultLimitBurst, + ManagerInterval: defaultManagerInterval, } } diff --git a/go.mod b/go.mod index 7c9ad4c..791b7b0 100644 --- a/go.mod +++ b/go.mod @@ -6,5 +6,6 @@ require ( github.com/BurntSushi/toml v0.4.1 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect github.com/urfave/cli/v2 v2.3.0 + golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index 2cd4b5d..91f925e 100644 --- a/go.sum +++ b/go.sum @@ -1,23 +1,20 @@ -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw= github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= +golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.3 h1:fvjTMHxHEw/mxHbtzPi3JCcKXQRAnQTBRo6YCJSVHKI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/server/index.html b/server/index.html index 1e3c231..ddef43d 100644 --- a/server/index.html +++ b/server/index.html @@ -3,37 +3,64 @@ ntfy.sh
-

ntfy.sh

- +

ntfy.sh - simple HTTP-based pub-sub

- ntfy (pronounce: notify) is a simple HTTP-based pub-sub notification service. It allows you to send desktop and (soon) phone notifications - via scripts, without signup or cost. It's entirely free and open source. You can find the source code on GitHub. + ntfy (pronounce: notify) is a simple HTTP-based pub-sub notification service and tool. + It allows you to send desktop notifications via scripts, entirely without signup or cost. + It's entirely free and open source. You can find the source code on GitHub.

- -

- You can subscribe to a topic either in this web UI, or in your own app by subscribing to an SSE/EventSource - or JSON feed. Once subscribed, you can publish messages via PUT or POST. -

-

+

Subscribe to a topic

+

+ Topics are created on the fly by subscribing to them. You can create and subscribe to a topic either in this web UI, or in + your own app by subscribing to an EventSource, + a JSON feed, or raw feed. +

+

+ Because there is no sign-up, the topic is essentially a password, so pick something that's not easily guessable. +

+ +

Subscribe via web

+

+ If you subscribe to a topic via this web UI in the field below, messages published to any subscribed topic + will show up as desktop notification. +

- + +

- -

Subscribed topics:

+

Subscribed topics:

+

Subscribe via your app, or via the CLI

+ + curl -s ntfy.sh/mytopic/raw # one message per line (\n are replaced with a space)
+ curl -s ntfy.sh/mytopic/json # one JSON message per line
+ curl -s ntfy.sh/mytopic/sse # server-sent events (SSE) stream +
+ +

Publishing messages

+

+ Publishing messages can be done via PUT or POST using. Here's an example using curl: +

+ + curl -d "long process is done" ntfy.sh/mytopic + +

+ Messages published to a non-existing topic or a topic without subscribers will not be delivered later. + There is (currently) no buffering of any kind. If you're not listening, the message won't be delivered. +