Ejemplo n.º 1
0
async def test_bad_framework(path: str) -> None:
    server = MockH11()
    server.app = bad_framework  # type: ignore
    request = h11.Request(method="GET",
                          target=path.encode(),
                          headers=[(b"host", b"hypercorn")])
    await server.handle_request(request)
    assert server.sent_events == [
        h11.Response(
            status_code=500,
            headers=[
                (b"content-length", b"0"),
                (b"connection", b"close"),
                (b"server", b"hypercorn"),
            ],
        ),
        h11.EndOfMessage(),
    ]
Ejemplo n.º 2
0
def insert_live_chat_message_builder(authorization_header, *, live_chat_id,
                                     message_text):
    data = h11.Data(data=json.dumps({
        "snippet": {
            "liveChatId": live_chat_id,
            "type": "textMessageEvent",
            "textMessageDetails": {
                "messageText": message_text
            }
        }
    }).encode("utf-8"))
    request = h11.Request(method="POST",
                          target="/youtube/v3/liveChat/messages?" +
                          parse.urlencode({"part": "snippet"}),
                          headers=[("host", "www.googleapis.com"),
                                   ("content-type", "application/json"),
                                   ("content-length", str(len(data.data))),
                                   authorization_header])
    return request, data
Ejemplo n.º 3
0
    def _initiate_connection(self, request: Request) -> bytes:
        self._initiating_request = request
        self._nonce = generate_nonce()

        headers = [
            (b"Host", request.host.encode("ascii")),
            (b"Upgrade", b"WebSocket"),
            (b"Connection", b"Upgrade"),
            (b"Sec-WebSocket-Key", self._nonce),
            (b"Sec-WebSocket-Version", WEBSOCKET_VERSION),
        ]

        if request.subprotocols:
            headers.append((
                b"Sec-WebSocket-Protocol",
                (", ".join(request.subprotocols)).encode("ascii"),
            ))

        if request.extensions:
            offers: Dict[str, Union[str, bool]] = {}
            for e in request.extensions:
                assert isinstance(e, Extension)
                offers[e.name] = e.offer()
            extensions = []
            for name, params in offers.items():
                bname = name.encode("ascii")
                if isinstance(params, bool):
                    if params:
                        extensions.append(bname)
                else:
                    extensions.append(b"%s; %s" %
                                      (bname, params.encode("ascii")))
            if extensions:
                headers.append(
                    (b"Sec-WebSocket-Extensions", b", ".join(extensions)))

        upgrade = h11.Request(
            method=b"GET",
            target=request.target.encode("ascii"),
            headers=headers + request.extra_headers,
        )
        return self._h11_connection.send(upgrade)
Ejemplo n.º 4
0
    async def send(self,
                   request: AsyncRequest,
                   timeout: TimeoutTypes = None) -> AsyncResponse:
        timeout = None if timeout is None else TimeoutConfig(timeout)

        #  Start sending the request.
        method = request.method.encode("ascii")
        target = request.url.full_path.encode("ascii")
        headers = request.headers.raw
        if "Host" not in request.headers:
            host = request.url.authority.encode("ascii")
            headers = [(b"host", host)] + headers
        event = h11.Request(method=method, target=target, headers=headers)
        await self._send_event(event, timeout)

        # Send the request body.
        async for data in request.stream():
            event = h11.Data(data=data)
            await self._send_event(event, timeout)

        # Finalize sending the request.
        event = h11.EndOfMessage()
        await self._send_event(event, timeout)

        # Start getting the response.
        event = await self._receive_event(timeout)
        if isinstance(event, h11.InformationalResponse):
            event = await self._receive_event(timeout)

        assert isinstance(event, h11.Response)
        status_code = event.status_code
        headers = event.headers
        content = self._body_iter(timeout)

        return AsyncResponse(
            status_code=status_code,
            protocol="HTTP/1.1",
            headers=headers,
            content=content,
            on_close=self.response_closed,
            request=request,
        )
