package descriptions, unused imports, etc...

This commit is contained in:
Jimmy Zelinskie 2013-06-23 22:34:13 -04:00
parent 8615347c50
commit e24c5cacc3
7 changed files with 44 additions and 31 deletions

View file

@ -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 (

View file

@ -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
} }

View file

@ -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")
} }

View file

@ -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)

View file

@ -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) {

View file

@ -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() {

View file

@ -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 (