示例#1
0
async def test_cookies_jar_single_cookie():
    fake_pools = FakePools([
        Response(200, [
            (b"Set-Cookie", write_response_cookie(Cookie(b"X-Foo", b"Foo")))
        ]).with_content(TextContent("Hello, World!")),
        Response(200, None, TextContent("Hello!")),
    ])
    check_cookie = False

    async def middleware_for_assertions(request, next_handler):
        if check_cookie:
            cookie = request.cookies.get("X-Foo")
            assert (cookie is not None
                    ), "X-Foo cookie must be configured for following requests"

        return await next_handler(request)

    async with ClientSession(
            base_url=b"https://bezkitu.org",
            pools=fake_pools,
            middlewares=[middleware_for_assertions],
    ) as client:
        await client.get(
            b"/"
        )  # the first request doesn't have any cookie because the response will set;
        check_cookie = True
        await client.get(b"/")
示例#2
0
def get_response_for_file(request, resource_path: str, cache_time: int):
    stat = os.stat(resource_path)
    file_size = stat.st_size
    modified_time = stat.st_mtime
    current_etag = str(modified_time).encode()
    previous_etag = request.if_none_match

    headers = [
        (b'Last-Modified', unix_timestamp_to_datetime(modified_time)),
        (b'ETag', current_etag)
    ]

    if cache_time > 0:
        headers.append((b'Cache-Control', b'max-age=' + str(cache_time).encode()))

    if previous_etag and current_etag == previous_etag:
        return Response(304, headers, None)

    if request.method == 'HEAD':
        headers.append((b'Content-Type', get_mime_type(resource_path)))
        headers.append((b'Content-Length', str(file_size).encode()))
        return Response(200, headers, None)

    return Response(200, 
                    headers,
                    StreamedContent(get_mime_type(resource_path),
                                    get_file_data(resource_path, file_size)))
示例#3
0
文件: app.py 项目: perfmjs/BlackSheep
async def echo_headers(request):
    response = Response(200)

    for header in request.headers:
        response.add_header(header[0], header[1])

    return response
示例#4
0
async def test_cookies_jar(first_request_url, second_request_url, set_cookies,
                           expected_cookies):
    fake_pools = FakePools([
        Response(200, Headers(set_cookies), TextContent('Hello, World!')),
        Response(200, Headers(), TextContent('Hello!'))
    ])
    check_cookie = False

    async def middleware_for_assertions(request, next_handler):
        if check_cookie:
            if not expected_cookies:
                assert not request.cookies

            for expected_cookie in expected_cookies:
                cookie = request.cookies.get(expected_cookie)
                assert cookie is not None, f'{cookie.name.decode()} cookie must be configured for following requests'

        return await next_handler(request)

    async with ClientSession(
            pools=fake_pools,
            middlewares=[middleware_for_assertions],
    ) as client:
        await client.get(first_request_url)
        check_cookie = True
        await client.get(second_request_url)
示例#5
0
async def test_cookies_jar_single_cookie():
    fake_pools = FakePools([
        Response(
            200,
            Headers([
                Header(b'Set-Cookie',
                       write_response_cookie(Cookie(b'X-Foo', b'Foo')))
            ]), TextContent('Hello, World!')),
        Response(200, Headers(), TextContent('Hello!'))
    ])
    check_cookie = False

    async def middleware_for_assertions(request, next_handler):
        if check_cookie:
            cookie = request.cookies.get(b'X-Foo')
            assert cookie is not None, 'X-Foo cookie must be configured for following requests'

        return await next_handler(request)

    async with ClientSession(url=b'https://bezkitu.org',
                             pools=fake_pools,
                             middlewares=[middleware_for_assertions
                                          ]) as client:
        await client.get(
            b'/'
        )  # the first request doesn't have any cookie because the response will set;
        check_cookie = True
        await client.get(b'/')
示例#6
0
def test_response_supports_dynamic_attributes():
    response = Response(200)
    foo = object()

    assert hasattr(response, 'response') is False, 'This test makes sense if such attribute is not defined'
    response.foo = foo
    assert response.foo is foo
