Use common, shared, code
authorJohn Carr <john.carr@unrouted.co.uk>
Wed, 24 Dec 2008 22:42:23 +0000 (22:42 +0000)
committerJohn Carr <john.carr@unrouted.co.uk>
Wed, 24 Dec 2008 22:42:23 +0000 (22:42 +0000)
dulwich/server.py

index 9c3b79556248962cc0aa16200af37c42b89ec9e9..5670b97dd6bd601817465713a36fdc3e87c43f2c 100644 (file)
@@ -166,44 +166,7 @@ class Handler(object):
 
     def __init__(self, backend, read, write):
         self.backend = backend
-        self.read = read
-        self.write = write
-
-    def read_pkt_line(self):
-        """
-        Reads a 'pkt line' from the remote git process
-
-        :return: The next string from the stream
-        """
-        sizestr = self.read(4)
-        if not sizestr:
-            return None
-        size = int(sizestr, 16)
-        if size == 0:
-            return None
-        return self.read(size-4)
-
-    def write_pkt_line(self, line):
-        """
-        Sends a 'pkt line' to the remote git process
-
-        :param line: A string containing the data to send
-        """
-        self.write("%04x%s" % (len(line)+4, line))
-
-    def write_sideband(self, channel, blob):
-        """
-        Write data to the sideband (a git multiplexing method)
-
-        :param channel: int specifying which channel to write to
-        :param blob: a blob of data (as a string) to send on this channel
-        """
-        # a pktline can be a max of 65535. a sideband line can therefore be
-        # 65535-5 = 65530
-        # WTF: Why have the len in ASCII, but the channel in binary.
-        while blob:
-            self.write_pkt_line("%s%s" % (chr(channel), blob[:65530]))
-            blob = blob[65530:]
+        self.proto = Protocol(read, write)
 
     def capabilities(self):
         return " ".join(self.default_capabilities())
@@ -223,12 +186,6 @@ class Handler(object):
 
         return blob
 
-    def handle(self):
-        """
-        Deal with the request
-        """
-        raise NotImplementedError
-
 
 class UploadPackHandler(Handler):
 
@@ -239,17 +196,17 @@ class UploadPackHandler(Handler):
         refs = self.backend.get_refs()
 
         if refs:
-            self.write_pkt_line("%s %s\x00%s\n" % (refs[0][1], refs[0][0], self.capabilities()))
+            self.proto.write_pkt_line("%s %s\x00%s\n" % (refs[0][1], refs[0][0], self.capabilities()))
             for i in range(1, len(refs)):
                 ref = refs[i]
-                self.write_pkt_line("%s %s\n" % (ref[1], ref[0]))
+                self.proto.write_pkt_line("%s %s\n" % (ref[1], ref[0]))
 
-        # i'm done...
-        self.write("0000")
+        # i'm done..
+        self.proto.write("0000")
 
         # Now client will either send "0000", meaning that it doesnt want to pull.
         # or it will start sending want want want commands
-        want = self.read_pkt_line()
+        want = self.proto.read_pkt_line()
         if want == None:
             return
 
@@ -262,35 +219,35 @@ class UploadPackHandler(Handler):
             # FIXME: This check probably isnt needed?
             if self.backend.has_revision(want_rev):
                want_revs.append(want_rev)
-            want = self.read_pkt_line()
+            want = self.proto.read_pkt_line()
         
         # Client will now tell us which commits it already has - if we have them we ACK them
         # this allows client to stop looking at that commits parents (main reason why git pull is fast)
         last_sha = None
         have_revs = []
-        have = self.read_pkt_line()
+        have = self.proto.read_pkt_line()
         while have and have[:4] == 'have':
             have_ref = have[6:46]
             if self.backend.has_revision(have_ref):
-                self.write_pkt_line("ACK %s continue\n" % have_ref)
+                self.proto.write_pkt_line("ACK %s continue\n" % have_ref)
                 last_sha = have_ref
                 have_revs.append(have_ref)
-            have = self.read_pkt_line()
+            have = self.proto.read_pkt_line()
 
         # At some point client will stop sending commits and will tell us it is done
         assert(have[:4] == "done")
 
         # Oddness: Git seems to resend the last ACK, without the "continue" statement
         if last_sha:
-            self.write_pkt_line("ACK %s\n" % last_sha)
+            self.proto.write_pkt_line("ACK %s\n" % last_sha)
 
         # The exchange finishes with a NAK
-        self.write_pkt_line("NAK\n")
+        self.proto.write_pkt_line("NAK\n")
       
-        self.backend.generate_pack(want_revs, have_revs, lambda x: self.write_sideband(1, x), lambda x: self.write_sideband(2, x))
+        self.backend.generate_pack(want_revs, have_revs, lambda x: self.proto.write_sideband(1, x), lambda x: self.proto.write_sideband(2, x))
 
         # we are done
-        self.write("0000")
+        self.proto.write("0000")
 
 
 class ReceivePackHandler(Handler):
@@ -302,17 +259,17 @@ class ReceivePackHandler(Handler):
         refs = self.backend.get_refs()
 
         if refs:
-            self.write_pkt_line("%s %s\x00%s\n" % (refs[0][1], refs[0][0], self.capabilities()))
+            self.proto.write_pkt_line("%s %s\x00%s\n" % (refs[0][1], refs[0][0], self.capabilities()))
             for i in range(1, len(refs)):
                 ref = refs[i]
-                self.write_pkt_line("%s %s\n" % (ref[1], ref[0]))
+                self.proto.write_pkt_line("%s %s\n" % (ref[1], ref[0]))
         else:
-            self.write_pkt_line("0000000000000000000000000000000000000000 capabilities^{} %s" % self.capabilities())
+            self.proto.write_pkt_line("0000000000000000000000000000000000000000 capabilities^{} %s" % self.capabilities())
 
-        self.write("0000")
+        self.proto.write("0000")
 
         client_refs = []
-        ref = self.read_pkt_line()
+        ref = self.proto.read_pkt_line()
 
         # if ref is none then client doesnt want to send us anything..
         if ref is None:
@@ -323,10 +280,10 @@ class ReceivePackHandler(Handler):
         # client will now send us a list of (oldsha, newsha, ref)
         while ref:
             client_refs.append(ref.split())
-            ref = self.read_pkt_line()
+            ref = self.proto.read_pkt_line()
 
         # backend can now deal with this refs and read a pack using self.read
-        self.backend.apply_pack(client_refs, self.read)
+        self.backend.apply_pack(client_refs, self.proto.read)
 
         # when we have read all the pack from the client, it assumes everything worked OK
         # there is NO ack from the server before it reports victory.
@@ -342,7 +299,7 @@ class TCPGitRequestHandler(SocketServer.StreamRequestHandler, Handler):
         #so we can't call this in a sane place??
         Handler.__init__(self, self.server.backend, self.rfile.read, self.wfile.write)
 
-        request = self.read_pkt_line()
+        request = self.proto.read_pkt_line()
 
         # up until the space is the command to run, everything after is parameters
         splice_point = request.find(' ')
@@ -359,7 +316,7 @@ class TCPGitRequestHandler(SocketServer.StreamRequestHandler, Handler):
         else:
             return
 
-        h = cls(self.backend, self.read, self.write)
+        h = cls(self.backend, self.proto.read, self.proto.write)
         h.handle()