def test_headers():
    h = Headers(raw=[(b"a", b"123"), (b"a", b"456"), (b"b", b"789")])
    assert "a" in h
    assert "A" in h
    assert "b" in h
    assert "B" in h
    assert "c" not in h
    assert h["a"] == "123"
    assert h.get("a") == "123"
    assert h.get("nope", default=None) is None
    assert h.getlist("a") == ["123", "456"]
    assert h.keys() == ["a", "a", "b"]
    assert h.values() == ["123", "456", "789"]
    assert h.items() == [("a", "123"), ("a", "456"), ("b", "789")]
    assert list(h) == ["a", "a", "b"]
    assert dict(h) == {"a": "123", "b": "789"}
    assert repr(
        h) == "Headers(raw=[(b'a', b'123'), (b'a', b'456'), (b'b', b'789')])"
    assert h == Headers(raw=[(b"a", b"123"), (b"b", b"789"), (b"a", b"456")])
    assert h != [(b"a", b"123"), (b"A", b"456"), (b"b", b"789")]

    h = Headers({"a": "123", "b": "789"})
    assert h["A"] == "123"
    assert h["B"] == "789"
    assert h.raw == [(b"a", b"123"), (b"b", b"789")]
    assert repr(h) == "Headers({'a': '123', 'b': '789'})"
Example #2
0
    async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
        if self.allow_any or scope["type"] not in (
            "http",
            "websocket",
        ):  # pragma: no cover
            await self.app(scope, receive, send)
            return

        headers = Headers(scope=scope)
        host = headers.get("host", "").split(":")[0]
        is_valid_host = False
        found_www_redirect = False
        for pattern in self.allowed_hosts:
            if host == pattern or (
                pattern.startswith("*") and host.endswith(pattern[1:])
            ):
                is_valid_host = True
                break
            elif "www." + host == pattern:
                found_www_redirect = True

        if is_valid_host:
            await self.app(scope, receive, send)
        else:
            response: Response
            if found_www_redirect and self.www_redirect:
                url = URL(scope=scope)
                redirect_url = url.replace(netloc="www." + url.netloc)
                response = RedirectResponse(url=str(redirect_url))
            else:
                response = PlainTextResponse("Invalid host header", status_code=400)
            await response(scope, receive, send)
Example #3
0
    async def __call__(
            self, scope, receive, send
    ) -> None:
        if scope["type"] != "http":  # pragma: no cover
            handler = await self.app(scope, receive, send)
            await handler.__call__(receive, send)
            return

        method = scope["method"]
        headers = Headers(scope=scope)
        origin = headers.get("origin")

        if origin is None:
            handler = await self.app(scope, receive, send)
            await handler.__call__(receive, send)
            return

        if method == "OPTIONS" and "access-control-request-method" in headers:
            response = self.preflight_response(request_headers=headers)
            await response(scope, receive, send)
            return

        await self.simple_response(
            scope, receive, send, request_headers=headers
        )
Example #4
0
 async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
     if scope["type"] == "http":
         headers = Headers(scope=scope)
         if "gzip" in headers.get("Accept-Encoding", ""):
             responder = GZipResponder(self.app, self.minimum_size)
             await responder(scope, receive, send)
             return
     await self.app(scope, receive, send)
Example #5
0
File: span.py Project: nbashev/noc
 async def __call__(self, scope: Scope, receive: Receive,
                    send: Send) -> None:
     if scope["type"] != "http":
         await self.app(scope, receive, send)
         return
     headers = Headers(scope=scope)
     span_ctx = headers.get("x-noc-span-ctx", 0)
     span_id = headers.get("x-noc-span", 0)
     sample = 1 if span_ctx and span_id else 0
     with Span(
             server=self.service_name,
             service="api",
             sample=sample,
             parent=span_id,
             context=span_ctx,
             in_label=scope["path"],
     ):
         await self.app(scope, receive, send)
