Mercurial > hg
comparison hgext/lfs/blobstore.py @ 41427:40efcf78f3df
py3: raw stringify various JSON and HTTP headers in the LFS blobstore module
This is (almost?) entirely from Augie's work. I'm a bit surprised that the JSON
data is being encoded with ASCII via `pycompat.bytesurl()`- I would have thought
UTF-8.
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Sun, 27 Jan 2019 15:42:55 -0500 |
parents | 02d0a7774882 |
children | 7df10ea7a5b8 |
comparison
equal
deleted
inserted
replaced
41426:02d0a7774882 | 41427:40efcf78f3df |
---|---|
289 """Get metadata about objects pointed by pointers for given action | 289 """Get metadata about objects pointed by pointers for given action |
290 | 290 |
291 Return decoded JSON object like {'objects': [{'oid': '', 'size': 1}]} | 291 Return decoded JSON object like {'objects': [{'oid': '', 'size': 1}]} |
292 See https://github.com/git-lfs/git-lfs/blob/master/docs/api/batch.md | 292 See https://github.com/git-lfs/git-lfs/blob/master/docs/api/batch.md |
293 """ | 293 """ |
294 objects = [{'oid': p.oid(), 'size': p.size()} for p in pointers] | 294 objects = [{r'oid': pycompat.strurl(p.oid()), |
295 requestdata = json.dumps({ | 295 r'size': p.size()} for p in pointers] |
296 'objects': objects, | 296 requestdata = pycompat.bytesurl(json.dumps({ |
297 'operation': action, | 297 r'objects': objects, |
298 }) | 298 r'operation': pycompat.strurl(action), |
299 })) | |
299 url = b'%s/objects/batch' % self.baseurl | 300 url = b'%s/objects/batch' % self.baseurl |
300 batchreq = util.urlreq.request(pycompat.strurl(url), data=requestdata) | 301 batchreq = util.urlreq.request(pycompat.strurl(url), data=requestdata) |
301 batchreq.add_header('Accept', 'application/vnd.git-lfs+json') | 302 batchreq.add_header(r'Accept', r'application/vnd.git-lfs+json') |
302 batchreq.add_header('Content-Type', 'application/vnd.git-lfs+json') | 303 batchreq.add_header(r'Content-Type', r'application/vnd.git-lfs+json') |
303 try: | 304 try: |
304 with contextlib.closing(self.urlopener.open(batchreq)) as rsp: | 305 with contextlib.closing(self.urlopener.open(batchreq)) as rsp: |
305 rawjson = rsp.read() | 306 rawjson = rsp.read() |
306 except util.urlerr.httperror as ex: | 307 except util.urlerr.httperror as ex: |
307 hints = { | 308 hints = { |
330 # lfs-test-server and hg serve return headers in different order | 331 # lfs-test-server and hg serve return headers in different order |
331 headers = pycompat.bytestr(rsp.info()) | 332 headers = pycompat.bytestr(rsp.info()) |
332 self.ui.debug(b'%s\n' | 333 self.ui.debug(b'%s\n' |
333 % b'\n'.join(sorted(headers.splitlines()))) | 334 % b'\n'.join(sorted(headers.splitlines()))) |
334 | 335 |
335 if 'objects' in response: | 336 if r'objects' in response: |
336 response['objects'] = sorted(response['objects'], | 337 response[r'objects'] = sorted(response[r'objects'], |
337 key=lambda p: p['oid']) | 338 key=lambda p: p[r'oid']) |
338 self.ui.debug('%s\n' | 339 self.ui.debug(b'%s\n' |
339 % json.dumps(response, indent=2, | 340 % pycompat.bytesurl( |
340 separators=('', ': '), sort_keys=True)) | 341 json.dumps(response, indent=2, |
342 separators=(r'', r': '), | |
343 sort_keys=True))) | |
341 | 344 |
342 return response | 345 return response |
343 | 346 |
344 def _checkforservererror(self, pointers, responses, action): | 347 def _checkforservererror(self, pointers, responses, action): |
345 """Scans errors from objects | 348 """Scans errors from objects |
417 # If uploading blobs, read data from local blobstore. | 420 # If uploading blobs, read data from local blobstore. |
418 if not localstore.verify(oid): | 421 if not localstore.verify(oid): |
419 raise error.Abort(_(b'detected corrupt lfs object: %s') % oid, | 422 raise error.Abort(_(b'detected corrupt lfs object: %s') % oid, |
420 hint=_(b'run hg verify')) | 423 hint=_(b'run hg verify')) |
421 request.data = filewithprogress(localstore.open(oid), None) | 424 request.data = filewithprogress(localstore.open(oid), None) |
422 request.get_method = lambda: 'PUT' | 425 request.get_method = lambda: r'PUT' |
423 request.add_header('Content-Type', 'application/octet-stream') | 426 request.add_header(r'Content-Type', r'application/octet-stream') |
424 | 427 |
425 for k, v in headers: | 428 for k, v in headers: |
426 request.add_header(k, v) | 429 request.add_header(k, v) |
427 | 430 |
428 response = b'' | 431 response = b'' |