hgext/lfs/wireprotolfsserver.py
author Pierre-Yves David <pierre-yves.david@octobus.net>
Tue, 16 Feb 2021 05:46:32 +0100
changeset 46585 2f99dedf96b1
parent 44085 0ee0a3f6a990
child 48966 6000f5b25c9b
permissions -rw-r--r--
test-copies: improve description of the G+F case This will make its role clearer. Differential Revision: https://phab.mercurial-scm.org/D10042
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
37150
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
37151
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
    10
import datetime
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
    11
import errno
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
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
37151
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
    14
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
    15
from mercurial.hgweb import common as hgwebcommon
37150
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
    16
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
    17
from mercurial import (
41051
84d61fdcefa5 lfs: convert to using exthelper to wrap functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 39474
diff changeset
    18
    exthelper,
37150
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
    19
    pycompat,
37851
3790efb388ca lfs: bypass wrapped functions when reposetup() hasn't been called (issue5902)
Matt Harbison <matt_harbison@yahoo.com>
parents: 37766
diff changeset
    20
    util,
41051
84d61fdcefa5 lfs: convert to using exthelper to wrap functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 39474
diff changeset
    21
    wireprotoserver,
37150
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
37151
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
    26
HTTP_OK = hgwebcommon.HTTP_OK
37152
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37151
diff changeset
    27
HTTP_CREATED = hgwebcommon.HTTP_CREATED
37151
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
    28
HTTP_BAD_REQUEST = hgwebcommon.HTTP_BAD_REQUEST
37252
9640ccf44ac0 lfs: ensure the transfer request is for a known URI
Matt Harbison <matt_harbison@yahoo.com>
parents: 37251
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
37151
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
    33
41051
84d61fdcefa5 lfs: convert to using exthelper to wrap functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 39474
diff changeset
    34
eh = exthelper.exthelper()
84d61fdcefa5 lfs: convert to using exthelper to wrap functions
Matt Harbison <matt_harbison@yahoo.com>
parents: 39474
diff changeset
    35
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
    36
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    37
@eh.wrapfunction(wireprotoserver, b'handlewsgirequest')
37150
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
    38
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
    39
    """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
    40
    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
    41
    """
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
    42
    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
    43
        return True
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
    44
41446
7a11e4e55d5f py3: add b'' prefixes to the LFS server module
Matt Harbison <matt_harbison@yahoo.com>
parents: 41051
diff changeset
    45
    if not rctx.repo.ui.configbool(b'experimental', b'lfs.serve'):
37250
dfb38c4850a9 lfs: add an experimental knob to disable blob serving
Matt Harbison <matt_harbison@yahoo.com>
parents: 37152
diff changeset
    46
        return False
dfb38c4850a9 lfs: add an experimental knob to disable blob serving
Matt Harbison <matt_harbison@yahoo.com>
parents: 37152
diff changeset
    47
43115
4aa72cdf616f py3: delete b'' prefix from safehasattr arguments
Martin von Zweigbergk <martinvonz@google.com>
parents: 43077
diff changeset
    48
    if not util.safehasattr(rctx.repo.svfs, 'lfslocalblobstore'):
37851
3790efb388ca lfs: bypass wrapped functions when reposetup() hasn't been called (issue5902)
Matt Harbison <matt_harbison@yahoo.com>
parents: 37766
diff changeset
    49
        return False
3790efb388ca lfs: bypass wrapped functions when reposetup() hasn't been called (issue5902)
Matt Harbison <matt_harbison@yahoo.com>
parents: 37766
diff changeset
    50
37150
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
    51
    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
    52
        return False
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
    53
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
    54
    try:
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
    55
        if req.dispatchpath == b'.git/info/lfs/objects/batch':
41446
7a11e4e55d5f py3: add b'' prefixes to the LFS server module
Matt Harbison <matt_harbison@yahoo.com>
parents: 41051
diff changeset
    56
            checkperm(rctx, req, b'pull')
37150
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
    57
            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
    58
        # 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
    59
        #       namespace?
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
    60
        elif req.dispatchpath.startswith(b'.hg/lfs/objects'):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
    61
            return _processbasictransfer(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
    62
                rctx.repo, req, res, lambda perm: checkperm(rctx, req, perm)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
    63
            )
37150
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
    64
        return False
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
    65
    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
    66
        # 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
    67
        #      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
    68
        #      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
    69
        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
    70
            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
    71
        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
    72
        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
    73
        return True
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
    74
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
    75
37151
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
    76
def _sethttperror(res, code, message=None):
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
    77
    res.status = hgwebcommon.statusmessage(code, message=message)
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
    78
    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: 37150
diff changeset
    79
    res.setbodybytes(b'')
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
    80
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
    81
37690
726c4102db9e lfs: log information about Internal Server Errors reported in the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37617
diff changeset
    82
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
    83
    """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
    84
    tb = pycompat.sysbytes(traceback.format_exc())
41446
7a11e4e55d5f py3: add b'' prefixes to the LFS server module
Matt Harbison <matt_harbison@yahoo.com>
parents: 41051
diff changeset
    85
    errorlog = req.rawenv[b'wsgi.errors']
37690
726c4102db9e lfs: log information about Internal Server Errors reported in the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37617
diff changeset
    86
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 = b''
726c4102db9e lfs: log information about Internal Server Errors reported in the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37617
diff changeset
    88
    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
    89
        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
    90
    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
    91
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
    92
    errorlog.write(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
    93
        b"Exception happened while processing request '%s':\n%s" % (uri, tb)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
    94
    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
    95
37690
726c4102db9e lfs: log information about Internal Server Errors reported in the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37617
diff changeset
    96
37150
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
    97
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
    98
    """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
    99
    access.
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
   100
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
   101
    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
   102
    """
37151
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   103
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   104
    # Mercurial client request:
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   105
    #
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   106
    #   HOST: localhost:$HGPORT
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   107
    #   ACCEPT: application/vnd.git-lfs+json
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   108
    #   ACCEPT-ENCODING: identity
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   109
    #   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: 37150
diff changeset
   110
    #   Content-Length: 125
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   111
    #   Content-Type: application/vnd.git-lfs+json
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   112
    #
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   113
    #   {
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   114
    #     "objects": [
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   115
    #       {
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   116
    #         "oid": "31cf...8e5b"
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   117
    #         "size": 12
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   118
    #       }
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   119
    #     ]
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   120
    #     "operation": "upload"
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   121
    #  }
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   122
37693
31a0d47d69b3 lfs: update the HTTP status codes in error cases
Matt Harbison <matt_harbison@yahoo.com>
parents: 37692
diff changeset
   123
    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
   124
        _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
   125
        return True
31a0d47d69b3 lfs: update the HTTP status codes in error cases
Matt Harbison <matt_harbison@yahoo.com>
parents: 37692
diff changeset
   126
31a0d47d69b3 lfs: update the HTTP status codes in error cases
Matt Harbison <matt_harbison@yahoo.com>
parents: 37692
diff changeset
   127
    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
   128
        _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
   129
        return True
31a0d47d69b3 lfs: update the HTTP status codes in error cases
Matt Harbison <matt_harbison@yahoo.com>
parents: 37692
diff changeset
   130
31a0d47d69b3 lfs: update the HTTP status codes in error cases
Matt Harbison <matt_harbison@yahoo.com>
parents: 37692
diff changeset
   131
    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
   132
        _sethttperror(res, HTTP_NOT_ACCEPTABLE)
37151
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   133
        return True
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   134
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   135
    # XXX: specify an encoding?
43380
579672b347d2 py3: define and use json.loads polyfill
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43115
diff changeset
   136
    lfsreq = pycompat.json_loads(req.bodyfh.read())
37151
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   137
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   138
    # If no transfer handlers are explicitly requested, 'basic' is assumed.
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
   139
    if 'basic' not in lfsreq.get('transfers', ['basic']):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
   140
        _sethttperror(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
   141
            res,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
   142
            HTTP_BAD_REQUEST,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
   143
            b'Only the basic LFS transfer handler is supported',
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
   144
        )
37151
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   145
        return True
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   146
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
   147
    operation = lfsreq.get('operation')
41447
6d7f18cd81d9 py3: raw stringify various things in the LFS server module
Matt Harbison <matt_harbison@yahoo.com>
parents: 41446
diff changeset
   148
    operation = pycompat.bytestr(operation)
6d7f18cd81d9 py3: raw stringify various things in the LFS server module
Matt Harbison <matt_harbison@yahoo.com>
parents: 41446
diff changeset
   149
6d7f18cd81d9 py3: raw stringify various things in the LFS server module
Matt Harbison <matt_harbison@yahoo.com>
parents: 41446
diff changeset
   150
    if operation not in (b'upload', b'download'):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
   151
        _sethttperror(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
   152
            res,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
   153
            HTTP_BAD_REQUEST,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
   154
            b'Unsupported LFS transfer operation: %s' % operation,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
   155
        )
37151
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   156
        return True
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   157
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   158
    localstore = repo.svfs.lfslocalblobstore
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   159
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
   160
    objects = [
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
   161
        p
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
   162
        for p in _batchresponseobjects(
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
   163
            req, lfsreq.get('objects', []), operation, localstore
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
   164
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
   165
    ]
37151
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   166
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   167
    rsp = {
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
   168
        'transfer': 'basic',
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
   169
        'objects': objects,
37151
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   170
    }
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   171
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   172
    res.status = hgwebcommon.statusmessage(HTTP_OK)
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   173
    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: 37150
diff changeset
   174
    res.setbodybytes(pycompat.bytestr(json.dumps(rsp)))
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   175
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   176
    return True
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   177
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
   178
37151
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   179
def _batchresponseobjects(req, objects, action, store):
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   180
    """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: 37150
diff changeset
   181
    object in the list.
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   182
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   183
    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: 37150
diff changeset
   184
    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: 37150
diff changeset
   185
    action: 'upload' or 'download'
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   186
    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: 37150
diff changeset
   187
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   188
    # 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: 37150
diff changeset
   189
    # {
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   190
    #    u'objects': [{
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   191
    #       u'size': 12,
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   192
    #       u'oid': u'31cf...8e5b',
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   193
    #       u'actions': {
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   194
    #           u'upload': {
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   195
    #               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: 37150
diff changeset
   196
    #               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: 37150
diff changeset
   197
    #               u'header': {
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   198
    #                   u'Accept': u'application/vnd.git-lfs'
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   199
    #               }
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   200
    #           }
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   201
    #       }
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   202
    #    }]
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   203
    # }
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   204
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   205
    # 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: 37150
diff changeset
   206
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   207
    for obj in objects:
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   208
        # Convert unicode to ASCII to create a filesystem path
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
   209
        soid = obj.get('oid')
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
   210
        oid = soid.encode('ascii')
37151
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   211
        rsp = {
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
   212
            'oid': soid,
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
   213
            'size': obj.get('size'),  # XXX: should this check the local size?
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
   214
            # 'authenticated': True,
37151
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   215
        }
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   216
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   217
        exists = True
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   218
        verifies = False
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   219
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   220
        # 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: 37150
diff changeset
   221
        # 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: 37150
diff changeset
   222
        # 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: 37150
diff changeset
   223
        # (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: 37150
diff changeset
   224
        # 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: 37150
diff changeset
   225
        # 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: 37150
diff changeset
   226
        # 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: 37150
diff changeset
   227
        try:
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   228
            verifies = store.verify(oid)
41446
7a11e4e55d5f py3: add b'' prefixes to the LFS server module
Matt Harbison <matt_harbison@yahoo.com>
parents: 41051
diff changeset
   229
            if verifies and action == b'upload':
39474
a913d2892e17 lfs: ensure the blob is linked to the remote store on skipped uploads
Matt Harbison <matt_harbison@yahoo.com>
parents: 37851
diff changeset
   230
                # The client will skip this upload, but make sure it remains
a913d2892e17 lfs: ensure the blob is linked to the remote store on skipped uploads
Matt Harbison <matt_harbison@yahoo.com>
parents: 37851
diff changeset
   231
                # available locally.
a913d2892e17 lfs: ensure the blob is linked to the remote store on skipped uploads
Matt Harbison <matt_harbison@yahoo.com>
parents: 37851
diff changeset
   232
                store.linkfromusercache(oid)
37151
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   233
        except IOError as inst:
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   234
            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
   235
                _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
   236
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
   237
                rsp['error'] = {
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
   238
                    'code': 500,
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
   239
                    'message': inst.strerror or 'Internal Server Server',
37151
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   240
                }
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   241
                yield rsp
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   242
                continue
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   243
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   244
            exists = False
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   245
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   246
        # 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: 37150
diff changeset
   247
        # IFF they already exist locally.
41446
7a11e4e55d5f py3: add b'' prefixes to the LFS server module
Matt Harbison <matt_harbison@yahoo.com>
parents: 41051
diff changeset
   248
        if action == b'download':
37151
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   249
            if not exists:
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
   250
                rsp['error'] = {
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
   251
                    'code': 404,
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
   252
                    'message': "The object does not exist",
37151
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   253
                }
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   254
                yield rsp
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   255
                continue
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   256
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   257
            elif not verifies:
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
   258
                rsp['error'] = {
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
   259
                    'code': 422,  # XXX: is this the right code?
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
   260
                    'message': "The object is corrupt",
37151
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   261
                }
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   262
                yield rsp
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   263
                continue
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   264
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   265
        elif verifies:
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   266
            yield rsp  # Skip 'actions': already uploaded
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   267
            continue
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   268
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   269
        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: 37150
diff changeset
   270
37766
925707ac2855 lfs: add the 'Authorization' property to the Batch API response, if present
Matt Harbison <matt_harbison@yahoo.com>
parents: 37693
diff changeset
   271
        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
   272
            # 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
   273
            # 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
   274
            # output.
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
   275
            hdr = {'Accept': 'application/vnd.git-lfs'}
37766
925707ac2855 lfs: add the 'Authorization' property to the Batch API response, if present
Matt Harbison <matt_harbison@yahoo.com>
parents: 37693
diff changeset
   276
41446
7a11e4e55d5f py3: add b'' prefixes to the LFS server module
Matt Harbison <matt_harbison@yahoo.com>
parents: 41051
diff changeset
   277
            auth = req.headers.get(b'Authorization', b'')
7a11e4e55d5f py3: add b'' prefixes to the LFS server module
Matt Harbison <matt_harbison@yahoo.com>
parents: 41051
diff changeset
   278
            if auth.startswith(b'Basic '):
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
   279
                hdr['Authorization'] = pycompat.strurl(auth)
37766
925707ac2855 lfs: add the 'Authorization' property to the Batch API response, if present
Matt Harbison <matt_harbison@yahoo.com>
parents: 37693
diff changeset
   280
925707ac2855 lfs: add the 'Authorization' property to the Batch API response, if present
Matt Harbison <matt_harbison@yahoo.com>
parents: 37693
diff changeset
   281
            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
   282
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
   283
        rsp['actions'] = {
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
   284
            '%s'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
   285
            % pycompat.strurl(action): {
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
   286
                'href': pycompat.strurl(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
   287
                    b'%s%s/.hg/lfs/objects/%s' % (req.baseurl, req.apppath, oid)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
   288
                ),
37151
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   289
                # datetime.isoformat() doesn't include the 'Z' suffix
43554
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
   290
                "expires_at": expiresat.strftime('%Y-%m-%dT%H:%M:%SZ'),
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43551
diff changeset
   291
                'header': _buildheader(),
37151
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   292
            }
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   293
        }
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   294
ea6fc58524d7 lfs: add server side support for the Batch API
Matt Harbison <matt_harbison@yahoo.com>
parents: 37150
diff changeset
   295
        yield rsp
37150
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
   296
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
   297
37150
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
   298
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
   299
    """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
   300
    Transfer Adapter.
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
   301
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
   302
    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
   303
    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
   304
    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
   305
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
   306
    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
   307
    """
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
   308
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
   309
    method = req.method
37251
fe061e47a2cf lfs: avoid an improper usage of os.path.basename() to parse a URI
Matt Harbison <matt_harbison@yahoo.com>
parents: 37250
diff changeset
   310
    oid = req.dispatchparts[-1]
37152
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37151
diff changeset
   311
    localstore = repo.svfs.lfslocalblobstore
37150
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
   312
37252
9640ccf44ac0 lfs: ensure the transfer request is for a known URI
Matt Harbison <matt_harbison@yahoo.com>
parents: 37251
diff changeset
   313
    if len(req.dispatchparts) != 4:
9640ccf44ac0 lfs: ensure the transfer request is for a known URI
Matt Harbison <matt_harbison@yahoo.com>
parents: 37251
diff changeset
   314
        _sethttperror(res, HTTP_NOT_FOUND)
9640ccf44ac0 lfs: ensure the transfer request is for a known URI
Matt Harbison <matt_harbison@yahoo.com>
parents: 37251
diff changeset
   315
        return True
9640ccf44ac0 lfs: ensure the transfer request is for a known URI
Matt Harbison <matt_harbison@yahoo.com>
parents: 37251
diff changeset
   316
37150
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
   317
    if method == b'PUT':
41446
7a11e4e55d5f py3: add b'' prefixes to the LFS server module
Matt Harbison <matt_harbison@yahoo.com>
parents: 41051
diff changeset
   318
        checkperm(b'upload')
37152
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37151
diff changeset
   319
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37151
diff changeset
   320
        # TODO: verify Content-Type?
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37151
diff changeset
   321
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37151
diff changeset
   322
        existed = localstore.has(oid)
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37151
diff changeset
   323
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37151
diff changeset
   324
        # 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: 37151
diff changeset
   325
        #       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: 37151
diff changeset
   326
        #       says it will?
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37151
diff changeset
   327
37692
10e5bb9678f4 lfs: gracefully handle aborts on the server when corrupt blobs are detected
Matt Harbison <matt_harbison@yahoo.com>
parents: 37690
diff changeset
   328
        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
   329
        try:
44085
0ee0a3f6a990 lfs: check content length after downloading content
Matt Harbison <matt_harbison@yahoo.com>
parents: 43554
diff changeset
   330
            localstore.download(oid, req.bodyfh, req.headers[b'Content-Length'])
37692
10e5bb9678f4 lfs: gracefully handle aborts on the server when corrupt blobs are detected
Matt Harbison <matt_harbison@yahoo.com>
parents: 37690
diff changeset
   331
            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
   332
        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
   333
            _logexception(req)
37152
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37151
diff changeset
   334
37692
10e5bb9678f4 lfs: gracefully handle aborts on the server when corrupt blobs are detected
Matt Harbison <matt_harbison@yahoo.com>
parents: 37690
diff changeset
   335
            # 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
   336
            res.status = statusmessage(422, b'corrupt blob')
37152
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37151
diff changeset
   337
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37151
diff changeset
   338
        # 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: 37151
diff changeset
   339
        # sends back.  This eliminates some gratuitous test output conditionals.
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37151
diff changeset
   340
        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: 37151
diff changeset
   341
        res.setbodybytes(b'')
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37151
diff changeset
   342
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37151
diff changeset
   343
        return True
37150
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
   344
    elif method == b'GET':
41446
7a11e4e55d5f py3: add b'' prefixes to the LFS server module
Matt Harbison <matt_harbison@yahoo.com>
parents: 41051
diff changeset
   345
        checkperm(b'pull')
37150
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents:
diff changeset
   346
37152
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37151
diff changeset
   347
        res.status = hgwebcommon.statusmessage(HTTP_OK)
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37151
diff changeset
   348
        res.headers[b'Content-Type'] = b'application/octet-stream'
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37151
diff changeset
   349
37692
10e5bb9678f4 lfs: gracefully handle aborts on the server when corrupt blobs are detected
Matt Harbison <matt_harbison@yahoo.com>
parents: 37690
diff changeset
   350
        try:
10e5bb9678f4 lfs: gracefully handle aborts on the server when corrupt blobs are detected
Matt Harbison <matt_harbison@yahoo.com>
parents: 37690
diff changeset
   351
            # 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
   352
            #       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
   353
            #       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
   354
            #       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
   355
            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
   356
        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
   357
            _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
   358
10e5bb9678f4 lfs: gracefully handle aborts on the server when corrupt blobs are detected
Matt Harbison <matt_harbison@yahoo.com>
parents: 37690
diff changeset
   359
            # 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
   360
            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
   361
            res.setbodybytes(b'')
37152
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37151
diff changeset
   362
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37151
diff changeset
   363
        return True
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37151
diff changeset
   364
    else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
   365
        _sethttperror(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
   366
            res,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
   367
            HTTP_METHOD_NOT_ALLOWED,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
   368
            message=b'Unsupported LFS transfer method: %s' % method,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41447
diff changeset
   369
        )
37152
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37151
diff changeset
   370
        return True