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(), ]
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
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)
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, )
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')
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)
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
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)
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
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)
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
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)
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)
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), }
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"), ], )))
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
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
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
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
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):
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
def h11_get_request(request): return h11.Request( method="GET", target="/", headers=[("Host", "localhost")], )
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)
def get_registrations_builder(): request = h11.Request(method="GET", target="/giveaway/winner", headers=[("host", "bluespan.gg"), ("authorization", _token)]) return request,
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:
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)
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
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
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