def test_check_container_format(self):
     invalid_versions_locations = ("container/with/slashes", "")  # empty
     for versions_location in invalid_versions_locations:
         req = Request.blank("/v/a/c/o", headers={"X-Versions-Location": versions_location})
         try:
             constraints.check_container_format(req, req.headers["X-Versions-Location"])
         except HTTPException as e:
             self.assertTrue(e.body.startswith("Container name cannot"))
         else:
             self.fail("check_container_format did not raise error for %r" % req.headers["X-Versions-Location"])
示例#2
0
 def test_check_container_format(self):
     invalid_versions_locations = (
         'container/with/slashes',
         '',  # empty
     )
     for versions_location in invalid_versions_locations:
         req = Request.blank(
             '/v/a/c/o', headers={'X-Versions-Location': versions_location})
         with self.assertRaises(HTTPException) as cm:
             constraints.check_container_format(
                 req, req.headers['X-Versions-Location'])
         self.assertTrue(
             cm.exception.body.startswith(b'Container name cannot'))
示例#3
0
 def test_check_container_format(self):
     invalid_versions_locations = (
         'container/with/slashes',
         '',  # empty
     )
     for versions_location in invalid_versions_locations:
         req = Request.blank(
             '/v/a/c/o', headers={
                 'X-Versions-Location': versions_location})
         with self.assertRaises(HTTPException) as cm:
             constraints.check_container_format(
                 req, req.headers['X-Versions-Location'])
         self.assertTrue(cm.exception.body.startswith(
             b'Container name cannot'))
示例#4
0
    def container_request(self, req, start_response, enabled):
        # set version location header as sysmeta
        if VERSIONS_LOC_CLIENT in req.headers:
            val = req.headers.get(VERSIONS_LOC_CLIENT)
            if val:
                # differently from previous version, we are actually
                # returning an error if user tries to set versions location
                # while feature is explicitly disabled.
                if not config_true_value(enabled) and \
                        req.method in ('PUT', 'POST'):
                    raise HTTPPreconditionFailed(
                        request=req, content_type='text/plain',
                        body='Versioned Writes is disabled')

                location = check_container_format(req, val)
                req.headers[VERSIONS_LOC_SYSMETA] = location

                # reset original header to maintain sanity
                # now only sysmeta is source of Versions Location
                req.headers[VERSIONS_LOC_CLIENT] = ''

                # if both headers are in the same request
                # adding location takes precedence over removing
                if 'X-Remove-Versions-Location' in req.headers:
                    del req.headers['X-Remove-Versions-Location']
            else:
                # empty value is the same as X-Remove-Versions-Location
                req.headers['X-Remove-Versions-Location'] = 'x'

        # handle removing versions container
        val = req.headers.get('X-Remove-Versions-Location')
        if val:
            req.headers.update({VERSIONS_LOC_SYSMETA: '',
                                VERSIONS_LOC_CLIENT: ''})
            del req.headers['X-Remove-Versions-Location']

        # handle versioning mode
        if VERSIONS_MODE_CLIENT in req.headers:
            val = req.headers.pop(VERSIONS_MODE_CLIENT)
            if val:
                if not config_true_value(enabled) and \
                        req.method in ('PUT', 'POST'):
                    raise HTTPPreconditionFailed(
                        request=req, content_type='text/plain',
                        body='Versioned Writes is disabled')
                if val not in VERSIONING_MODES:
                    raise HTTPBadRequest(
                        request=req, content_type='text/plain',
                        body='X-Versions-Mode must be one of %s' % ', '.join(
                            VERSIONING_MODES))
                req.headers[VERSIONS_MODE_SYSMETA] = val
            else:
                req.headers['X-Remove-Versions-Mode'] = 'x'

        if req.headers.pop('X-Remove-Versions-Mode', None):
            req.headers.update({VERSIONS_MODE_SYSMETA: ''})

        # send request and translate sysmeta headers from response
        vw_ctx = VersionedWritesContext(self.app, self.logger)
        return vw_ctx.handle_container_request(req.environ, start_response)
