Example #1
0
    def _getPiece(self, response, piece, site):
        """Process the retrieved headers from the peer."""
        if response.code == 404:
            # Peer no longer has this file, move on
            log.msg('Peer sharing piece %d no longer has it: %r' % (piece, self.peers[site]['peer']))
            self.completePieces[piece] = False
            if response.stream and response.stream.length:
                stream.readAndDiscard(response.stream)
            
            # Don't add the site back, just move on
            site = None
        elif ((len(self.completePieces) > 1 and response.code != 206) or
            (response.code not in (200, 206))):
            # Request failed, try a different peer
            log.msg('Wrong response type %d for piece %d from peer %r' % (response.code, piece, self.peers[site]['peer']))
            self.peers[site]['peer'].hashError('Peer responded with the wrong type of download: %r' % response.code)
            self.completePieces[piece] = False
            self.peers[site]['errors'] = self.peers[site].get('errors', 0) + 1
            if response.stream and response.stream.length:
                stream.readAndDiscard(response.stream)

            # After 3 errors in a row, drop the peer
            if self.peers[site]['errors'] >= 3:
                site = None
        else:
            if self.defer:
                # Start sending the return file
                df = self.defer
                self.defer = None
                self.stream = GrowingFileStream(self.file, self.hash.expSize)

                # Get the headers from the peer's response
                headers = {}
                if response.headers.hasHeader('last-modified'):
                    headers['last-modified'] = response.headers.getHeader('last-modified')
                resp = Response(200, headers, self.stream)
                df.callback(resp)

            # Read the response stream to the file
            log.msg('Streaming piece %d from peer %r' % (piece, self.peers[site]['peer']))
            if response.code == 206:
                df = StreamToFile(self.hash.newPieceHasher(), response.stream,
                                  self.file, piece*PIECE_SIZE, PIECE_SIZE).run()
            else:
                df = StreamToFile(self.hash.newHasher(), response.stream,
                                  self.file).run()
            reactor.callLater(0, df.addCallbacks,
                              *(self._gotPiece, self._gotError),
                              **{'callbackArgs': (piece, site),
                                 'errbackArgs': (piece, site)})

        self.outstanding -= 1
        if site:
            self.sitelist.append(site)
        else:
            self.addMirror()
        self.getPieces()
Example #2
0
 def close(self):
     # Assume error will be raised again and handled by MMS?
     readAndDiscard(self).addErrback(lambda _: None)
Example #3
0
 def close(self):
     # Assume error will be raised again and handled by MMS?
     readAndDiscard(self).addErrback(lambda _: None)
Example #4
0
    def _getPiece(self, response, piece, site):
        """Process the retrieved headers from the peer."""
        if response.code == 404:
            # Peer no longer has this file, move on
            log.msg('Peer sharing piece %d no longer has it: %r' %
                    (piece, self.peers[site]['peer']))
            self.completePieces[piece] = False
            if response.stream and response.stream.length:
                stream.readAndDiscard(response.stream)

            # Don't add the site back, just move on
            site = None
        elif ((len(self.completePieces) > 1 and response.code != 206)
              or (response.code not in (200, 206))):
            # Request failed, try a different peer
            log.msg('Wrong response type %d for piece %d from peer %r' %
                    (response.code, piece, self.peers[site]['peer']))
            self.peers[site]['peer'].hashError(
                'Peer responded with the wrong type of download: %r' %
                response.code)
            self.completePieces[piece] = False
            self.peers[site]['errors'] = self.peers[site].get('errors', 0) + 1
            if response.stream and response.stream.length:
                stream.readAndDiscard(response.stream)

            # After 3 errors in a row, drop the peer
            if self.peers[site]['errors'] >= 3:
                site = None
        else:
            if self.defer:
                # Start sending the return file
                df = self.defer
                self.defer = None
                self.stream = GrowingFileStream(self.file, self.hash.expSize)

                # Get the headers from the peer's response
                headers = {}
                if response.headers.hasHeader('last-modified'):
                    headers['last-modified'] = response.headers.getHeader(
                        'last-modified')
                resp = Response(200, headers, self.stream)
                df.callback(resp)

            # Read the response stream to the file
            log.msg('Streaming piece %d from peer %r' %
                    (piece, self.peers[site]['peer']))
            if response.code == 206:
                df = StreamToFile(self.hash.newPieceHasher(), response.stream,
                                  self.file, piece * PIECE_SIZE,
                                  PIECE_SIZE).run()
            else:
                df = StreamToFile(self.hash.newHasher(), response.stream,
                                  self.file).run()
            reactor.callLater(
                0, df.addCallbacks, *(self._gotPiece, self._gotError), **{
                    'callbackArgs': (piece, site),
                    'errbackArgs': (piece, site)
                })

        self.outstanding -= 1
        if site:
            self.sitelist.append(site)
        else:
            self.addMirror()
        self.getPieces()