annotate hgext/lfs/wireprotolfsserver.py @ 38178:3790efb388ca stable

lfs: bypass wrapped functions when reposetup() hasn't been called (issue5902) There are only a handful of methods that access repo attributes that are applied in reposetup(). The `diff` test covers all of the commands that call scmutil.prefetchfiles(). Along the way, I saw that adding files and upgrading the repo format were also problems (also tested here). I don't think running `hg serve` through the commandserver is sane, but I conditionalized both the capabilities and the wsgirequest handler because it's trivially correct. It doesn't look like there has ever been a caller of candownload(), so there's no test for that path. The upload case isn't testable, because uploadblobs() bails if there are no pointers. The requirement should be added any time pointers are introduced, and that would force the extension to be loaded specifically for the repo. This covers `debuglfsupload`, the pre-push hook (which isn't set until the repo is promoted to LFS), and uploadblobsfromrevs(), which can be called by other extensions. I think readfromstore() and writetostore() are only reachable as a flag processor for revlog.REVIDX_EXTSTORED, and a requirement is added as soon as that is seen, so I don't think those are a problem.
author Matt Harbison <matt_harbison@yahoo.com>
date Thu, 31 May 2018 09:19:09 -0400
parents 925707ac2855
children a913d2892e17
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
37147
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
1 # wireprotolfsserver.py - lfs protocol server side implementation
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
2 #
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
3 # Copyright 2018 Matt Harbison <matt_harbison@yahoo.com>
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
4 #
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
5 # This software may be used and distributed according to the terms of the
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
6 # GNU General Public License version 2 or any later version.
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
7
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
8 from __future__ import absolute_import
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
9
37148
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
10 import datetime
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
11 import errno
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
12 import json
37690
726c4102db9e lfs: log information about Internal Server Errors reported in the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37617
diff changeset
13 import traceback
37148
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
14
37147
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
15 from mercurial.hgweb import (
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
16 common as hgwebcommon,
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
17 )
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
18
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
19 from mercurial import (
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
20 pycompat,
38178
3790efb388ca lfs: bypass wrapped functions when reposetup() hasn't been called (issue5902)
Matt Harbison <matt_harbison@yahoo.com>
parents: 37766
diff changeset
21 util,
37147
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
22 )
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
23
37692
10e5bb9678f4 lfs: gracefully handle aborts on the server when corrupt blobs are detected
Matt Harbison <matt_harbison@yahoo.com>
parents: 37690
diff changeset
24 from . import blobstore
10e5bb9678f4 lfs: gracefully handle aborts on the server when corrupt blobs are detected
Matt Harbison <matt_harbison@yahoo.com>
parents: 37690
diff changeset
25
37148
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
26 HTTP_OK = hgwebcommon.HTTP_OK
37149
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37148
diff changeset
27 HTTP_CREATED = hgwebcommon.HTTP_CREATED
37148
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
28 HTTP_BAD_REQUEST = hgwebcommon.HTTP_BAD_REQUEST
37250
9640ccf44ac0 lfs: ensure the transfer request is for a known URI
Matt Harbison <matt_harbison@yahoo.com>
parents: 37249
diff changeset
29 HTTP_NOT_FOUND = hgwebcommon.HTTP_NOT_FOUND
37693
31a0d47d69b3 lfs: update the HTTP status codes in error cases
Matt Harbison <matt_harbison@yahoo.com>
parents: 37692
diff changeset
30 HTTP_METHOD_NOT_ALLOWED = hgwebcommon.HTTP_METHOD_NOT_ALLOWED
31a0d47d69b3 lfs: update the HTTP status codes in error cases
Matt Harbison <matt_harbison@yahoo.com>
parents: 37692
diff changeset
31 HTTP_NOT_ACCEPTABLE = hgwebcommon.HTTP_NOT_ACCEPTABLE
31a0d47d69b3 lfs: update the HTTP status codes in error cases
Matt Harbison <matt_harbison@yahoo.com>
parents: 37692
diff changeset
32 HTTP_UNSUPPORTED_MEDIA_TYPE = hgwebcommon.HTTP_UNSUPPORTED_MEDIA_TYPE
37148
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
33
37147
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
34 def handlewsgirequest(orig, rctx, req, res, checkperm):
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
35 """Wrap wireprotoserver.handlewsgirequest() to possibly process an LFS
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
36 request if it is left unprocessed by the wrapped method.
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
37 """
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
38 if orig(rctx, req, res, checkperm):
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
39 return True
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
40
37248
dfb38c4850a9 lfs: add an experimental knob to disable blob serving
Matt Harbison <matt_harbison@yahoo.com>
parents: 37149
diff changeset
41 if not rctx.repo.ui.configbool('experimental', 'lfs.serve'):
dfb38c4850a9 lfs: add an experimental knob to disable blob serving
Matt Harbison <matt_harbison@yahoo.com>
parents: 37149
diff changeset
42 return False
dfb38c4850a9 lfs: add an experimental knob to disable blob serving
Matt Harbison <matt_harbison@yahoo.com>
parents: 37149
diff changeset
43
38178
3790efb388ca lfs: bypass wrapped functions when reposetup() hasn't been called (issue5902)
Matt Harbison <matt_harbison@yahoo.com>
parents: 37766
diff changeset
44 if not util.safehasattr(rctx.repo.svfs, 'lfslocalblobstore'):
3790efb388ca lfs: bypass wrapped functions when reposetup() hasn't been called (issue5902)
Matt Harbison <matt_harbison@yahoo.com>
parents: 37766
diff changeset
45 return False
3790efb388ca lfs: bypass wrapped functions when reposetup() hasn't been called (issue5902)
Matt Harbison <matt_harbison@yahoo.com>
parents: 37766
diff changeset
46
37147
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
47 if not req.dispatchpath:
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
48 return False
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
49
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
50 try:
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
51 if req.dispatchpath == b'.git/info/lfs/objects/batch':
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
52 checkperm(rctx, req, 'pull')
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
53 return _processbatchrequest(rctx.repo, req, res)
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
54 # TODO: reserve and use a path in the proposed http wireprotocol /api/
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
55 # namespace?
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
56 elif req.dispatchpath.startswith(b'.hg/lfs/objects'):
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
57 return _processbasictransfer(rctx.repo, req, res,
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
58 lambda perm:
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
59 checkperm(rctx, req, perm))
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
60 return False
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
61 except hgwebcommon.ErrorResponse as e:
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
62 # XXX: copied from the handler surrounding wireprotoserver._callhttp()
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
63 # in the wrapped function. Should this be moved back to hgweb to
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
64 # be a common handler?
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
65 for k, v in e.headers:
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
66 res.headers[k] = v
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
67 res.status = hgwebcommon.statusmessage(e.code, pycompat.bytestr(e))
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
68 res.setbodybytes(b'0\n%s\n' % pycompat.bytestr(e))
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
69 return True
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
70
37148
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
71 def _sethttperror(res, code, message=None):
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
72 res.status = hgwebcommon.statusmessage(code, message=message)
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
73 res.headers[b'Content-Type'] = b'text/plain; charset=utf-8'
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
74 res.setbodybytes(b'')
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
75
37690
726c4102db9e lfs: log information about Internal Server Errors reported in the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37617
diff changeset
76 def _logexception(req):
726c4102db9e lfs: log information about Internal Server Errors reported in the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37617
diff changeset
77 """Write information about the current exception to wsgi.errors."""
726c4102db9e lfs: log information about Internal Server Errors reported in the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37617
diff changeset
78 tb = pycompat.sysbytes(traceback.format_exc())
726c4102db9e lfs: log information about Internal Server Errors reported in the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37617
diff changeset
79 errorlog = req.rawenv[r'wsgi.errors']
726c4102db9e lfs: log information about Internal Server Errors reported in the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37617
diff changeset
80
726c4102db9e lfs: log information about Internal Server Errors reported in the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37617
diff changeset
81 uri = b''
726c4102db9e lfs: log information about Internal Server Errors reported in the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37617
diff changeset
82 if req.apppath:
726c4102db9e lfs: log information about Internal Server Errors reported in the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37617
diff changeset
83 uri += req.apppath
726c4102db9e lfs: log information about Internal Server Errors reported in the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37617
diff changeset
84 uri += b'/' + req.dispatchpath
726c4102db9e lfs: log information about Internal Server Errors reported in the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37617
diff changeset
85
726c4102db9e lfs: log information about Internal Server Errors reported in the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37617
diff changeset
86 errorlog.write(b"Exception happened while processing request '%s':\n%s" %
726c4102db9e lfs: log information about Internal Server Errors reported in the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37617
diff changeset
87 (uri, tb))
726c4102db9e lfs: log information about Internal Server Errors reported in the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37617
diff changeset
88
37147
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
89 def _processbatchrequest(repo, req, res):
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
90 """Handle a request for the Batch API, which is the gateway to granting file
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
91 access.
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
92
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
93 https://github.com/git-lfs/git-lfs/blob/master/docs/api/batch.md
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
94 """
37148
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
95
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
96 # Mercurial client request:
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
97 #
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
98 # HOST: localhost:$HGPORT
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
99 # ACCEPT: application/vnd.git-lfs+json
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
100 # ACCEPT-ENCODING: identity
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
101 # USER-AGENT: git-lfs/2.3.4 (Mercurial 4.5.2+1114-f48b9754f04c+20180316)
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
102 # Content-Length: 125
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
103 # Content-Type: application/vnd.git-lfs+json
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
104 #
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
105 # {
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
106 # "objects": [
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
107 # {
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
108 # "oid": "31cf...8e5b"
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
109 # "size": 12
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
110 # }
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
111 # ]
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
112 # "operation": "upload"
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
113 # }
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
114
37693
31a0d47d69b3 lfs: update the HTTP status codes in error cases
Matt Harbison <matt_harbison@yahoo.com>
parents: 37692
diff changeset
115 if req.method != b'POST':
31a0d47d69b3 lfs: update the HTTP status codes in error cases
Matt Harbison <matt_harbison@yahoo.com>
parents: 37692
diff changeset
116 _sethttperror(res, HTTP_METHOD_NOT_ALLOWED)
31a0d47d69b3 lfs: update the HTTP status codes in error cases
Matt Harbison <matt_harbison@yahoo.com>
parents: 37692
diff changeset
117 return True
31a0d47d69b3 lfs: update the HTTP status codes in error cases
Matt Harbison <matt_harbison@yahoo.com>
parents: 37692
diff changeset
118
31a0d47d69b3 lfs: update the HTTP status codes in error cases
Matt Harbison <matt_harbison@yahoo.com>
parents: 37692
diff changeset
119 if req.headers[b'Content-Type'] != b'application/vnd.git-lfs+json':
31a0d47d69b3 lfs: update the HTTP status codes in error cases
Matt Harbison <matt_harbison@yahoo.com>
parents: 37692
diff changeset
120 _sethttperror(res, HTTP_UNSUPPORTED_MEDIA_TYPE)
31a0d47d69b3 lfs: update the HTTP status codes in error cases
Matt Harbison <matt_harbison@yahoo.com>
parents: 37692
diff changeset
121 return True
31a0d47d69b3 lfs: update the HTTP status codes in error cases
Matt Harbison <matt_harbison@yahoo.com>
parents: 37692
diff changeset
122
31a0d47d69b3 lfs: update the HTTP status codes in error cases
Matt Harbison <matt_harbison@yahoo.com>
parents: 37692
diff changeset
123 if req.headers[b'Accept'] != b'application/vnd.git-lfs+json':
31a0d47d69b3 lfs: update the HTTP status codes in error cases
Matt Harbison <matt_harbison@yahoo.com>
parents: 37692
diff changeset
124 _sethttperror(res, HTTP_NOT_ACCEPTABLE)
37148
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
125 return True
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
126
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
127 # XXX: specify an encoding?
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
128 lfsreq = json.loads(req.bodyfh.read())
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
129
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
130 # If no transfer handlers are explicitly requested, 'basic' is assumed.
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
131 if 'basic' not in lfsreq.get('transfers', ['basic']):
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
132 _sethttperror(res, HTTP_BAD_REQUEST,
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
133 b'Only the basic LFS transfer handler is supported')
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
134 return True
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
135
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
136 operation = lfsreq.get('operation')
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
137 if operation not in ('upload', 'download'):
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
138 _sethttperror(res, HTTP_BAD_REQUEST,
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
139 b'Unsupported LFS transfer operation: %s' % operation)
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
140 return True
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
141
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
142 localstore = repo.svfs.lfslocalblobstore
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
143
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
144 objects = [p for p in _batchresponseobjects(req, lfsreq.get('objects', []),
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
145 operation, localstore)]
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
146
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
147 rsp = {
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
148 'transfer': 'basic',
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
149 'objects': objects,
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
150 }
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
151
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
152 res.status = hgwebcommon.statusmessage(HTTP_OK)
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
153 res.headers[b'Content-Type'] = b'application/vnd.git-lfs+json'
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
154 res.setbodybytes(pycompat.bytestr(json.dumps(rsp)))
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
155
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
156 return True
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
157
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
158 def _batchresponseobjects(req, objects, action, store):
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
159 """Yield one dictionary of attributes for the Batch API response for each
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
160 object in the list.
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
161
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
162 req: The parsedrequest for the Batch API request
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
163 objects: The list of objects in the Batch API object request list
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
164 action: 'upload' or 'download'
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
165 store: The local blob store for servicing requests"""
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
166
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
167 # Successful lfs-test-server response to solict an upload:
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
168 # {
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
169 # u'objects': [{
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
170 # u'size': 12,
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
171 # u'oid': u'31cf...8e5b',
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
172 # u'actions': {
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
173 # u'upload': {
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
174 # u'href': u'http://localhost:$HGPORT/objects/31cf...8e5b',
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
175 # u'expires_at': u'0001-01-01T00:00:00Z',
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
176 # u'header': {
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
177 # u'Accept': u'application/vnd.git-lfs'
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
178 # }
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
179 # }
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
180 # }
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
181 # }]
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
182 # }
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
183
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
184 # TODO: Sort out the expires_at/expires_in/authenticated keys.
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
185
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
186 for obj in objects:
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
187 # Convert unicode to ASCII to create a filesystem path
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
188 oid = obj.get('oid').encode('ascii')
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
189 rsp = {
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
190 'oid': oid,
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
191 'size': obj.get('size'), # XXX: should this check the local size?
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
192 #'authenticated': True,
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
193 }
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
194
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
195 exists = True
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
196 verifies = False
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
197
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
198 # Verify an existing file on the upload request, so that the client is
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
199 # solicited to re-upload if it corrupt locally. Download requests are
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
200 # also verified, so the error can be flagged in the Batch API response.
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
201 # (Maybe we can use this to short circuit the download for `hg verify`,
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
202 # IFF the client can assert that the remote end is an hg server.)
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
203 # Otherwise, it's potentially overkill on download, since it is also
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
204 # verified as the file is streamed to the caller.
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
205 try:
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
206 verifies = store.verify(oid)
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
207 except IOError as inst:
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
208 if inst.errno != errno.ENOENT:
37690
726c4102db9e lfs: log information about Internal Server Errors reported in the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37617
diff changeset
209 _logexception(req)
726c4102db9e lfs: log information about Internal Server Errors reported in the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37617
diff changeset
210
37148
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
211 rsp['error'] = {
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
212 'code': 500,
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
213 'message': inst.strerror or 'Internal Server Server'
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
214 }
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
215 yield rsp
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
216 continue
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
217
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
218 exists = False
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
219
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
220 # Items are always listed for downloads. They are dropped for uploads
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
221 # IFF they already exist locally.
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
222 if action == 'download':
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
223 if not exists:
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
224 rsp['error'] = {
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
225 'code': 404,
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
226 'message': "The object does not exist"
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
227 }
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
228 yield rsp
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
229 continue
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
230
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
231 elif not verifies:
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
232 rsp['error'] = {
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
233 'code': 422, # XXX: is this the right code?
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
234 'message': "The object is corrupt"
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
235 }
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
236 yield rsp
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
237 continue
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
238
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
239 elif verifies:
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
240 yield rsp # Skip 'actions': already uploaded
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
241 continue
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
242
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
243 expiresat = datetime.datetime.now() + datetime.timedelta(minutes=10)
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
244
37766
925707ac2855 lfs: add the 'Authorization' property to the Batch API response, if present
Matt Harbison <matt_harbison@yahoo.com>
parents: 37693
diff changeset
245 def _buildheader():
925707ac2855 lfs: add the 'Authorization' property to the Batch API response, if present
Matt Harbison <matt_harbison@yahoo.com>
parents: 37693
diff changeset
246 # The spec doesn't mention the Accept header here, but avoid
925707ac2855 lfs: add the 'Authorization' property to the Batch API response, if present
Matt Harbison <matt_harbison@yahoo.com>
parents: 37693
diff changeset
247 # a gratuitous deviation from lfs-test-server in the test
925707ac2855 lfs: add the 'Authorization' property to the Batch API response, if present
Matt Harbison <matt_harbison@yahoo.com>
parents: 37693
diff changeset
248 # output.
925707ac2855 lfs: add the 'Authorization' property to the Batch API response, if present
Matt Harbison <matt_harbison@yahoo.com>
parents: 37693
diff changeset
249 hdr = {
925707ac2855 lfs: add the 'Authorization' property to the Batch API response, if present
Matt Harbison <matt_harbison@yahoo.com>
parents: 37693
diff changeset
250 'Accept': 'application/vnd.git-lfs'
925707ac2855 lfs: add the 'Authorization' property to the Batch API response, if present
Matt Harbison <matt_harbison@yahoo.com>
parents: 37693
diff changeset
251 }
925707ac2855 lfs: add the 'Authorization' property to the Batch API response, if present
Matt Harbison <matt_harbison@yahoo.com>
parents: 37693
diff changeset
252
925707ac2855 lfs: add the 'Authorization' property to the Batch API response, if present
Matt Harbison <matt_harbison@yahoo.com>
parents: 37693
diff changeset
253 auth = req.headers.get('Authorization', '')
925707ac2855 lfs: add the 'Authorization' property to the Batch API response, if present
Matt Harbison <matt_harbison@yahoo.com>
parents: 37693
diff changeset
254 if auth.startswith('Basic '):
925707ac2855 lfs: add the 'Authorization' property to the Batch API response, if present
Matt Harbison <matt_harbison@yahoo.com>
parents: 37693
diff changeset
255 hdr['Authorization'] = auth
925707ac2855 lfs: add the 'Authorization' property to the Batch API response, if present
Matt Harbison <matt_harbison@yahoo.com>
parents: 37693
diff changeset
256
925707ac2855 lfs: add the 'Authorization' property to the Batch API response, if present
Matt Harbison <matt_harbison@yahoo.com>
parents: 37693
diff changeset
257 return hdr
925707ac2855 lfs: add the 'Authorization' property to the Batch API response, if present
Matt Harbison <matt_harbison@yahoo.com>
parents: 37693
diff changeset
258
37148
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
259 rsp['actions'] = {
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
260 '%s' % action: {
37617
b03f2e0fdb88 lfs: teach the blob server to handle --prefix
Matt Harbison <matt_harbison@yahoo.com>
parents: 37250
diff changeset
261 'href': '%s%s/.hg/lfs/objects/%s'
b03f2e0fdb88 lfs: teach the blob server to handle --prefix
Matt Harbison <matt_harbison@yahoo.com>
parents: 37250
diff changeset
262 % (req.baseurl, req.apppath, oid),
37148
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
263 # datetime.isoformat() doesn't include the 'Z' suffix
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
264 "expires_at": expiresat.strftime('%Y-%m-%dT%H:%M:%SZ'),
37766
925707ac2855 lfs: add the 'Authorization' property to the Batch API response, if present
Matt Harbison <matt_harbison@yahoo.com>
parents: 37693
diff changeset
265 'header': _buildheader(),
37148
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
266 }
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
267 }
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
268
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
269 yield rsp
37147
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
270
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
271 def _processbasictransfer(repo, req, res, checkperm):
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
272 """Handle a single file upload (PUT) or download (GET) action for the Basic
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
273 Transfer Adapter.
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
274
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
275 After determining if the request is for an upload or download, the access
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
276 must be checked by calling ``checkperm()`` with either 'pull' or 'upload'
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
277 before accessing the files.
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
278
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
279 https://github.com/git-lfs/git-lfs/blob/master/docs/api/basic-transfers.md
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
280 """
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
281
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
282 method = req.method
37249
fe061e47a2cf lfs: avoid an improper usage of os.path.basename() to parse a URI
Matt Harbison <matt_harbison@yahoo.com>
parents: 37248
diff changeset
283 oid = req.dispatchparts[-1]
37149
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37148
diff changeset
284 localstore = repo.svfs.lfslocalblobstore
37147
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
285
37250
9640ccf44ac0 lfs: ensure the transfer request is for a known URI
Matt Harbison <matt_harbison@yahoo.com>
parents: 37249
diff changeset
286 if len(req.dispatchparts) != 4:
9640ccf44ac0 lfs: ensure the transfer request is for a known URI
Matt Harbison <matt_harbison@yahoo.com>
parents: 37249
diff changeset
287 _sethttperror(res, HTTP_NOT_FOUND)
9640ccf44ac0 lfs: ensure the transfer request is for a known URI
Matt Harbison <matt_harbison@yahoo.com>
parents: 37249
diff changeset
288 return True
9640ccf44ac0 lfs: ensure the transfer request is for a known URI
Matt Harbison <matt_harbison@yahoo.com>
parents: 37249
diff changeset
289
37147
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
290 if method == b'PUT':
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
291 checkperm('upload')
37149
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37148
diff changeset
292
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37148
diff changeset
293 # TODO: verify Content-Type?
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37148
diff changeset
294
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37148
diff changeset
295 existed = localstore.has(oid)
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37148
diff changeset
296
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37148
diff changeset
297 # TODO: how to handle timeouts? The body proxy handles limiting to
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37148
diff changeset
298 # Content-Length, but what happens if a client sends less than it
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37148
diff changeset
299 # says it will?
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37148
diff changeset
300
37692
10e5bb9678f4 lfs: gracefully handle aborts on the server when corrupt blobs are detected
Matt Harbison <matt_harbison@yahoo.com>
parents: 37690
diff changeset
301 statusmessage = hgwebcommon.statusmessage
10e5bb9678f4 lfs: gracefully handle aborts on the server when corrupt blobs are detected
Matt Harbison <matt_harbison@yahoo.com>
parents: 37690
diff changeset
302 try:
10e5bb9678f4 lfs: gracefully handle aborts on the server when corrupt blobs are detected
Matt Harbison <matt_harbison@yahoo.com>
parents: 37690
diff changeset
303 localstore.download(oid, req.bodyfh)
10e5bb9678f4 lfs: gracefully handle aborts on the server when corrupt blobs are detected
Matt Harbison <matt_harbison@yahoo.com>
parents: 37690
diff changeset
304 res.status = statusmessage(HTTP_OK if existed else HTTP_CREATED)
10e5bb9678f4 lfs: gracefully handle aborts on the server when corrupt blobs are detected
Matt Harbison <matt_harbison@yahoo.com>
parents: 37690
diff changeset
305 except blobstore.LfsCorruptionError:
10e5bb9678f4 lfs: gracefully handle aborts on the server when corrupt blobs are detected
Matt Harbison <matt_harbison@yahoo.com>
parents: 37690
diff changeset
306 _logexception(req)
37149
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37148
diff changeset
307
37692
10e5bb9678f4 lfs: gracefully handle aborts on the server when corrupt blobs are detected
Matt Harbison <matt_harbison@yahoo.com>
parents: 37690
diff changeset
308 # XXX: Is this the right code?
10e5bb9678f4 lfs: gracefully handle aborts on the server when corrupt blobs are detected
Matt Harbison <matt_harbison@yahoo.com>
parents: 37690
diff changeset
309 res.status = statusmessage(422, b'corrupt blob')
37149
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37148
diff changeset
310
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37148
diff changeset
311 # There's no payload here, but this is the header that lfs-test-server
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37148
diff changeset
312 # sends back. This eliminates some gratuitous test output conditionals.
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37148
diff changeset
313 res.headers[b'Content-Type'] = b'text/plain; charset=utf-8'
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37148
diff changeset
314 res.setbodybytes(b'')
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37148
diff changeset
315
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37148
diff changeset
316 return True
37147
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
317 elif method == b'GET':
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
318 checkperm('pull')
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
319
37149
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37148
diff changeset
320 res.status = hgwebcommon.statusmessage(HTTP_OK)
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37148
diff changeset
321 res.headers[b'Content-Type'] = b'application/octet-stream'
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37148
diff changeset
322
37692
10e5bb9678f4 lfs: gracefully handle aborts on the server when corrupt blobs are detected
Matt Harbison <matt_harbison@yahoo.com>
parents: 37690
diff changeset
323 try:
10e5bb9678f4 lfs: gracefully handle aborts on the server when corrupt blobs are detected
Matt Harbison <matt_harbison@yahoo.com>
parents: 37690
diff changeset
324 # TODO: figure out how to send back the file in chunks, instead of
10e5bb9678f4 lfs: gracefully handle aborts on the server when corrupt blobs are detected
Matt Harbison <matt_harbison@yahoo.com>
parents: 37690
diff changeset
325 # reading the whole thing. (Also figure out how to send back
10e5bb9678f4 lfs: gracefully handle aborts on the server when corrupt blobs are detected
Matt Harbison <matt_harbison@yahoo.com>
parents: 37690
diff changeset
326 # an error status if an IOError occurs after a partial write
10e5bb9678f4 lfs: gracefully handle aborts on the server when corrupt blobs are detected
Matt Harbison <matt_harbison@yahoo.com>
parents: 37690
diff changeset
327 # in that case. Here, everything is read before starting.)
10e5bb9678f4 lfs: gracefully handle aborts on the server when corrupt blobs are detected
Matt Harbison <matt_harbison@yahoo.com>
parents: 37690
diff changeset
328 res.setbodybytes(localstore.read(oid))
10e5bb9678f4 lfs: gracefully handle aborts on the server when corrupt blobs are detected
Matt Harbison <matt_harbison@yahoo.com>
parents: 37690
diff changeset
329 except blobstore.LfsCorruptionError:
10e5bb9678f4 lfs: gracefully handle aborts on the server when corrupt blobs are detected
Matt Harbison <matt_harbison@yahoo.com>
parents: 37690
diff changeset
330 _logexception(req)
10e5bb9678f4 lfs: gracefully handle aborts on the server when corrupt blobs are detected
Matt Harbison <matt_harbison@yahoo.com>
parents: 37690
diff changeset
331
10e5bb9678f4 lfs: gracefully handle aborts on the server when corrupt blobs are detected
Matt Harbison <matt_harbison@yahoo.com>
parents: 37690
diff changeset
332 # XXX: Is this the right code?
10e5bb9678f4 lfs: gracefully handle aborts on the server when corrupt blobs are detected
Matt Harbison <matt_harbison@yahoo.com>
parents: 37690
diff changeset
333 res.status = hgwebcommon.statusmessage(422, b'corrupt blob')
10e5bb9678f4 lfs: gracefully handle aborts on the server when corrupt blobs are detected
Matt Harbison <matt_harbison@yahoo.com>
parents: 37690
diff changeset
334 res.setbodybytes(b'')
37149
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37148
diff changeset
335
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37148
diff changeset
336 return True
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37148
diff changeset
337 else:
37693
31a0d47d69b3 lfs: update the HTTP status codes in error cases
Matt Harbison <matt_harbison@yahoo.com>
parents: 37692
diff changeset
338 _sethttperror(res, HTTP_METHOD_NOT_ALLOWED,
37149
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37148
diff changeset
339 message=b'Unsupported LFS transfer method: %s' % method)
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37148
diff changeset
340 return True