示例#5
0
 def test_check_container_format(self):
     invalid_versions_locations = (
         'container/with/slashes',
         '',  # empty
     )
     for versions_location in invalid_versions_locations:
         req = Request.blank(
             '/v/a/c/o', headers={'X-Versions-Location': versions_location})
         try:
             constraints.check_container_format(
                 req, req.headers['X-Versions-Location'])
         except HTTPException as e:
             self.assertTrue(e.body.startswith('Container name cannot'))
         else:
             self.fail('check_container_format did not raise error for %r' %
                       req.headers['X-Versions-Location'])
示例#6
0
 def test_check_container_format(self):
     invalid_versions_locations = (
         'container/with/slashes',
         '',  # empty
     )
     for versions_location in invalid_versions_locations:
         req = Request.blank(
             '/v/a/c/o', headers={
                 'X-Versions-Location': versions_location})
         try:
             constraints.check_container_format(
                 req, req.headers['X-Versions-Location'])
         except HTTPException as e:
             self.assertTrue(e.body.startswith('Container name cannot'))
         else:
             self.fail('check_container_format did not raise error for %r' %
                       req.headers['X-Versions-Location'])
示例#7
0
    def container_request(self, req, start_response, enabled):
        # set version location header as sysmeta
        if VERSIONS_LOC_CLIENT in req.headers:
            val = req.headers.get(VERSIONS_LOC_CLIENT)
            if val:
                # differently from previous version, we are actually
                # returning an error if user tries to set versions location
                # while feature is explicitly disabled.
                if not config_true_value(enabled) and req.method in ("PUT", "POST"):
                    raise HTTPPreconditionFailed(
                        request=req, content_type="text/plain", body="Versioned Writes is disabled"
                    )

                location = check_container_format(req, val)
                req.headers[VERSIONS_LOC_SYSMETA] = location

                # reset original header to maintain sanity
                # now only sysmeta is source of Versions Location
                req.headers[VERSIONS_LOC_CLIENT] = ""

                # if both headers are in the same request
                # adding location takes precedence over removing
                if "X-Remove-Versions-Location" in req.headers:
                    del req.headers["X-Remove-Versions-Location"]
            else:
                # empty value is the same as X-Remove-Versions-Location
                req.headers["X-Remove-Versions-Location"] = "x"

        # handle removing versions container
        val = req.headers.get("X-Remove-Versions-Location")
        if val:
            req.headers.update({VERSIONS_LOC_SYSMETA: "", VERSIONS_LOC_CLIENT: ""})
            del req.headers["X-Remove-Versions-Location"]

        # handle versioning mode
        if VERSIONS_MODE_CLIENT in req.headers:
            val = req.headers.pop(VERSIONS_MODE_CLIENT)
            if val:
                if not config_true_value(enabled) and req.method in ("PUT", "POST"):
                    raise HTTPPreconditionFailed(
                        request=req, content_type="text/plain", body="Versioned Writes is disabled"
                    )
                if val not in VERSIONING_MODES:
                    raise HTTPBadRequest(
                        request=req,
                        content_type="text/plain",
                        body="X-Versions-Mode must be one of %s" % ", ".join(VERSIONING_MODES),
                    )
                req.headers[VERSIONS_MODE_SYSMETA] = val
            else:
                req.headers["X-Remove-Versions-Mode"] = "x"

        if req.headers.pop("X-Remove-Versions-Mode", None):
            req.headers.update({VERSIONS_MODE_SYSMETA: ""})

        # send request and translate sysmeta headers from response
        vw_ctx = VersionedWritesContext(self.app, self.logger)
        return vw_ctx.handle_container_request(req.environ, start_response)
    def container_request(self, req, start_response, enabled):
        sysmeta_version_hdr = get_sys_meta_prefix('container') + \
            'versions-location'

        # set version location header as sysmeta
        if 'X-Versions-Location' in req.headers:
            val = req.headers.get('X-Versions-Location')
            if val:
                # diferently from previous version, we are actually
                # returning an error if user tries to set versions location
                # while feature is explicitly disabled.
                if not config_true_value(enabled) and \
                        req.method in ('PUT', 'POST'):
                    raise HTTPPreconditionFailed(
                        request=req,
                        content_type='text/plain',
                        body='Versioned Writes is disabled')

                location = check_container_format(req, val)
                req.headers[sysmeta_version_hdr] = location

                # reset original header to maintain sanity
                # now only sysmeta is source of Versions Location
                req.headers['X-Versions-Location'] = ''

                # if both headers are in the same request
                # adding location takes precendence over removing
                if 'X-Remove-Versions-Location' in req.headers:
                    del req.headers['X-Remove-Versions-Location']
            else:
                # empty value is the same as X-Remove-Versions-Location
                req.headers['X-Remove-Versions-Location'] = 'x'

        # handle removing versions container
        val = req.headers.get('X-Remove-Versions-Location')
        if val:
            req.headers.update({sysmeta_version_hdr: ''})
            req.headers.update({'X-Versions-Location': ''})
            del req.headers['X-Remove-Versions-Location']

        # send request and translate sysmeta headers from response
        vw_ctx = VersionedWritesContext(self.app, self.logger)
        return vw_ctx.handle_container_request(req.environ, start_response)
