[Debtorrent-commits] r85 - in /debtorrent/branches/http-listen/DebTorrent: BT1/AptListener.py download_bt1.py
camrdale-guest at users.alioth.debian.org
camrdale-guest at users.alioth.debian.org
Mon Jun 4 05:05:11 UTC 2007
Author: camrdale-guest
Date: Mon Jun 4 05:05:08 2007
New Revision: 85
URL: http://svn.debian.org/wsvn/debtorrent/?sc=1&rev=85
Log:
Make AptListener proxy download all requested files.
Add AptListener configuration options.
Modified:
debtorrent/branches/http-listen/DebTorrent/BT1/AptListener.py
debtorrent/branches/http-listen/DebTorrent/download_bt1.py
Modified: debtorrent/branches/http-listen/DebTorrent/BT1/AptListener.py
URL: http://svn.debian.org/wsvn/debtorrent/debtorrent/branches/http-listen/DebTorrent/BT1/AptListener.py?rev=85&op=diff
==============================================================================
--- debtorrent/branches/http-listen/DebTorrent/BT1/AptListener.py (original)
+++ debtorrent/branches/http-listen/DebTorrent/BT1/AptListener.py Mon Jun 4 05:05:08 2007
@@ -44,6 +44,8 @@
True = 1
False = 0
bool = lambda x: not not x
+
+DEBUG = True
def statefiletemplate(x):
"""Check the saved state file for corruption.
@@ -190,10 +192,9 @@
"""
self.config = config
- return
self.dfile = config['dfile']
favicon = config['favicon']
- self.parse_dir_interval = config['parse_dir_interval']
+ self.parse_dir_interval = config['apt_parse_dir_interval']
self.favicon = None
if favicon:
try:
@@ -231,7 +232,7 @@
self.save_dfile_interval = config['save_dfile_interval']
self.show_names = config['show_names']
- rawserver.add_task(self.save_state, self.save_dfile_interval)
+ #rawserver.add_task(self.save_state, self.save_dfile_interval)
self.prevtime = clock()
self.logfile = None
self.log = None
@@ -267,7 +268,6 @@
self.allowed_list_mtime = 0
self.parse_allowed()
self.remove_from_state('allowed','allowed_dir_files')
- config['allowed_controls'] = 0
elif config['allowed_dir']:
self.allowed = self.state.setdefault('allowed',{})
@@ -279,7 +279,6 @@
else:
self.allowed = None
self.remove_from_state('allowed','allowed_dir_files', 'allowed_list')
- config['allowed_controls'] = 0
self.uq_broken = unquote('+') != ' '
self.Filter = Filter(rawserver.add_task)
@@ -287,7 +286,7 @@
def get_infopage(self):
"""Format the info page to display for normal browsers.
- Formats the currently tracked torrents into a table in human-readable
+ Formats the currently downloading torrents into a table in human-readable
format to display in a browser window.
@rtype: (C{int}, C{string}, C{dictionary}, C{string})
@@ -311,8 +310,8 @@
s.write('</head>\n<body>\n' \
'<h3>DebTorrent download info</h3>\n'\
'<ul>\n'
- '<li><strong>tracker version:</strong> %s</li>\n' \
- '<li><strong>server time:</strong> %s</li>\n' \
+ '<li><strong>client version:</strong> %s</li>\n' \
+ '<li><strong>client time:</strong> %s</li>\n' \
'</ul>\n' % (version, isotime()))
if self.config['allowed_dir']:
if self.show_names:
@@ -324,7 +323,7 @@
else:
names = [ (None,hash) for hash in self.downloads.keys() ]
if not names:
- s.write('<p>not tracking any files yet...</p>\n')
+ s.write('<p>not downloading any files yet...</p>\n')
else:
names.sort()
tn = 0
@@ -386,72 +385,39 @@
return (500, 'Internal Server Error', {'Content-Type': 'text/html; charset=iso-8859-1'}, 'Server Error')
- def get_file(self, hash):
- """Get the metainfo file for a torrent.
-
- @type hash: C{string}
- @param hash: the infohash of the torrent to get the metainfo of
+ def get_file(self, path):
+ """Proxy the download of a file from a mirror.
+
+ @type path: C{list} of C{string}
+ @param hash: the path of the file to download, starting with the mirror name
@rtype: (C{int}, C{string}, C{dictionary}, C{string})
@return: the HTTP status code, status message, headers, and bencoded
metainfo file
"""
- if not self.allow_get:
- return (400, 'Not Authorized', {'Content-Type': 'text/plain', 'Pragma': 'no-cache'},
- 'get function is not available with this tracker.')
- if not self.allowed.has_key(hash):
- return (404, 'Not Found', {'Content-Type': 'text/plain', 'Pragma': 'no-cache'}, alas)
- fname = self.allowed[hash]['file']
- fpath = self.allowed[hash]['path']
- return (200, 'OK', {'Content-Type': 'application/x-debtorrent',
- 'Content-Disposition': 'attachment; filename=' + fname},
- open(fpath, 'rb').read())
-
-
- def check_allowed(self, infohash, paramslist):
- """Determine whether the tracker is tracking this torrent.
-
- @type infohash: C{string}
- @param infohash: the infohash of the torrent to check
- @type paramslist: C{dictionary}
- @param paramslist: the query parameters from the GET request
- @rtype: (C{int}, C{string}, C{dictionary}, C{string})
- @return: the HTTP status code, status message, headers, and bencoded
- message body if the request is not allowed, or None if it is
-
- """
-
- if ( self.aggregator_key is not None
- and not ( paramslist.has_key('password')
- and paramslist['password'][0] == self.aggregator_key ) ):
- return (200, 'Not Authorized', {'Content-Type': 'text/plain', 'Pragma': 'no-cache'},
- bencode({'failure reason':
- 'Requested download is not authorized for use with this tracker.'}))
-
- if self.allowed is not None:
- if not self.allowed.has_key(infohash):
- return (200, 'Not Authorized', {'Content-Type': 'text/plain', 'Pragma': 'no-cache'},
- bencode({'failure reason':
- 'Requested download is not authorized for use with this tracker.'}))
- if self.config['allowed_controls']:
- if self.allowed[infohash].has_key('failure reason'):
- return (200, 'Not Authorized', {'Content-Type': 'text/plain', 'Pragma': 'no-cache'},
- bencode({'failure reason': self.allowed[infohash]['failure reason']}))
-
- if paramslist.has_key('tracker'):
- if ( self.config['multitracker_allowed'] == 'none' or # turned off
- paramslist['peer_id'][0] == self.trackerid ): # oops! contacted myself
- return (200, 'Not Authorized', {'Content-Type': 'text/plain', 'Pragma': 'no-cache'},
- bencode({'failure reason': 'disallowed'}))
-
- if ( self.config['multitracker_allowed'] == 'autodetect'
- and not self.allowed[infohash].has_key('announce-list') ):
- return (200, 'Not Authorized', {'Content-Type': 'text/plain', 'Pragma': 'no-cache'},
- bencode({'failure reason':
- 'Requested download is not authorized for multitracker use.'}))
-
- return None
+ try:
+ url = 'http://'
+ url += '/'.join(path)
+ if DEBUG:
+ print 'fetching:', url
+ f = urlopen(url)
+ headers = {}
+ for k,v in f.response.getheaders():
+ if k.lower() != 'content-length':
+ headers[k] = v
+ data = f.read()
+
+ return (200, 'OK', headers, data)
+
+ except IOError, e:
+ try:
+ (msg, status) = e
+ except:
+ status = 404
+ msg = 'Unknown error occurred'
+ return (status, 'Not Found', {'Content-Type': 'text/plain', 'Pragma': 'no-cache'}, msg)
+
def get(self, connection, path, headers):
@@ -488,16 +454,7 @@
or (self.banned_IPs and self.banned_IPs.includes(ip)) ):
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
+ 'your IP is not allowed on this proxy'}))
paramslist = {}
def params(key, default = None, l = paramslist):
@@ -534,78 +491,29 @@
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 not path in ('announce', 'announce.php', 'tracker.php/announce'):
+ if path == 'favicon.ico':
+ if self.favicon is not None:
+ return (200, 'OK', {'Content-Type' : 'image/x-icon'}, self.favicon)
+ else:
+ return (404, 'Not Found', {'Content-Type': 'text/plain', 'Pragma': 'no-cache'}, alas)
+
+ # Process the rest as a proxy
+ path = path.split('/')
+
+ if 'Packages.diff' in path:
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)
-
+# if path[-1] in ('Packages', 'Packages.gz', 'Packages.bz2'):
+# return self.get_Packages(path)
+
+# if path[-1][-4:] == '.deb':
+# return self.get_package(path)
+
+ return self.get_file(path)
+
except ValueError, e:
return (400, 'Bad Request', {'Content-Type': 'text/plain'},
'you sent me garbage - ' + str(e))
-
- if self.aggregate_forward and not paramslist.has_key('tracker'):
- 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 paramslist.has_key('scrape'): # 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))
def remove_from_state(self, *l):
Modified: debtorrent/branches/http-listen/DebTorrent/download_bt1.py
URL: http://svn.debian.org/wsvn/debtorrent/debtorrent/branches/http-listen/DebTorrent/download_bt1.py?rev=85&op=diff
==============================================================================
--- debtorrent/branches/http-listen/DebTorrent/download_bt1.py (original)
+++ debtorrent/branches/http-listen/DebTorrent/download_bt1.py Mon Jun 4 05:05:08 2007
@@ -194,6 +194,30 @@
"minutes between automatic flushes to disk (0 = disabled)"),
('dedicated_seed_id', '',
"code to send to tracker identifying as a dedicated seed"),
+ ('dfile', '', 'file to store recent apt downloader info in'),
+ ('socket_timeout', 15, 'timeout for closing connections'),
+ ('save_dfile_interval', 5 * 60, 'seconds between saving dfile'),
+ ('min_time_between_log_flushes', 3.0,
+ 'minimum time it must have been since the last flush to do another one'),
+ ('min_time_between_cache_refreshes', 600.0,
+ 'minimum time in seconds before a cache is considered stale and is flushed'),
+ ('allowed_dir', '', 'only allow downloads for .dtorrents in this dir'),
+ ('allowed_list', '', 'only allow downloads for hashes in this list (hex format, one per line)'),
+ ('hupmonitor', 0, 'whether to reopen the log file upon receipt of HUP signal'),
+ ('http_timeout', 60,
+ 'number of seconds to wait before assuming that an http connection has timed out'),
+ ('apt_parse_dir_interval', 60, 'seconds between reloading of allowed_dir or allowed_file ' +
+ 'and allowed_ips and banned_ips lists for apt'),
+ ('show_infopage', 1, "whether to display an info page when the tracker's root dir is loaded"),
+ ('infopage_redirect', '', 'a URL to redirect the info page to'),
+ ('show_names', 1, 'whether to display names from allowed dir'),
+ ('favicon', '', 'file containing x-icon data to return when browser requests favicon.ico'),
+ ('allowed_ips', '', 'only allow connections from IPs specified in the given file; '+
+ 'file contains subnet data in the format: aa.bb.cc.dd/len'),
+ ('banned_ips', '', "don't allow connections from IPs specified in the given file; "+
+ 'file contains IP range data in the format: xxx:xxx:ip1-ip2'),
+ ('logfile', '', 'file to write the tracker logs, use - for stdout (default)'),
+ ('allow_get', 0, 'use with allowed_dir; adds a /file?hash={hash} url that allows users to download the torrent file'),
]
argslistheader = 'Arguments are:\n\n'
More information about the Debtorrent-commits
mailing list