diff --git a/http/announce.go b/http/announce.go index ba96d1e..9becda7 100644 --- a/http/announce.go +++ b/http/announce.go @@ -16,27 +16,27 @@ import ( "github.com/chihaya/chihaya/models" ) -func (t *Tracker) ServeAnnounce(w http.ResponseWriter, r *http.Request, p httprouter.Params) int { +func (t *Tracker) ServeAnnounce(w http.ResponseWriter, r *http.Request, p httprouter.Params) (int, error) { ann, err := models.NewAnnounce(t.cfg, r, p) if err == models.ErrMalformedRequest { fail(w, r, err) - return http.StatusOK + return http.StatusOK, nil } else if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } conn, err := t.tp.Get() if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } if t.cfg.Whitelist { err = conn.FindClient(ann.ClientID()) if err == tracker.ErrClientUnapproved { fail(w, r, err) - return http.StatusOK + return http.StatusOK, nil } else if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } } @@ -45,43 +45,43 @@ func (t *Tracker) ServeAnnounce(w http.ResponseWriter, r *http.Request, p httpro user, err = conn.FindUser(ann.Passkey) if err == tracker.ErrUserDNE { fail(w, r, err) - return http.StatusOK + return http.StatusOK, nil } else if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } } torrent, err := conn.FindTorrent(ann.Infohash) if err == tracker.ErrTorrentDNE { fail(w, r, err) - return http.StatusOK + return http.StatusOK, nil } else if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } peer := models.NewPeer(ann, user, torrent) created, err := updateTorrent(conn, ann, peer, torrent) if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } snatched, err := handleEvent(conn, ann, peer, user, torrent) if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } if t.cfg.Private { delta := models.NewAnnounceDelta(ann, peer, user, torrent, created, snatched) err = t.bc.RecordAnnounce(delta) if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } } writeAnnounceResponse(w, ann, user, torrent) - return http.StatusOK + return http.StatusOK, nil } func updateTorrent(c tracker.Conn, a *models.Announce, p *models.Peer, t *models.Torrent) (created bool, err error) { diff --git a/http/api.go b/http/api.go index a48eaeb..b8f4cbd 100644 --- a/http/api.go +++ b/http/api.go @@ -15,156 +15,156 @@ import ( "github.com/chihaya/chihaya/models" ) -func (t *Tracker) getTorrent(w http.ResponseWriter, r *http.Request, p httprouter.Params) int { +func (t *Tracker) getTorrent(w http.ResponseWriter, r *http.Request, p httprouter.Params) (int, error) { conn, err := t.tp.Get() if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } torrent, err := conn.FindTorrent(p.ByName("infohash")) if err == tracker.ErrTorrentDNE { - return http.StatusNotFound + return http.StatusNotFound, err } else if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } e := json.NewEncoder(w) err = e.Encode(torrent) if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } - return http.StatusOK + return http.StatusOK, nil } -func (t *Tracker) putTorrent(w http.ResponseWriter, r *http.Request, p httprouter.Params) int { +func (t *Tracker) putTorrent(w http.ResponseWriter, r *http.Request, p httprouter.Params) (int, error) { body, err := ioutil.ReadAll(r.Body) if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } var torrent models.Torrent err = json.Unmarshal(body, &torrent) if err != nil { - return http.StatusBadRequest + return http.StatusBadRequest, err } conn, err := t.tp.Get() if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } err = conn.PutTorrent(&torrent) if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } - return http.StatusOK + return http.StatusOK, nil } -func (t *Tracker) delTorrent(w http.ResponseWriter, r *http.Request, p httprouter.Params) int { +func (t *Tracker) delTorrent(w http.ResponseWriter, r *http.Request, p httprouter.Params) (int, error) { conn, err := t.tp.Get() if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } err = conn.DeleteTorrent(p.ByName("infohash")) if err == tracker.ErrTorrentDNE { - return http.StatusNotFound + return http.StatusNotFound, err } else if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } - return http.StatusOK + return http.StatusOK, nil } -func (t *Tracker) getUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) int { +func (t *Tracker) getUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) (int, error) { conn, err := t.tp.Get() if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } user, err := conn.FindUser(p.ByName("passkey")) if err == tracker.ErrUserDNE { - return http.StatusNotFound + return http.StatusNotFound, err } else if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } e := json.NewEncoder(w) err = e.Encode(user) if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } - return http.StatusOK + return http.StatusOK, nil } -func (t *Tracker) putUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) int { +func (t *Tracker) putUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) (int, error) { body, err := ioutil.ReadAll(r.Body) if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } var user models.User err = json.Unmarshal(body, &user) if err != nil { - return http.StatusBadRequest + return http.StatusBadRequest, err } conn, err := t.tp.Get() if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } err = conn.PutUser(&user) if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } - return http.StatusOK + return http.StatusOK, nil } -func (t *Tracker) delUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) int { +func (t *Tracker) delUser(w http.ResponseWriter, r *http.Request, p httprouter.Params) (int, error) { conn, err := t.tp.Get() if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } err = conn.DeleteUser(p.ByName("passkey")) if err == tracker.ErrUserDNE { - return http.StatusNotFound + return http.StatusNotFound, err } else if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } - return http.StatusOK + return http.StatusOK, nil } -func (t *Tracker) putClient(w http.ResponseWriter, r *http.Request, p httprouter.Params) int { +func (t *Tracker) putClient(w http.ResponseWriter, r *http.Request, p httprouter.Params) (int, error) { conn, err := t.tp.Get() if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } err = conn.PutClient(p.ByName("clientID")) if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } - return http.StatusOK + return http.StatusOK, nil } -func (t *Tracker) delClient(w http.ResponseWriter, r *http.Request, p httprouter.Params) int { +func (t *Tracker) delClient(w http.ResponseWriter, r *http.Request, p httprouter.Params) (int, error) { conn, err := t.tp.Get() if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } err = conn.DeleteClient(p.ByName("clientID")) if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } - return http.StatusOK + return http.StatusOK, nil } diff --git a/http/http.go b/http/http.go index d6de1b9..d2676f6 100644 --- a/http/http.go +++ b/http/http.go @@ -42,12 +42,15 @@ func NewTracker(cfg *config.Config) (*Tracker, error) { }, nil } -type ResponseHandler func(http.ResponseWriter, *http.Request, httprouter.Params) int +type ResponseHandler func(http.ResponseWriter, *http.Request, httprouter.Params) (int, error) func makeHandler(handler ResponseHandler) httprouter.Handle { return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { start := time.Now() - code := handler(w, r, p) + code, err := handler(w, r, p) + if err != nil { + http.Error(w, err.Error(), code) + } glog.Infof( "Completed %v %s %s in %v", code, @@ -60,14 +63,27 @@ func makeHandler(handler ResponseHandler) httprouter.Handle { func setupRoutes(t *Tracker, cfg *config.Config) *httprouter.Router { r := httprouter.New() + + r.GET("/torrents/:infohash", makeHandler(t.getTorrent)) + r.PUT("/torrents/:infohash", makeHandler(t.putTorrent)) + r.DELETE("/torrents/:infohash", makeHandler(t.delTorrent)) + if cfg.Private { r.GET("/:passkey/announce", makeHandler(t.ServeAnnounce)) r.GET("/:passkey/scrape", makeHandler(t.ServeScrape)) + + r.PUT("/users/:passkey", makeHandler(t.putUser)) + r.DELETE("/users/:passkey", makeHandler(t.delUser)) } else { r.GET("/announce", makeHandler(t.ServeAnnounce)) r.GET("/scrape", makeHandler(t.ServeScrape)) } + if cfg.Whitelist { + r.PUT("/clients/:clientID", makeHandler(t.putClient)) + r.DELETE("/clients/:clientID", makeHandler(t.delClient)) + } + return r } diff --git a/http/scrape.go b/http/scrape.go index 6b49155..3e5273e 100644 --- a/http/scrape.go +++ b/http/scrape.go @@ -16,27 +16,27 @@ import ( "github.com/chihaya/chihaya/models" ) -func (t *Tracker) ServeScrape(w http.ResponseWriter, r *http.Request, p httprouter.Params) int { +func (t *Tracker) ServeScrape(w http.ResponseWriter, r *http.Request, p httprouter.Params) (int, error) { scrape, err := models.NewScrape(t.cfg, r, p) if err == models.ErrMalformedRequest { fail(w, r, err) - return http.StatusOK + return http.StatusOK, nil } else if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } conn, err := t.tp.Get() if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } if t.cfg.Private { _, err = conn.FindUser(scrape.Passkey) if err == tracker.ErrUserDNE { fail(w, r, err) - return http.StatusOK + return http.StatusOK, nil } else if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } } @@ -45,9 +45,9 @@ func (t *Tracker) ServeScrape(w http.ResponseWriter, r *http.Request, p httprout torrent, err := conn.FindTorrent(infohash) if err == tracker.ErrTorrentDNE { fail(w, r, err) - return http.StatusOK + return http.StatusOK, nil } else if err != nil { - return http.StatusInternalServerError + return http.StatusInternalServerError, err } torrents = append(torrents, torrent) } @@ -60,7 +60,7 @@ func (t *Tracker) ServeScrape(w http.ResponseWriter, r *http.Request, p httprout } fmt.Fprintf(w, "e") - return http.StatusOK + return http.StatusOK, nil } func writeTorrentStatus(w io.Writer, t *models.Torrent) {