示例#7
0
def get_response_for_file(request, resource_path, cache_time):
    # TODO: support for accept-range and bytes ranges
    file_size = os.path.getsize(resource_path)
    modified_time = os.path.getmtime(resource_path)
    current_etag = str(modified_time).encode()
    previous_etag = request.if_none_match

    headers = [
        Header(b'Last-Modified', unix_timestamp_to_datetime(modified_time)),
        Header(b'ETag', current_etag)
    ]

    if cache_time > 0:
        headers.append(
            Header(b'Cache-Control', b'max-age=' + str(cache_time).encode()))

    if previous_etag and current_etag == previous_etag:
        return Response(304, headers, None)

    if request.method == b'HEAD':
        headers.append(Header(b'Content-Type', get_mime_type(resource_path)))
        headers.append(Header(b'Content-Length', str(file_size).encode()))
        return Response(200, headers, None)

    return Response(
        200, Headers(headers),
        Content(get_mime_type(resource_path),
                get_file_data(resource_path, file_size)))
def test_response_supports_dynamic_attributes():
    response = Response(200)
    foo = object()

    assert (hasattr(response, "response") is
            False), "This test makes sense if such attribute is not defined"
    response.foo = foo  # type: ignore
    assert response.foo is foo  # type: ignore
示例#9
0
 def on_headers_complete(self):
     status = self.parser.get_status_code()
     self.response = Response(
         status,
         Headers(self.headers),
         None
     )
     self.response_ready.set()
示例#10
0
def status_code(status: int = 200, message: Any = None) -> Response:
    """
    Returns a plain response with given status, with optional message;
    sent as plain text or JSON.
    """
    if not message:
        return Response(status)
    return Response(status, content=_optional_content(message))
示例#11
0
 def on_headers_complete(self) -> None:
     status = self.parser.get_status_code()
     self.response = Response(status, self.headers, None)
     # NB: check if headers declare a content-length
     if self._has_content():
         self.response.content = IncomingContent(
             self.response.get_single_header(b"content-type"))
     self.response_ready.set()
示例#12
0
def status_code(status: int = 200, message: MessageType = None):
    """Returns a plain response with given status, with optional message; sent as plain text or JSON."""
    if not message:
        return Response(status)
    if isinstance(message, str):
        content = TextContent(message)
    else:
        content = JsonContent(message)
    return Response(status, content=content)
示例#13
0
    async def frozen_file_getter(request):
        previous_etag = request.if_none_match

        if previous_etag and previous_etag == current_etag:
            return Response(304, headers, None)

        if request.method == b'HEAD':
            return Response(200, head_headers, None)

        return Response(200, Headers(headers), Content(mime, data))
示例#14
0
def test_is_redirect():
    # 301 Moved Permanently
    # 302 Found
    # 303 See Other
    # 307 Temporary Redirect
    # 308 Permanent Redirect
    for status in range(200, 500):
        response = Response(status)
        is_redirect = status in {301, 302, 303, 307, 308}
        assert response.is_redirect() == is_redirect
示例#15
0
    async def static_files_handler(request: Request) -> Response:
        assert request.route_values is not None, "Expects a route pattern with star *"
        tail = unquote(request.route_values.get("tail", "")).lstrip("/")

        try:
            return get_response_for_resource_path(
                request,
                tail,
                files_list_html,
                source_folder_name,
                files_handler,
                source_folder_full_path,
                discovery,
                cache_time,
                extensions,
                root_path,
                index_document,
            )
        except NotFound:
            if fallback_document is None:
                return Response(404)

            return get_response_for_resource_path(
                request,
                fallback_document,
                files_list_html,
                source_folder_name,
                files_handler,
                source_folder_full_path,
                discovery,
                cache_time,
                extensions,
                root_path,
                None,
            )
示例#16
0
def html(value: str, status: int = 200) -> Response:
    """
    Returns a response with text/html content,
    and given status (default HTTP 200 OK).
    """
    return Response(status, None,
                    Content(b"text/html; charset=utf-8", value.encode("utf8")))
示例#17
0
async def multiple_db_queries_test(request):
    """Test type 3: Multiple Database Queries"""

    num_queries = get_num_queries(request)

    row_ids = [randint(1, 10000) for _ in range(num_queries)]
    worlds = []

    connection = await db_pool.acquire()
    try:
        statement = await connection.prepare(
            'SELECT "randomnumber" FROM "world" WHERE id = $1'
        )
        for row_id in row_ids:
            number = await statement.fetchval(row_id)
            worlds.append({"id": row_id, "randomNumber": number})
    finally:
        await db_pool.release(connection)

    return Response(
        200,
        content=Content(
            b"application/json; charset=utf-8", json_dumps(worlds).encode("utf-8")
        ),
    )
