Move tracker-specific logic out of http/query and into http

This commit is contained in:
Justin Li
2014-07-23 15:56:15 -04:00
parent 9292900afc
commit 98542c0ff1
3 changed files with 97 additions and 96 deletions
+93 -2
View File
@@ -5,7 +5,11 @@
package http
import (
"errors"
"net"
"net/http"
"strconv"
"strings"
"github.com/julienschmidt/httprouter"
@@ -23,7 +27,7 @@ func NewAnnounce(cfg *config.Config, r *http.Request, p httprouter.Params) (*mod
compact := q.Params["compact"] != "0"
event, _ := q.Params["event"]
numWant := q.RequestedPeerCount(cfg.NumWantFallback)
numWant := requestedPeerCount(q, cfg.NumWantFallback)
infohash, exists := q.Params["info_hash"]
if !exists {
@@ -35,7 +39,7 @@ func NewAnnounce(cfg *config.Config, r *http.Request, p httprouter.Params) (*mod
return nil, models.ErrMalformedRequest
}
ipv4, ipv6, err := q.RequestedIP(r, &cfg.NetConfig)
ipv4, ipv6, err := requestedIP(q, r, &cfg.NetConfig)
if err != nil {
return nil, models.ErrMalformedRequest
}
@@ -99,3 +103,90 @@ func NewScrape(cfg *config.Config, r *http.Request, p httprouter.Params) (*model
Infohashes: q.Infohashes,
}, nil
}
// requestedPeerCount returns the wanted peer count or the provided fallback.
func requestedPeerCount(q *query.Query, fallback int) int {
if numWantStr, exists := q.Params["numwant"]; exists {
numWant, err := strconv.Atoi(numWantStr)
if err != nil {
return fallback
}
return numWant
}
return fallback
}
// requestedIP returns the IP addresses for a request. If there are multiple
// IP addresses in the request, one IPv4 and one IPv6 will be returned.
func requestedIP(q *query.Query, r *http.Request, cfg *config.NetConfig) (v4, v6 net.IP, err error) {
var done bool
if cfg.AllowIPSpoofing {
if str, ok := q.Params["ip"]; ok {
if v4, v6, done = getIPs(str, v4, v6, cfg); done {
return
}
}
if str, ok := q.Params["ipv4"]; ok {
if v4, v6, done = getIPs(str, v4, v6, cfg); done {
return
}
}
if str, ok := q.Params["ipv6"]; ok {
if v4, v6, done = getIPs(str, v4, v6, cfg); done {
return
}
}
}
if cfg.RealIPHeader != "" {
if xRealIPs, ok := q.Params[cfg.RealIPHeader]; ok {
if v4, v6, done = getIPs(string(xRealIPs[0]), v4, v6, cfg); done {
return
}
}
} else {
if r.RemoteAddr == "" {
if v4 == nil {
v4 = net.ParseIP("127.0.0.1")
}
return
}
if idx := strings.LastIndex(r.RemoteAddr, ":"); idx != -1 {
if v4, v6, done = getIPs(r.RemoteAddr[0:idx], v4, v6, cfg); done {
return
}
}
}
if v4 == nil && v6 == nil {
err = errors.New("failed to parse IP address")
}
return
}
func getIPs(ipstr string, ipv4, ipv6 net.IP, cfg *config.NetConfig) (net.IP, net.IP, bool) {
var done bool
if ip := net.ParseIP(ipstr); ip != nil {
newIPv4 := ip.To4()
if ipv4 == nil && newIPv4 != nil {
ipv4 = newIPv4
} else if ipv6 == nil && newIPv4 == nil {
ipv6 = ip
}
}
if cfg.DualStackedPeers {
done = ipv4 != nil && ipv6 != nil
} else {
done = ipv4 != nil || ipv6 != nil
}
return ipv4, ipv6, done
}