Ejemplo n.º 5
0
async def test_not_found(
    serving_app: Quart,
    event_loop: asyncio.AbstractEventLoop,
) -> None:
    transport = MockTransport()
    request = h11.Request(
        method='GET',
        target='/not/',
        headers=[
            ('host', 'quart.com'),
            ('connection', 'upgrade'),
            ('upgrade', 'websocket'),
            ('Sec-WebSocket-Key', 'NA63HJnrvVYlgKt6wI58Yw=='),
            ('Sec-WebSocket-Version', '13'),
        ],
    )
    WebsocketServer(serving_app, event_loop, transport, None,
                    request)  # type: ignore
    await transport.closed.wait()
    assert transport.data.startswith(b'HTTP/1.1 404')
Ejemplo n.º 6
0
async def test_post_request(event_loop: asyncio.AbstractEventLoop) -> None:
    connection = MockConnection(event_loop)
    await connection.send(
        h11.Request(
            method='POST',
            target='/echo',
            headers=BASIC_HEADERS +
            [('content-length', str(len(BASIC_DATA.encode())))],
        ), )
    await connection.send(h11.Data(data=BASIC_DATA.encode()))
    await connection.send(h11.EndOfMessage())
    await connection.transport.closed.wait()
    response, *data, end = connection.get_events()
    assert isinstance(response, h11.Response)
    assert response.status_code == 200
    assert all(isinstance(datum, h11.Data) for datum in data)
    data = json.loads(b''.join(datum.data for datum in data).decode())
    assert data['scope']['method'] == 'POST'  # type: ignore
    assert data['request_body'] == BASIC_DATA  # type: ignore
    assert isinstance(end, h11.EndOfMessage)
Ejemplo n.º 7
0
    def client_handshake(self,
                         uri,
                         *,
                         subprotocols=None,
                         extensions=None,
                         **kwargs):

        scheme, netloc, path, _, _, _ = urlparse(uri)
        try:
            netloc, port = netloc.split(':', 1)
        except ValueError:
            if scheme.lower() == 'wss':
                port = '443'
            elif scheme.lower() == 'ws':
                port = '80'
            else:
                raise ValueError('Supplied bad location schema')

        request_uri = urlunparse((scheme, netloc, path, '', '', ''))
        self.nonce = nonce_creator()
        headers = {
            'host': ':'.join((netloc, port)),
            'upgrade': 'websocket',
            'connection': 'upgrade',
            'sec-websocket-key': self.nonce,
            'sec-websocket-version': '13'
        }
        if subprotocols is not None:
            headers['sec-websocket-protocol'] = self._addon_header_str_ifier(
                subprotocols)
        if extensions is not None:
            headers['sec-websocket-extensions'] = self._addon_header_str_ifier(
                extensions)
        if kwargs:
            headers.update(kwargs)

        handshake = h11.Request(method='GET',
                                target=request_uri,
                                headers=headers.items())

        return handshake
Ejemplo n.º 8
0
    def _initiate_connection(self, request: Request) -> bytes:
        self._initiating_request = request
        self._nonce = generate_nonce()

        headers = [
            (b"Host", request.host.encode("ascii")),
            (b"Upgrade", b"WebSocket"),
            (b"Connection", b"Upgrade"),
            (b"Sec-WebSocket-Key", self._nonce),
            (b"Sec-WebSocket-Version", WEBSOCKET_VERSION),
        ]

        if request.subprotocols:
            headers.append((
                b"Sec-WebSocket-Protocol",
                (", ".join(request.subprotocols)).encode("ascii"),
            ))

        if request.extensions:
            offers = {e.name: e.offer()
                      for e in request.extensions}  # type: ignore
            extensions = []
            for name, params in offers.items():
                name = name.encode("ascii")
                if params is True:
                    extensions.append(name)
                elif params:
                    extensions.append(
                        b"%s; %s" %
                        (name, params.encode("ascii"))  # type: ignore
                    )
            if extensions:
                headers.append(
                    (b"Sec-WebSocket-Extensions", b", ".join(extensions)))

        upgrade = h11.Request(
            method=b"GET",
            target=request.target.encode("ascii"),
            headers=headers + request.extra_headers,
        )
        return self._h11_connection.send(upgrade)