Example #6
0
    def __call__(self, scope: Scope) -> ASGIInstance:
        if scope["type"] in ("http", "websocket") and not self.allow_any:
            headers = Headers(scope=scope)
            host = headers.get("host")
            if host not in self.allowed_hosts:
                return PlainTextResponse("Invalid host header",
                                         status_code=400)

        return self.app(scope)
Example #7
0
 def is_not_modified(self, stat_headers: typing.Dict[str, str]) -> bool:
     etag = stat_headers["etag"]
     last_modified = stat_headers["last-modified"]
     req_headers = Headers(scope=self.scope)
     if etag == req_headers.get("if-none-match"):
         return True
     if "if-modified-since" not in req_headers:
         return False
     last_req_time = req_headers["if-modified-since"]
     return parsedate(last_req_time) >= parsedate(last_modified)  # type: ignore
Example #8
0
    def get_context(self, scope):
        request_method = scope.get("method")
        if request_method:
            trace_name = f"starlette_http_{request_method.lower()}"
        else:
            trace_name = "starlette_http"

        headers = Headers(scope=scope)

        return {
            "name": trace_name,
            "type": "http_server",
            "request.host": headers.get("host"),
            "request.method": request_method,
            "request.path": scope.get("path"),
            "request.content_length": int(headers.get("content-length", 0)),
            "request.user_agent": headers.get("user-agent"),
            "request.scheme": scope.get("scheme"),
            "request.query": scope.get("query_string").decode("ascii"),
        }
Example #9
0
    def get_jwt(self, header: Headers) -> str:
        if "Authorization" not in header:
            return

        token = header.get("Authorization")
        scheme, jwt = token.split()
        if scheme.lower() != "bearer":
            raise InvalidAuthorizationToken("header dose not start \
                with 'Bearer'")

        return jwt
Example #10
0
 async def __call__(self, scope: Scope, receive: Receive,
                    send: Send) -> None:
     if scope["type"] == "http":
         headers = Headers(scope=scope)
         if "br" in headers.get("Accept-Encoding", ""):
             responder = BrotliResponder(
                 self.app,
                 self.quality,
                 self.mode,
                 self.lgwin,
                 self.lgblock,
                 self.minimum_size,
             )
             await responder(scope, receive, send)
             return
         if self.gzip_fallback and "gzip" in headers.get(
                 "Accept-Encoding", ""):
             responder = GZipResponder(self.app, self.minimum_size)
             await responder(scope, receive, send)
             return
     await self.app(scope, receive, send)
Example #11
0
 async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
     headers = Headers(scope=scope)
     self.should_decode_from_msgpack_to_json = (
         "application/x-msgpack" in headers.get("content-type", "")
     )
     # Take an initial guess, although we eventually may not
     # be able to do the conversion.
     self.should_encode_from_json_to_msgpack = (
         "application/x-msgpack" in headers.getlist("accept")
     )
     self.receive = receive
     self.send = send
     await self.app(scope, self.receive_with_msgpack, self.send_with_msgpack)
Example #12
0
 def matches(self, scope: Scope) -> typing.Tuple[Match, Scope]:
     headers = Headers(scope=scope)
     host = headers.get("host", "").split(":")[0]
     match = self.host_regex.match(host)
     if match:
         matched_params = match.groupdict()
         for key, value in matched_params.items():
             matched_params[key] = self.param_convertors[key].convert(value)
         path_params = dict(scope.get("path_params", {}))
         path_params.update(matched_params)
         child_scope = {"path_params": path_params, "endpoint": self.app}
         return Match.FULL, child_scope
     return Match.NONE, {}
Example #13
0
    def __call__(self, scope: Scope) -> ASGIInstance:
        if scope["type"] == "http":
            method = scope["method"]
            headers = Headers(scope=scope)
            origin = headers.get("origin")

            if origin is not None:
                if method == "OPTIONS" and "access-control-request-method" in headers:
                    return self.preflight_response(request_headers=headers)
                else:
                    return functools.partial(self.simple_response,
                                             scope=scope,
                                             request_headers=headers)

        return self.app(scope)
