Merge pull request #465 from elotreum/custom-routes
http: allow for customized routes
This commit is contained in:
commit
85d646d1ad
5 changed files with 70 additions and 25 deletions
|
@ -54,6 +54,22 @@ type QueryParams struct {
|
||||||
infoHashes []InfoHash
|
infoHashes []InfoHash
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type routeParamsKey struct{}
|
||||||
|
|
||||||
|
// RouteParamsKey is a key for the context of a request that
|
||||||
|
// contains the named parameters from the http router.
|
||||||
|
var RouteParamsKey = routeParamsKey{}
|
||||||
|
|
||||||
|
// RouteParam is a type that contains the values from the named parameters
|
||||||
|
// on the route.
|
||||||
|
type RouteParam struct {
|
||||||
|
Key string
|
||||||
|
Value string
|
||||||
|
}
|
||||||
|
|
||||||
|
// RouteParams is a collection of RouteParam instances.
|
||||||
|
type RouteParams []RouteParam
|
||||||
|
|
||||||
// ParseURLData parses a request URL or UDP URLData as defined in BEP41.
|
// ParseURLData parses a request URL or UDP URLData as defined in BEP41.
|
||||||
// It expects a concatenated string of the request's path and query parts as
|
// It expects a concatenated string of the request's path and query parts as
|
||||||
// defined in RFC 3986. As both the udp: and http: scheme used by BitTorrent
|
// defined in RFC 3986. As both the udp: and http: scheme used by BitTorrent
|
||||||
|
|
28
dist/example_config.yaml
vendored
28
dist/example_config.yaml
vendored
|
@ -41,15 +41,25 @@ chihaya:
|
||||||
# Disabling this should increase performance/decrease load.
|
# Disabling this should increase performance/decrease load.
|
||||||
enable_request_timing: false
|
enable_request_timing: false
|
||||||
|
|
||||||
# Whether to listen on /announce.php and /scrape.php in addition to their
|
# An array of routes to listen on for announce requests. This is an option
|
||||||
# non-.php counterparts.
|
# to support trackers that do not listen for /announce or need to listen
|
||||||
# This is an option for compatibility with (very) old clients or otherwise
|
# on multiple routes.
|
||||||
# outdated systems.
|
#
|
||||||
# This might be useful to retracker.local users, for more information see
|
# This supports named parameters and catch-all parameters as described at
|
||||||
# http://rutracker.wiki/Оптимизация_обмена_битторрент_траффиком_в_локальных_сетях
|
# https://github.com/julienschmidt/httprouter#named-parameters
|
||||||
# and
|
announce_routes:
|
||||||
# http://rutracker.wiki/Retracker.local
|
- "/announce"
|
||||||
enable_legacy_php_urls: false
|
# - "/announce.php"
|
||||||
|
|
||||||
|
# An array of routes to listen on for scrape requests. This is an option
|
||||||
|
# to support trackers that do not listen for /scrape or need to listen
|
||||||
|
# on multiple routes.
|
||||||
|
#
|
||||||
|
# This supports named parameters and catch-all parameters as described at
|
||||||
|
# https://github.com/julienschmidt/httprouter#named-parameters
|
||||||
|
scrape_routes:
|
||||||
|
- "/scrape"
|
||||||
|
# - "/scrape.php"
|
||||||
|
|
||||||
# When enabled, the IP address used to connect to the tracker will not
|
# When enabled, the IP address used to connect to the tracker will not
|
||||||
# override the value clients advertise as their IP address.
|
# override the value clients advertise as their IP address.
|
||||||
|
|
5
dist/travis/config_memory.yaml
vendored
5
dist/travis/config_memory.yaml
vendored
|
@ -16,7 +16,10 @@ chihaya:
|
||||||
enable_keepalive: false
|
enable_keepalive: false
|
||||||
idle_timeout: 30s
|
idle_timeout: 30s
|
||||||
enable_request_timing: false
|
enable_request_timing: false
|
||||||
enable_legacy_php_urls: false
|
announce_routes:
|
||||||
|
- "/announce"
|
||||||
|
scrape_routes:
|
||||||
|
- "/scrape"
|
||||||
allow_ip_spoofing: false
|
allow_ip_spoofing: false
|
||||||
real_ip_header: "x-real-ip"
|
real_ip_header: "x-real-ip"
|
||||||
max_numwant: 100
|
max_numwant: 100
|
||||||
|
|
5
dist/travis/config_redis.yaml
vendored
5
dist/travis/config_redis.yaml
vendored
|
@ -16,7 +16,10 @@ chihaya:
|
||||||
enable_keepalive: false
|
enable_keepalive: false
|
||||||
idle_timeout: 30s
|
idle_timeout: 30s
|
||||||
enable_request_timing: false
|
enable_request_timing: false
|
||||||
enable_legacy_php_urls: false
|
announce_routes:
|
||||||
|
- "/announce"
|
||||||
|
scrape_routes:
|
||||||
|
- "/scrape"
|
||||||
allow_ip_spoofing: false
|
allow_ip_spoofing: false
|
||||||
real_ip_header: "x-real-ip"
|
real_ip_header: "x-real-ip"
|
||||||
max_numwant: 100
|
max_numwant: 100
|
||||||
|
|
|
@ -29,7 +29,8 @@ type Config struct {
|
||||||
EnableKeepAlive bool `yaml:"enable_keepalive"`
|
EnableKeepAlive bool `yaml:"enable_keepalive"`
|
||||||
TLSCertPath string `yaml:"tls_cert_path"`
|
TLSCertPath string `yaml:"tls_cert_path"`
|
||||||
TLSKeyPath string `yaml:"tls_key_path"`
|
TLSKeyPath string `yaml:"tls_key_path"`
|
||||||
EnableLegacyPHPURLs bool `yaml:"enable_legacy_php_urls"`
|
AnnounceRoutes []string `yaml:"announce_routes"`
|
||||||
|
ScrapeRoutes []string `yaml:"scrape_routes"`
|
||||||
EnableRequestTiming bool `yaml:"enable_request_timing"`
|
EnableRequestTiming bool `yaml:"enable_request_timing"`
|
||||||
ParseOptions `yaml:",inline"`
|
ParseOptions `yaml:",inline"`
|
||||||
}
|
}
|
||||||
|
@ -45,7 +46,8 @@ func (cfg Config) LogFields() log.Fields {
|
||||||
"enableKeepAlive": cfg.EnableKeepAlive,
|
"enableKeepAlive": cfg.EnableKeepAlive,
|
||||||
"tlsCertPath": cfg.TLSCertPath,
|
"tlsCertPath": cfg.TLSCertPath,
|
||||||
"tlsKeyPath": cfg.TLSKeyPath,
|
"tlsKeyPath": cfg.TLSKeyPath,
|
||||||
"enableLegacyPHPURLs": cfg.EnableLegacyPHPURLs,
|
"announceRoutes": cfg.AnnounceRoutes,
|
||||||
|
"scrapeRoutes": cfg.ScrapeRoutes,
|
||||||
"enableRequestTiming": cfg.EnableRequestTiming,
|
"enableRequestTiming": cfg.EnableRequestTiming,
|
||||||
"allowIPSpoofing": cfg.AllowIPSpoofing,
|
"allowIPSpoofing": cfg.AllowIPSpoofing,
|
||||||
"realIPHeader": cfg.RealIPHeader,
|
"realIPHeader": cfg.RealIPHeader,
|
||||||
|
@ -154,6 +156,10 @@ func NewFrontend(logic frontend.TrackerLogic, provided Config) (*Frontend, error
|
||||||
return nil, errors.New("must specify addr or https_addr or both")
|
return nil, errors.New("must specify addr or https_addr or both")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(cfg.AnnounceRoutes) < 1 || len(cfg.ScrapeRoutes) < 1 {
|
||||||
|
return nil, errors.New("must specify routes")
|
||||||
|
}
|
||||||
|
|
||||||
// If TLS is enabled, create a key pair.
|
// If TLS is enabled, create a key pair.
|
||||||
if cfg.TLSCertPath != "" && cfg.TLSKeyPath != "" {
|
if cfg.TLSCertPath != "" && cfg.TLSKeyPath != "" {
|
||||||
var err error
|
var err error
|
||||||
|
@ -236,15 +242,12 @@ func (f *Frontend) makeStopFunc(stopSrv *http.Server) stop.Func {
|
||||||
|
|
||||||
func (f *Frontend) handler() http.Handler {
|
func (f *Frontend) handler() http.Handler {
|
||||||
router := httprouter.New()
|
router := httprouter.New()
|
||||||
router.GET("/announce", f.announceRoute)
|
for _, route := range f.AnnounceRoutes {
|
||||||
router.GET("/scrape", f.scrapeRoute)
|
router.GET(route, f.announceRoute)
|
||||||
|
}
|
||||||
if f.EnableLegacyPHPURLs {
|
for _, route := range f.ScrapeRoutes {
|
||||||
log.Info("http: enabling legacy PHP URLs")
|
router.GET(route, f.scrapeRoute)
|
||||||
router.GET("/announce.php", f.announceRoute)
|
|
||||||
router.GET("/scrape.php", f.scrapeRoute)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return router
|
return router
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,8 +291,16 @@ func (f *Frontend) serveHTTPS(l net.Listener) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func injectRouteParamsToContext(ctx context.Context, ps httprouter.Params) context.Context {
|
||||||
|
rp := bittorrent.RouteParams{}
|
||||||
|
for _, p := range ps {
|
||||||
|
rp = append(rp, bittorrent.RouteParam{Key: p.Key, Value: p.Value})
|
||||||
|
}
|
||||||
|
return context.WithValue(ctx, bittorrent.RouteParamsKey, rp)
|
||||||
|
}
|
||||||
|
|
||||||
// announceRoute parses and responds to an Announce.
|
// announceRoute parses and responds to an Announce.
|
||||||
func (f *Frontend) announceRoute(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
func (f *Frontend) announceRoute(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||||
var err error
|
var err error
|
||||||
var start time.Time
|
var start time.Time
|
||||||
if f.EnableRequestTiming {
|
if f.EnableRequestTiming {
|
||||||
|
@ -312,7 +323,8 @@ func (f *Frontend) announceRoute(w http.ResponseWriter, r *http.Request, _ httpr
|
||||||
af = new(bittorrent.AddressFamily)
|
af = new(bittorrent.AddressFamily)
|
||||||
*af = req.IP.AddressFamily
|
*af = req.IP.AddressFamily
|
||||||
|
|
||||||
ctx, resp, err := f.logic.HandleAnnounce(context.Background(), req)
|
ctx := injectRouteParamsToContext(context.Background(), ps)
|
||||||
|
ctx, resp, err := f.logic.HandleAnnounce(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
WriteError(w, err)
|
WriteError(w, err)
|
||||||
return
|
return
|
||||||
|
@ -329,7 +341,7 @@ func (f *Frontend) announceRoute(w http.ResponseWriter, r *http.Request, _ httpr
|
||||||
}
|
}
|
||||||
|
|
||||||
// scrapeRoute parses and responds to a Scrape.
|
// scrapeRoute parses and responds to a Scrape.
|
||||||
func (f *Frontend) scrapeRoute(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
func (f *Frontend) scrapeRoute(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||||
var err error
|
var err error
|
||||||
var start time.Time
|
var start time.Time
|
||||||
if f.EnableRequestTiming {
|
if f.EnableRequestTiming {
|
||||||
|
@ -370,7 +382,8 @@ func (f *Frontend) scrapeRoute(w http.ResponseWriter, r *http.Request, _ httprou
|
||||||
af = new(bittorrent.AddressFamily)
|
af = new(bittorrent.AddressFamily)
|
||||||
*af = req.AddressFamily
|
*af = req.AddressFamily
|
||||||
|
|
||||||
ctx, resp, err := f.logic.HandleScrape(context.Background(), req)
|
ctx := injectRouteParamsToContext(context.Background(), ps)
|
||||||
|
ctx, resp, err := f.logic.HandleScrape(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
WriteError(w, err)
|
WriteError(w, err)
|
||||||
return
|
return
|
||||||
|
|
Loading…
Reference in a new issue