Example #1
0
	def patch(self):
		# Overwrite a region of an existing file
		req = self.req
		obj = req.context
		req.dav.user_acl(req, obj, dprops.ACL_WRITE_CONTENT)
		self.conditional_request(obj)
		ctype = req.content_type
		if ctype == 'application/x-sabredav-partialupdate':
			if 'Content-Length' not in req.headers:
				raise dav.DAVLengthRequiredError('SabreDAV PATCH method requires Content-Length: HTTP header.')
			if 'X-Update-Range' not in req.headers:
				raise dav.DAVBadRequestError('Patch range must be specified via X-Update-Range: HTTP header.')
			range_hdr = req.headers.get('X-Update-Range')
			if ',' in range_hdr:
				raise dav.DAVBadRequestError('Malformed patch range or multiple ranges supplied via X-Update-Range: HTTP header.')
			r_start = r_end = None
			obj_sz = getattr(obj, 'size', None)
			if callable(obj_sz):
				obj_sz = obj_sz(req)
			if range_hdr == 'append':
				if obj_sz is None:
					raise dav.DAVNotImplementedError('Node does not support appending data.')
				r_start = obj_sz
				r_end = r_start + req.content_length
			else:
				patch_range = parse_range(range_hdr)
				if patch_range is None:
					raise dav.DAVBadRequestError('Malformed patch range supplied via X-Update-Range: HTTP header.')
				r_start = patch_range.start
				r_end = patch_range.end
				if (r_start is not None) and (r_end is not None):
					if (r_end - r_start) != req.content_length:
						raise dav.DAVUnsatisfiableRangeError('Content length and range supplied via X-Update-Range: HTTP header are not consistent.')
				if r_start < 0:
					if obj_sz is None:
						raise dav.DAVNotImplementedError('Node does not support relative file offsets.')
					r_start = obj_sz + r_start
					if r_start < 0:
						raise dav.DAVUnsatisfiableRangeError('Relative offset (supplied via X-Update-Range: HTTP header) is before file start.')
					r_end = r_start + req.content_length
				if r_end is None:
					r_end = r_start + req.content_length
			putter = getattr(obj, 'dav_put', None)
			if putter is None:
				raise dav.DAVNotImplementedError('Unable to patch node.')
			modified = putter(req, req.body_file_seekable, r_start, r_end - r_start) # TODO: handle IOErrors, handle non-seekable request body
			if modified:
				etag = None
			else:
				etag = getattr(obj, 'etag', None)
				if callable(etag):
					etag = etag(req)
			resp = dav.DAVOverwriteResponse(request=req, etag=etag)
			req.dav.set_features(resp, node=obj)
			resp.headers.add('MS-Author-Via', 'DAV')
			return resp
		raise dav.DAVUnsupportedMediaTypeError('Unknown content type specified in PATCH request.')
Example #2
0
def test_parse_range_type():
    from webob.byterange import Range
    from webob.descriptors import parse_range

    val = parse_range("bytes=1-500")
    assert type(val) is type(Range.parse("bytes=1-500"))  # noqa: E701
Example #3
0
def test_parse_range_none():
    from webob.descriptors import parse_range

    assert parse_range(None) is None
Example #4
0
def test_parse_range_type():
    from webob.byterange import Range
    from webob.descriptors import parse_range
    val = parse_range("bytes=1-500")
    assert type(val) == type(Range.parse("bytes=1-500"))
Example #5
0
def test_parse_range_none():
    from webob.descriptors import parse_range
    assert parse_range(None) == None
Example #6
0
def test_parse_range_type():
    from webob.byterange import Range
    from webob.descriptors import parse_range
    val = parse_range("bytes=1-500")
    eq_(type(val), type(Range.parse("bytes=1-500")))
Example #7
0
def test_parse_range_none():
    from webob.descriptors import parse_range
    eq_(parse_range(None), None)
Example #8
0
def test_parse_range_values():
    from webob.byterange import Range
    from webob.descriptors import parse_range
    val = parse_range("bytes=1-500")
    eq_(val.ranges, Range.parse("bytes=1-500").ranges)
Example #9
0
def test_parse_range_none():
    from webob.descriptors import parse_range
    val = parse_range(None)
    eq_(val, None)
Example #10
0
def test_parse_range_none():
    from webob.descriptors import parse_range

    eq_(parse_range(None), None)
def test_parse_range_values():
    from webob.byterange import Range
    from webob.descriptors import parse_range
    val = parse_range("bytes=1-500")
    eq_(val.ranges, Range.parse("bytes=1-500").ranges)
def test_parse_range_none():
    from webob.descriptors import parse_range
    val = parse_range(None)
    eq_(val, None)