def putlfile(self, sha, fd):
     # unfortunately, httprepository._callpush tries to convert its
     # input file-like into a bundle before sending it, so we can't use
     # it ...
     if issubclass(self.__class__, httppeer.httppeer):
         res = self._call(
             'putlfile',
             data=fd,
             sha=sha,
             headers={'content-type': 'application/mercurial-0.1'})
         try:
             d, output = res.split('\n', 1)
             for l in output.splitlines(True):
                 self.ui.warn(_('remote: '), l)  # assume l ends with \n
             return int(d)
         except ValueError:
             self.ui.warn(_('unexpected putlfile response: %r\n') % res)
             return 1
     # ... but we can't use sshrepository._call because the data=
     # argument won't get sent, and _callpush does exactly what we want
     # in this case: send the data straight through
     else:
         try:
             ret, output = self._callpush("putlfile", fd, sha=sha)
             if ret == "":
                 raise error.ResponseError(_('putlfile failed:'),
                                           output)
             return int(ret)
         except IOError:
             return 1
         except ValueError:
             raise error.ResponseError(
                 _('putlfile failed (unexpected response):'), ret)
Esempio n. 2
0
    def receivemissing(self, pipe, filename, node):
        line = pipe.readline()[:-1]
        if not line:
            raise error.ResponseError(_("error downloading file contents:"),
                                      _("connection closed early"))
        size = int(line)
        data = pipe.read(size)
        if len(data) != size:
            raise error.ResponseError(
                _("error downloading file contents:"),
                _("only received %s of %s bytes") % (len(data), size))

        self.writedata.addremotefilelognode(filename, bin(node),
                                            zlib.decompress(data))
Esempio n. 3
0
def consumev1(repo, fp, filecount, bytecount):
    """Apply the contents from version 1 of a streaming clone file handle.

    This takes the output from "streamout" and applies it to the specified
    repository.

    Like "streamout," the status line added by the wire protocol is not handled
    by this function.
    """
    lock = repo.lock()
    try:
        repo.ui.status(
            _('%d files to transfer, %s of data\n') %
            (filecount, util.bytecount(bytecount)))
        handled_bytes = 0
        repo.ui.progress(_('clone'), 0, total=bytecount)
        start = time.time()

        tr = repo.transaction(_('clone'))
        try:
            for i in xrange(filecount):
                # XXX doesn't support '\n' or '\r' in filenames
                l = fp.readline()
                try:
                    name, size = l.split('\0', 1)
                    size = int(size)
                except (ValueError, TypeError):
                    raise error.ResponseError(
                        _('unexpected response from remote server:'), l)
                if repo.ui.debugflag:
                    repo.ui.debug('adding %s (%s)\n' %
                                  (name, util.bytecount(size)))
                # for backwards compat, name was partially encoded
                ofp = repo.svfs(store.decodedir(name), 'w')
                for chunk in util.filechunkiter(fp, limit=size):
                    handled_bytes += len(chunk)
                    repo.ui.progress(_('clone'),
                                     handled_bytes,
                                     total=bytecount)
                    ofp.write(chunk)
                ofp.close()
            tr.close()
        finally:
            tr.release()

        # Writing straight to files circumvented the inmemory caches
        repo.invalidate()

        elapsed = time.time() - start
        if elapsed <= 0:
            elapsed = 0.001
        repo.ui.progress(_('clone'), None)
        repo.ui.status(
            _('transferred %s in %.1f seconds (%s/sec)\n') %
            (util.bytecount(bytecount), elapsed,
             util.bytecount(bytecount / elapsed)))
    finally:
        lock.release()
Esempio n. 4
0
 def getlfile(self, sha):
     stream = self._callstream("getlfile", sha=sha)
     length = stream.readline()
     try:
         length = int(length)
     except ValueError:
         self._abort(
             error.ResponseError(_("unexpected response:"), length))
     return (length, stream)
Esempio n. 5
0
    def receivemissing(self, pipe, missingid):
        line = pipe.readline()[:-1]
        if not line:
            raise error.ResponseError(
                _("error downloading file " +
                  "contents: connection closed early\n"), '')
        size = int(line)
        data = pipe.read(size)

        self.localcache.write(missingid, lz4.decompress(data))
        def getlfile(self, sha):
            """returns an iterable with the chunks of the file with sha sha"""
            stream = self._callstream("getlfile", sha=sha)
            length = stream.readline()
            try:
                length = int(length)
            except ValueError:
                self._abort(
                    error.ResponseError(_("unexpected response:"), length))

            # SSH streams will block if reading more than length
            for chunk in util.filechunkiter(stream, limit=length):
                yield chunk
            # HTTP streams must hit the end to process the last empty
            # chunk of Chunked-Encoding so the connection can be reused.
            if issubclass(self.__class__, httppeer.httppeer):
                chunk = stream.read(1)
                if chunk:
                    self._abort(
                        error.ResponseError(_("unexpected response:"), chunk))
Esempio n. 7
0
def maybeperformlegacystreamclone(pullop):
    """Possibly perform a legacy stream clone operation.

    Legacy stream clones are performed as part of pull but before all other
    operations.

    A legacy stream clone will not be performed if a bundle2 stream clone is
    supported.
    """
    supported, requirements = canperformstreamclone(pullop)

    if not supported:
        return

    repo = pullop.repo
    remote = pullop.remote

    # Save remote branchmap. We will use it later to speed up branchcache
    # creation.
    rbranchmap = None
    if remote.capable('branchmap'):
        rbranchmap = remote.branchmap()

    repo.ui.status(_('streaming all changes\n'))

    fp = remote.stream_out()
    l = fp.readline()
    try:
        resp = int(l)
    except ValueError:
        raise error.ResponseError(_('unexpected response from remote server:'),
                                  l)
    if resp == 1:
        raise error.Abort(_('operation forbidden by server'))
    elif resp == 2:
        raise error.Abort(_('locking the remote repository failed'))
    elif resp != 0:
        raise error.Abort(_('the server sent an unknown error code'))

    l = fp.readline()
    try:
        filecount, bytecount = map(int, l.split(' ', 1))
    except (ValueError, TypeError):
        raise error.ResponseError(_('unexpected response from remote server:'),
                                  l)

    lock = repo.lock()
    try:
        consumev1(repo, fp, filecount, bytecount)

        # new requirements = old non-format requirements +
        #                    new format-related remote requirements
        # requirements from the streamed-in repository
        repo.requirements = requirements | (repo.requirements -
                                            repo.supportedformats)
        repo._applyopenerreqs()
        repo._writerequirements()

        if rbranchmap:
            branchmap.replacecache(repo, rbranchmap)

        repo.invalidate()
    finally:
        lock.release()