Пример #1
0
 def drain(self):
     '''need to read all data from request, httplib is half-duplex'''
     length = int(self.env.get('CONTENT_LENGTH', 0))
     for s in util.filechunkiter(self.inp, limit=length):
         pass
Пример #2
0
def unbundle(repo, req):

    proto = req.env.get('wsgi.url_scheme') or 'http'
    their_heads = req.form['heads'][0].split(' ')

    def check_heads():
        heads = map(hex, repo.heads())
        return their_heads == [hex('force')] or their_heads == heads

    # fail early if possible
    if not check_heads():
        req.drain()
        raise ErrorResponse(HTTP_OK, 'unsynced changes')

    # do not lock repo until all changegroup data is
    # streamed. save to temporary file.

    fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-')
    fp = os.fdopen(fd, 'wb+')
    try:
        length = int(req.env['CONTENT_LENGTH'])
        for s in util.filechunkiter(req, limit=length):
            fp.write(s)

        try:
            lock = repo.lock()
            try:
                if not check_heads():
                    raise ErrorResponse(HTTP_OK, 'unsynced changes')

                fp.seek(0)
                header = fp.read(6)
                if header.startswith('HG') and not header.startswith('HG10'):
                    raise ValueError('unknown bundle version')
                elif header not in changegroupmod.bundletypes:
                    raise ValueError('unknown bundle compression type')
                gen = changegroupmod.unbundle(header, fp)

                # send addchangegroup output to client

                oldio = sys.stdout, sys.stderr
                sys.stderr = sys.stdout = cStringIO.StringIO()

                try:
                    url = 'remote:%s:%s:%s' % (
                        proto, urllib.quote(req.env.get('REMOTE_HOST', '')),
                        urllib.quote(req.env.get('REMOTE_USER', '')))
                    try:
                        ret = repo.addchangegroup(gen, 'serve', url)
                    except util.Abort, inst:
                        sys.stdout.write("abort: %s\n" % inst)
                        ret = 0
                finally:
                    val = sys.stdout.getvalue()
                    sys.stdout, sys.stderr = oldio
                req.respond(HTTP_OK, HGTYPE)
                return '%d\n%s' % (ret, val),
            finally:
                lock.release()
        except ValueError, inst:
            raise ErrorResponse(HTTP_OK, inst)
        except (OSError, IOError), inst:
            filename = getattr(inst, 'filename', '')
            # Don't send our filesystem layout to the client
            if filename.startswith(repo.root):
                filename = filename[len(repo.root) + 1:]
            else:
                filename = ''
            error = getattr(inst, 'strerror', 'Unknown error')
            if inst.errno == errno.ENOENT:
                code = HTTP_NOT_FOUND
            else:
                code = HTTP_SERVER_ERROR
            raise ErrorResponse(code, '%s: %s' % (error, filename))
Пример #3
0
def unbundle(repo, req):

    proto = req.env.get('wsgi.url_scheme') or 'http'
    their_heads = req.form['heads'][0].split(' ')

    def check_heads():
        heads = map(hex, repo.heads())
        return their_heads == [hex('force')] or their_heads == heads

    # fail early if possible
    if not check_heads():
        req.drain()
        raise ErrorResponse(HTTP_OK, 'unsynced changes')

    # do not lock repo until all changegroup data is
    # streamed. save to temporary file.

    fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-')
    fp = os.fdopen(fd, 'wb+')
    try:
        length = int(req.env['CONTENT_LENGTH'])
        for s in util.filechunkiter(req, limit=length):
            fp.write(s)

        try:
            lock = repo.lock()
            try:
                if not check_heads():
                    raise ErrorResponse(HTTP_OK, 'unsynced changes')

                fp.seek(0)
                header = fp.read(6)
                if header.startswith('HG') and not header.startswith('HG10'):
                    raise ValueError('unknown bundle version')
                elif header not in changegroupmod.bundletypes:
                    raise ValueError('unknown bundle compression type')
                gen = changegroupmod.unbundle(header, fp)

                # send addchangegroup output to client

                oldio = sys.stdout, sys.stderr
                sys.stderr = sys.stdout = cStringIO.StringIO()

                try:
                    url = 'remote:%s:%s:%s' % (
                          proto,
                          urllib.quote(req.env.get('REMOTE_HOST', '')),
                          urllib.quote(req.env.get('REMOTE_USER', '')))
                    try:
                        ret = repo.addchangegroup(gen, 'serve', url)
                    except util.Abort, inst:
                        sys.stdout.write("abort: %s\n" % inst)
                        ret = 0
                finally:
                    val = sys.stdout.getvalue()
                    sys.stdout, sys.stderr = oldio
                req.respond(HTTP_OK, HGTYPE)
                return '%d\n%s' % (ret, val),
            finally:
                lock.release()
        except ValueError, inst:
            raise ErrorResponse(HTTP_OK, inst)
        except (OSError, IOError), inst:
            filename = getattr(inst, 'filename', '')
            # Don't send our filesystem layout to the client
            if filename.startswith(repo.root):
                filename = filename[len(repo.root)+1:]
            else:
                filename = ''
            error = getattr(inst, 'strerror', 'Unknown error')
            if inst.errno == errno.ENOENT:
                code = HTTP_NOT_FOUND
            else:
                code = HTTP_SERVER_ERROR
            raise ErrorResponse(code, '%s: %s' % (error, filename))