Example #1
0
    def handle(self):
        proto = ReceivableProtocol(self.connection.recv, self.wfile.write)
        command, args = proto.read_cmd()
        logger.info('Handling %s request, args=%s', command, args)

        cls = self.handlers.get(command, None)
        if not callable(cls):
            raise GitProtocolError('Invalid service %s' % command)
        h = cls(self.server.backend, args, proto)
        h.handle()
Example #2
0
    def handle(self):
        proto = ReceivableProtocol(self.connection.recv, self.wfile.write)
        command, args = proto.read_cmd()
        logger.info('Handling %s request, args=%s', command, args)

        cls = self.handlers.get(command, None)
        if not callable(cls):
            raise GitProtocolError('Invalid service %s' % command)
        h = cls(self.server.backend, args, proto)
        h.handle()
Example #3
0
    def run(self, flavor, repo_path, data):
        backend = load_backend(flavor, repo_path, cache=False)
        out = StringIO()
        proto = ReceivableProtocol(StringIO(data).read, out.write)
        handler = _ReceivePackHandler(WebBackend(), [backend],
                                      proto,
                                      stateless_rpc=True)
        handler.handle()

        sync_tasks = []
        for oldrev, newrev, name in handler._good_refs:
            if name.startswith('refs/heads/'):
                branch = name[11:]
                sync_tasks.append(
                    subtask(SyncTask,
                            args=[
                                backend.flavor, backend.path, oldrev, newrev,
                                branch
                            ]))

        if sync_tasks:
            taskset = TaskSet(tasks=sync_tasks)
            taskset.apply_async().join()

        return out.getvalue(), handler._good_refs
Example #4
0
def get_info_refs(req, backend, mat):
    params = parse_qs(req.environ["QUERY_STRING"])
    service = params.get("service", [None])[0]
    try:
        repo = get_repo(backend, mat)
    except NotGitRepository as e:
        yield req.not_found(str(e))
        return
    if service and not req.dumb:
        handler_cls = req.handlers.get(service.encode("ascii"), None)
        if handler_cls is None:
            yield req.forbidden("Unsupported service")
            return
        req.nocache()
        write = req.respond(HTTP_OK, "application/x-%s-advertisement" % service)
        proto = ReceivableProtocol(BytesIO().read, write)
        handler = handler_cls(
            backend,
            [url_prefix(mat)],
            proto,
            stateless_rpc=req,
            advertise_refs=True,
        )
        handler.proto.write_pkt_line(b"# service=" + service.encode("ascii") + b"\n")
        handler.proto.write_pkt_line(None)
        handler.handle()
    else:
        # non-smart fallback
        # TODO: select_getanyfile() (see http-backend.c)
        req.nocache()
        req.respond(HTTP_OK, "text/plain")
        logger.info("Emulating dumb info/refs")
        for text in generate_info_refs(repo):
            yield text
Example #5
0
def get_info_refs(req, backend, mat):
    params = parse_qs(req.environ['QUERY_STRING'])
    service = params.get('service', [None])[0]
    try:
        repo = get_repo(backend, mat)
    except NotGitRepository as e:
        yield req.not_found(str(e))
        return
    if service and not req.dumb:
        handler_cls = req.handlers.get(service.encode('ascii'), None)
        if handler_cls is None:
            yield req.forbidden('Unsupported service')
            return
        req.nocache()
        write = req.respond(
            HTTP_OK, 'application/x-%s-advertisement' % service)
        proto = ReceivableProtocol(BytesIO().read, write)
        handler = handler_cls(backend, [url_prefix(mat)], proto,
                              http_req=req, advertise_refs=True)
        handler.proto.write_pkt_line(
            b'# service=' + service.encode('ascii') + b'\n')
        handler.proto.write_pkt_line(None)
        handler.handle()
    else:
        # non-smart fallback
        # TODO: select_getanyfile() (see http-backend.c)
        req.nocache()
        req.respond(HTTP_OK, 'text/plain')
        logger.info('Emulating dumb info/refs')
        for text in generate_info_refs(repo):
            yield text
Example #6
0
 def handle():
     r = repo._git
     proto = ReceivableProtocol(inf.read, outf.write)
     handler = handler_cls(DictBackend({".": r}), ["."],
                           proto,
                           stateless_rpc=True)
     handler.handle()
