redis restructured to use strings of JSON
This commit is contained in:
parent
f7906b9089
commit
2cd3473d18
3 changed files with 49 additions and 54 deletions
|
@ -15,7 +15,7 @@ import (
|
||||||
"github.com/pushrax/chihaya/storage"
|
"github.com/pushrax/chihaya/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) serveAnnounce(w http.ResponseWriter, r *http.Request) {
|
func (s Server) serveAnnounce(w http.ResponseWriter, r *http.Request) {
|
||||||
// Parse the required parameters off of a query
|
// Parse the required parameters off of a query
|
||||||
compact, numWant, infohash, peerID, event, ip, port, uploaded, downloaded, left, err := s.validateAnnounceQuery(r)
|
compact, numWant, infohash, peerID, event, ip, port, uploaded, downloaded, left, err := s.validateAnnounceQuery(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -116,7 +116,7 @@ func (s *Server) serveAnnounce(w http.ResponseWriter, r *http.Request) {
|
||||||
default:
|
default:
|
||||||
// Check the user's slots to see if they're allowed to leech
|
// Check the user's slots to see if they're allowed to leech
|
||||||
if s.conf.Slots && user.Slots != -1 && left != 0 {
|
if s.conf.Slots && user.Slots != -1 && left != 0 {
|
||||||
if user.UsedSlots >= user.Slots {
|
if user.SlotsUsed >= user.Slots {
|
||||||
fail(errors.New("You've run out of download slots."), w, r)
|
fail(errors.New("You've run out of download slots."), w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -192,7 +192,7 @@ func (s *Server) serveAnnounce(w http.ResponseWriter, r *http.Request) {
|
||||||
// TODO compact, response, etc...
|
// TODO compact, response, etc...
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) validateAnnounceQuery(r *http.Request) (compact bool, numWant int, infohash, peerID, event, ip string, port, uploaded, downloaded, left uint64, err error) {
|
func (s Server) validateAnnounceQuery(r *http.Request) (compact bool, numWant int, infohash, peerID, event, ip string, port, uploaded, downloaded, left uint64, err error) {
|
||||||
pq, err := parseQuery(r.URL.RawQuery)
|
pq, err := parseQuery(r.URL.RawQuery)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, 0, "", "", "", "", 0, 0, 0, 0, err
|
return false, 0, "", "", "", "", 0, 0, 0, 0, err
|
||||||
|
|
|
@ -5,42 +5,34 @@
|
||||||
package storage
|
package storage
|
||||||
|
|
||||||
type Peer struct {
|
type Peer struct {
|
||||||
ID string
|
ID string `json:"id"`
|
||||||
UserID uint64
|
UserID uint64 `json:"user_id"`
|
||||||
TorrentID uint64
|
TorrentID uint64 `json:"torrent_id"`
|
||||||
|
IP string `json:"ip"`
|
||||||
IP string
|
Port uint64 `json:"port"`
|
||||||
Port uint64
|
Uploaded uint64 `json:"uploaded"`
|
||||||
|
Downloaded uint64 `json:"downloaded`
|
||||||
Uploaded uint64
|
Left uint64 `json:"left"`
|
||||||
Downloaded uint64
|
LastAnnounce int64 `json:"last_announce"`
|
||||||
Left uint64
|
|
||||||
|
|
||||||
LastAnnounce int64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Torrent struct {
|
type Torrent struct {
|
||||||
ID uint64
|
ID uint64 `json:"id"`
|
||||||
Infohash string
|
Infohash string `json:"infohash"`
|
||||||
UpMultiplier float64
|
Pruned bool `json:"pruned"`
|
||||||
DownMultiplier float64
|
Seeders map[string]Peer `json:"seeders"`
|
||||||
|
Leechers map[string]Peer `json:"leechers"`
|
||||||
Seeders map[string]Peer
|
Snatches uint `json:"snatches"`
|
||||||
Leechers map[string]Peer
|
UpMultiplier float64 `json:"up_multiplier"`
|
||||||
|
DownMultiplier float64 `json:"down_multipler"`
|
||||||
Snatches uint
|
LastAction int64 `json:"last_action"`
|
||||||
Pruned bool
|
|
||||||
LastAction int64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
ID uint64
|
ID uint64 `json:"id"`
|
||||||
Passkey string
|
Passkey string `json:"passkey"`
|
||||||
|
UpMultiplier float64 `json:"up_multiplier"`
|
||||||
UpMultiplier float64
|
DownMultiplier float64 `json:"down_multiplier"`
|
||||||
DownMultiplier float64
|
Slots int64 `json:"slots"`
|
||||||
|
SlotsUsed int64 `json:"slots_used"`
|
||||||
Slots int64
|
|
||||||
UsedSlots int64
|
|
||||||
SlotsLastChecked int64
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,16 @@
|
||||||
// which can be found in the LICENSE file.
|
// which can be found in the LICENSE file.
|
||||||
|
|
||||||
// Package redis implements the storage interface for a BitTorrent tracker.
|
// Package redis implements the storage interface for a BitTorrent tracker.
|
||||||
|
|
||||||
|
// The client whitelist is represented as a set with the key name "whitelist"
|
||||||
|
// with an optional prefix. Torrents and users are JSON-formatted strings.
|
||||||
|
// Torrents' keys are named "torrent_<infohash>" with an optional prefix.
|
||||||
|
// Users' keys are named "user_<passkey>" with an optional prefix.
|
||||||
package redis
|
package redis
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/garyburd/redigo/redis"
|
"github.com/garyburd/redigo/redis"
|
||||||
|
@ -67,19 +74,17 @@ func (ds *DS) FindUser(passkey string) (*storage.User, bool, error) {
|
||||||
conn := ds.Get()
|
conn := ds.Get()
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
key := ds.conf.Prefix + "User:" + passkey
|
key := ds.conf.Prefix + "user_" + passkey
|
||||||
reply, err := redis.Values(conn.Do("HGETALL", key))
|
reply, err := redis.String(conn.Do("GET", key))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, true, err
|
if err == redis.ErrNil {
|
||||||
}
|
return nil, false, nil
|
||||||
|
}
|
||||||
// If we get nothing back, the user isn't found.
|
return nil, false, err
|
||||||
if len(reply) == 0 {
|
|
||||||
return nil, false, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
user := &storage.User{}
|
user := &storage.User{}
|
||||||
err = redis.ScanStruct(reply, user)
|
err = json.NewDecoder(strings.NewReader(reply)).Decode(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, true, err
|
return nil, true, err
|
||||||
}
|
}
|
||||||
|
@ -90,19 +95,17 @@ func (ds *DS) FindTorrent(infohash string) (*storage.Torrent, bool, error) {
|
||||||
conn := ds.Get()
|
conn := ds.Get()
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
key := ds.conf.Prefix + "Torrent:" + infohash
|
key := ds.conf.Prefix + "torrent_" + infohash
|
||||||
reply, err := redis.Values(conn.Do("HGETALL", key))
|
reply, err := redis.String(conn.Do("GET", key))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if err == redis.ErrNil {
|
||||||
|
return nil, false, nil
|
||||||
|
}
|
||||||
return nil, false, err
|
return nil, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we get nothing back, the torrent isn't found.
|
|
||||||
if len(reply) == 0 {
|
|
||||||
return nil, false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
torrent := &storage.Torrent{}
|
torrent := &storage.Torrent{}
|
||||||
err = redis.ScanStruct(reply, torrent)
|
err = json.NewDecoder(strings.NewReader(reply)).Decode(torrent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, true, err
|
return nil, true, err
|
||||||
}
|
}
|
||||||
|
@ -113,8 +116,8 @@ func (ds *DS) ClientWhitelisted(peerID string) (bool, error) {
|
||||||
conn := ds.Get()
|
conn := ds.Get()
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
key := ds.conf.Prefix + "Whitelist:" + peerID
|
key := ds.conf.Prefix + "whitelist"
|
||||||
exists, err := redis.Bool(conn.Do("EXISTS", key))
|
exists, err := redis.Bool(conn.Do("SISMEMBER", key, peerID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue