package descriptions, unused imports, etc...
This commit is contained in:
parent
8615347c50
commit
e24c5cacc3
7 changed files with 44 additions and 31 deletions
|
@ -2,6 +2,7 @@
|
||||||
// Use of this source code is governed by the BSD 2-Clause license,
|
// Use of this source code is governed by the BSD 2-Clause license,
|
||||||
// which can be found in the LICENSE file.
|
// which can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package config implements the configuration for a BitTorrent tracker
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -14,32 +14,32 @@ import (
|
||||||
|
|
||||||
func (s *Server) serveAnnounce(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) serveAnnounce(w http.ResponseWriter, r *http.Request) {
|
||||||
passkey, _ := path.Split(r.URL.Path)
|
passkey, _ := path.Split(r.URL.Path)
|
||||||
user, err := validatePasskey(passkey, s.storage)
|
_, err := validatePasskey(passkey, s.storage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fail(err, w)
|
fail(err, w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
pq, err := parseQuery(r.URL.RawQuery)
|
pq, err := parseQuery(r.URL.RawQuery)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fail(errors.New("Error parsing query"), w)
|
fail(errors.New("Error parsing query"), w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ip, err := pq.determineIP(r)
|
_, err = pq.determineIP(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fail(err, w)
|
fail(err, w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = pq.validate()
|
err = pq.validate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fail(errors.New("Malformed request"), w)
|
fail(errors.New("Malformed request"), w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !s.conf.Whitelisted(pq.params["peerId"]) {
|
if !s.conf.Whitelisted(pq.params["peerId"]) {
|
||||||
fail(errors.New("Your client is not approved"), w)
|
fail(errors.New("Your client is not approved"), w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ func (s *Server) serveAnnounce(w http.ResponseWriter, r *http.Request) {
|
||||||
log.Panicf("server: %s", err)
|
log.Panicf("server: %s", err)
|
||||||
}
|
}
|
||||||
if !exists {
|
if !exists {
|
||||||
fail(errors.New("This torrent does not exist"), w)
|
fail(errors.New("This torrent does not exist"), w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,6 +66,7 @@ func (s *Server) serveAnnounce(w http.ResponseWriter, r *http.Request) {
|
||||||
left,
|
left,
|
||||||
),
|
),
|
||||||
w,
|
w,
|
||||||
|
r,
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,27 +97,27 @@ func parseQuery(query string) (*parsedQuery, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pq *parsedQuery) validate() error {
|
func (pq *parsedQuery) validate() error {
|
||||||
infohash, ok := pq.params["info_hash"]
|
infohash, _ := pq.params["info_hash"]
|
||||||
if infohash == "" {
|
if infohash == "" {
|
||||||
return errors.New("infohash does not exist")
|
return errors.New("infohash does not exist")
|
||||||
}
|
}
|
||||||
peerId, ok := pq.params["peer_id"]
|
peerId, _ := pq.params["peer_id"]
|
||||||
if peerId == "" {
|
if peerId == "" {
|
||||||
return errors.New("peerId does not exist")
|
return errors.New("peerId does not exist")
|
||||||
}
|
}
|
||||||
port, ok := pq.getUint64("port")
|
_, ok := pq.getUint64("port")
|
||||||
if ok == false {
|
if ok == false {
|
||||||
return errors.New("port does not exist")
|
return errors.New("port does not exist")
|
||||||
}
|
}
|
||||||
uploaded, ok := pq.getUint64("uploaded")
|
_, ok = pq.getUint64("uploaded")
|
||||||
if ok == false {
|
if ok == false {
|
||||||
return errors.New("uploaded does not exist")
|
return errors.New("uploaded does not exist")
|
||||||
}
|
}
|
||||||
downloaded, ok := pq.getUint64("downloaded")
|
_, ok = pq.getUint64("downloaded")
|
||||||
if ok == false {
|
if ok == false {
|
||||||
return errors.New("downloaded does not exist")
|
return errors.New("downloaded does not exist")
|
||||||
}
|
}
|
||||||
left, ok := pq.getUint64("left")
|
_, ok = pq.getUint64("left")
|
||||||
if ok == false {
|
if ok == false {
|
||||||
return errors.New("left does not exist")
|
return errors.New("left does not exist")
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"path"
|
"path"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -20,13 +21,13 @@ func (s *Server) serveScrape(w http.ResponseWriter, r *http.Request) {
|
||||||
passkey, _ := path.Split(r.URL.Path)
|
passkey, _ := path.Split(r.URL.Path)
|
||||||
_, err := validatePasskey(passkey, s.storage)
|
_, err := validatePasskey(passkey, s.storage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fail(err, w)
|
fail(err, w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
pq, err := parseQuery(r.URL.RawQuery)
|
pq, err := parseQuery(r.URL.RawQuery)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fail(errors.New("Error parsing query"), w)
|
fail(errors.New("Error parsing query"), w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +37,7 @@ func (s *Server) serveScrape(w http.ResponseWriter, r *http.Request) {
|
||||||
for _, infohash := range pq.infohashes {
|
for _, infohash := range pq.infohashes {
|
||||||
torrent, exists, err := s.storage.FindTorrent(infohash)
|
torrent, exists, err := s.storage.FindTorrent(infohash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("server: failed to find torrent")
|
log.Panicf("server: %s", err)
|
||||||
}
|
}
|
||||||
if exists {
|
if exists {
|
||||||
bencode(w, infohash)
|
bencode(w, infohash)
|
||||||
|
@ -46,7 +47,7 @@ func (s *Server) serveScrape(w http.ResponseWriter, r *http.Request) {
|
||||||
} else if infohash, exists := pq.params["info_hash"]; exists {
|
} else if infohash, exists := pq.params["info_hash"]; exists {
|
||||||
torrent, exists, err := s.storage.FindTorrent(infohash)
|
torrent, exists, err := s.storage.FindTorrent(infohash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("server: failed to find torrent")
|
log.Panicf("server: %s", err)
|
||||||
}
|
}
|
||||||
if exists {
|
if exists {
|
||||||
bencode(w, infohash)
|
bencode(w, infohash)
|
||||||
|
@ -54,7 +55,11 @@ func (s *Server) serveScrape(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
io.WriteString(w, "e")
|
io.WriteString(w, "e")
|
||||||
finalizeResponse(w, r)
|
|
||||||
|
r.Close = true
|
||||||
|
w.Header().Add("Content-Type", "text/plain")
|
||||||
|
w.Header().Add("Connection", "close")
|
||||||
|
w.(http.Flusher).Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeScrapeInfo(w io.Writer, torrent *storage.Torrent) {
|
func writeScrapeInfo(w io.Writer, torrent *storage.Torrent) {
|
||||||
|
@ -69,6 +74,7 @@ func writeScrapeInfo(w io.Writer, torrent *storage.Torrent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func bencode(w io.Writer, data interface{}) {
|
func bencode(w io.Writer, data interface{}) {
|
||||||
|
// A massive switch is faster than reflection
|
||||||
switch v := data.(type) {
|
switch v := data.(type) {
|
||||||
case string:
|
case string:
|
||||||
str := fmt.Sprintf("%s:%s", strconv.Itoa(len(v)), v)
|
str := fmt.Sprintf("%s:%s", strconv.Itoa(len(v)), v)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// Use of this source code is governed by the BSD 2-Clause license,
|
// Use of this source code is governed by the BSD 2-Clause license,
|
||||||
// which can be found in the LICENSE file.
|
// which can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package server implements a BitTorrent tracker
|
||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -90,7 +91,6 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
s.waitgroup.Add(1)
|
s.waitgroup.Add(1)
|
||||||
defer s.waitgroup.Done()
|
defer s.waitgroup.Done()
|
||||||
defer atomic.AddInt64(&s.deltaRequests, 1)
|
defer atomic.AddInt64(&s.deltaRequests, 1)
|
||||||
defer finalizeResponse(w, r)
|
|
||||||
|
|
||||||
if r.URL.Path == "/stats" {
|
if r.URL.Path == "/stats" {
|
||||||
s.serveStats(w, r)
|
s.serveStats(w, r)
|
||||||
|
@ -106,19 +106,12 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
s.serveScrape(w, r)
|
s.serveScrape(w, r)
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
fail(errors.New("Unknown action"), w)
|
fail(errors.New("Unknown action"), w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func finalizeResponse(w http.ResponseWriter, r *http.Request) {
|
func fail(err error, w http.ResponseWriter, r *http.Request) {
|
||||||
r.Close = true
|
|
||||||
w.Header().Add("Content-Type", "text/plain")
|
|
||||||
w.Header().Add("Connection", "close")
|
|
||||||
w.(http.Flusher).Flush()
|
|
||||||
}
|
|
||||||
|
|
||||||
func fail(err error, w http.ResponseWriter) {
|
|
||||||
errmsg := err.Error()
|
errmsg := err.Error()
|
||||||
message := fmt.Sprintf(
|
message := fmt.Sprintf(
|
||||||
"%s%s%s%s%s",
|
"%s%s%s%s%s",
|
||||||
|
@ -128,7 +121,12 @@ func fail(err error, w http.ResponseWriter) {
|
||||||
errmsg,
|
errmsg,
|
||||||
"e",
|
"e",
|
||||||
)
|
)
|
||||||
io.WriteString(w, message)
|
length, _ := io.WriteString(w, message)
|
||||||
|
r.Close = true
|
||||||
|
w.Header().Add("Content-Type", "text/plain")
|
||||||
|
w.Header().Add("Content-Length", string(length))
|
||||||
|
w.Header().Add("Connection", "close")
|
||||||
|
w.(http.Flusher).Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
func validatePasskey(dir string, s storage.Storage) (*storage.User, error) {
|
func validatePasskey(dir string, s storage.Storage) (*storage.User, error) {
|
||||||
|
|
|
@ -23,7 +23,12 @@ func (s *Server) serveStats(w http.ResponseWriter, r *http.Request) {
|
||||||
config.Duration{time.Now().Sub(s.startTime)},
|
config.Duration{time.Now().Sub(s.startTime)},
|
||||||
s.rpm,
|
s.rpm,
|
||||||
})
|
})
|
||||||
w.Write(stats)
|
|
||||||
|
length, _ := w.Write(stats)
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.Header().Set("Content-Length", string(length))
|
||||||
|
w.Header().Set("Connection", "close")
|
||||||
|
w.(http.Flusher).Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) updateRPM() {
|
func (s *Server) updateRPM() {
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
// Use of this source code is governed by the BSD 2-Clause license,
|
// Use of this source code is governed by the BSD 2-Clause license,
|
||||||
// which can be found in the LICENSE file.
|
// which can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package storage provides a generic interface for manipulating a
|
||||||
|
// BitTorrent tracker's data store.
|
||||||
package storage
|
package storage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
Loading…
Reference in a new issue