Example #7
0
File: web.py Project: wavii/dulwich
def handle_service_request(req, backend, mat):
    service = mat.group().lstrip('/')
    logger.info('Handling service request for %s', service)
    handler_cls = req.handlers.get(service, None)
    if handler_cls is None:
        yield req.forbidden('Unsupported service %s' % service)
        return
    req.nocache()
    write = req.respond(HTTP_OK, 'application/x-%s-result' % service)
    proto = ReceivableProtocol(req.environ['wsgi.input'].read, write)
    handler = handler_cls(backend, [url_prefix(mat)], proto, http_req=req)
    handler.handle()
Example #8
0
    def setUp(self):
        TestCase.setUp(self)
        self.rout = BytesIO()
        self.rin = ReceivableBytesIO()

        def _closeit():
            self.rout.close()
            self.rin.close()

        self.proto = ReceivableProtocol(self.rin.recv, self.rout.write, _closeit)
        self.proto._rbufsize = 8
        self.addCleanup(self.proto.close)
Example #9
0
async def dulwich_refs(request):
    package = request.match_info["package"]

    allow_writes = await is_worker(request.app.db, request)

    span = aiozipkin.request_span(request)
    with span.new_child('open-repo'):
        repo = await _git_open_repo(request.app.vcs_manager, request.app.db,
                                    package)
    r = repo._git

    service = request.query.get("service")
    _git_check_service(service, allow_writes)

    headers = {
        "Expires": "Fri, 01 Jan 1980 00:00:00 GMT",
        "Pragma": "no-cache",
        "Cache-Control": "no-cache, max-age=0, must-revalidate",
    }

    handler_cls = DULWICH_SERVICE_HANDLERS[service.encode("ascii")]

    response = web.StreamResponse(status=200, headers=headers)
    response.content_type = "application/x-%s-advertisement" % service

    await response.prepare(request)

    out = BytesIO()
    proto = ReceivableProtocol(BytesIO().read, out.write)
    handler = handler_cls(DictBackend({".": r}), ["."],
                          proto,
                          stateless_rpc=True,
                          advertise_refs=True)
    handler.proto.write_pkt_line(b"# service=" + service.encode("ascii") +
                                 b"\n")
    handler.proto.write_pkt_line(None)

    await asyncio.to_thread(handler.handle)

    await response.write(out.getvalue())

    await response.write_eof()

    return response
Example #10
0
def handle_service_request(req, backend, mat):
    service = mat.group().lstrip("/")
    logger.info("Handling service request for %s", service)
    handler_cls = req.handlers.get(service.encode("ascii"), None)
    if handler_cls is None:
        yield req.forbidden("Unsupported service")
        return
    try:
        get_repo(backend, mat)
    except NotGitRepository as e:
        yield req.not_found(str(e))
        return
    req.nocache()
    write = req.respond(HTTP_OK, "application/x-%s-result" % service)
    proto = ReceivableProtocol(req.environ["wsgi.input"].read, write)
    # TODO(user): Find a way to pass in repo, rather than having handler_cls
    # reopen.
    handler = handler_cls(backend, [url_prefix(mat)], proto, stateless_rpc=req)
    handler.handle()
Example #11
0
def handle_service_request(req, backend, mat):
    service = mat.group().lstrip('/')
    logger.info('Handling service request for %s', service)
    handler_cls = req.handlers.get(service.encode('ascii'), None)
    if handler_cls is None:
        yield req.forbidden('Unsupported service')
        return
    try:
        get_repo(backend, mat)
    except NotGitRepository as e:
        yield req.not_found(str(e))
        return
    req.nocache()
    write = req.respond(HTTP_OK, 'application/x-%s-result' % service)
    proto = ReceivableProtocol(req.environ['wsgi.input'].read, write)
    # TODO(jelmer): Find a way to pass in repo, rather than having handler_cls
    # reopen.
    handler = handler_cls(backend, [url_prefix(mat)], proto, http_req=req)
    handler.handle()