Example #14
0
    def __call__(self, scope: Scope) -> ASGIInstance:
        if scope["type"] in ("http", "websocket") and not self.allow_any:
            headers = Headers(scope=scope)
            host = headers.get("host", "").split(":")[0]
            for pattern in self.allowed_hosts:
                if (
                    host == pattern
                    or pattern.startswith("*")
                    and host.endswith(pattern[1:])
                ):
                    break
            else:
                return PlainTextResponse("Invalid host header", status_code=400)

        return self.app(scope)
Example #15
0
 async def __call__(self, scope: Scope, receive: Receive,
                    send: Send) -> None:
     if scope["type"] == "http":
         headers = Headers(scope=scope)
         accepted = {
             item.strip()
             for item in headers.get("accept-encoding", "").split(",")
             if item
         }
         responder = CompressionResponder(self.app, self.minimum_size,
                                          accepted,
                                          self.compression_registry)
         await responder(scope, receive, send)
         return
     await self.app(scope, receive, send)
    async def send_with_logging(self, message: Message) -> None:

        if message["type"] == "http.response.start":
            self._response_status_code = message.get("status")
            headers = Headers(raw=message["headers"])
            self.should_log_response_body = "application/json" in headers.get(
                "content-type", "")

            await self.send(message)

        elif message["type"] == "http.response.body":
            if not self.should_log_response_body:
                await self.send(message)
                return

            body: bytes = message.get("body", b"")
            self._response_body.extend(body)

            await self.send(message)
Example #17
0
    def preflight_response(self, request_headers: Headers) -> ASGIInstance:
        requested_origin = request_headers["origin"]
        requested_method = request_headers["access-control-request-method"]
        requested_headers = request_headers.get(
            "access-control-request-headers")
        requested_cookie = "cookie" in request_headers

        headers = dict(self.preflight_headers)
        failures = []

        if self.is_allowed_origin(origin=requested_origin):
            if not self.allow_all_origins:
                # If self.allow_all_origins is True, then the "Access-Control-Allow-Origin"
                # header is already set to "*".
                # If we only allow specific origins, then we have to mirror back
                # the Origin header in the response.
                headers["Access-Control-Allow-Origin"] = requested_origin
        else:
            failures.append("origin")

        if requested_method not in self.allow_methods:
            failures.append("method")

        # If we allow all headers, then we have to mirror back any requested
        # headers in the response.
        if self.allow_all_headers and requested_headers is not None:
            headers["Access-Control-Allow-Headers"] = requested_headers
        elif requested_headers is not None:
            for header in requested_headers.split(","):
                if header.strip() not in self.allow_headers:
                    failures.append("headers")

        # We don't strictly need to use 400 responses here, since its up to
        # the browser to enforce the CORS policy, but its more informative
        # if we do.
        if failures:
            failure_text = "Disallowed CORS " + ", ".join(failures)
            return PlainTextResponse(failure_text,
                                     status_code=400,
                                     headers=headers)

        return PlainTextResponse("OK", status_code=200, headers=headers)
Example #18
0
    def __call__(self, scope: Scope) -> ASGIInstance:
        if scope["type"] in ("http", "websocket") and not self.allow_any:
            headers = Headers(scope=scope)
            host = headers.get("host", "").split(":")[0]
            found_www_redirect = False
            for pattern in self.allowed_hosts:
                if host == pattern or (pattern.startswith("*")
                                       and host.endswith(pattern[1:])):
                    break
                elif "www." + host == pattern:
                    found_www_redirect = True
            else:
                if found_www_redirect and self.www_redirect:
                    url = URL(scope=scope)
                    redirect_url = url.replace(netloc="www." + url.netloc)
                    return RedirectResponse(url=str(redirect_url))
                return PlainTextResponse("Invalid host header",
                                         status_code=400)

        return self.app(scope)
    async def __call__(self, scope: Scope, receive: Receive,
                       send: Send) -> None:
        self.receive = receive
        self.send = send

        request = Request(scope)

        if self._should_ignore_request(request):
            await self.app(scope, self.receive, self.send)
            return

        self._method = request.method
        self._path = request.url.path
        headers = Headers(scope=scope)
        self.should_log_request_body = "application/json" in headers.get(
            "content-type", "")

        await self.app(scope, self.receive_with_logging,
                       self.send_with_logging)

        self._safe_log_request_response()