示例#9
0
    def container_request(self, req, start_response, enabled):
        sysmeta_version_hdr = get_sys_meta_prefix('container') + \
            'versions-location'

        # set version location header as sysmeta
        if 'X-Versions-Location' in req.headers:
            val = req.headers.get('X-Versions-Location')
            if val:
                # differently from previous version, we are actually
                # returning an error if user tries to set versions location
                # while feature is explicitly disabled.
                if not config_true_value(enabled) and \
                        req.method in ('PUT', 'POST'):
                    raise HTTPPreconditionFailed(
                        request=req, content_type='text/plain',
                        body='Versioned Writes is disabled')

                location = check_container_format(req, val)
                req.headers[sysmeta_version_hdr] = location

                # reset original header to maintain sanity
                # now only sysmeta is source of Versions Location
                req.headers['X-Versions-Location'] = ''

                # if both headers are in the same request
                # adding location takes precedence over removing
                if 'X-Remove-Versions-Location' in req.headers:
                    del req.headers['X-Remove-Versions-Location']
            else:
                # empty value is the same as X-Remove-Versions-Location
                req.headers['X-Remove-Versions-Location'] = 'x'

        # handle removing versions container
        val = req.headers.get('X-Remove-Versions-Location')
        if val:
            req.headers.update({sysmeta_version_hdr: ''})
            req.headers.update({'X-Versions-Location': ''})
            del req.headers['X-Remove-Versions-Location']

        # send request and translate sysmeta headers from response
        vw_ctx = VersionedWritesContext(self.app, self.logger)
        return vw_ctx.handle_container_request(req.environ, start_response)
示例#10
0
    def container_request(self, req, start_response, enabled):
        if CLIENT_VERSIONS_LOC in req.headers and \
                CLIENT_HISTORY_LOC in req.headers:
            if not req.headers[CLIENT_HISTORY_LOC]:
                # defer to versions location entirely
                del req.headers[CLIENT_HISTORY_LOC]
            elif req.headers[CLIENT_VERSIONS_LOC]:
                raise HTTPBadRequest(
                    request=req,
                    content_type='text/plain',
                    body='Only one of %s or %s may be specified' %
                    (CLIENT_VERSIONS_LOC, CLIENT_HISTORY_LOC))
            else:
                # history location is present and versions location is
                # present but empty -- clean it up
                del req.headers[CLIENT_VERSIONS_LOC]

        if CLIENT_VERSIONS_LOC in req.headers or \
                CLIENT_HISTORY_LOC in req.headers:
            if CLIENT_VERSIONS_LOC in req.headers:
                val = req.headers[CLIENT_VERSIONS_LOC]
                mode = 'stack'
            else:
                val = req.headers[CLIENT_HISTORY_LOC]
                mode = 'history'

            if not val:
                # empty value is the same as X-Remove-Versions-Location
                req.headers['X-Remove-Versions-Location'] = 'x'
            elif not config_true_value(enabled) and \
                    req.method in ('PUT', 'POST'):
                # differently from previous version, we are actually
                # returning an error if user tries to set versions location
                # while feature is explicitly disabled.
                raise HTTPPreconditionFailed(
                    request=req,
                    content_type='text/plain',
                    body='Versioned Writes is disabled')
            else:
                # OK, we received a value, have versioning enabled, and aren't
                # trying to set two modes at once. Validate the value and
                # translate to sysmeta.
                location = check_container_format(req, val)
                req.headers[SYSMETA_VERSIONS_LOC] = location
                req.headers[SYSMETA_VERSIONS_MODE] = mode

                # reset original header on container server to maintain sanity
                # now only sysmeta is source of Versions Location
                req.headers[CLIENT_VERSIONS_LOC] = ''

                # if both add and remove headers are in the same request
                # adding location takes precedence over removing
                for header in [
                        'X-Remove-Versions-Location',
                        'X-Remove-History-Location'
                ]:
                    if header in req.headers:
                        del req.headers[header]

        if any(
                req.headers.get(header) for header in
            ['X-Remove-Versions-Location', 'X-Remove-History-Location']):
            req.headers.update({
                CLIENT_VERSIONS_LOC: '',
                SYSMETA_VERSIONS_LOC: '',
                SYSMETA_VERSIONS_MODE: ''
            })
            for header in [
                    'X-Remove-Versions-Location', 'X-Remove-History-Location'
            ]:
                if header in req.headers:
                    del req.headers[header]

        # send request and translate sysmeta headers from response
        vw_ctx = VersionedWritesContext(self.app, self.logger)
        return vw_ctx.handle_container_request(req.environ, start_response)