Ejemplo n.º 9
0
 def __init__(self,
              path: str,
              *,
              framework: ASGIFramework = echo_framework) -> None:
     self.client_stream, server_stream = trio.testing.memory_stream_pair()
     server_stream.socket = MockSocket()
     self.client = h11.Connection(h11.CLIENT)
     self.server = WebsocketServer(framework, Config(), server_stream)
     self.server.connection.receive_data(
         self.client.send(
             h11.Request(
                 method="GET",
                 target=path,
                 headers=[
                     ("Host", "Hypercorn"),
                     ("Upgrade", "WebSocket"),
                     ("Connection", "Upgrade"),
                     ("Sec-WebSocket-Version", "13"),
                     ("Sec-WebSocket-Key", "121312"),
                 ],
             )))
def get_http(uri: str, headers: t.Dict[str, str]) -> socket.socket:
    """Given a URI and a set of headers, make a HTTP request and return the
    underlying socket. If there were a production-quality implementation of
    nonblocking HTTP this function would be replaced with the relevant one
    from that library."""
    parsed = urllib.parse.urlparse(uri)
    sock = socket.socket()
    if parsed.port:
        port = parsed.port
    else:
        port = 80
    headers["Host"] = parsed.netloc
    sock.connect((parsed.hostname, port))
    sock.setblocking(False)

    connection = h11.Connection(h11.CLIENT)
    request = h11.Request(method="GET", target=parsed.path, headers=headers.items())

    sock.send(connection.send(request))
    sock.send(connection.send(h11.EndOfMessage()))
    return sock
Ejemplo n.º 11
0
async def test_client_sends_chunked() -> None:
    connection = MockConnection()
    chunked_headers = [("transfer-encoding", "chunked"), ("expect", "100-continue")]
    await connection.send(
        h11.Request(method="POST", target="/echo", headers=BASIC_HEADERS + chunked_headers)
    )
    async with trio.open_nursery() as nursery:
        nursery.start_soon(connection.server.handle_connection)
        informational_response, *_ = await connection.get_events()
        assert isinstance(informational_response, h11.InformationalResponse)
        assert informational_response.status_code == 100
        for chunk in [b"chunked ", b"data"]:
            await connection.send(h11.Data(data=chunk, chunk_start=True, chunk_end=True))
        await connection.send(h11.EndOfMessage())
    response, *data, end = await connection.get_events()
    assert isinstance(response, h11.Response)
    assert response.status_code == 200
    assert all(isinstance(datum, h11.Data) for datum in data)
    data = json.loads(b"".join(datum.data for datum in data).decode())
    assert data["request_body"] == "chunked data"  # type: ignore
    assert isinstance(end, h11.EndOfMessage)
Ejemplo n.º 12
0
def _make_handshake_rejection(
    status_code: int, body: Optional[bytes] = None
) -> List[Event]:
    client = h11.Connection(h11.CLIENT)
    server = WSConnection(SERVER)
    nonce = generate_nonce()
    server.receive_data(
        client.send(
            h11.Request(
                method="GET",
                target="/",
                headers=[
                    (b"Host", b"localhost"),
                    (b"Connection", b"Keep-Alive, Upgrade"),
                    (b"Upgrade", b"WebSocket"),
                    (b"Sec-WebSocket-Version", b"13"),
                    (b"Sec-WebSocket-Key", nonce),
                ],
            )
        )
    )
    if body is not None:
        client.receive_data(
            server.send(
                RejectConnection(
                    headers=[(b"content-length", b"%d" % len(body))],
                    status_code=status_code,
                    has_body=True,
                )
            )
        )
        client.receive_data(server.send(RejectData(data=body)))
    else:
        client.receive_data(server.send(RejectConnection(status_code=status_code)))
    events = []
    while True:
        event = client.next_event()
        events.append(event)
        if isinstance(event, h11.EndOfMessage):
            return events
Ejemplo n.º 13
0
async def test_client_sends_chunked(
        serving_app: Quart, event_loop: asyncio.AbstractEventLoop,
) -> None:
    connection = MockConnection(serving_app, event_loop)
    chunked_headers = [('transfer-encoding', 'chunked'), ('expect', '100-continue')]
    await connection.send(
        h11.Request(method='POST', target='/echo', headers=BASIC_HEADERS + chunked_headers),
    )
    await connection.transport.updated.wait()
    informational_response = connection.get_events()[0]
    assert isinstance(informational_response, h11.InformationalResponse)
    assert informational_response.status_code == 100
    connection.transport.clear()
    for chunk in [b'chunked ', b'data']:
        await connection.send(h11.Data(data=chunk, chunk_start=True, chunk_end=True))
    await connection.send(h11.EndOfMessage())
    response, *data, end = connection.get_events()
    assert isinstance(response, h11.Response)
    assert response.status_code == 200
    assert all(isinstance(datum, h11.Data) for datum in data)
    assert b''.join(datum.data for datum in data) == b'chunked data'
    assert isinstance(end, h11.EndOfMessage)
