tests/wireprotosimplecache.py
changeset 40025 b099e6032f38
parent 40023 10cf8b116dd8
child 40170 f7ff5b4fe745
--- a/tests/wireprotosimplecache.py	Wed Sep 26 15:02:19 2018 -0700
+++ b/tests/wireprotosimplecache.py	Wed Sep 26 18:07:55 2018 -0700
@@ -12,6 +12,7 @@
     registrar,
     repository,
     util,
+    wireprotoserver,
     wireprototypes,
     wireprotov2server,
 )
@@ -25,18 +26,59 @@
 configtable = {}
 configitem = registrar.configitem(configtable)
 
+configitem('simplecache', 'cacheapi',
+           default=False)
 configitem('simplecache', 'cacheobjects',
            default=False)
 configitem('simplecache', 'redirectsfile',
            default=None)
 
+# API handler that makes cached keys available.
+def handlecacherequest(rctx, req, res, checkperm, urlparts):
+    if rctx.repo.ui.configbool('simplecache', 'cacheobjects'):
+        res.status = b'500 Internal Server Error'
+        res.setbodybytes(b'cacheobjects not supported for api server')
+        return
+
+    if not urlparts:
+        res.status = b'200 OK'
+        res.headers[b'Content-Type'] = b'text/plain'
+        res.setbodybytes(b'simple cache server')
+        return
+
+    key = b'/'.join(urlparts)
+
+    if key not in CACHE:
+        res.status = b'404 Not Found'
+        res.headers[b'Content-Type'] = b'text/plain'
+        res.setbodybytes(b'key not found in cache')
+        return
+
+    res.status = b'200 OK'
+    res.headers[b'Content-Type'] = b'application/mercurial-cbor'
+    res.setbodybytes(CACHE[key])
+
+def cachedescriptor(req, repo):
+    return {}
+
+wireprotoserver.API_HANDLERS[b'simplecache'] = {
+    'config': (b'simplecache', b'cacheapi'),
+    'handler': handlecacherequest,
+    'apidescriptor': cachedescriptor,
+}
+
 @interfaceutil.implementer(repository.iwireprotocolcommandcacher)
 class memorycacher(object):
-    def __init__(self, ui, command, encodefn):
+    def __init__(self, ui, command, encodefn, redirecttargets, redirecthashes,
+                 req):
         self.ui = ui
         self.encodefn = encodefn
+        self.redirecttargets = redirecttargets
+        self.redirecthashes = redirecthashes
+        self.req = req
         self.key = None
         self.cacheobjects = ui.configbool('simplecache', 'cacheobjects')
+        self.cacheapi = ui.configbool('simplecache', 'cacheapi')
         self.buffered = []
 
         ui.log('simplecache', 'cacher constructed for %s\n', command)
@@ -65,6 +107,37 @@
         entry = CACHE[self.key]
         self.ui.log('simplecache', 'cache hit for %s\n', self.key)
 
+        redirectable = True
+
+        if not self.cacheapi:
+            redirectable = False
+        elif not self.redirecttargets:
+            redirectable = False
+        else:
+            clienttargets = set(self.redirecttargets)
+            ourtargets = set(t[b'name'] for t in loadredirecttargets(self.ui))
+
+            # We only ever redirect to a single target (for now). So we don't
+            # need to store which target matched.
+            if not clienttargets & ourtargets:
+                redirectable = False
+
+        if redirectable:
+            paths = self.req.dispatchparts[:-3]
+            paths.append(b'simplecache')
+            paths.append(self.key)
+
+            url = b'%s/%s' % (self.req.advertisedbaseurl, b'/'.join(paths))
+
+            #url = b'http://example.com/%s' % self.key
+            self.ui.log('simplecache', 'sending content redirect for %s to '
+                                       '%s\n', self.key, url)
+            response = wireprototypes.alternatelocationresponse(
+                url=url,
+                mediatype=b'application/mercurial-cbor')
+
+            return {'objs': [response]}
+
         if self.cacheobjects:
             return {
                 'objs': entry,
@@ -91,8 +164,10 @@
 
         return []
 
-def makeresponsecacher(orig, repo, proto, command, args, objencoderfn):
-    return memorycacher(repo.ui, command, objencoderfn)
+def makeresponsecacher(orig, repo, proto, command, args, objencoderfn,
+                       redirecttargets, redirecthashes):
+    return memorycacher(repo.ui, command, objencoderfn, redirecttargets,
+                        redirecthashes, proto._req)
 
 def loadredirecttargets(ui):
     path = ui.config('simplecache', 'redirectsfile')