mirror of
https://github.com/dutchcoders/transfer.sh.git
synced 2024-11-26 22:20:18 +01:00
Implement rate limiting option, fixes #71
This commit is contained in:
parent
989debecb5
commit
2f35235865
3 changed files with 43 additions and 17 deletions
10
cmd/cmd.go
10
cmd/cmd.go
|
@ -95,6 +95,12 @@ var globalFlags = []cli.Flag{
|
||||||
Value: "",
|
Value: "",
|
||||||
EnvVar: "BUCKET",
|
EnvVar: "BUCKET",
|
||||||
},
|
},
|
||||||
|
cli.IntFlag{
|
||||||
|
Name: "rate-limit",
|
||||||
|
Usage: "requests per minute",
|
||||||
|
Value: 0,
|
||||||
|
EnvVar: "",
|
||||||
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "lets-encrypt-hosts",
|
Name: "lets-encrypt-hosts",
|
||||||
Usage: "host1, host2",
|
Usage: "host1, host2",
|
||||||
|
@ -190,6 +196,10 @@ func New() *Cmd {
|
||||||
options = append(options, server.ClamavHost(v))
|
options = append(options, server.ClamavHost(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if v := c.Int("rate-limit"); v > 0 {
|
||||||
|
options = append(options, server.RateLimit(v))
|
||||||
|
}
|
||||||
|
|
||||||
if cert := c.String("tls-cert-file"); cert == "" {
|
if cert := c.String("tls-cert-file"); cert == "" {
|
||||||
} else if pk := c.String("tls-private-key"); pk == "" {
|
} else if pk := c.String("tls-private-key"); pk == "" {
|
||||||
} else {
|
} else {
|
||||||
|
|
23
lock.json
23
lock.json
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"memo": "332a50078a5c89ced2186b6c9b5e55af4ac02ba87d5990e840080683f703ca9a",
|
"memo": "5b27aecb0272e40f3b8b8f9a5deeb7c9f5dbf06c53b1134de2b84eac466d27e0",
|
||||||
"projects": [
|
"projects": [
|
||||||
{
|
{
|
||||||
"name": "github.com/PuerkitoBio/ghost",
|
"name": "github.com/PuerkitoBio/ghost",
|
||||||
|
@ -10,6 +10,15 @@
|
||||||
"handlers"
|
"handlers"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "github.com/VojtechVitek/ratelimit",
|
||||||
|
"branch": "master",
|
||||||
|
"revision": "dc172bc0f6d241e980010dbc63957ef1a2c8ca33",
|
||||||
|
"packages": [
|
||||||
|
".",
|
||||||
|
"memory"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "github.com/dutchcoders/go-clamd",
|
"name": "github.com/dutchcoders/go-clamd",
|
||||||
"branch": "master",
|
"branch": "master",
|
||||||
|
@ -100,14 +109,6 @@
|
||||||
"."
|
"."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "github.com/kennygrant/sanitize",
|
|
||||||
"version": "v1.2",
|
|
||||||
"revision": "6a0bfdde8629a3a3a7418a7eae45c54154692514",
|
|
||||||
"packages": [
|
|
||||||
"."
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "github.com/mattn/go-colorable",
|
"name": "github.com/mattn/go-colorable",
|
||||||
"version": "v0.0.7",
|
"version": "v0.0.7",
|
||||||
|
@ -179,9 +180,7 @@
|
||||||
"revision": "a6577fac2d73be281a500b310739095313165611",
|
"revision": "a6577fac2d73be281a500b310739095313165611",
|
||||||
"packages": [
|
"packages": [
|
||||||
"context",
|
"context",
|
||||||
"context/ctxhttp",
|
"context/ctxhttp"
|
||||||
"html",
|
|
||||||
"html/atom"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -42,6 +42,8 @@ import (
|
||||||
context "golang.org/x/net/context"
|
context "golang.org/x/net/context"
|
||||||
|
|
||||||
"github.com/PuerkitoBio/ghost/handlers"
|
"github.com/PuerkitoBio/ghost/handlers"
|
||||||
|
"github.com/VojtechVitek/ratelimit"
|
||||||
|
"github.com/VojtechVitek/ratelimit/memory"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
|
||||||
_ "net/http/pprof"
|
_ "net/http/pprof"
|
||||||
|
@ -116,6 +118,12 @@ func LogFile(s string) OptionFn {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RateLimit(requests int) OptionFn {
|
||||||
|
return func(srvr *Server) {
|
||||||
|
srvr.rateLimitRequests = requests
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func ForceHTTPs() OptionFn {
|
func ForceHTTPs() OptionFn {
|
||||||
return func(srvr *Server) {
|
return func(srvr *Server) {
|
||||||
srvr.forceHTTPs = true
|
srvr.forceHTTPs = true
|
||||||
|
@ -180,6 +188,8 @@ type Server struct {
|
||||||
|
|
||||||
locks map[string]*sync.Mutex
|
locks map[string]*sync.Mutex
|
||||||
|
|
||||||
|
rateLimitRequests int
|
||||||
|
|
||||||
storage Storage
|
storage Storage
|
||||||
|
|
||||||
forceHTTPs bool
|
forceHTTPs bool
|
||||||
|
@ -267,10 +277,12 @@ func (s *Server) Run() {
|
||||||
r.PathPrefix("/favicon.ico").Handler(staticHandler)
|
r.PathPrefix("/favicon.ico").Handler(staticHandler)
|
||||||
r.PathPrefix("/robots.txt").Handler(staticHandler)
|
r.PathPrefix("/robots.txt").Handler(staticHandler)
|
||||||
|
|
||||||
|
r.HandleFunc("/health.html", healthHandler).Methods("GET")
|
||||||
|
r.HandleFunc("/", s.viewHandler).Methods("GET")
|
||||||
|
|
||||||
r.HandleFunc("/({files:.*}).zip", s.zipHandler).Methods("GET")
|
r.HandleFunc("/({files:.*}).zip", s.zipHandler).Methods("GET")
|
||||||
r.HandleFunc("/({files:.*}).tar", s.tarHandler).Methods("GET")
|
r.HandleFunc("/({files:.*}).tar", s.tarHandler).Methods("GET")
|
||||||
r.HandleFunc("/({files:.*}).tar.gz", s.tarGzHandler).Methods("GET")
|
r.HandleFunc("/({files:.*}).tar.gz", s.tarGzHandler).Methods("GET")
|
||||||
r.HandleFunc("/download/{token}/{filename}", s.getHandler).Methods("GET")
|
|
||||||
|
|
||||||
r.HandleFunc("/{token}/{filename}", s.previewHandler).MatcherFunc(func(r *http.Request, rm *mux.RouteMatch) (match bool) {
|
r.HandleFunc("/{token}/{filename}", s.previewHandler).MatcherFunc(func(r *http.Request, rm *mux.RouteMatch) (match bool) {
|
||||||
match = false
|
match = false
|
||||||
|
@ -294,17 +306,22 @@ func (s *Server) Run() {
|
||||||
return
|
return
|
||||||
}).Methods("GET")
|
}).Methods("GET")
|
||||||
|
|
||||||
r.HandleFunc("/{token}/{filename}", s.getHandler).Methods("GET")
|
getHandlerFn := s.getHandler
|
||||||
r.HandleFunc("/get/{token}/{filename}", s.getHandler).Methods("GET")
|
if s.rateLimitRequests > 0 {
|
||||||
|
getHandlerFn = ratelimit.Request(ratelimit.IP).Rate(s.rateLimitRequests, 60*time.Second).LimitBy(memory.New())(http.HandlerFunc(getHandlerFn)).ServeHTTP
|
||||||
|
}
|
||||||
|
|
||||||
|
r.HandleFunc("/{token}/{filename}", getHandlerFn).Methods("GET")
|
||||||
|
r.HandleFunc("/get/{token}/{filename}", getHandlerFn).Methods("GET")
|
||||||
|
r.HandleFunc("/download/{token}/{filename}", getHandlerFn).Methods("GET")
|
||||||
|
|
||||||
r.HandleFunc("/{filename}/virustotal", s.virusTotalHandler).Methods("PUT")
|
r.HandleFunc("/{filename}/virustotal", s.virusTotalHandler).Methods("PUT")
|
||||||
r.HandleFunc("/{filename}/scan", s.scanHandler).Methods("PUT")
|
r.HandleFunc("/{filename}/scan", s.scanHandler).Methods("PUT")
|
||||||
r.HandleFunc("/put/{filename}", s.putHandler).Methods("PUT")
|
r.HandleFunc("/put/{filename}", s.putHandler).Methods("PUT")
|
||||||
r.HandleFunc("/upload/{filename}", s.putHandler).Methods("PUT")
|
r.HandleFunc("/upload/{filename}", s.putHandler).Methods("PUT")
|
||||||
r.HandleFunc("/{filename}", s.putHandler).Methods("PUT")
|
r.HandleFunc("/{filename}", s.putHandler).Methods("PUT")
|
||||||
r.HandleFunc("/health.html", healthHandler).Methods("GET")
|
|
||||||
r.HandleFunc("/", s.postHandler).Methods("POST")
|
r.HandleFunc("/", s.postHandler).Methods("POST")
|
||||||
// r.HandleFunc("/{page}", viewHandler).Methods("GET")
|
// r.HandleFunc("/{page}", viewHandler).Methods("GET")
|
||||||
r.HandleFunc("/", s.viewHandler).Methods("GET")
|
|
||||||
|
|
||||||
r.NotFoundHandler = http.HandlerFunc(s.notFoundHandler)
|
r.NotFoundHandler = http.HandlerFunc(s.notFoundHandler)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue