← Back to team overview

dulwich-users team mailing list archive

[PATCH 01/13] Pass an HTTP request object through to handlers.

 

From: Dave Borowitz <dborowitz@xxxxxxxxxx>

Replaces the boolean stateless_rpc argument. This allows handlers to
not only detect whether they're running in a stateless RPC call, but
also to use request-specific data.

Change-Id: I19623fda358c6806ac759a61a183ed561a357a86
---
 NEWS                         |    2 ++
 dulwich/server.py            |   29 ++++++++++++++---------------
 dulwich/tests/test_server.py |    4 ++--
 dulwich/tests/test_web.py    |    8 ++++----
 dulwich/web.py               |    4 ++--
 5 files changed, 24 insertions(+), 23 deletions(-)

diff --git a/NEWS b/NEWS
index 9de2604..6746e66 100644
--- a/NEWS
+++ b/NEWS
@@ -87,6 +87,8 @@
 
   * Optionally pass a RenameDetector to tree_changes. (Dave Borowitz)
 
+  * Optionally pass a request object through to server handlers. (Dave Borowitz)
+
  TEST CHANGES
 
   * If setuptools is installed, "python setup.py test" will now run the testsuite.
diff --git a/dulwich/server.py b/dulwich/server.py
index f69ba15..dcb5695 100644
--- a/dulwich/server.py
+++ b/dulwich/server.py
@@ -140,9 +140,10 @@ class FileSystemBackend(Backend):
 class Handler(object):
     """Smart protocol command handler base class."""
 
-    def __init__(self, backend, proto):
+    def __init__(self, backend, proto, http_req=None):
         self.backend = backend
         self.proto = proto
+        self.http_req = http_req
         self._client_capabilities = None
 
     @classmethod
@@ -186,12 +187,11 @@ class Handler(object):
 class UploadPackHandler(Handler):
     """Protocol handler for uploading a pack to the server."""
 
-    def __init__(self, backend, args, proto,
-                 stateless_rpc=False, advertise_refs=False):
-        Handler.__init__(self, backend, proto)
+    def __init__(self, backend, args, proto, http_req=None,
+                 advertise_refs=False):
+        Handler.__init__(self, backend, proto, http_req=http_req)
         self.repo = backend.open_repository(args[0])
         self._graph_walker = None
-        self.stateless_rpc = stateless_rpc
         self.advertise_refs = advertise_refs
 
     @classmethod
@@ -312,7 +312,7 @@ class ProtocolGraphWalker(object):
         self.store = object_store
         self.get_peeled = get_peeled
         self.proto = handler.proto
-        self.stateless_rpc = handler.stateless_rpc
+        self.http_req = handler.http_req
         self.advertise_refs = handler.advertise_refs
         self._wants = []
         self._cached = False
@@ -334,7 +334,7 @@ class ProtocolGraphWalker(object):
         if not heads:
             raise GitProtocolError('No heads found')
         values = set(heads.itervalues())
-        if self.advertise_refs or not self.stateless_rpc:
+        if self.advertise_refs or not self.http_req:
             for i, (ref, sha) in enumerate(heads.iteritems()):
                 line = "%s %s" % (sha, ref)
                 if not i:
@@ -371,7 +371,7 @@ class ProtocolGraphWalker(object):
 
         self.set_wants(want_revs)
 
-        if self.stateless_rpc and self.proto.eof():
+        if self.http_req and self.proto.eof():
             # The client may close the socket at this point, expecting a
             # flush-pkt from the server. We might be ready to send a packfile at
             # this point, so we need to explicitly short-circuit in this case.
@@ -388,7 +388,7 @@ class ProtocolGraphWalker(object):
 
     def next(self):
         if not self._cached:
-            if not self._impl and self.stateless_rpc:
+            if not self._impl and self.http_req:
                 return None
             return self._impl.next()
         self._cache_index += 1
@@ -553,7 +553,7 @@ class MultiAckDetailedGraphWalkerImpl(object):
             command, sha = self.walker.read_proto_line(_GRAPH_WALKER_COMMANDS)
             if command is None:
                 self.walker.send_nak()
-                if self.walker.stateless_rpc:
+                if self.walker.http_req:
                     return None
                 continue
             elif command == 'done':
@@ -575,11 +575,10 @@ class MultiAckDetailedGraphWalkerImpl(object):
 class ReceivePackHandler(Handler):
     """Protocol handler for downloading a pack from the client."""
 