Example #12
0
def handle_service_request(req, backend, mat):
    service = mat.group().lstrip('/')
    logger.info('Handling service request for %s', service)
    handler_cls = req.handlers.get(service, None)
    if handler_cls is None:
        yield req.forbidden('Unsupported service %s' % service)
        return
    req.nocache()
    write = req.respond(HTTP_OK, 'application/x-%s-result' % service)

    input = req.environ['wsgi.input']
    # This is not necessary if this app is run from a conforming WSGI server.
    # Unfortunately, there's no way to tell that at this point.
    # TODO: git may used HTTP/1.1 chunked encoding instead of specifying
    # content-length
    content_length = req.environ.get('CONTENT_LENGTH', '')
    if content_length:
        input = _LengthLimitedFile(input, int(content_length))
    proto = ReceivableProtocol(input.read, write)
    handler = handler_cls(backend, [url_prefix(mat)], proto, http_req=req)
    handler.handle()
Example #13
0
class ReceivableProtocolTests(BaseProtocolTests, TestCase):

    def setUp(self):
        TestCase.setUp(self)
        self.rout = BytesIO()
        self.rin = ReceivableBytesIO()

        def _closeit():
            self.rout.close()
            self.rin.close()

        self.proto = ReceivableProtocol(self.rin.recv, self.rout.write, _closeit)
        self.proto._rbufsize = 8
        self.addCleanup(self.proto.close)

    def test_eof(self):
        # Allow blocking reads past EOF just for this test. The only parts of
        # the protocol that might check for EOF do not depend on the recv()
        # semantics anyway.
        self.rin.allow_read_past_eof = True
        BaseProtocolTests.test_eof(self)

    def test_recv(self):
        all_data = b'1234567' * 10  # not a multiple of bufsize
        self.rin.write(all_data)
        self.rin.seek(0)
        data = b''
        # We ask for 8 bytes each time and actually read 7, so it should take
        # exactly 10 iterations.
        for _ in range(10):
            data += self.proto.recv(10)
        # any more reads would block
        self.assertRaises(AssertionError, self.proto.recv, 10)
        self.assertEqual(all_data, data)

    def test_recv_read(self):
        all_data = b'1234567'  # recv exactly in one call
        self.rin.write(all_data)
        self.rin.seek(0)
        self.assertEqual(b'1234', self.proto.recv(4))
        self.assertEqual(b'567', self.proto.read(3))
        self.assertRaises(AssertionError, self.proto.recv, 10)

    def test_read_recv(self):
        all_data = b'12345678abcdefg'
        self.rin.write(all_data)
        self.rin.seek(0)
        self.assertEqual(b'1234', self.proto.read(4))
        self.assertEqual(b'5678abc', self.proto.recv(8))
        self.assertEqual(b'defg', self.proto.read(4))
        self.assertRaises(AssertionError, self.proto.recv, 10)

    def test_mixed(self):
        # arbitrary non-repeating string
        all_data = ','.join(str(i) for i in range(100)).encode('utf-8')
        self.rin.write(all_data)
        self.rin.seek(0)
        data = b''

        for i in range(1, 100):
            data += self.proto.recv(i)
            # if we get to the end, do a non-blocking read instead of blocking
            if len(data) + i > len(all_data):
                data += self.proto.recv(i)
                # ReceivableBytesIO leaves off the last byte unless we ask
                # nicely
                data += self.proto.recv(1)
                break
            else:
                data += self.proto.read(i)
        else:
            # didn't break, something must have gone wrong
            self.fail()

        self.assertEqual(all_data, data)
Example #14
0
 def setUp(self):
     TestCase.setUp(self)
     self.rout = StringIO()
     self.rin = ReceivableStringIO()
     self.proto = ReceivableProtocol(self.rin.recv, self.rout.write)
     self.proto._rbufsize = 8