Ejemplo n.º 14
0
async def test_client_sends_chunked(event_loop: asyncio.AbstractEventLoop,) -> None:
    connection = MockConnection(event_loop)
    chunked_headers = [("transfer-encoding", "chunked"), ("expect", "100-continue")]
    await connection.send(
        h11.Request(method="POST", target="/echo", headers=BASIC_HEADERS + chunked_headers)
    )
    await connection.transport.updated.wait()
    informational_response = connection.get_events()[0]
    assert isinstance(informational_response, h11.InformationalResponse)
    assert informational_response.status_code == 100
    connection.transport.clear()
    for chunk in [b"chunked ", b"data"]:
        await connection.send(h11.Data(data=chunk, chunk_start=True, chunk_end=True))
    await connection.send(h11.EndOfMessage())
    await connection.transport.closed.wait()
    response, *data, end = connection.get_events()
    assert isinstance(response, h11.Response)
    assert response.status_code == 200
    assert all(isinstance(datum, h11.Data) for datum in data)
    data = json.loads(b"".join(datum.data for datum in data).decode())
    assert data["request_body"] == "chunked data"
    assert isinstance(end, h11.EndOfMessage)
Ejemplo n.º 15
0
async def test_asgi_scope() -> None:
    server = MockH11()
    request = h11.Request(method="GET",
                          target=b"/path?a=b",
                          headers=[(b"host", b"hypercorn")])
    await server.handle_request(request)
    scope = server.scope
    assert scope == {
        "type": "http",
        "http_version": "1.1",
        "asgi": {
            "spec_version": "2.1",
            "version": "3.0"
        },
        "method": "GET",
        "scheme": "http",
        "path": "/path",
        "query_string": b"a=b",
        "root_path": "",
        "headers": [(b"host", b"hypercorn")],
        "client": ("127.0.0.1", 5000),
        "server": ("remote", 5000),
    }
Ejemplo n.º 16
0
 def __init__(
     self,
     path: str,
     event_loop: asyncio.AbstractEventLoop,
     *,
     framework: Type[ASGIFramework] = EchoFramework,
 ) -> None:
     self.transport = MockTransport()
     self.client = h11.Connection(h11.CLIENT)
     self.server = WebsocketServer(  # type: ignore
         framework, event_loop, Config(), self.transport)
     self.server.data_received(
         self.client.send(
             h11.Request(
                 method="GET",
                 target=path,
                 headers=[
                     ("Host", "Hypercorn"),
                     ("Upgrade", "WebSocket"),
                     ("Connection", "Upgrade"),
                     ("Sec-WebSocket-Version", "13"),
                     ("Sec-WebSocket-Key", "121312"),
                 ],
             )))
Ejemplo n.º 17
0
def tracker_request(torrent, event) -> h11.Request:
    """
    Tracker request is an http GET request, sent with parameters telling
    the tracker about your client.
    """
    d = {
        b"info_hash": urllib_parse.quote_from_bytes(torrent.info_hash).encode(),
        b"peer_id": torrent.peer_id
        # ip
        ,
        b"port": _int2bytes(torrent.listening_port),
        b"uploaded": _int2bytes(torrent.uploaded),
        b"downloaded": _int2bytes(torrent.downloaded),
        b"left": _int2bytes(torrent.left)
        # , b'event': event
        # , b'compact': b'1'
        ,
        b"compact": b"0"
        # testing
        # , b'supportcrypto': b'1'
        # , b'key': b'71c04610'
        # , b'numwant': b'80'
    }
    if event:
        d[b"event"] = event
    params = b"&".join([k + b"=" + v for k, v in d.items()])
    path = torrent.tracker_path + b"?" + params
    host = torrent.tracker_address + b":" + str(torrent.tracker_port).encode()
    headers = [
        ("Host", host),
        ("Accept-Encoding", "gzip;q=1.0, deflate, identity"),
        ("Accept", "*/*"),
        ("User-Agent", "toytorrent"),
    ]
    r = h11.Request(method="GET", target=path, headers=headers)
    return r
Ejemplo n.º 18
0
def _make_handshake(
    request_headers: Headers,
    accept_headers: Optional[Headers] = None,
    subprotocol: Optional[str] = None,
    extensions: Optional[List[Extension]] = None,
) -> Tuple[h11.InformationalResponse, bytes]:
    client = h11.Connection(h11.CLIENT)
    server = WSConnection(SERVER)
    nonce = generate_nonce()
    server.receive_data(
        client.send(
            h11.Request(
                method="GET",
                target="/",
                headers=[
                    (b"Host", b"localhost"),
                    (b"Connection", b"Keep-Alive, Upgrade"),
                    (b"Upgrade", b"WebSocket"),
                    (b"Sec-WebSocket-Version", b"13"),
                    (b"Sec-WebSocket-Key", nonce),
                ]
                + request_headers,
            )
        )
    )
    client.receive_data(
        server.send(
            AcceptConnection(
                extra_headers=accept_headers or [],
                subprotocol=subprotocol,
                extensions=extensions or [],
            )
        )
    )
    event = client.next_event()
    return event, nonce
Ejemplo n.º 19
0
    async def _prepare_https_proxy(self, sock, address):
        '''
        To use https-tunnelling http proxies, we first ``CONNECT`` the proxy
        server, the server should open a SSL tunnel for us.

            CONNECT httpbin.org:443 HTTP/1.1
            Host: httpbin.org:443

        Then we must do TLS handshake and so on, to do this we must
        wrap raw socket into a secure one.

        Args:
            sock (SockeStream) raw socket to proxy server
            address (tuple(str, int)) remote server address, not proxy
        '''
        host = '{}:{}'.format(address[0], address[1])
        connect_req = h11.Request(method='CONNECT',
                                  target=host,
                                  headers=[('Host', host),
                                           ('Proxy-Connection', 'Keep-Alive')])
        hconnection = h11.Connection(our_role=h11.CLIENT)
        await send_event(sock, connect_req, None, hconnection)
        try:
            rsp = await recv_event(sock, hconnection)
            if rsp.status_code == 200:
                # server_name is crucial here, it means we handshake
                # with remote server, not the proxy
                sock._server_hostname = address[0]
                sock = await sock.start_tls()
                sock._active = True
                return sock
            else:
                raise ProxyError('status code {}, message {}'.format(
                    rsp.status_code, rsp.message))
        except RemoteProtocolError as e:
            raise ProxyError('Can not connect to proxy server') from e
Ejemplo n.º 20
0
def test_response_headers_1(example):
    resp, _ = example.send(
        h11.Request(method='GET', target='/', headers=[('Host', 'example')]),
        h11.EndOfMessage())
    assert (b'cache-control', b'max-age=3600') in resp.headers
    assert (b'cache-control', b'public') not in resp.headers
Ejemplo n.º 21
0
from typing import Callable, Generator

import h11
import pytest
import trio

from hypercorn.config import Config
from hypercorn.trio.tcp_server import TCPServer
from hypercorn.trio.worker_context import WorkerContext
from hypercorn.typing import Scope
from ..helpers import MockSocket

KEEP_ALIVE_TIMEOUT = 0.01
REQUEST = h11.Request(method="GET",
                      target="/",
                      headers=[(b"host", b"hypercorn")])


async def slow_framework(scope: Scope, receive: Callable,
                         send: Callable) -> None:
    while True:
        event = await receive()
        if event["type"] == "http.disconnect":
            break
        elif event["type"] == "lifespan.startup":
            await send({"type": "lifspan.startup.complete"})
        elif event["type"] == "lifespan.shutdown":
            await send({"type": "lifspan.shutdown.complete"})
        elif event["type"] == "http.request" and not event.get(
                "more_body", False):
