mirror of
https://github.com/sot-tech/mochi.git
synced 2026-05-23 08:14:48 -07:00
make it compile!
This commit is contained in:
@@ -32,14 +32,9 @@ func ParseAnnounce(r *http.Request, realIPHeader string, allowIPSpoofing bool) (
|
||||
return nil, err
|
||||
}
|
||||
|
||||
request := &bittorrent.AnnounceRequest{Params: q}
|
||||
request := &bittorrent.AnnounceRequest{Params: qp}
|
||||
|
||||
eventStr, err := qp.String("event")
|
||||
if err == query.ErrKeyNotFound {
|
||||
eventStr = ""
|
||||
} else if err != nil {
|
||||
return nil, bittorrent.ClientError("failed to parse parameter: event")
|
||||
}
|
||||
eventStr, _ := qp.String("event")
|
||||
request.Event, err = bittorrent.NewEvent(eventStr)
|
||||
if err != nil {
|
||||
return nil, bittorrent.ClientError("failed to provide valid client event")
|
||||
@@ -57,14 +52,14 @@ func ParseAnnounce(r *http.Request, realIPHeader string, allowIPSpoofing bool) (
|
||||
}
|
||||
request.InfoHash = infoHashes[0]
|
||||
|
||||
peerID, err := qp.String("peer_id")
|
||||
if err != nil {
|
||||
peerID, ok := qp.String("peer_id")
|
||||
if !ok {
|
||||
return nil, bittorrent.ClientError("failed to parse parameter: peer_id")
|
||||
}
|
||||
if len(peerID) != 20 {
|
||||
return nil, bittorrent.ClientError("failed to provide valid peer_id")
|
||||
}
|
||||
request.PeerID = bittorrent.PeerIDFromString(peerID)
|
||||
request.Peer.ID = bittorrent.PeerIDFromString(peerID)
|
||||
|
||||
request.Left, err = qp.Uint64("left")
|
||||
if err != nil {
|
||||
@@ -85,24 +80,24 @@ func ParseAnnounce(r *http.Request, realIPHeader string, allowIPSpoofing bool) (
|
||||
if err != nil {
|
||||
return nil, bittorrent.ClientError("failed to parse parameter: numwant")
|
||||
}
|
||||
request.NumWant = int32(numwant)
|
||||
request.NumWant = uint32(numwant)
|
||||
|
||||
port, err := qp.Uint64("port")
|
||||
if err != nil {
|
||||
return nil, bittorrent.ClientError("failed to parse parameter: port")
|
||||
}
|
||||
request.Port = uint16(port)
|
||||
request.Peer.Port = uint16(port)
|
||||
|
||||
request.IP, err = requestedIP(q, r, realIPHeader, allowIPSpoofing)
|
||||
if err != nil {
|
||||
return nil, bittorrent.ClientError("failed to parse peer IP address: " + err.Error())
|
||||
request.Peer.IP = requestedIP(r, qp, realIPHeader, allowIPSpoofing)
|
||||
if request.Peer.IP == nil {
|
||||
return nil, bittorrent.ClientError("failed to parse peer IP address")
|
||||
}
|
||||
|
||||
return request, nil
|
||||
}
|
||||
|
||||
// ParseScrape parses an bittorrent.ScrapeRequest from an http.Request.
|
||||
func ParseScrape(r *http.Request) (*bittorent.ScrapeRequest, error) {
|
||||
func ParseScrape(r *http.Request) (*bittorrent.ScrapeRequest, error) {
|
||||
qp, err := NewQueryParams(r.URL.RawQuery)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -115,7 +110,7 @@ func ParseScrape(r *http.Request) (*bittorent.ScrapeRequest, error) {
|
||||
|
||||
request := &bittorrent.ScrapeRequest{
|
||||
InfoHashes: infoHashes,
|
||||
Params: q,
|
||||
Params: qp,
|
||||
}
|
||||
|
||||
return request, nil
|
||||
@@ -126,46 +121,31 @@ func ParseScrape(r *http.Request) (*bittorent.ScrapeRequest, error) {
|
||||
// If allowIPSpoofing is true, IPs provided via params will be used.
|
||||
// If realIPHeader is not empty string, the first value of the HTTP Header with
|
||||
// that name will be used.
|
||||
func requestedIP(r *http.Request, p bittorent.Params, realIPHeader string, allowIPSpoofing bool) (net.IP, error) {
|
||||
func requestedIP(r *http.Request, p bittorrent.Params, realIPHeader string, allowIPSpoofing bool) net.IP {
|
||||
if allowIPSpoofing {
|
||||
if ipstr, err := p.String("ip"); err == nil {
|
||||
ip, err := net.ParseIP(str)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ip, nil
|
||||
if ipstr, ok := p.String("ip"); ok {
|
||||
ip := net.ParseIP(ipstr)
|
||||
return ip
|
||||
}
|
||||
|
||||
if ipstr, err := p.String("ipv4"); err == nil {
|
||||
ip, err := net.ParseIP(str)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ip, nil
|
||||
if ipstr, ok := p.String("ipv4"); ok {
|
||||
ip := net.ParseIP(ipstr)
|
||||
return ip
|
||||
}
|
||||
|
||||
if ipstr, err := p.String("ipv6"); err == nil {
|
||||
ip, err := net.ParseIP(str)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ip, nil
|
||||
if ipstr, ok := p.String("ipv6"); ok {
|
||||
ip := net.ParseIP(ipstr)
|
||||
return ip
|
||||
}
|
||||
}
|
||||
|
||||
if realIPHeader != "" {
|
||||
if ips, ok := r.Header[realIPHeader]; ok && len(ips) > 0 {
|
||||
ip, err := net.ParseIP(ips[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ip, nil
|
||||
ip := net.ParseIP(ips[0])
|
||||
return ip
|
||||
}
|
||||
}
|
||||
|
||||
return r.RemoteAddr
|
||||
host, _, _ := net.SplitHostPort(r.RemoteAddr)
|
||||
return net.ParseIP(host)
|
||||
}
|
||||
|
||||
@@ -40,14 +40,14 @@ type QueryParams struct {
|
||||
}
|
||||
|
||||
// NewQueryParams parses a raw URL query.
|
||||
func NewQueryParams(query string) (*Query, error) {
|
||||
func NewQueryParams(query string) (*QueryParams, error) {
|
||||
var (
|
||||
keyStart, keyEnd int
|
||||
valStart, valEnd int
|
||||
|
||||
onKey = true
|
||||
|
||||
q = &Query{
|
||||
q = &QueryParams{
|
||||
query: query,
|
||||
infoHashes: nil,
|
||||
params: make(map[string]string),
|
||||
@@ -111,18 +111,15 @@ func NewQueryParams(query string) (*Query, error) {
|
||||
|
||||
// String returns a string parsed from a query. Every key can be returned as a
|
||||
// string because they are encoded in the URL as strings.
|
||||
func (q *Query) String(key string) (string, error) {
|
||||
val, exists := q.params[key]
|
||||
if !exists {
|
||||
return "", ErrKeyNotFound
|
||||
}
|
||||
return val, nil
|
||||
func (qp *QueryParams) String(key string) (string, bool) {
|
||||
value, ok := qp.params[key]
|
||||
return value, ok
|
||||
}
|
||||
|
||||
// Uint64 returns a uint parsed from a query. After being called, it is safe to
|
||||
// cast the uint64 to your desired length.
|
||||
func (q *Query) Uint64(key string) (uint64, error) {
|
||||
str, exists := q.params[key]
|
||||
func (qp *QueryParams) Uint64(key string) (uint64, error) {
|
||||
str, exists := qp.params[key]
|
||||
if !exists {
|
||||
return 0, ErrKeyNotFound
|
||||
}
|
||||
@@ -136,6 +133,6 @@ func (q *Query) Uint64(key string) (uint64, error) {
|
||||
}
|
||||
|
||||
// InfoHashes returns a list of requested infohashes.
|
||||
func (q *Query) InfoHashes() []bittorrent.InfoHash {
|
||||
return q.infoHashes
|
||||
func (qp *QueryParams) InfoHashes() []bittorrent.InfoHash {
|
||||
return qp.infoHashes
|
||||
}
|
||||
|
||||
@@ -16,6 +16,19 @@
|
||||
// described in BEP 3 and BEP 23.
|
||||
package http
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/tylerb/graceful"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/jzelinskie/trakr/bittorrent"
|
||||
)
|
||||
|
||||
var promResponseDurationMilliseconds = prometheus.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
Name: "trakr_http_response_duration_milliseconds",
|
||||
@@ -27,9 +40,14 @@ var promResponseDurationMilliseconds = prometheus.NewHistogramVec(
|
||||
|
||||
// recordResponseDuration records the duration of time to respond to a UDP
|
||||
// Request in milliseconds .
|
||||
func recordResponseDuration(action, err error, duration time.Duration) {
|
||||
func recordResponseDuration(action string, err error, duration time.Duration) {
|
||||
var errString string
|
||||
if err != nil {
|
||||
errString = err.Error()
|
||||
}
|
||||
|
||||
promResponseDurationMilliseconds.
|
||||
WithLabelValues(action, err.Error()).
|
||||
WithLabelValues(action, errString).
|
||||
Observe(float64(duration.Nanoseconds()) / float64(time.Millisecond))
|
||||
}
|
||||
|
||||
@@ -53,8 +71,8 @@ type Tracker struct {
|
||||
}
|
||||
|
||||
// NewTracker allocates a new instance of a Tracker.
|
||||
func NewTracker(funcs bittorrent.TrackerFuncs, cfg Config) {
|
||||
return &Server{
|
||||
func NewTracker(funcs bittorrent.TrackerFuncs, cfg Config) *Tracker {
|
||||
return &Tracker{
|
||||
TrackerFuncs: funcs,
|
||||
Config: cfg,
|
||||
}
|
||||
@@ -66,11 +84,11 @@ func (t *Tracker) Stop() {
|
||||
<-t.grace.StopChan()
|
||||
}
|
||||
|
||||
func (t *Tracker) handler() {
|
||||
func (t *Tracker) handler() http.Handler {
|
||||
router := httprouter.New()
|
||||
router.GET("/announce", t.announceRoute)
|
||||
router.GET("/scrape", t.scrapeRoute)
|
||||
return server
|
||||
return router
|
||||
}
|
||||
|
||||
// ListenAndServe listens on the TCP network address t.Addr and blocks serving
|
||||
@@ -111,18 +129,15 @@ func (t *Tracker) ListenAndServe() error {
|
||||
panic("http: failed to gracefully run HTTP server: " + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// announceRoute parses and responds to an Announce by using t.TrackerFuncs.
|
||||
func (t *Tracker) announceRoute(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
||||
var err error
|
||||
start := time.Now()
|
||||
defer func() {
|
||||
var errString string
|
||||
if err != nil {
|
||||
errString = err.Error()
|
||||
}
|
||||
recordResponseDuration("announce", errString, time.Since(start))
|
||||
}()
|
||||
defer recordResponseDuration("announce", err, time.Since(start))
|
||||
|
||||
req, err := ParseAnnounce(r, t.RealIPHeader, t.AllowIPSpoofing)
|
||||
if err != nil {
|
||||
@@ -130,7 +145,7 @@ func (t *Tracker) announceRoute(w http.ResponseWriter, r *http.Request, _ httpro
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := t.HandleAnnounce(req)
|
||||
resp, err := t.HandleAnnounce(context.TODO(), req)
|
||||
if err != nil {
|
||||
WriteError(w, err)
|
||||
return
|
||||
@@ -145,19 +160,13 @@ func (t *Tracker) announceRoute(w http.ResponseWriter, r *http.Request, _ httpro
|
||||
if t.AfterAnnounce != nil {
|
||||
go t.AfterAnnounce(req, resp)
|
||||
}
|
||||
recordResponseDuration("announce")
|
||||
}
|
||||
|
||||
// scrapeRoute parses and responds to a Scrape by using t.TrackerFuncs.
|
||||
func (t *Tracker) scrapeRoute(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
||||
var err error
|
||||
start := time.Now()
|
||||
defer func() {
|
||||
var errString string
|
||||
if err != nil {
|
||||
errString = err.Error()
|
||||
}
|
||||
recordResponseDuration("scrape", errString, time.Since(start))
|
||||
}()
|
||||
defer recordResponseDuration("scrape", err, time.Since(start))
|
||||
|
||||
req, err := ParseScrape(r)
|
||||
if err != nil {
|
||||
@@ -165,7 +174,7 @@ func (t *Tracker) scrapeRoute(w http.ResponseWriter, r *http.Request, _ httprout
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := t.HandleScrape(req)
|
||||
resp, err := t.HandleScrape(context.TODO(), req)
|
||||
if err != nil {
|
||||
WriteError(w, err)
|
||||
return
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/jzelinskie/trakr/bittorrent"
|
||||
"github.com/jzelinskie/trakr/bittorrent/http/bencode"
|
||||
)
|
||||
|
||||
// WriteError communicates an error to a BitTorrent client over HTTP.
|
||||
|
||||
@@ -18,8 +18,9 @@ import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/jzelinskie/trakr/bittorrent"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/jzelinskie/trakr/bittorrent"
|
||||
)
|
||||
|
||||
func TestWriteError(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user