def get_response(file, url, errorfunc):
    try:
        if file:
            h = open(file, 'rb')
            try:
                # quick test to see if responsefile contains a dict
                line = h.read(10)
                front = line.split(':', 1)[0]
                assert front[0] == 'd'
                int(front[1:])
            except (AssertionError, IOError):
                errorfunc(file + ' is not a valid responsefile')
                return None
            try:
                h.seek(0)
            except IOError:
                try:
                    h.close()
                except IOError:
                    pass
                h = open(file, 'rb')
        else:
            try:
                h = urlopen(url)
            except socket.error:
                errorfunc(url + ' bad url')
                return None
        response = h.read()

    except IOError as e:
        errorfunc('problem getting response info - ' + str(e))
        return None
    try:
        h.close()
    except (IOError, socket.error):
        pass
    try:
        try:
            response = bdecode(response)
        except ValueError:
            errorfunc("warning: bad data in responsefile")
            response = bdecode(response, sloppy=1)
        check_type(response, dict)
        check_info(response.get('info'))
        check_type(response.get('announce'), str)
    except ValueError as e:
        errorfunc("got bad file info - " + str(e))
        return None

    return response
Exemple #2
0
 def getTorrentData(self, torrent):
     """Read a torrent data file from cache"""
     if torrent in self.torrentDataBuffer:
         return self.torrentDataBuffer[torrent]
     fname = os.path.join(self.dir_datacache, hexlify(torrent))
     if not os.path.exists(fname):
         return None
     try:
         with open(fname, 'rb') as f:
             data = bdecode(f.read())
     except (IOError, ValueError):
         data = None
     self.torrentDataBuffer[fname] = data
     return data
Exemple #3
0
    def getTorrent(self, torrent, version=-1):
        """Return the contents of a torrent file

        If version is -1 (default), get the most recent.
        If version is specified and > -1, retrieve specified version."""
        torrent = hexlify(torrent)
        fname = os.path.join(self.dir_torrentcache, torrent)

        if version == -1:
            version = max(self.getTorrentVariations(torrent))
        if version:
            fname += '.' + str(version)

        try:
            with open(fname, 'rb') as f:
                return bdecode(f.read())
        except (IOError, ValueError):
            return None
Exemple #4
0
    def _open(self, url):
        self.tries += 1
        if self.tries > MAX_REDIRECTS:
            raise IOError(('http error', 500,
                           "Internal Server Error: Redirect Recursion"))
        (scheme, netloc, path, pars, query, _) = urlparse.urlparse(url)
        if scheme != 'http' and scheme != 'https':
            raise IOError(('url error', 'unknown url type', scheme, url))
        url = path
        if pars:
            url += ';' + pars
        if query:
            url += '?' + query
#        if fragment:
        try:
            if scheme == 'http':
                self.connection = btHTTPcon(netloc)
            else:
                self.connection = btHTTPScon(netloc)
            self.connection.request('GET', url, None, {
                'User-Agent': VERSION,
                'Accept-Encoding': 'gzip'
            })
            self.response = self.connection.getresponse()
        except httplib.HTTPException as e:
            raise IOError(('http error', str(e)))
        status = self.response.status
        if status in (301, 302):
            try:
                self.connection.close()
            except socket.error:
                pass
            self._open(self.response.getheader('Location'))
            return
        if status != 200:
            try:
                data = self._read()
                d = bdecode(data)
                if 'failure reason' in d:
                    self.error_return = data
                    return
            except (IOError, ValueError):
                pass
            raise IOError(('http error', status, self.response.reason))
    def _rerequest_single(self, t, s, l, callback):
        try:
            closer = [None]

            def timedout(self=self, l=l, closer=closer):
                if self.lock.trip(l):
                    self.errorcodes['troublecode'] = 'Problem connecting to ' \
                        'tracker - timeout exceeded'
                    self.lock.unwait(l)
                try:
                    closer[0]()
                except Exception:
                    pass

            self.externalsched(timedout, self.timeout)

            err = None
            try:
                url, q = t.split('?', 1)
                q += '&' + s
            except ValueError:
                url = t
                q = s
            try:
                h = urlopen(url + '?' + q)
                closer[0] = h.close
                data = h.read()
            except (IOError, socket.error) as e:
                err = 'Problem connecting to tracker - ' + str(e)
            except Exception:
                err = 'Problem connecting to tracker'
            try:
                h.close()
            except socket.error:
                pass
            if err:
                if self.lock.trip(l):
                    self.errorcodes['troublecode'] = err
                    self.lock.unwait(l)
                return

            if data == '':
                if self.lock.trip(l):
                    self.errorcodes['troublecode'] = 'no data from tracker'
                    self.lock.unwait(l)
                return

            try:
                r = bdecode(data, sloppy=1)
                check_peers(r)
            except ValueError as e:
                if self.lock.trip(l):
                    self.errorcodes['bad_data'] = 'bad data from tracker - ' \
                        + str(e)
                    self.lock.unwait(l)
                return

            if 'failure reason' in r:
                if self.lock.trip(l):
                    self.errorcodes['rejected'] = self.rejectedmessage + \
                        r['failure reason']
                    self.lock.unwait(l)
                return

            if self.lock.trip(l, True):  # success!
                self.lock.unwait(l)
            else:
                # attempt timed out, don't do a callback
                callback = lambda: None

            # even if the attempt timed out, go ahead and process data
            def add(self=self, r=r, callback=callback):
                self.postrequest(r, callback)

            self.externalsched(add)
        except Exception:
            self.exception(callback)