Ejemplo n.º 22
0
    async def make_request(self, redirect=False):
        '''
        Acts as the central hub for preparing requests to be sent, and
        returning them upon completion. Generally just pokes through
        self's attribs and makes decisions about what to do.

        Returns:
            sock: The socket to be returned to the calling session's
                pool.
            Response: The response object, after any redirects. If there were
                redirects, the redirect responses will be stored in the final
                response object's `.history`.
        '''
        hconnection = h11.Connection(our_role=h11.CLIENT)
        self.scheme, self.netloc, self.path, _, self.query, _ = urlparse(
            self.uri)

        if not redirect:
            self.initial_scheme = self.scheme
            self.initial_netloc = self.netloc

        host = (self.netloc if
                (self.port == '80' or self.port == '443') else self.netloc +
                ':' + self.port)
        # default header construction
        asks_headers = c_i_dict([('Host', host), ('Connection', 'keep-alive'),
                                 ('Accept-Encoding', 'gzip, deflate'),
                                 ('Accept', '*/*'), ('Content-Length', '0'),
                                 ('User-Agent', 'python-asks/1.3.6')])

        # check for a CookieTracker object, and if it's there inject
        # the relevant cookies in to the (next) request.
        if self.persist_cookies is not None:
            self.cookies.update(
                self.persist_cookies.get_additional_cookies(
                    self.netloc, self.path))

        # formulate path / query and intended extra querys for use in uri
        self._build_path()

        # handle building the request body, if any
        body = ''
        if any((self.data, self.files, self.json)):
            content_type, content_len, body = await self._formulate_body()
            asks_headers['Content-Type'] = content_type
            asks_headers['Content-Length'] = content_len

        # add custom headers, if any
        # note that custom headers take precedence
        if self.headers is not None:
            asks_headers.update(self.headers)

        # add auth
        if self.auth is not None:
            asks_headers.update(await self._auth_handler_pre())
            asks_headers.update(await self._auth_handler_post_get_auth())

        # add cookies
        if self.cookies:
            cookie_str = ''
            for k, v in self.cookies.items():
                cookie_str += '{}={}; '.format(k, v)
            asks_headers['Cookie'] = cookie_str[:-1]

        # Construct h11 body object, if any body.
        if body:
            if not isinstance(body, bytes):
                body = bytes(body, self.encoding)
                asks_headers['Content-Length'] = str(len(body))
            req_body = h11.Data(data=body)
        else:
            req_body = None

        # Construct h11 request object.
        req = h11.Request(method=self.method,
                          target=self.path,
                          headers=asks_headers.items())

        # call i/o handling func
        response_obj = await self._request_io(req, req_body, hconnection)

        # check to see if the final socket object is suitable to be returned
        # to the calling session's connection pool.
        # We don't want to return sockets that are of a difference schema or
        # different top level domain, as they are less likely to be useful.
        if redirect:
            if not (self.scheme == self.initial_scheme
                    and self.netloc == self.initial_netloc):
                self.sock._active = False

        if self.streaming:
            return None, response_obj

        return self.sock, response_obj
Ejemplo n.º 23
0
def h11_get_request(request):
    return h11.Request(
        method="GET",
        target="/",
        headers=[("Host", "localhost")],
    )
Ejemplo n.º 24
0
    async def send(
        self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None
    ) -> requests.Response:
        urlparts = urlparse(request.url)

        hostname = urlparts.hostname
        port = urlparts.port
        if port is None:
            port = {"http": 80, "https": 443}[urlparts.scheme]
        target = urlparts.path
        if urlparts.query:
            target += "?" + urlparts.query
        headers = [("host", urlparts.netloc)] + list(request.headers.items())

        conn_kwargs = {"ssl": no_verify()} if urlparts.scheme == "https" else {}

        if isinstance(timeout, tuple):
            connect_timeout, read_timeout = timeout
        else:
            connect_timeout = timeout
            read_timeout = timeout

        try:
            reader, writer = await asyncio.wait_for(
                asyncio.open_connection(hostname, port, **conn_kwargs), connect_timeout
            )
        except asyncio.TimeoutError:
            raise requests.ConnectTimeout()

        conn = h11.Connection(our_role=h11.CLIENT)

        message = h11.Request(method=request.method, target=target, headers=headers)
        data = conn.send(message)
        writer.write(data)

        if request.body:
            message = h11.Data(data=request.body.encode("utf-8"))
            data = conn.send(message)
            writer.write(data)

        message = h11.EndOfMessage()
        data = conn.send(message)
        writer.write(data)

        status_code = 0
        headers = []
        reason = b""
        buffer = io.BytesIO()

        while True:
            event = conn.next_event()
            event_type = type(event)

            if event_type is h11.NEED_DATA:
                try:
                    data = await asyncio.wait_for(reader.read(2048), read_timeout)
                except asyncio.TimeoutError:
                    raise requests.ReadTimeout()
                conn.receive_data(data)

            elif event_type is h11.Response:
                status_code = event.status_code
                headers = [
                    (key.decode(), value.decode()) for key, value in event.headers
                ]
                reason = event.reason

            elif event_type is h11.Data:
                buffer.write(event.data)

            elif event_type is h11.EndOfMessage:
                buffer.seek(0)
                break

        writer.close()
        if hasattr(writer, "wait_closed"):
            await writer.wait_closed()

        resp = urllib3.HTTPResponse(
            body=buffer,
            headers=headers,
            status=status_code,
            reason=reason,
            preload_content=False,
        )

        return self.build_response(request, resp)