-    def __init__(self, backend, args, proto,
-                 stateless_rpc=False, advertise_refs=False):
-        Handler.__init__(self, backend, proto)
+    def __init__(self, backend, args, proto, http_req=None,
+                 advertise_refs=False):
+        Handler.__init__(self, backend, proto, http_req=http_req)
         self.repo = backend.open_repository(args[0])
-        self.stateless_rpc = stateless_rpc
         self.advertise_refs = advertise_refs
 
     @classmethod
@@ -650,7 +649,7 @@ class ReceivePackHandler(Handler):
     def handle(self):
         refs = self.repo.get_refs().items()
 
-        if self.advertise_refs or not self.stateless_rpc:
+        if self.advertise_refs or not self.http_req:
             if refs:
                 self.proto.write_pkt_line(
                   "%s %s\x00%s\n" % (refs[0][1], refs[0][0],
diff --git a/dulwich/tests/test_server.py b/dulwich/tests/test_server.py
index a630489..3e5d34a 100644
--- a/dulwich/tests/test_server.py
+++ b/dulwich/tests/test_server.py
@@ -337,7 +337,7 @@ class TestProtocolGraphWalker(object):
         self.acks = []
         self.lines = []
         self.done = False
-        self.stateless_rpc = False
+        self.http_req = None
         self.advertise_refs = False
 
     def read_proto_line(self, allowed):
@@ -633,7 +633,7 @@ class MultiAckDetailedGraphWalkerImplTestCase(AckGraphWalkerImplTestCase):
     def test_multi_ack_stateless(self):
         # transmission ends with a flush-pkt
         self._walker.lines[-1] = (None, None)
-        self._walker.stateless_rpc = True
+        self._walker.http_req = True
 
         self.assertNextEquals(TWO)
         self.assertNoAck()
diff --git a/dulwich/tests/test_web.py b/dulwich/tests/test_web.py
index 8509140..112c875 100644
--- a/dulwich/tests/test_web.py
+++ b/dulwich/tests/test_web.py
@@ -282,11 +282,11 @@ class DumbHandlersTestCase(WebTestCase):
 class SmartHandlersTestCase(WebTestCase):
 
     class _TestUploadPackHandler(object):
-        def __init__(self, backend, args, proto, stateless_rpc=False,
+        def __init__(self, backend, args, proto, http_req=None,
                      advertise_refs=False):
             self.args = args
             self.proto = proto
-            self.stateless_rpc = stateless_rpc
+            self.http_req = http_req
             self.advertise_refs = advertise_refs
 
         def handle(self):
@@ -318,7 +318,7 @@ class SmartHandlersTestCase(WebTestCase):
         self.assertEqual('handled input: foo', write_output)
         self.assertContentTypeEquals('application/x-git-upload-pack-response')
         self.assertFalse(self._handler.advertise_refs)
-        self.assertTrue(self._handler.stateless_rpc)
+        self.assertTrue(self._handler.http_req)
         self.assertFalse(self._req.cached)
 
     def test_handle_service_request(self):
@@ -350,7 +350,7 @@ class SmartHandlersTestCase(WebTestCase):
         # Ensure all output was written via the write callback.
         self.assertEquals('', handler_output)
         self.assertTrue(self._handler.advertise_refs)
-        self.assertTrue(self._handler.stateless_rpc)
+        self.assertTrue(self._handler.http_req)
         self.assertFalse(self._req.cached)
 
 
diff --git a/dulwich/web.py b/dulwich/web.py
index 3f354db..9734b33 100644
--- a/dulwich/web.py
+++ b/dulwich/web.py
@@ -169,7 +169,7 @@ def get_info_refs(req, backend, mat):
         write = req.respond(HTTP_OK, 'application/x-%s-advertisement' % service)
         proto = ReceivableProtocol(StringIO().read, write)
         handler = handler_cls(backend, [url_prefix(mat)], proto,
-                              stateless_rpc=True, advertise_refs=True)
+                              http_req=req, advertise_refs=True)
         handler.proto.write_pkt_line('# service=%s\n' % service)
         handler.proto.write_pkt_line(None)
         handler.handle()
@@ -246,7 +246,7 @@ def handle_service_request(req, backend, mat):
     if content_length:
         input = _LengthLimitedFile(input, int(content_length))
     proto = ReceivableProtocol(input.read, write)
-    handler = handler_cls(backend, [url_prefix(mat)], proto, stateless_rpc=True)
+    handler = handler_cls(backend, [url_prefix(mat)], proto, http_req=req)
     handler.handle()
 
 
-- 
1.7.3.1



References