first pass with linter

This commit is contained in:
Jimmy Zelinskie 2014-05-01 00:30:46 -04:00
parent f0bed27b6d
commit b32eaebcd6
9 changed files with 80 additions and 25 deletions

View file

@ -12,14 +12,17 @@ import (
"time" "time"
) )
// Duration wraps a time.Duration and adds JSON marshalling.
type Duration struct { type Duration struct {
time.Duration time.Duration
} }
// MarshalJSON transforms a duration into JSON.
func (d *Duration) MarshalJSON() ([]byte, error) { func (d *Duration) MarshalJSON() ([]byte, error) {
return json.Marshal(d.String()) return json.Marshal(d.String())
} }
// UnmarshalJSON transform JSON into a Duration.
func (d *Duration) UnmarshalJSON(b []byte) error { func (d *Duration) UnmarshalJSON(b []byte) error {
var str string var str string
err := json.Unmarshal(b, &str) err := json.Unmarshal(b, &str)
@ -61,8 +64,7 @@ type Config struct {
// Open is a shortcut to open a file, read it, and generate a Config. // Open is a shortcut to open a file, read it, and generate a Config.
// It supports relative and absolute paths. // It supports relative and absolute paths.
func Open(path string) (*Config, error) { func Open(path string) (*Config, error) {
expandedPath := os.ExpandEnv(path) f, err := os.Open(os.ExpandEnv(path))
f, err := os.Open(expandedPath)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -44,7 +44,7 @@ func (s Server) serveAnnounce(w http.ResponseWriter, r *http.Request) {
log.Panicf("server: %s", err) log.Panicf("server: %s", err)
} }
if !whitelisted { if !whitelisted {
fail(errors.New("Your client is not approved"), w, r) fail(errors.New("client is not approved"), w, r)
return return
} }
@ -54,7 +54,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, r) fail(errors.New("torrent does not exist"), w, r)
return return
} }
@ -270,7 +270,7 @@ func (s Server) validateAnnounceQuery(r *http.Request) (compact bool, numWant in
uploadedErr != nil || uploadedErr != nil ||
downloadedErr != nil || downloadedErr != nil ||
leftErr != nil { leftErr != nil {
return false, 0, "", "", "", "", 0, 0, 0, 0, errors.New("Malformed request") return false, 0, "", "", "", "", 0, 0, 0, 0, errors.New("malformed request")
} }
return return
} }
@ -306,7 +306,7 @@ func requestedIP(r *http.Request, pq *parsedQuery) (string, error) {
if portIndex != -1 { if portIndex != -1 {
return r.RemoteAddr[0:portIndex], nil return r.RemoteAddr[0:portIndex], nil
} }
return "", errors.New("Failed to parse IP address") return "", errors.New("failed to parse IP address")
} }
func minInt(a, b int) int { func minInt(a, b int) int {

View file

@ -8,18 +8,18 @@ import (
var ( var (
baseAddr = "https://www.subdomain.tracker.com:80/" baseAddr = "https://www.subdomain.tracker.com:80/"
testInfoHash = "01234567890123456789" testInfoHash = "01234567890123456789"
testPeerId = "-TEST01-6wfG2wk6wWLc" testPeerID = "-TEST01-6wfG2wk6wWLc"
ValidAnnounceArguments = []url.Values{ ValidAnnounceArguments = []url.Values{
url.Values{"info_hash": {testInfoHash}, "peer_id": {testPeerId}, "port": {"6881"}, "downloaded": {"1234"}, "left": {"4321"}}, url.Values{"info_hash": {testInfoHash}, "peer_id": {testPeerID}, "port": {"6881"}, "downloaded": {"1234"}, "left": {"4321"}},
url.Values{"info_hash": {testInfoHash}, "peer_id": {testPeerId}, "ip": {"192.168.0.1"}, "port": {"6881"}, "downloaded": {"1234"}, "left": {"4321"}}, url.Values{"info_hash": {testInfoHash}, "peer_id": {testPeerID}, "ip": {"192.168.0.1"}, "port": {"6881"}, "downloaded": {"1234"}, "left": {"4321"}},
url.Values{"info_hash": {testInfoHash}, "peer_id": {testPeerId}, "ip": {"192.168.0.1"}, "port": {"6881"}, "downloaded": {"1234"}, "left": {"4321"}, "numwant": {"28"}}, url.Values{"info_hash": {testInfoHash}, "peer_id": {testPeerID}, "ip": {"192.168.0.1"}, "port": {"6881"}, "downloaded": {"1234"}, "left": {"4321"}, "numwant": {"28"}},
url.Values{"info_hash": {testInfoHash}, "peer_id": {testPeerId}, "ip": {"192.168.0.1"}, "port": {"6881"}, "downloaded": {"1234"}, "left": {"4321"}, "event": {"stopped"}}, url.Values{"info_hash": {testInfoHash}, "peer_id": {testPeerID}, "ip": {"192.168.0.1"}, "port": {"6881"}, "downloaded": {"1234"}, "left": {"4321"}, "event": {"stopped"}},
url.Values{"info_hash": {testInfoHash}, "peer_id": {testPeerId}, "ip": {"192.168.0.1"}, "port": {"6881"}, "downloaded": {"1234"}, "left": {"4321"}, "event": {"started"}, "numwant": {"13"}}, url.Values{"info_hash": {testInfoHash}, "peer_id": {testPeerID}, "ip": {"192.168.0.1"}, "port": {"6881"}, "downloaded": {"1234"}, "left": {"4321"}, "event": {"started"}, "numwant": {"13"}},
url.Values{"info_hash": {testInfoHash}, "peer_id": {testPeerId}, "port": {"6881"}, "downloaded": {"1234"}, "left": {"4321"}, "no_peer_id": {"1"}}, url.Values{"info_hash": {testInfoHash}, "peer_id": {testPeerID}, "port": {"6881"}, "downloaded": {"1234"}, "left": {"4321"}, "no_peer_id": {"1"}},
url.Values{"info_hash": {testInfoHash}, "peer_id": {testPeerId}, "port": {"6881"}, "downloaded": {"1234"}, "left": {"4321"}, "compact": {"0"}, "no_peer_id": {"1"}}, url.Values{"info_hash": {testInfoHash}, "peer_id": {testPeerID}, "port": {"6881"}, "downloaded": {"1234"}, "left": {"4321"}, "compact": {"0"}, "no_peer_id": {"1"}},
url.Values{"info_hash": {testInfoHash}, "peer_id": {testPeerId}, "port": {"6881"}, "downloaded": {"1234"}, "left": {"4321"}, "compact": {"0"}, "no_peer_id": {"1"}, "key": {"peerKey"}}, url.Values{"info_hash": {testInfoHash}, "peer_id": {testPeerID}, "port": {"6881"}, "downloaded": {"1234"}, "left": {"4321"}, "compact": {"0"}, "no_peer_id": {"1"}, "key": {"peerKey"}},
url.Values{"info_hash": {testInfoHash}, "peer_id": {testPeerId}, "port": {"6881"}, "downloaded": {"1234"}, "left": {"4321"}, "compact": {"0"}, "no_peer_id": {"1"}, "key": {"peerKey"}, "trackerid": {"trackerId"}}, url.Values{"info_hash": {testInfoHash}, "peer_id": {testPeerID}, "port": {"6881"}, "downloaded": {"1234"}, "left": {"4321"}, "compact": {"0"}, "no_peer_id": {"1"}, "key": {"peerKey"}, "trackerid": {"trackerId"}},
url.Values{"info_hash": {testInfoHash}, "peer_id": {"%3Ckey%3A+0x90%3E"}, "port": {"6881"}, "downloaded": {"1234"}, "left": {"4321"}, "compact": {"0"}, "no_peer_id": {"1"}, "key": {"peerKey"}, "trackerid": {"trackerId"}}, url.Values{"info_hash": {testInfoHash}, "peer_id": {"%3Ckey%3A+0x90%3E"}, "port": {"6881"}, "downloaded": {"1234"}, "left": {"4321"}, "compact": {"0"}, "no_peer_id": {"1"}, "key": {"peerKey"}, "trackerid": {"trackerId"}},
url.Values{"info_hash": {testInfoHash}, "peer_id": {"%3Ckey%3A+0x90%3E"}, "compact": {"1"}}, url.Values{"info_hash": {testInfoHash}, "peer_id": {"%3Ckey%3A+0x90%3E"}, "compact": {"1"}},
} }

View file

@ -18,7 +18,7 @@ func (s *Server) serveScrape(w http.ResponseWriter, r *http.Request) {
// Parse the query // Parse the query
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, r) fail(errors.New("error parsing query"), w, r)
return return
} }

View file

@ -24,6 +24,7 @@ import (
"github.com/chihaya/chihaya/storage/tracker" "github.com/chihaya/chihaya/storage/tracker"
) )
// Server represents BitTorrent tracker server.
type Server struct { type Server struct {
conf *config.Config conf *config.Config
listener *stoppableListener.StoppableListener listener *stoppableListener.StoppableListener
@ -38,6 +39,7 @@ type Server struct {
http.Server http.Server
} }
// New creates a new Server.
func New(conf *config.Config) (*Server, error) { func New(conf *config.Config) (*Server, error) {
trackerPool, err := tracker.Open(&conf.Tracker) trackerPool, err := tracker.Open(&conf.Tracker)
if err != nil { if err != nil {
@ -66,6 +68,7 @@ func New(conf *config.Config) (*Server, error) {
return s, nil return s, nil
} }
// ListenAndServe starts listening and handling incoming HTTP requests.
func (s *Server) ListenAndServe() error { func (s *Server) ListenAndServe() error {
l, err := net.Listen("tcp", s.Addr) l, err := net.Listen("tcp", s.Addr)
if err != nil { if err != nil {
@ -81,6 +84,7 @@ func (s *Server) ListenAndServe() error {
return nil return nil
} }
// Stop cleanly ends the handling of incoming HTTP requests.
func (s *Server) Stop() error { func (s *Server) Stop() error {
s.listener.Stop <- true s.listener.Stop <- true
err := s.trackerPool.Close() err := s.trackerPool.Close()
@ -106,7 +110,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
s.serveStats(w, r) s.serveStats(w, r)
return return
default: default:
fail(errors.New("Unknown action"), w, r) fail(errors.New("unknown action"), w, r)
return return
} }
} }
@ -121,7 +125,7 @@ func fail(err error, w http.ResponseWriter, r *http.Request) {
func validateUser(conn tracker.Conn, dir string) (*storage.User, error) { func validateUser(conn tracker.Conn, dir string) (*storage.User, error) {
if len(dir) != 34 { if len(dir) != 34 {
return nil, errors.New("Passkey is invalid") return nil, errors.New("passkey is invalid")
} }
passkey := dir[1:33] passkey := dir[1:33]
@ -130,7 +134,7 @@ func validateUser(conn tracker.Conn, dir string) (*storage.User, error) {
log.Panicf("server: %s", err) log.Panicf("server: %s", err)
} }
if !exists { if !exists {
return nil, errors.New("User not found") return nil, errors.New("user not found")
} }
return user, nil return user, nil

View file

@ -9,8 +9,8 @@ import (
) )
type PeerClientPair struct { type PeerClientPair struct {
peerId string peerID string
clientId string clientID string
} }
var TestClients = []PeerClientPair{ var TestClients = []PeerClientPair{
@ -59,8 +59,8 @@ var TestClients = []PeerClientPair{
func TestParseClientID(t *testing.T) { func TestParseClientID(t *testing.T) {
for _, pair := range TestClients { for _, pair := range TestClients {
if parsedId := parsePeerID(pair.peerId); parsedId != pair.clientId { if parsedID := parsePeerID(pair.peerID); parsedID != pair.clientID {
t.Error("Incorrectly parsed peer ID", pair.peerId, "as", parsedId) t.Error("Incorrectly parsed peer ID", pair.peerID, "as", parsedID)
} }
} }
} }

View file

@ -16,6 +16,8 @@ import (
var drivers = make(map[string]Driver) var drivers = make(map[string]Driver)
// Driver represents an interface to a long-running connection with a
// consistent data store.
type Driver interface { type Driver interface {
New(*config.DataStore) Conn New(*config.DataStore) Conn
} }

View file

@ -16,6 +16,7 @@ type Conn struct {
func (c *Conn) FindUser(passkey string) (*storage.User, bool, error) { func (c *Conn) FindUser(passkey string) (*storage.User, bool, error) {
c.usersM.RLock() c.usersM.RLock()
defer c.usersM.RUnlock() defer c.usersM.RUnlock()
user, ok := c.users[passkey] user, ok := c.users[passkey]
if !ok { if !ok {
return nil, false, nil return nil, false, nil
@ -27,6 +28,7 @@ func (c *Conn) FindUser(passkey string) (*storage.User, bool, error) {
func (c *Conn) FindTorrent(infohash string) (*storage.Torrent, bool, error) { func (c *Conn) FindTorrent(infohash string) (*storage.Torrent, bool, error) {
c.torrentsM.RLock() c.torrentsM.RLock()
defer c.torrentsM.RUnlock() defer c.torrentsM.RUnlock()
torrent, ok := c.torrents[infohash] torrent, ok := c.torrents[infohash]
if !ok { if !ok {
return nil, false, nil return nil, false, nil
@ -38,6 +40,7 @@ func (c *Conn) FindTorrent(infohash string) (*storage.Torrent, bool, error) {
func (c *Conn) ClientWhitelisted(peerID string) (bool, error) { func (c *Conn) ClientWhitelisted(peerID string) (bool, error) {
c.whitelistM.RLock() c.whitelistM.RLock()
defer c.whitelistM.RUnlock() defer c.whitelistM.RUnlock()
_, ok := c.whitelist[peerID] _, ok := c.whitelist[peerID]
if !ok { if !ok {
return false, nil return false, nil
@ -48,108 +51,134 @@ func (c *Conn) ClientWhitelisted(peerID string) (bool, error) {
func (c *Conn) RecordSnatch(u *storage.User, t *storage.Torrent) error { func (c *Conn) RecordSnatch(u *storage.User, t *storage.Torrent) error {
c.torrentsM.Lock() c.torrentsM.Lock()
defer c.torrentsM.Unlock() defer c.torrentsM.Unlock()
torrent, ok := c.torrents[t.Infohash] torrent, ok := c.torrents[t.Infohash]
if !ok { if !ok {
return tracker.ErrMissingResource return tracker.ErrMissingResource
} }
torrent.Snatches++ torrent.Snatches++
t.Snatches++ t.Snatches++
return nil return nil
} }
func (c *Conn) MarkActive(t *storage.Torrent) error { func (c *Conn) MarkActive(t *storage.Torrent) error {
c.torrentsM.Lock() c.torrentsM.Lock()
defer c.torrentsM.Unlock() defer c.torrentsM.Unlock()
torrent, ok := c.torrents[t.Infohash] torrent, ok := c.torrents[t.Infohash]
if !ok { if !ok {
return tracker.ErrMissingResource return tracker.ErrMissingResource
} }
torrent.Active = true torrent.Active = true
t.Active = true t.Active = true
return nil return nil
} }
func (c *Conn) MarkInactive(t *storage.Torrent) error { func (c *Conn) MarkInactive(t *storage.Torrent) error {
c.torrentsM.Lock() c.torrentsM.Lock()
defer c.torrentsM.Unlock() defer c.torrentsM.Unlock()
torrent, ok := c.torrents[t.Infohash] torrent, ok := c.torrents[t.Infohash]
if !ok { if !ok {
return tracker.ErrMissingResource return tracker.ErrMissingResource
} }
torrent.Active = false torrent.Active = false
t.Active = false t.Active = false
return nil return nil
} }
func (c *Conn) AddLeecher(t *storage.Torrent, p *storage.Peer) error { func (c *Conn) AddLeecher(t *storage.Torrent, p *storage.Peer) error {
c.torrentsM.Lock() c.torrentsM.Lock()
defer c.torrentsM.Unlock() defer c.torrentsM.Unlock()
torrent, ok := c.torrents[t.Infohash] torrent, ok := c.torrents[t.Infohash]
if !ok { if !ok {
return tracker.ErrMissingResource return tracker.ErrMissingResource
} }
torrent.Leechers[storage.PeerMapKey(p)] = *p torrent.Leechers[storage.PeerMapKey(p)] = *p
t.Leechers[storage.PeerMapKey(p)] = *p t.Leechers[storage.PeerMapKey(p)] = *p
return nil return nil
} }
func (c *Conn) AddSeeder(t *storage.Torrent, p *storage.Peer) error { func (c *Conn) AddSeeder(t *storage.Torrent, p *storage.Peer) error {
c.torrentsM.Lock() c.torrentsM.Lock()
defer c.torrentsM.Unlock() defer c.torrentsM.Unlock()
torrent, ok := c.torrents[t.Infohash] torrent, ok := c.torrents[t.Infohash]
if !ok { if !ok {
return tracker.ErrMissingResource return tracker.ErrMissingResource
} }
torrent.Leechers[storage.PeerMapKey(p)] = *p torrent.Leechers[storage.PeerMapKey(p)] = *p
t.Leechers[storage.PeerMapKey(p)] = *p t.Leechers[storage.PeerMapKey(p)] = *p
return nil return nil
} }
func (c *Conn) RemoveLeecher(t *storage.Torrent, p *storage.Peer) error { func (c *Conn) RemoveLeecher(t *storage.Torrent, p *storage.Peer) error {
c.torrentsM.Lock() c.torrentsM.Lock()
defer c.torrentsM.Unlock() defer c.torrentsM.Unlock()
torrent, ok := c.torrents[t.Infohash] torrent, ok := c.torrents[t.Infohash]
if !ok { if !ok {
return tracker.ErrMissingResource return tracker.ErrMissingResource
} }
delete(torrent.Leechers, storage.PeerMapKey(p)) delete(torrent.Leechers, storage.PeerMapKey(p))
delete(t.Leechers, storage.PeerMapKey(p)) delete(t.Leechers, storage.PeerMapKey(p))
return nil return nil
} }
func (c *Conn) RemoveSeeder(t *storage.Torrent, p *storage.Peer) error { func (c *Conn) RemoveSeeder(t *storage.Torrent, p *storage.Peer) error {
c.torrentsM.Lock() c.torrentsM.Lock()
defer c.torrentsM.Unlock() defer c.torrentsM.Unlock()
torrent, ok := c.torrents[t.Infohash] torrent, ok := c.torrents[t.Infohash]
if !ok { if !ok {
return tracker.ErrMissingResource return tracker.ErrMissingResource
} }
delete(torrent.Seeders, storage.PeerMapKey(p)) delete(torrent.Seeders, storage.PeerMapKey(p))
delete(t.Seeders, storage.PeerMapKey(p)) delete(t.Seeders, storage.PeerMapKey(p))
return nil return nil
} }
func (c *Conn) SetLeecher(t *storage.Torrent, p *storage.Peer) error { func (c *Conn) SetLeecher(t *storage.Torrent, p *storage.Peer) error {
c.torrentsM.Lock() c.torrentsM.Lock()
defer c.torrentsM.Unlock() defer c.torrentsM.Unlock()
torrent, ok := c.torrents[t.Infohash] torrent, ok := c.torrents[t.Infohash]
if !ok { if !ok {
return tracker.ErrMissingResource return tracker.ErrMissingResource
} }
torrent.Leechers[storage.PeerMapKey(p)] = *p torrent.Leechers[storage.PeerMapKey(p)] = *p
t.Leechers[storage.PeerMapKey(p)] = *p t.Leechers[storage.PeerMapKey(p)] = *p
return nil return nil
} }
func (c *Conn) SetSeeder(t *storage.Torrent, p *storage.Peer) error { func (c *Conn) SetSeeder(t *storage.Torrent, p *storage.Peer) error {
c.torrentsM.Lock() c.torrentsM.Lock()
defer c.torrentsM.Unlock() defer c.torrentsM.Unlock()
torrent, ok := c.torrents[t.Infohash] torrent, ok := c.torrents[t.Infohash]
if !ok { if !ok {
return tracker.ErrMissingResource return tracker.ErrMissingResource
} }
torrent.Seeders[storage.PeerMapKey(p)] = *p torrent.Seeders[storage.PeerMapKey(p)] = *p
t.Seeders[storage.PeerMapKey(p)] = *p t.Seeders[storage.PeerMapKey(p)] = *p
return nil return nil
} }
@ -164,51 +193,65 @@ func (c *Conn) LeecherFinished(t *storage.Torrent, p *storage.Peer) error {
torrent.Seeders[storage.PeerMapKey(p)] = *p torrent.Seeders[storage.PeerMapKey(p)] = *p
delete(torrent.Leechers, storage.PeerMapKey(p)) delete(torrent.Leechers, storage.PeerMapKey(p))
t.Seeders[storage.PeerMapKey(p)] = *p t.Seeders[storage.PeerMapKey(p)] = *p
delete(t.Leechers, storage.PeerMapKey(p)) delete(t.Leechers, storage.PeerMapKey(p))
return nil return nil
} }
func (c *Conn) AddTorrent(t *storage.Torrent) error { func (c *Conn) AddTorrent(t *storage.Torrent) error {
c.torrentsM.Lock() c.torrentsM.Lock()
defer c.torrentsM.Unlock() defer c.torrentsM.Unlock()
torrent := *t torrent := *t
c.torrents[t.Infohash] = &torrent c.torrents[t.Infohash] = &torrent
return nil return nil
} }
func (c *Conn) RemoveTorrent(t *storage.Torrent) error { func (c *Conn) RemoveTorrent(t *storage.Torrent) error {
c.torrentsM.Lock() c.torrentsM.Lock()
defer c.torrentsM.Unlock() defer c.torrentsM.Unlock()
delete(c.torrents, t.Infohash) delete(c.torrents, t.Infohash)
return nil return nil
} }
func (c *Conn) AddUser(u *storage.User) error { func (c *Conn) AddUser(u *storage.User) error {
c.usersM.Lock() c.usersM.Lock()
defer c.usersM.Unlock() defer c.usersM.Unlock()
user := *u user := *u
c.users[u.Passkey] = &user c.users[u.Passkey] = &user
return nil return nil
} }
func (c *Conn) RemoveUser(u *storage.User) error { func (c *Conn) RemoveUser(u *storage.User) error {
c.usersM.Lock() c.usersM.Lock()
defer c.usersM.Unlock() defer c.usersM.Unlock()
delete(c.users, u.Passkey) delete(c.users, u.Passkey)
return nil return nil
} }
func (c *Conn) WhitelistClient(peerID string) error { func (c *Conn) WhitelistClient(peerID string) error {
c.whitelistM.Lock() c.whitelistM.Lock()
defer c.whitelistM.Unlock() defer c.whitelistM.Unlock()
c.whitelist[peerID] = true c.whitelist[peerID] = true
return nil return nil
} }
func (c *Conn) UnWhitelistClient(peerID string) error { func (c *Conn) UnWhitelistClient(peerID string) error {
c.whitelistM.Lock() c.whitelistM.Lock()
defer c.whitelistM.Unlock() defer c.whitelistM.Unlock()
delete(c.whitelist, peerID) delete(c.whitelist, peerID)
return nil return nil
} }

View file

@ -15,10 +15,14 @@ import (
) )
var ( var (
// ErrMissingResource is an error returned when a resource does not exist.
ErrMissingResource = errors.New("tracker: resource missing") ErrMissingResource = errors.New("tracker: resource missing")
drivers = make(map[string]Driver)
drivers = make(map[string]Driver)
) )
// Driver represents an interface to pool of connections to storage used for
// the tracker.
type Driver interface { type Driver interface {
New(*config.DataStore) Pool New(*config.DataStore) Pool
} }