github.com/uber/kraken@v0.1.4/tracker/trackerserver/announce.go (about) 1 // Copyright (c) 2016-2019 Uber Technologies, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 package trackerserver 15 16 import ( 17 "encoding/json" 18 "fmt" 19 "net/http" 20 21 "github.com/uber/kraken/core" 22 "github.com/uber/kraken/tracker/announceclient" 23 "github.com/uber/kraken/utils/errutil" 24 "github.com/uber/kraken/utils/handler" 25 "github.com/uber/kraken/utils/httputil" 26 "github.com/uber/kraken/utils/log" 27 ) 28 29 func (s *Server) announceHandlerV1(w http.ResponseWriter, r *http.Request) error { 30 req := new(announceclient.Request) 31 if err := json.NewDecoder(r.Body).Decode(req); err != nil { 32 return handler.Errorf("json decode request: %s", err) 33 } 34 d, err := req.GetDigest() 35 if err != nil { 36 return handler.Errorf("get request digest: %s", err) 37 } 38 resp, err := s.announce(d, req.InfoHash, req.Peer) 39 if err != nil { 40 return err 41 } 42 if err := json.NewEncoder(w).Encode(resp); err != nil { 43 return handler.Errorf("json encode response: %s", err) 44 } 45 return nil 46 } 47 48 func (s *Server) announceHandlerV2(w http.ResponseWriter, r *http.Request) error { 49 infohash, err := httputil.ParseParam(r, "infohash") 50 if err != nil { 51 return err 52 } 53 h, err := core.NewInfoHashFromHex(infohash) 54 if err != nil { 55 return fmt.Errorf("parse infohash: %s", err) 56 } 57 req := new(announceclient.Request) 58 if err := json.NewDecoder(r.Body).Decode(req); err != nil { 59 return handler.Errorf("json decode request: %s", err) 60 } 61 d, err := req.GetDigest() 62 if err != nil { 63 return handler.Errorf("get request digest: %s", err) 64 } 65 resp, err := s.announce(d, h, req.Peer) 66 if err != nil { 67 return err 68 } 69 if err := json.NewEncoder(w).Encode(resp); err != nil { 70 return handler.Errorf("json encode response: %s", err) 71 } 72 return nil 73 } 74 75 func (s *Server) announce( 76 d core.Digest, h core.InfoHash, peer *core.PeerInfo) (*announceclient.Response, error) { 77 78 if err := s.peerStore.UpdatePeer(h, peer); err != nil { 79 log.With( 80 "hash", h, 81 "peer_id", peer.PeerID).Errorf("Error updating peer: %s", err) 82 } 83 peers, err := s.getPeerHandout(d, h, peer) 84 if err != nil { 85 return nil, err 86 } 87 return &announceclient.Response{ 88 Peers: peers, 89 Interval: s.config.AnnounceInterval, 90 }, nil 91 } 92 93 func (s *Server) getPeerHandout( 94 d core.Digest, h core.InfoHash, peer *core.PeerInfo) ([]*core.PeerInfo, error) { 95 96 if peer.Complete { 97 // If the peer is announcing as complete, don't return a peer handout since 98 // the peer does not need it. 99 return nil, nil 100 } 101 var errs []error 102 peers, err := s.peerStore.GetPeers(h, s.config.PeerHandoutLimit) 103 if err != nil { 104 errs = append(errs, fmt.Errorf("peer store: %s", err)) 105 } 106 origins, err := s.originStore.GetOrigins(d) 107 if err != nil { 108 errs = append(errs, fmt.Errorf("origin store: %s", err)) 109 } 110 peers = append(peers, origins...) 111 if len(peers) == 0 { 112 return nil, handler.Errorf("no peers available: %s", errutil.Join(errs)) 113 } 114 return s.policy.SortPeers(peer, peers), nil 115 }