Ejemplo n.º 25
0
def get_registrations_builder():
    request = h11.Request(method="GET",
                          target="/giveaway/winner",
                          headers=[("host", "bluespan.gg"),
                                   ("authorization", _token)])
    return request,
Ejemplo n.º 26
0

def send(event):
    print("Sending event:")
    print(event)
    print()
    # Pass the event through h11's state machine and encoding machinery
    data = conn.send(event)
    # Send the resulting bytes on the wire
    sock.sendall(data)


send(
    h11.Request(
        method="GET",
        target="/get",
        headers=[("Host", "httpbin.org"), ("Connection", "close")],
    )
)
send(h11.EndOfMessage())

################################################################
# Receiving the response
################################################################


def next_event():
    while True:
        # Check if an event is already available
        event = conn.next_event()
        if event is h11.NEED_DATA:
Ejemplo n.º 27
0
    async def send(self,
                   request,
                   stream=False,
                   timeout=None,
                   verify=True,
                   cert=None,
                   proxies=None) -> requests.Response:
        urlparts = urlparse(request.url)

        if isinstance(timeout, tuple):
            connect_timeout, read_timeout = timeout
        else:
            connect_timeout = timeout
            read_timeout = timeout

        connection = await self.manager.get_connection(url=urlparts,
                                                       verify=verify,
                                                       cert=cert,
                                                       timeout=connect_timeout)

        target = urlparts.path
        if urlparts.query:
            target += "?" + urlparts.query
        headers = [("host", urlparts.netloc)] + list(request.headers.items())

        message = h11.Request(method=request.method,
                              target=target,
                              headers=headers)
        await connection.send_event(message)

        if request.body:
            body = (_encode(request.body)
                    if isinstance(request.body, str) else request.body)
            message = h11.Data(data=body)
            await connection.send_event(message)

        message = h11.EndOfMessage()
        await connection.send_event(message)

        status_code = 0
        headers = []
        reason = b""
        buffer = io.BytesIO()

        while True:
            event = await connection.receive_event(read_timeout)
            event_type = type(event)

            if event_type is h11.Response:
                status_code = event.status_code
                headers = [(key.decode(), value.decode())
                           for key, value in event.headers]
                reason = event.reason

            elif event_type is h11.Data:
                buffer.write(event.data)

            elif event_type is h11.EndOfMessage:
                buffer.seek(0)
                break

        await connection.close()

        resp = urllib3.HTTPResponse(
            body=buffer,
            headers=headers,
            status=status_code,
            reason=reason,
            preload_content=False,
        )

        return self.build_response(request, resp)
