def test_send_seek(): src = memory.Backend("r", b"0123456789") src.seek(8) dst = io.BytesIO() op = ops.Send(src, dst, 5) op.run() assert dst.getvalue() == b"01234"
def test_send_partial_content(user_file, offset, size): with io.open(user_file.path, "wb") as f: f.truncate(offset + size - 1) dst = io.BytesIO() with file.open(user_file.url, "r") as src: op = ops.Send(src, dst, size, offset=offset) with pytest.raises(errors.PartialContent) as e: op.run() assert e.value.requested == size assert e.value.available == size - 1
def test_send_no_size(user_file, offset, size): data = b"b" * size with io.open(user_file.path, "wb") as f: f.write(b"a" * offset) f.write(data) dst = io.BytesIO() with file.open(user_file.url, "r") as src: op = ops.Send(src, dst, offset=offset) op.run() assert dst.getvalue() == data
def test_send_repr(): op = ops.Send(None, None, 200, offset=24) rep = repr(op) assert "Send" in rep assert "size=200 offset=24 buffersize=4096 done=0" in rep
def get(self, req, resp, ticket_id): if not ticket_id: raise http.Error(http.BAD_REQUEST, "Ticket id is required") offset = 0 size = None if req.range: offset = req.range.first if offset < 0: # TODO: support suffix-byte-range-spec "bytes=-last". # See https://tools.ietf.org/html/rfc7233#section-2.1. raise http.Error( http.REQUESTED_RANGE_NOT_SATISFIABLE, "suffix-byte-range-spec not supported yet") if req.range.last is not None: # Add 1 to include the last byte in the payload. size = req.range.last - offset + 1 # TODO: validate size with actual image size. try: ticket = auth.authorize(ticket_id, "read") except errors.AuthorizationError as e: raise http.Error(http.FORBIDDEN, str(e)) backend = self._backend(req, ticket) if size is not None: validate.allowed_range(offset, size, ticket) validate.available_range(offset, size, ticket, backend) else: size = min(ticket.size, backend.size()) - offset log.info( "[%s] READ size=%d offset=%d ticket=%s", req.client_addr, size, offset, ticket_id) content_disposition = "attachment" if ticket.filename: content_disposition += "; filename=%s" % ticket.filename resp.headers["content-length"] = size resp.headers["content-type"] = "application/octet-stream" resp.headers["content-disposition"] = content_disposition if req.range: resp.status_code = http.PARTIAL_CONTENT resp.headers["content-range"] = "bytes %d-%d/%d" % ( offset, offset + size - 1, ticket.size) op = ops.Send( self._backend(req, ticket), resp, size, offset=offset, buffersize=self.config.daemon.buffer_size, clock=req.clock) try: ticket.run(op) except errors.PartialContent as e: raise http.Error(http.BAD_REQUEST, str(e))