def test_funcs(self): # Generated IPs should be valid for _ in range(10): self.assertTrue(is_valid_ip(str(IPv4(random.randint(0, IPV4MAX))))) self.assertTrue(is_valid_ip(str(IPv6(random.randint(0, IPV6MAX))))) badips = ('NotAnAddress', '127.0.0.256', '::ff::', '::fffg:0:0', '-1') for badip in badips: self.assertFalse(is_valid_ip(badip)) for _ in range(10): rand4 = random.randint(0, IPV4MAX) str4 = str(IPv4(rand4)) str6 = str(IPv6(rand4 + IP.v4mask)) self.assertEqual(str4, to_ipv4(str4)) self.assertEqual(str4, to_ipv4(str6))
def get(self, connection, path, headers): real_ip = connection.get_ip() ip = real_ip if is_ipv4(ip): ipv4 = True else: try: ip = ipv6_to_ipv4(ip) ipv4 = True except ValueError: ipv4 = False if self.allowed_IPs and ip not in self.allowed_IPs or \ self.banned_IPs and ip in self.banned_IPs: return (400, 'Not Authorized', {'Content-Type': 'text/plain', 'Pragma': 'no-cache'}, bencode({'failure reason': 'your IP is not allowed on this tracker'})) nip = get_forwarded_ip(headers) if nip and not self.only_local_override_ip: ip = nip try: ip = to_ipv4(ip) ipv4 = True except ValueError: ipv4 = False paramslist = {} def params(key, default=None, l=paramslist): if key in l: return l[key][0] return default try: (_, _, path, _, query, _) = urlparse(path) if self.uq_broken == 1: path = path.replace('+', ' ') query = query.replace('+', ' ') path = urllib.unquote(path)[1:] for s in query.split('&'): if s: i = s.index('=') kw = urllib.unquote(s[:i]) paramslist.setdefault(kw, []) paramslist[kw] += [urllib.unquote(s[i + 1:])] if path == '' or path == 'index.html': return self.get_infopage() if path == 'file': return self.get_file(params('info_hash')) if path == 'favicon.ico' and self.favicon is not None: return (200, 'OK', {'Content-Type': 'image/x-icon'}, self.favicon) # automated access from here on if path in ('scrape', 'scrape.php', 'tracker.php/scrape'): return self.get_scrape(paramslist) if path not in ('announce', 'announce.php', 'tracker.php/announce'): return (404, 'Not Found', {'Content-Type': 'text/plain', 'Pragma': 'no-cache'}, alas) # main tracker function #filtered = self.Filter.check(real_ip, paramslist, headers) #if filtered: # return (400, 'Not Authorized', {'Content-Type': 'text/plain', # 'Pragma': 'no-cache'}, # bencode({'failure reason': filtered})) infohash = params('info_hash') if not infohash: raise ValueError('no info hash') notallowed = self.check_allowed(infohash, paramslist) if notallowed: return notallowed event = params('event') rsize = self.add_data(infohash, event, ip, paramslist) except ValueError as e: return (400, 'Bad Request', {'Content-Type': 'text/plain'}, 'you sent me garbage - ' + str(e)) if self.aggregate_forward and 'tracker' not in paramslist: self.aggregate_senddata(query) if self.is_aggregator: # don't return peer data here return (200, 'OK', {'Content-Type': 'text/plain', 'Pragma': 'no-cache'}, bencode({'response': 'OK'})) if params('compact') and ipv4: if params('requirecrypto'): return_type = 1 elif params('supportcrypto'): return_type = 2 else: return_type = 0 elif self.config['compact_reqd'] and ipv4: return (400, 'Bad Request', {'Content-Type': 'text/plain'}, 'your client is outdated, please upgrade') elif params('no_peer_id'): return_type = 4 else: return_type = 3 data = self.peerlist(infohash, event == 'stopped', params('tracker'), not params('left'), return_type, rsize, params('supportcrypto')) if 'scrape' in paramslist: # deprecated data['scrape'] = self.scrapedata(infohash, False) if self.dedicated_seed_id: if params('seed_id') == self.dedicated_seed_id and \ params('left') == 0: self.is_seeded[infohash] = True if params('check_seeded') and self.is_seeded.get(infohash): data['seeded'] = 1 return (200, 'OK', {'Content-Type': 'text/plain', 'Pragma': 'no-cache'}, bencode(data))