示例#18
0
async def test_multiple_middleware():
    fake_pools = FakePools([Response(200, None, TextContent("Hello, World!"))])

    steps = []

    async def middleware_one(request, next_handler):
        steps.append(1)
        response = await next_handler(request)
        steps.append(2)
        return response

    async def middleware_two(request, next_handler):
        steps.append(3)
        response = await next_handler(request)
        steps.append(4)
        return response

    async def middleware_three(request, next_handler):
        steps.append(5)
        response = await next_handler(request)
        steps.append(6)
        return response

    async with ClientSession(
            base_url=b"http://localhost:8080",
            pools=fake_pools,
            middlewares=[middleware_one, middleware_two, middleware_three],
    ) as client:
        response = await client.get(b"/")

        assert steps == [1, 3, 5, 6, 4, 2]
        assert response.status == 200
        text = await response.text()
        assert text == "Hello, World!"
示例#19
0
def get_files_list_html_response(
    template: str,
    parent_folder_path: str,
    contents: Sequence[Dict[str, str]],
    root_path: str,
) -> Response:
    info_lines = []
    for item in contents:
        rel_path = item.get("rel_path")
        assert rel_path is not None
        full_rel_path = html.escape(
            join_fragments(root_path, parent_folder_path, rel_path))
        info_lines.append(
            f'<li><a href="/{full_rel_path}">{rel_path}</a></li>')
    info = "".join(info_lines)
    p = []
    whole_p = [root_path]
    for fragment in parent_folder_path.split("/"):
        if fragment:
            whole_p.append(html.escape(fragment))
            fragment_path = "/".join(whole_p)
            p.append(f'<a href="/{fragment_path}">{html.escape(fragment)}</a>')

    # TODO: use chunked encoding here, yielding HTML fragments
    return Response(
        200,
        content=HtmlContent(
            template.format_map({
                "path": "/".join(p),
                "info": info
            })),
    )
示例#20
0
async def db_updates_test(request):
    """Test type 5: Database Updates"""

    num_queries = get_num_queries(request)

    updates = [(randint(1, 10000), randint(1, 10000))
               for _ in range(num_queries)]
    worlds = [{
        'id': row_id,
        'randomNumber': number
    } for row_id, number in updates]

    connection = await db_pool.acquire()
    try:
        statement = await connection.prepare(
            'SELECT "randomnumber" FROM "world" WHERE id = $1')
        for row_id, _ in updates:
            await statement.fetchval(row_id)
        await connection.executemany(
            'UPDATE "world" SET "randomnumber"=$1 WHERE id=$2', updates)
    finally:
        await db_pool.release(connection)

    return Response(200,
                    content=Content(b'application/json',
                                    json_dumps(worlds).encode('utf-8')))
示例#21
0
def test_session_raises_for_redirect_without_location():
    """
    If a server returns a redirect status without location response header,
    the client raises an exception.
    """

    with pytest.raises(MissingLocationForRedirect):
        ClientSession.extract_redirect_location(Response(http.HTTPStatus.FOUND.value))
示例#22
0
async def json_test(request):
    """Test type 1: JSON Serialization"""

    return Response(200,
                    content=Content(
                        b'application/json; charset=utf-8',
                        json_dumps({
                            'message': 'Hello, world!'
                        }).encode('utf-8')))
示例#23
0
async def handle_unauthorized(app: Any, request: Request,
                              http_exception: UnauthorizedError) -> Response:
    www_authenticate = get_www_authenticated_header_from_generic_unauthorized_error(
        http_exception)
    return Response(
        401,
        [www_authenticate] if www_authenticate else None,
        content=TextContent("Unauthorized"),
    )
示例#24
0
def created(message: Any = None, location: AnyStr = "") -> Response:
    """
    Returns an HTTP 201 Created response, to the given location
    and with optional JSON content.
    """
    return Response(
        201,
        [(b"Location", _ensure_bytes(location))] if location else [],
        content=_optional_content(message) if message else None,
    )
示例#25
0
async def json_test(request):
    """Test type 1: JSON Serialization"""

    return Response(
        200,
        content=Content(
            b"application/json; charset=utf-8",
            json_dumps({"message": "Hello, world!"}).encode("utf-8"),
        ),
    )