Example #20
0
    def preflight_response(self, request_headers: Headers) -> Response:
        requested_origin = request_headers["origin"]
        requested_method = request_headers["access-control-request-method"]
        requested_headers = request_headers.get(
            "access-control-request-headers")

        headers = dict(self.preflight_headers)
        failures = []

        if self.is_allowed_origin(origin=requested_origin):
            if self.preflight_explicit_allow_origin:
                # The "else" case is already accounted for in self.preflight_headers
                # and the value would be "*".
                headers["Access-Control-Allow-Origin"] = requested_origin
        else:
            failures.append("origin")

        if requested_method not in self.allow_methods:
            failures.append("method")

        # If we allow all headers, then we have to mirror back any requested
        # headers in the response.
        if self.allow_all_headers and requested_headers is not None:
            headers["Access-Control-Allow-Headers"] = requested_headers
        elif requested_headers is not None:
            for header in [h.lower() for h in requested_headers.split(",")]:
                if header.strip() not in self.allow_headers:
                    failures.append("headers")
                    break

        # We don't strictly need to use 400 responses here, since its up to
        # the browser to enforce the CORS policy, but its more informative
        # if we do.
        if failures:
            failure_text = "Disallowed CORS " + ", ".join(failures)
            return PlainTextResponse(failure_text,
                                     status_code=400,
                                     headers=headers)

        return PlainTextResponse("OK", status_code=200, headers=headers)
Example #21
0
 def _get_token(self, headers: Headers):
     authorization = headers.get("Authorization")
     if authorization and authorization.startswith("Bearer "):
         return authorization[7:]
 def __call__(self, scope):
     headers = Headers(scope["headers"])
     if headers.get("host") != self.hostname:
         return PlainTextResponse("Invalid host header", status_code=400)
     return self.app(scope)
Example #23
0
 def __call__(self, scope: Scope) -> ASGIInstance:
     if scope["type"] == "http":
         headers = Headers(scope=scope)
         if "gzip" in headers.get("Accept-Encoding", ""):
             return GZipResponder(self.app, scope, self.minimum_size)
     return self.app(scope)
def _get_content_range(headers_200: Headers, s: slice) -> str:
    s = _normalize(headers_200, s)
    total = headers_200.get("content-length", "*")
    return f"bytes {s.start}-{s.stop - 1}/{total}"
Example #25
0
 async def __call__(self, scope, receive, send):
     headers = Headers(scope=scope)
     scope["user"] = "******" if headers.get(
         "Authorization") == "Bearer 123" else None
     await self.app(scope, receive, send)