Example #15
0
class ReceivableProtocolTests(BaseProtocolTests, TestCase):

    def setUp(self):
        TestCase.setUp(self)
        self.rout = StringIO()
        self.rin = ReceivableStringIO()
        self.proto = ReceivableProtocol(self.rin.recv, self.rout.write)
        self.proto._rbufsize = 8

    def test_recv(self):
        all_data = "1234567" * 10  # not a multiple of bufsize
        self.rin.write(all_data)
        self.rin.seek(0)
        data = ""
        # We ask for 8 bytes each time and actually read 7, so it should take
        # exactly 10 iterations.
        for _ in xrange(10):
            data += self.proto.recv(10)
        # any more reads would block
        self.assertRaises(AssertionError, self.proto.recv, 10)
        self.assertEquals(all_data, data)

    def test_recv_read(self):
        all_data = "1234567"  # recv exactly in one call
        self.rin.write(all_data)
        self.rin.seek(0)
        self.assertEquals("1234", self.proto.recv(4))
        self.assertEquals("567", self.proto.read(3))
        self.assertRaises(AssertionError, self.proto.recv, 10)

    def test_read_recv(self):
        all_data = "12345678abcdefg"
        self.rin.write(all_data)
        self.rin.seek(0)
        self.assertEquals("1234", self.proto.read(4))
        self.assertEquals("5678abc", self.proto.recv(8))
        self.assertEquals("defg", self.proto.read(4))
        self.assertRaises(AssertionError, self.proto.recv, 10)

    def test_mixed(self):
        # arbitrary non-repeating string
        all_data = ",".join(str(i) for i in xrange(100))
        self.rin.write(all_data)
        self.rin.seek(0)
        data = ""

        for i in xrange(1, 100):
            data += self.proto.recv(i)
            # if we get to the end, do a non-blocking read instead of blocking
            if len(data) + i > len(all_data):
                data += self.proto.recv(i)
                # ReceivableStringIO leaves off the last byte unless we ask
                # nicely
                data += self.proto.recv(1)
                break
            else:
                data += self.proto.read(i)
        else:
            # didn't break, something must have gone wrong
            self.fail()

        self.assertEquals(all_data, data)
Example #16
0
 def setUp(self):
     TestCase.setUp(self)
     self.rout = StringIO()
     self.rin = ReceivableStringIO()
     self.proto = ReceivableProtocol(self.rin.recv, self.rout.write)
     self.proto._rbufsize = 8
Example #17
0
class ReceivableProtocolTests(BaseProtocolTests, TestCase):
    def setUp(self):
        TestCase.setUp(self)
        self.rout = StringIO()
        self.rin = ReceivableStringIO()
        self.proto = ReceivableProtocol(self.rin.recv, self.rout.write)
        self.proto._rbufsize = 8

    def test_eof(self):
        # Allow blocking reads past EOF just for this test. The only parts of
        # the protocol that might check for EOF do not depend on the recv()
        # semantics anyway.
        self.rin.allow_read_past_eof = True
        BaseProtocolTests.test_eof(self)

    def test_recv(self):
        all_data = '1234567' * 10  # not a multiple of bufsize
        self.rin.write(all_data)
        self.rin.seek(0)
        data = ''
        # We ask for 8 bytes each time and actually read 7, so it should take
        # exactly 10 iterations.
        for _ in xrange(10):
            data += self.proto.recv(10)
        # any more reads would block
        self.assertRaises(AssertionError, self.proto.recv, 10)
        self.assertEquals(all_data, data)

    def test_recv_read(self):
        all_data = '1234567'  # recv exactly in one call
        self.rin.write(all_data)
        self.rin.seek(0)
        self.assertEquals('1234', self.proto.recv(4))
        self.assertEquals('567', self.proto.read(3))
        self.assertRaises(AssertionError, self.proto.recv, 10)

    def test_read_recv(self):
        all_data = '12345678abcdefg'
        self.rin.write(all_data)
        self.rin.seek(0)
        self.assertEquals('1234', self.proto.read(4))
        self.assertEquals('5678abc', self.proto.recv(8))
        self.assertEquals('defg', self.proto.read(4))
        self.assertRaises(AssertionError, self.proto.recv, 10)

    def test_mixed(self):
        # arbitrary non-repeating string
        all_data = ','.join(str(i) for i in xrange(100))
        self.rin.write(all_data)
        self.rin.seek(0)
        data = ''

        for i in xrange(1, 100):
            data += self.proto.recv(i)
            # if we get to the end, do a non-blocking read instead of blocking
            if len(data) + i > len(all_data):
                data += self.proto.recv(i)
                # ReceivableStringIO leaves off the last byte unless we ask
                # nicely
                data += self.proto.recv(1)
                break
            else:
                data += self.proto.read(i)
        else:
            # didn't break, something must have gone wrong
            self.fail()

        self.assertEquals(all_data, data)