示例#26
0
async def test_remove_cookie_with_expiration():
    expire_cookie = Cookie(b'X-Foo', b'Foo')
    expire_cookie.expiration = datetime.utcnow() + timedelta(days=-2)
    fake_pools = FakePools([
        Response(
            200,
            Headers([
                Header(b'Set-Cookie',
                       write_response_cookie(Cookie(b'X-Foo', b'Foo')))
            ]), TextContent('Hello, World!')),
        Response(200, Headers(), TextContent('Hello!')),
        Response(
            200,
            Headers(
                [Header(b'Set-Cookie', write_response_cookie(expire_cookie))]),
            TextContent('Hello, World!')),
        Response(200, Headers(), TextContent('Hello!'))
    ])
    expect_cookie = False

    async def middleware_for_assertions(request, next_handler):
        cookie = request.cookies.get(b'X-Foo')
        if expect_cookie:
            assert cookie is not None, 'X-Foo cookie must be configured'
        else:
            assert cookie is None

        return await next_handler(request)

    async with ClientSession(url=b'https://bezkitu.org',
                             pools=fake_pools,
                             middlewares=[middleware_for_assertions
                                          ]) as client:
        await client.get(b'/')  # <-- cookie set here
        expect_cookie = True
        await client.get(b'/')  # <-- expect cookie in request
        expect_cookie = True
        await client.get(
            b'/')  # <-- expect cookie in request; it gets removed here
        expect_cookie = False
        await client.get(
            b'/'
        )  # <-- expect missing cookie; was deleted by previous response
示例#27
0
async def test_remove_cookie_with_max_age():
    expire_cookie = Cookie("X-Foo", "Foo")
    expire_cookie.max_age = 0
    fake_pools = FakePools(
        [
            Response(
                200,
                [(b"Set-Cookie", write_response_cookie(Cookie("X-Foo", "Foo")))],
                TextContent("Hello, World!"),
            ),
            Response(200, None, TextContent("Hello!")),
            Response(
                200,
                [(b"Set-Cookie", write_response_cookie(expire_cookie))],
                TextContent("Hello, World!"),
            ),
            Response(200, None, TextContent("Hello!")),
        ]
    )
    expect_cookie = False

    async def middleware_for_assertions(request, next_handler):
        cookie = request.cookies.get("X-Foo")
        if expect_cookie:
            assert cookie is not None, "X-Foo cookie must be configured"
        else:
            assert cookie is None
        return await next_handler(request)

    async with ClientSession(
        base_url=b"https://bezkitu.org",
        pools=fake_pools,
        middlewares=[middleware_for_assertions],
    ) as client:
        await client.get(b"/")  # <-- cookie set here
        expect_cookie = True
        await client.get(b"/")  # <-- expect cookie in request
        expect_cookie = True
        await client.get(b"/")  # <-- expect cookie in request; it gets removed here
        expect_cookie = False
        await client.get(
            b"/"
        )  # <-- expect missing cookie; was deleted by previous response
示例#28
0
    def extract_redirect_location(response: Response) -> URL:
        # if the server returned more than one value, use the first header in order
        location = response.get_first_header(b'Location')
        if not location:
            raise MissingLocationForRedirect(response)

        # if the location cannot be parsed as URL, let exception happen: this might be a redirect to a URN!!
        # simply don't follows the redirect, and returns the response to the caller
        try:
            return URL(location)
        except InvalidURL:
            raise UnsupportedRedirect()
示例#29
0
    async def create_cat(request):
        nonlocal called_times
        called_times += 1
        assert request is not None

        content = await request.read()
        assert b'{"name":"Celine","kind":"Persian"}' == content

        data = await request.json()
        assert {"name": "Celine", "kind": "Persian"} == data

        return Response(201, [(b'Server', b'Python/3.7')], JsonContent({'id': '123'}))
示例#30
0
    async def upload_files(request):
        files = await request.files('files[]')

        # NB: in this example; we save files to output folder and verify
        # that their binaries are identical
        for part in files:
            full_path = pkg_resources.resource_filename(__name__, 'out/'
                                                        + part.file_name.decode())
            with open(full_path, mode='wb') as saved_file:
                saved_file.write(part.data)

        return Response(200)