Example #26
0
 def __call__(self, scope):
     headers = Headers(scope=scope)
     scope["user"] = "******" if headers.get(
         "Authorization") == "Bearer 123" else None
     return self.app(scope)
    async def parse(self) -> FormData:
        # Parse the Content-Type header to get the multipart boundary.
        content_type, params = parse_options_header(self.headers["Content-Type"])
        boundary = params.get(b"boundary")

        # Callbacks dictionary.
        callbacks = {
            "on_part_begin": self.on_part_begin,
            "on_part_data": self.on_part_data,
            "on_part_end": self.on_part_end,
            "on_header_field": self.on_header_field,
            "on_header_value": self.on_header_value,
            "on_header_end": self.on_header_end,
            "on_headers_finished": self.on_headers_finished,
            "on_end": self.on_end,
        }

        # Create the parser.
        parser = multipart.MultipartParser(boundary, callbacks)
        header_field = b""
        header_value = b""
        raw_headers = []  # type: typing.List[typing.Tuple[bytes, bytes]]
        field_name = ""
        data = b""
        file = None  # type: typing.Optional[UploadFile]

        items = (
            []
        )  # type: typing.List[typing.Tuple[str, typing.Union[str, UploadFile]]]

        # Feed the parser with data from the request.
        async for chunk in self.stream:
            parser.write(chunk)
            messages = list(self.messages)
            self.messages.clear()
            for message_type, message_bytes in messages:
                if message_type == MultiPartMessage.PART_BEGIN:
                    raw_headers = []
                    data = b""
                elif message_type == MultiPartMessage.HEADER_FIELD:
                    header_field += message_bytes
                elif message_type == MultiPartMessage.HEADER_VALUE:
                    header_value += message_bytes
                elif message_type == MultiPartMessage.HEADER_END:
                    raw_headers.append((header_field.lower(), header_value))
                    header_field = b""
                    header_value = b""
                elif message_type == MultiPartMessage.HEADERS_FINISHED:
                    headers = Headers(raw=raw_headers)
                    content_disposition = headers.get("Content-Disposition")
                    content_type = headers.get("Content-Type", "")
                    disposition, options = parse_options_header(content_disposition)
                    field_name = options[b"name"].decode("latin-1")
                    if b"filename" in options:
                        filename = options[b"filename"].decode("latin-1")
                        file = UploadFile(filename=filename, content_type=content_type)
                    else:
                        file = None
                elif message_type == MultiPartMessage.PART_DATA:
                    if file is None:
                        data += message_bytes
                    else:
                        await file.write(message_bytes)
                elif message_type == MultiPartMessage.PART_END:
                    if file is None:
                        items.append((field_name, data.decode("latin-1")))
                    else:
                        await file.seek(0)
                        items.append((field_name, file))
                elif message_type == MultiPartMessage.END:
                    pass

        parser.finalize()
        return FormData(items)
Example #28
0
    async def __call__(self, scope: Scope, receive: Receive,
                       send: Send) -> None:
        """Make the call."""
        request_headers = Headers(scope=scope)

        range_header = request_headers.get("range", None)
        async with self.s3client as s3_client:
            try:
                kwargs = {"Bucket": self.bucket, "Key": self.key}
                if range_header is not None:
                    kwargs["Range"] = range_header
                obj_info = await s3_client.get_object(**kwargs)
                last_modified = formatdate(datetime.timestamp(
                    obj_info["LastModified"]),
                                           usegmt=True)
                self.headers.setdefault("content-length",
                                        str(obj_info["ContentLength"]))
                self.headers.setdefault("content-range",
                                        str(obj_info.get("ContentRange")))
                self.headers.setdefault("last-modified", last_modified)
                self.headers.setdefault("etag", obj_info["ETag"])
            except ClientError as err:
                self.status_code = 404
                await send({
                    "type": "http.response.start",
                    "status": self.status_code,
                    "headers": self.raw_headers,
                })
                await send({
                    "type":
                    "http.response.body",
                    "body":
                    "File not found, details: "
                    f"{json.dumps(err.response)}".encode("utf-8"),
                    "more_body":
                    False,
                })
            except Exception as err:
                raise RuntimeError(
                    f"File at path {self.path} does not exist, details: {err}"
                ) from err
            else:
                await send({
                    "type": "http.response.start",
                    "status": self.status_code,
                    "headers": self.raw_headers,
                })
                if self.send_header_only:
                    await send({
                        "type": "http.response.body",
                        "body": b"",
                        "more_body": False
                    })
                else:
                    # Tentatively ignoring type checking failure to work around the
                    # wrong type definitions for aiofiles that come with typeshed. See
                    # https://github.com/python/typeshed/pull/4650

                    total_size = obj_info["ContentLength"]
                    sent_size = 0
                    chunks = obj_info["Body"].iter_chunks(
                        chunk_size=self.chunk_size)
                    async for chunk in chunks:
                        sent_size += len(chunk)
                        await send({
                            "type": "http.response.body",
                            "body": chunk,
                            "more_body": sent_size < total_size,
                        })

            if self.background is not None:
                await self.background()