Ejemplo n.º 28
0
    async def make_request(self, redirect=False):
        """
        Acts as the central hub for preparing requests to be sent, and
        returning them upon completion. Generally just pokes through
        self's attribs and makes decisions about what to do.

        Returns:
            sock: The socket to be returned to the calling session's
                pool.
            Response: The response object, after any redirects. If there were
                redirects, the redirect responses will be stored in the final
                response object's `.history`.
        """
        h11_connection = h11.Connection(our_role=h11.CLIENT)
        (
            self.scheme,
            self.host,
            self.path,
            self.uri_parameters,
            self.query,
            _,
        ) = urlparse(self.uri)

        if not redirect:
            self.initial_scheme = self.scheme
            self.initial_netloc = self.host

        # leave default the host on 80 / 443
        # otherwise use the base host with :port appended.
        host = (
            self.host
            if (self.port == "80" or self.port == "443")
            else self.host.split(":")[0] + ":" + self.port
        )

        # default header construction
        asks_headers = c_i_dict(
            [
                ("Host", host),
                ("Connection", "close"),
                ("Accept-Encoding", "gzip, deflate"),
                ("Accept", "*/*"),
                ("Content-Length", "0"),
                ("User-Agent", "python-asks/2.4.8"),
            ]
        )

        # check for a CookieTracker object, and if it's there inject
        # the relevant cookies in to the (next) request.
        # What the f**k is this shit.
        if self.persist_cookies is not None:
            self.cookies.update(
                self.persist_cookies.get_additional_cookies(self.host, self.path)
            )

        # formulate path / query and intended extra querys for use in uri
        self._build_path()

        # handle building the request body, if any
        body = ""
        if any((self.data, self.files, self.json, self.multipart is not None)):
            content_type, content_len, body = await self._formulate_body()
            asks_headers["Content-Type"] = content_type
            asks_headers["Content-Length"] = content_len
            self.body = body

        # add custom headers, if any
        # note that custom headers take precedence
        if self.headers is not None:
            asks_headers.update(self.headers)

        # add auth
        if self.auth is not None:
            asks_headers.update(await self._auth_handler_pre())
            asks_headers.update(await self._auth_handler_post_get_auth())

        # add cookies
        if self.cookies:
            cookie_str = ""
            for k, v in self.cookies.items():
                cookie_str += "{}={}; ".format(k, v)
            asks_headers["Cookie"] = cookie_str[:-1]

        # Construct h11 body object, if any body.
        if body:
            if not isinstance(body, bytes):
                body = bytes(body, self.encoding)
                asks_headers["Content-Length"] = str(len(body))
            req_body = h11.Data(data=body)
        else:
            req_body = None

        # Construct h11 request object.
        req = h11.Request(
            method=self.method, target=self.path, headers=asks_headers.items()
        )

        # call i/o handling func
        response_obj = await self._request_io(req, req_body, h11_connection)

        # check to see if the final socket object is suitable to be returned
        # to the calling session's connection pool.
        # We don't want to return sockets that are of a difference schema or
        # different top level domain, as they are less likely to be useful.
        if redirect:
            if not (
                self.scheme == self.initial_scheme and self.host == self.initial_netloc
            ):
                self.sock._active = False

        if self.streaming:
            return None, response_obj

        return self.sock, response_obj
Ejemplo n.º 29
0
ctx = SecureTransportClientContext(
    TLSConfiguration(
        ciphers=list(CipherSuite),
        lowest_supported_version=TLSVersion.TLSv1,
        highest_supported_version=TLSVersion.TLSv1_2,
    )
)
mysock = socket.create_connection(('httpbin.org', 443))
tls_sock = ctx.wrap_socket(mysock, server_hostname=b"httpbin.org")
print(tls_sock.negotiated_tls_version())
print(tls_sock.cipher())
tls_sock.do_handshake()
print(tls_sock.negotiated_tls_version())
print(tls_sock.cipher())

data = conn.send(h11.Request(method=b'GET', target=b'/get', headers=[(b'host', b'httpbin.org')]))
data += conn.send(h11.EndOfMessage())
tls_sock.sendall(data)

response_complete = False

while not response_complete:
    data = tls_sock.recv(8192)
    print(data.decode('utf-8'),)
    conn.receive_data(data)

    while True:
        evt = conn.next_event()
        if evt is h11.NEED_DATA:
            break
Ejemplo n.º 30
0
def test_response_headers_2(example):
    resp, _ = example.send(
        h11.Request(method='GET', target='/', headers=[('Host', 'example')]),
        h11.EndOfMessage())
    assert (b'set-cookie', b'sessionid=123456') in resp.headers
    assert (b'set-cookie', b'__adtrack=abcdef') in resp.headers