コード例 #1
0
    def _redirect(self, new_url, old_query):
        """Update announce URL from HTTP redirect"""
        if self._redirects >= self.MAX_REDIRECTS:
            raise IOError(('http error', 500,
                           'Internal Server Error: Redirect Recursion'))
        scheme, netloc, path, query, frag = urllib.parse.urlsplit(new_url)

        # If we got our own query string back, remove it
        oq_dict = urllib.parse.parse_qs(old_query)
        new_query = urllib.parse.urlencode(
            (key, val) for key, val in urllib.parse.parse_qsl(query)
            if val != oq_dict.get(key, ''))
        tracker_url = urllib.parse.urlunsplit(
            (scheme, netloc, path, new_query, frag))

        with self.announcer_lock:
            # It's possible to have the same redirect happen
            if tracker_url in self.announcers and \
                    self.announcers[tracker_url] == self:
                return
            self._redirects += 1
            self.announcers[tracker_url] = self

            self.stream = SharedStream(tracker_url)
            self.basequery = path + '?' + new_query + '&'[:bool(new_query)]
コード例 #2
0
    def __new__(cls, tracker_url, port, *args, **kwargs):
        """Return the Announcer associated with the tracker URL, creating a
        new one, if needed.

        Client port is made available to Announcer objects, but is assumed
        not to vary within a program, so calling with the same URL and two
        different ports will return the same object."""

        # Use Announcer() to allow scheme to decide on subclass
        if cls is Announcer:
            scheme = urllib.parse.urlsplit(tracker_url)[0]
            return cls.subclasses[scheme](tracker_url, port, *args, **kwargs)

        with cls.announcer_lock:
            # Assume port will not change within single Python instance
            # If this changes, change key to (tracker_url, port)
            if tracker_url not in cls.announcers:
                announcer = super(Announcer, cls).__new__(cls)
                # Keys allow trackers to recognize clients with IP changes
                announcer.key = random.randint(0,
                                               0xffffffff).to_bytes(4, 'big')
                announcer.stream = SharedStream(tracker_url)
                cls.announcers[tracker_url] = announcer
        return cls.announcers[tracker_url]