Example #29
0
class CallbackClient:
    """
    A class to abstract the callback logic.
    """
    def __init__(self, function: Callable[..., Any],
                 callback: Union[Dict[str, Any], bool]) -> None:
        self.__function = function
        self.__attribute_finders = self.__prepare_and_validate_finders(
            callback)
        self.__headers = Headers()
        self.__params: Dict[str, str] = {}
        self.__invalid_callback_object = ""

    @property
    def url(self) -> str:
        """Returns the callback URL if it was included, or None."""
        location = self.__attribute_finders.get("callback_url_header")
        return self.__headers.get(location, "") if location is not None else ""

    @property
    def http_method(self) -> str:
        """Returns the callback HTTP method if it was included, or POST."""
        location = self.__attribute_finders.get("callback_method_header", "")
        # POST is the default HTTP method
        http_method = self.__headers[
            location] if location in self.__headers else "POST"
        return http_method.upper()

    @property
    def custom_key(self) -> Optional[str]:
        """Returns the custom callback key container if it was included, or None."""
        location = self.__attribute_finders.get("custom_callback_key_header",
                                                "")
        if location in self.__headers:
            return self.__headers.get(location)
        return None

    def handle_callback(self, headers: Headers,
                        params: Dict[str, Any]) -> JSONResponse:
        """
        Validates that the callback data from the request is correct
        and delegates the main function call. Returns a JSON response.
        """
        if self.__invalid_callback_object:
            # Callback object was defective, server should have stopped
            return JSONResponse({"message": self.__invalid_callback_object},
                                status_code=500)

        try:
            # Set headers and params
            self.__headers = headers
            self.__params = params

            # Validate callback data
            self.__validate_callback_url()
            self.__validate_callback_http_method()

            # Delegate function
            asyncio.ensure_future(self.__callback_call())

            return JSONResponse({}, status_code=202)
        except InvalidCallbackHeadersError as error:
            return JSONResponse({"message": str(error)}, status_code=422)

    @staticmethod
    def __prepare_and_validate_finders(
            callback: Union[Dict[str, Any], bool]) -> Dict[str, str]:
        """
        Collects and returns the callback data finders and validates
        that they are correct on decoration-time.
        """
        try:
            validate_callback_data(callback)
            return get_header_finders(callback)
        except InvalidCallbackObjectError as error:
            log(str(error), level="critical")
            raise InvalidCallbackObjectError(error) from error

    def __validate_callback_url(self) -> None:
        """
        Validates that the callback URL within the request
        header is valid.
        """
        if not self.url:
            raise InvalidCallbackHeadersError("Invalid callback URL")

    def __validate_callback_http_method(self) -> None:
        """
        Validates that the callback HTTP method within the request
        header is valid.
        """
        if self.http_method.lower() not in HTTP_METHODS:
            raise InvalidCallbackHeadersError("Invalid callback HTTP method")

    async def __callback_call(self) -> None:
        """
        Executes the function and makes the request to the callback endpoint.
        """
        try:
            response = await generic_call(self.__function, self.__params)
            if self.custom_key is not None:
                response = {self.custom_key: response}

            async with httpx.AsyncClient() as client:
                await client.request(
                    self.http_method,
                    self.url,
                    json=response,
                )
        except Exception as error:
            message = "Error while executing the delegated method: "
            message += str(error)
            log(message, level="warn")
Example #30
0
    def prepare_fhir_scopes(
        scope: Scope,
        headers: Headers,
        params: QueryParams,
        errors: typing.List[typing.Any],
    ):
        # Generate Request ID
        scope["FHIR_REQUEST_ID"] = uuid.uuid4()

        # 1. Prepare Accept & FHIR Version
        # --------------------------------
        accept = headers.get("accept", None)
        if accept:
            parts = accept.split(";")
            accept = parts[0].strip()
            if accept in ("application/json", "text/json"):
                accept = "application/fhir+json"
            if accept in ALLOWED_ACCEPTS:
                scope["FHIR_RESPONSE_ACCEPT"] = accept
            else:
                errors.append({
                    "loc": "Header.Accept",
                    "msg": f"Accept mime '{accept}' is not supported.",
                    "original": headers.get("accept"),
                })
            if len(parts) > 1:
                version_str = None
                try:
                    name, version_str = parts[1].strip().split("=")
                    if name == "fhirVersion":
                        version = MIME_FHIR_VERSION_MAP[version_str]
                        scope["FHIR_VERSION"] = version
                        scope["FHIR_VERSION_ORIGINAL"] = version_str
                    else:
                        errors.append({
                            "loc": "Header.Accept",
                            "msg":
                            "Invalid format of FHIR Version is provided in mime",
                            "original": headers.get("accept"),
                        })
                except KeyError:
                    errors.append({
                        "loc": "Header.Accept",
                        "msg":
                        f"Unsupported FHIR Version '{version_str}' is provided in mime",
                        "original": headers.get("accept"),
                    })
                except ValueError:
                    errors.append({
                        "loc": "Header.Accept",
                        "msg":
                        "Invalid format of FHIR Version is provided in mime",
                        "original": headers.get("accept"),
                    })
        else:
            scope["FHIR_RESPONSE_ACCEPT"] = "application/fhir+json"

        if (scope.get("FHIR_VERSION_ORIGINAL", None) is None
                and scope.get("FHIR_VERSION", None) is None):
            scope["FHIR_VERSION"] = MIME_FHIR_VERSION_MAP[DEFAULT_FHIR_VERSION]

        # 2. Check Query String
        # ---------------------
        format_mime = params.get("_format", None)
        if format_mime is not None:
            if format_mime in ALLOWED_ACCEPTS:
                scope["FHIR_RESPONSE_FORMAT"] = format_mime
            else:
                errors.append({
                    "loc": "QueryString._format",
                    "msg": f"Format mime '{format_mime}' is not supported.",
                    "original": format_mime,
                })
        pretty_response = params.get("_pretty", None)
        if pretty_response is not None:
            if pretty_response in ("true", "false"):
                scope["FHIR_RESPONSE_PRETTY"] = pretty_response == "true"

            else:
                errors.append({
                    "loc": "QueryString._pretty",
                    "msg":
                    f"Invalid ``_pretty`` value '{pretty_response}' is provided.",
                    "original": pretty_response,
                })

        # 3. Prepare Conditional Headers
        # ------------------------------
        if headers.get("If-None-Exist"):
            scope["FHIR_CONDITION_NONE_EXIST"] = [
                tuple(
                    map(lambda x: x.strip(),
                        headers.get("If-None-Exist").split("=")))
            ]

        if headers.get("If-Modified-Since"):
            try:
                scope["FHIR_CONDITION_MODIFIED_SINCE"] = parsedate_to_datetime(
                    headers.get("If-Modified-Since"))
            except ValueError:
                errors.append({
                    "loc": "Header.If-Modified-Since",
                    "msg": "Invalid formatted datetime value is provided.",
                    "original": headers.get("If-Modified-Since"),
                })
        if headers.get("If-None-Match"):
            try:
                scope["FHIR_CONDITION_NONE_MATCH"] = literal_eval(
                    headers.get("If-None-Match").replace("W/", ""))
            except (SyntaxError, ValueError):
                errors.append({
                    "loc": "Header.If-None-Match",
                    "msg": "Invalid formatted ETag value is provided.",
                    "original": headers.get("If-None-Match"),
                })

        if headers.get("If-Match"):
            try:
                scope["FHIR_CONDITION_MATCH"] = literal_eval(
                    headers.get("If-Match").replace("W/", ""))
            except (SyntaxError, ValueError):
                errors.append({
                    "loc": "Header.If-Match",
                    "msg": "Invalid formatted ETag value is provided.",
                    "original": headers.get("If-Match"),
                })