Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
async def http_serve(stream):
wrapper = TrioHTTPWrapper(stream)
wrapper.info("Got new connection")
while True:
assert wrapper.conn.states == {
h11.CLIENT: h11.IDLE, h11.SERVER: h11.IDLE}
try:
with trio.fail_after(TIMEOUT):
wrapper.info("Server main loop waiting for request")
event = await wrapper.next_event()
wrapper.info("Server main loop got event:", event)
if type(event) is h11.Request:
await send_echo_response(wrapper, event)
except Exception as exc:
wrapper.info("Error during response handler:", exc)
await maybe_send_error_response(wrapper, exc)
if wrapper.conn.our_state is h11.MUST_CLOSE:
wrapper.info("connection is not reusable, so shutting down")
await wrapper.shutdown_and_clean_up()
return
async def http_serve(request_handler, sock):
wrapper = TrioHTTPWrapper(sock)
while True:
assert wrapper.conn.states == {
h11.CLIENT: h11.IDLE, h11.SERVER: h11.IDLE}
try:
with trio.move_on_after(TIMEOUT):
wrapper.info("Server main loop waiting for request")
event = await wrapper.next_event()
wrapper.info("Server main loop got event:", event)
if type(event) is h11.Request:
await request_handler(wrapper, event)
except Exception as exc:
wrapper.info("Error during response handler:", exc)
await maybe_send_error_response(wrapper, exc)
if wrapper.conn.our_state is h11.MUST_CLOSE:
wrapper.info("connection is not reusable, so shutting down")
await wrapper.shutdown_and_clean_up()
return
async def http_serve(sock, addr):
wrapper = CurioHTTPWrapper(sock)
while True:
assert wrapper.conn.states == {
h11.CLIENT: h11.IDLE, h11.SERVER: h11.IDLE}
try:
async with curio.timeout_after(TIMEOUT):
wrapper.info("Server main loop waiting for request")
event = await wrapper.next_event()
wrapper.info("Server main loop got event:", event)
if type(event) is h11.Request:
await send_echo_response(wrapper, event)
except Exception as exc:
wrapper.info("Error during response handler:", exc)
await maybe_send_error_response(wrapper, exc)
if wrapper.conn.our_state is h11.MUST_CLOSE:
wrapper.info("connection is not reusable, so shutting down")
await wrapper.shutdown_and_clean_up()
return
async def http_serve(sock, addr):
wrapper = CurioHTTPWrapper(sock)
while True:
assert wrapper.conn.states == {
h11.CLIENT: h11.IDLE, h11.SERVER: h11.IDLE}
try:
async with curio.timeout_after(TIMEOUT):
event = await wrapper.next_event()
if type(event) is h11.Request:
await send_echo_response(wrapper, event)
except Exception as exc:
await maybe_send_error_response(wrapper, exc)
if wrapper.conn.our_state is h11.MUST_CLOSE:
await wrapper.shutdown_and_clean_up()
return
else:
try:
wrapper.conn.start_next_cycle()
except h11.ProtocolError:
# `RulesContext` takes care of handling one complete
# request/response cycle.
RulesContext(self.server.compiled_rules, self)._run(event)
self._logger.debug('states: %r', self._hconn.states)
if self._hconn.states == {h11.CLIENT: h11.DONE,
h11.SERVER: h11.DONE}:
# Connection persists, proceed to the next cycle.
self._hconn.start_next_cycle()
else:
# Connection has to be closed (e.g. because HTTP/1.0
# or because somebody sent "Connection: close").
break
except Exception as e:
self._logger.error('error: %s', e)
self._logger.debug('states: %r', self._hconn.states)
if self._hconn.our_state in [h11.SEND_RESPONSE, h11.IDLE]:
self._send_fatal_error(e)
def complete(self):
"""
XX what is this supposed to do? check if the response has been fully
iterated over? check for that + the connection being reusable?
"""
our_state = self._state_machine.our_state
their_state = self._state_machine.their_state
return (our_state is h11.IDLE and their_state is h11.IDLE)
def send(self, request, uuid=None):
# type: (TransportRequest, Optional[UUID]) -> Tuple[UUID, bytes]
data = b""
if not isinstance(request, HttpRequest):
raise TypeError("Invalid request type for HttpConnection")
if (
self._connection.our_state == h11.IDLE
and not self._current_response
):
data = data + self._connection.send(request._request)
if request._data:
data = data + self._connection.send(request._data)
data = data + self._connection.send(request._end_of_message)
if request.response:
self._current_response = request.response
else:
self._current_response = HttpResponse(uuid, request.timeout)
# Make mypy happy
assert self._current_response
def wrapper(*args, **kwargs):
log.info("trying to send error response...")
if _request_local.transport.conn.our_state not in {h11.IDLE, h11.SEND_RESPONSE}:
log.info(f"...but I can't, because our state is {_request_local.transport.conn.our_state}")
return
try:
return handler(*args, **kwargs)
except Exception as exc:
log.info(f"error while sending error response: {exc}")
async def _tunnel(self, sock):
"""
This method establishes a CONNECT tunnel shortly after connection.
"""
# Basic sanity check that _tunnel is only called at appropriate times.
assert self._state_machine.our_state is h11.IDLE
tunnel_request = _build_tunnel_request(
self._tunnel_host, self._tunnel_port, self._tunnel_headers
)
tunnel_state_machine = h11.Connection(our_role=h11.CLIENT)
h11_response = await _start_http_request(
tunnel_request, tunnel_state_machine, sock
)
# XX this is wrong -- 'self' here will try to iterate using
# self._state_machine, not tunnel_state_machine. Also, we need to
# think about how this failure case interacts with the pool's
# connection lifecycle management.
tunnel_response = _response_from_h11(h11_response, self)
def complete(self):
"""
XX what is this supposed to do? check if the response has been fully
iterated over? check for that + the connection being reusable?
"""
our_state = self._state_machine.our_state
their_state = self._state_machine.their_state
return (our_state is h11.IDLE and their_state is h11.IDLE)