mercurial/wireprotov1server.py
changeset 50666 60f9602b413e
parent 50550 9e24f8442640
equal deleted inserted replaced
50646:c814101560d9 50666:60f9602b413e
    19     changegroup as changegroupmod,
    19     changegroup as changegroupmod,
    20     discovery,
    20     discovery,
    21     encoding,
    21     encoding,
    22     error,
    22     error,
    23     exchange,
    23     exchange,
       
    24     hook,
    24     pushkey as pushkeymod,
    25     pushkey as pushkeymod,
    25     pycompat,
    26     pycompat,
    26     repoview,
    27     repoview,
    27     requirements as requirementsmod,
    28     requirements as requirementsmod,
    28     streamclone,
    29     streamclone,
   262         r.append(wireprototypes.encodelist(b) + b"\n")
   263         r.append(wireprototypes.encodelist(b) + b"\n")
   263 
   264 
   264     return wireprototypes.bytesresponse(b''.join(r))
   265     return wireprototypes.bytesresponse(b''.join(r))
   265 
   266 
   266 
   267 
       
   268 @wireprotocommand(b'get_inline_clone_bundle', b'path', permission=b'pull')
       
   269 def get_inline_clone_bundle(repo, proto, path):
       
   270     """
       
   271     Server command to send a clonebundle to the client
       
   272     """
       
   273     if hook.hashook(repo.ui, b'pretransmit-inline-clone-bundle'):
       
   274         hook.hook(
       
   275             repo.ui,
       
   276             repo,
       
   277             b'pretransmit-inline-clone-bundle',
       
   278             throw=True,
       
   279             clonebundlepath=path,
       
   280         )
       
   281 
       
   282     bundle_dir = repo.vfs.join(bundlecaches.BUNDLE_CACHE_DIR)
       
   283     clonebundlepath = repo.vfs.join(bundle_dir, path)
       
   284     if not repo.vfs.exists(clonebundlepath):
       
   285         raise error.Abort(b'clonebundle %s does not exist' % path)
       
   286 
       
   287     clonebundles_dir = os.path.realpath(bundle_dir)
       
   288     if not os.path.realpath(clonebundlepath).startswith(clonebundles_dir):
       
   289         raise error.Abort(b'clonebundle %s is using an illegal path' % path)
       
   290 
       
   291     def generator(vfs, bundle_path):
       
   292         with vfs(bundle_path) as f:
       
   293             length = os.fstat(f.fileno())[6]
       
   294             yield util.uvarintencode(length)
       
   295             for chunk in util.filechunkiter(f):
       
   296                 yield chunk
       
   297 
       
   298     stream = generator(repo.vfs, clonebundlepath)
       
   299     return wireprototypes.streamres(gen=stream, prefer_uncompressed=True)
       
   300 
       
   301 
   267 @wireprotocommand(b'clonebundles', b'', permission=b'pull')
   302 @wireprotocommand(b'clonebundles', b'', permission=b'pull')
   268 def clonebundles(repo, proto):
   303 def clonebundles(repo, proto):
   269     """Server command for returning info for available bundles to seed clones.
   304     """Server command for returning info for available bundles to seed clones.
   270 
   305 
   271     Clients will parse this response and determine what bundle to fetch.
   306     Clients will parse this response and determine what bundle to fetch.
   272 
   307 
   273     Extensions may wrap this command to filter or dynamically emit data
   308     Extensions may wrap this command to filter or dynamically emit data
   274     depending on the request. e.g. you could advertise URLs for the closest
   309     depending on the request. e.g. you could advertise URLs for the closest
   275     data center given the client's IP address.
   310     data center given the client's IP address.
   276     """
   311 
   277     manifest = bundlecaches.get_manifest(repo)
   312     The only filter on the server side is filtering out inline clonebundles
   278     return wireprototypes.bytesresponse(manifest)
   313     in case a client does not support them.
       
   314     Otherwise, older clients would retrieve and error out on those.
       
   315     """
       
   316     manifest_contents = bundlecaches.get_manifest(repo)
       
   317     clientcapabilities = proto.getprotocaps()
       
   318     if b'inlineclonebundles' in clientcapabilities:
       
   319         return wireprototypes.bytesresponse(manifest_contents)
       
   320     modified_manifest = []
       
   321     for line in manifest_contents.splitlines():
       
   322         if line.startswith(bundlecaches.CLONEBUNDLESCHEME):
       
   323             continue
       
   324         modified_manifest.append(line)
       
   325     return wireprototypes.bytesresponse(b'\n'.join(modified_manifest))
   279 
   326 
   280 
   327 
   281 wireprotocaps = [
   328 wireprotocaps = [
   282     b'lookup',
   329     b'lookup',
   283     b'branchmap',
   330     b'branchmap',