On Wed, Mar 7, 2018 at 8:49 PM, Matt Harbison <mharbiso...@gmail.com> wrote:
> # HG changeset patch > # User Matt Harbison <matt_harbi...@yahoo.com> > # Date 1519275362 18000 > # Wed Feb 21 23:56:02 2018 -0500 > # Node ID 5544688dec388a7c8a988c074aab659f059f549f > # Parent 89382cb20bb19e089513b2ce69ef8acfa1f523fd > hgweb: add a hook for processing LFS file transfer requests > > As part of this, the PUT request needs to be handled to upload files. > Unlike > the requests to the Batch API, this URI is internally controlled, and > provided > to the client in the Batch API. So without any interoperability concerns, > the > URI starts with '/.hg', and reflects where the files are actually stored. > > The permission check is deferred to the processing function, because this > request is used for both uploads and downloads. > > diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py > --- a/mercurial/hgweb/hgweb_mod.py > +++ b/mercurial/hgweb/hgweb_mod.py > @@ -96,6 +96,15 @@ > """ > raise ErrorResponse(HTTP_NOT_FOUND) > > +def _processlfstransfer(repo, req): > + """A hook for the LFS extension to wrap that handles file transfer > requests. > + > + The caller MUST call ``req.checkperm()`` with 'push' or 'pull' after > it > + determines whether this is an upload or a download, prior to > accessing any > + repository data. > + """ > + raise ErrorResponse(HTTP_NOT_FOUND) > + > class requestcontext(object): > """Holds state/context for an individual request. > > @@ -382,14 +391,20 @@ > except ErrorResponse as inst: > return protohandler['handleerror'](inst) > > - # Route LFS Batch API requests to the appropriate handler > + # Route LFS Batch API and transfer requests to the appropriate > handler > > if req.env.get(r'HTTP_USER_AGENT', r'').startswith(r'git-lfs/'): > try: > - path = req.env.get(r'PATH_INFO') > + path = req.env.get(r'PATH_INFO', '') > if path == '/.git/info/lfs/objects/batch': > self.check_perm(rctx, req, None) > return _processlfsbatchreq(rctx.repo, req) > + elif path.startswith('/.hg/store/lfs/objects'): > This scares me a bit because we're leaking internal storage paths into the URI space. Must we do this? What's relying on this behavior? > + # NB: This function is responsible for doing the > appropriate > + # permission checks after determining if this is an > upload > + # or a download. > + req.checkperm = lambda op: self.check_perm(rctx, req, > op) > + return _processlfstransfer(rctx.repo, req) > else: > raise ErrorResponse(HTTP_NOT_FOUND) > except ErrorResponse as inst: > diff --git a/mercurial/hgweb/server.py b/mercurial/hgweb/server.py > --- a/mercurial/hgweb/server.py > +++ b/mercurial/hgweb/server.py > @@ -111,6 +111,9 @@ > self.log_error(r"Exception happened during processing " > r"request '%s':%s%s", self.path, newline, tb) > > + def do_PUT(self): > + self.do_POST() > + > def do_GET(self): > self.do_POST() > > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel@mercurial-scm.org > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel >
_______________________________________________ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel