Ejemplo n.º 1
0
def set_request(wsgi_environ, app=None, transport=None):
    """
    Test helper context manager that mocks the sanic request
    """
    environ = {}
    headers = Header()
    environ.update(wsgi_environ)
    for k, v in REQUEST_DEFAULTS.items():
        environ.setdefault(k, v)
    url_bytes = b"%s://%s" % (environ['SCHEME'], environ['HOST'])
    headers.setdefault('Host', environ['HOST'].decode('utf-8'))
    if environ['SCHEME'] == b"http" and environ['PORT'] in (80, b"80"):
        pass
    elif environ['SCHEME'] == b"https" and environ['PORT'] in (443, b"443"):
        pass
    else:
        port = environ['PORT']
        if isinstance(port, int):
            port = str(port)
        if isinstance(port, str):
            port = port.encode('latin-1')

        url_bytes = b"%s:%s" % (url_bytes, port)
    if environ['PATH'] == b"":
        pass
    else:
        path = environ['PATH']
        if path == b"/":
            path = b""
        url_bytes = b"%s/%s" % (url_bytes, path)
    if environ['QUERY_STRING'] == b"":
        pass
    else:
        url_bytes = b"%s?%s" % (url_bytes, environ['QUERY_STRING'])
    version = environ['VERSION'].decode('utf-8')
    method = environ['METHOD'].decode('utf-8')
    if app is None:
        app = set_request.app
    if transport is None:
        transport = DummyTransport()
    r = SanicRequest(url_bytes, headers, version, method, transport, app)

    with mock.patch.dict(extract_params.__globals__, {'request': r}):
        yield
Ejemplo n.º 2
0
class BaseHTTPResponse:
    """
    The base class for all HTTP Responses
    """

    def __init__(self):
        self.asgi: bool = False
        self.body: Optional[bytes] = None
        self.content_type: Optional[str] = None
        self.stream: Http = None
        self.status: int = None
        self.headers = Header({})
        self._cookies: Optional[CookieJar] = None

    def _encode_body(self, data: Optional[AnyStr]):
        if data is None:
            return b""
        return (
            data.encode() if hasattr(data, "encode") else data  # type: ignore
        )

    @property
    def cookies(self) -> CookieJar:
        """
        The response cookies. Cookies should be set and written as follows:

        .. code-block:: python

                response.cookies["test"] = "It worked!"
                response.cookies["test"]["domain"] = ".yummy-yummy-cookie.com"
                response.cookies["test"]["httponly"] = True

        `See user guide
        <https://sanicframework.org/guide/basics/cookies.html>`_

        :return: the cookie jar
        :rtype: CookieJar
        """
        if self._cookies is None:
            self._cookies = CookieJar(self.headers)
        return self._cookies

    @property
    def processed_headers(self) -> Iterator[Tuple[bytes, bytes]]:
        """
        Obtain a list of header tuples encoded in bytes for sending.

        Add and remove headers based on status and content_type.

        :return: response headers
        :rtype: Tuple[Tuple[bytes, bytes], ...]
        """
        # TODO: Make a blacklist set of header names and then filter with that
        if self.status in (304, 412):  # Not Modified, Precondition Failed
            self.headers = remove_entity_headers(self.headers)
        if has_message_body(self.status):
            self.headers.setdefault("content-type", self.content_type)
        # Encode headers into bytes
        return (
            (name.encode("ascii"), f"{value}".encode(errors="surrogateescape"))
            for name, value in self.headers.items()
        )

    async def send(
        self,
        data: Optional[Union[AnyStr]] = None,
        end_stream: Optional[bool] = None,
    ) -> None:
        """
        Send any pending response headers and the given data as body.

        :param data: str or bytes to be written
        :param end_stream: whether to close the stream after this block
        """
        if data is None and end_stream is None:
            end_stream = True
        if end_stream and not data and self.stream.send is None:
            return
        data = (
            data.encode()  # type: ignore
            if hasattr(data, "encode")
            else data or b""
        )
        await self.stream.send(data, end_stream=end_stream)