示例#11
0
    def container_request(self, req, start_response, enabled):
        if CLIENT_VERSIONS_LOC in req.headers and \
                CLIENT_HISTORY_LOC in req.headers:
            if not req.headers[CLIENT_HISTORY_LOC]:
                # defer to versions location entirely
                del req.headers[CLIENT_HISTORY_LOC]
            elif req.headers[CLIENT_VERSIONS_LOC]:
                raise HTTPBadRequest(
                    request=req, content_type='text/plain',
                    body='Only one of %s or %s may be specified' % (
                        CLIENT_VERSIONS_LOC, CLIENT_HISTORY_LOC))
            else:
                # history location is present and versions location is
                # present but empty -- clean it up
                del req.headers[CLIENT_VERSIONS_LOC]

        if CLIENT_VERSIONS_LOC in req.headers or \
                CLIENT_HISTORY_LOC in req.headers:
            if CLIENT_VERSIONS_LOC in req.headers:
                val = req.headers[CLIENT_VERSIONS_LOC]
                mode = 'stack'
            else:
                val = req.headers[CLIENT_HISTORY_LOC]
                mode = 'history'

            if not val:
                # empty value is the same as X-Remove-Versions-Location
                req.headers['X-Remove-Versions-Location'] = 'x'
            elif not config_true_value(enabled) and \
                    req.method in ('PUT', 'POST'):
                # differently from previous version, we are actually
                # returning an error if user tries to set versions location
                # while feature is explicitly disabled.
                raise HTTPPreconditionFailed(
                    request=req, content_type='text/plain',
                    body='Versioned Writes is disabled')
            else:
                # OK, we received a value, have versioning enabled, and aren't
                # trying to set two modes at once. Validate the value and
                # translate to sysmeta.
                location = check_container_format(req, val)
                req.headers[SYSMETA_VERSIONS_LOC] = location
                req.headers[SYSMETA_VERSIONS_MODE] = mode

                # reset original header on container server to maintain sanity
                # now only sysmeta is source of Versions Location
                req.headers[CLIENT_VERSIONS_LOC] = ''

                # if both add and remove headers are in the same request
                # adding location takes precedence over removing
                for header in ['X-Remove-Versions-Location',
                               'X-Remove-History-Location']:
                    if header in req.headers:
                        del req.headers[header]

        if any(req.headers.get(header) for header in [
                'X-Remove-Versions-Location',
                'X-Remove-History-Location']):
            req.headers.update({CLIENT_VERSIONS_LOC: '',
                                SYSMETA_VERSIONS_LOC: '',
                                SYSMETA_VERSIONS_MODE: ''})
            for header in ['X-Remove-Versions-Location',
                           'X-Remove-History-Location']:
                if header in req.headers:
                    del req.headers[header]

        # send request and translate sysmeta headers from response
        vw_ctx = VersionedWritesContext(self.app, self.logger)
        return vw_ctx.handle_container_request(req.environ, start_response)