def _on_request(self, event, client): request, response = client headers = request.headers if not headers.element('Connection').upgrade or not headers.element('Upgrade').tls: return data = Response(status=SWITCHING_PROTOCOLS().code) data.headers['Upgrade'] = '%s, %s' % (headers['Upgrade'], response.protocol) data.headers['Connection'] = 'Upgrade' data = b'%s%s' % (data, data.headers) self.fire(write(data, client.socket), client.server.channel) yield self.wait(starttls(client.socket))
def _on_read(self, event, socket, data): """parse data and fire request event""" server = Server(event.value.manager) if socket not in self._buffers: self._buffers[socket] = State(self, socket, server) if not server.secure and is_ssl_handshake(data): if self.ssl_through_http(socket) is NotImplemented: return if self._buffers[socket].tunnel: return # TODO: find a circuits way for this http = self._buffers[socket].parser try: requests = tuple(http.parse(data)) except StatusException as httperror: client = Client(http.request, http.response, socket, server) self._add_client(client) self.fire(HTTPError(client, httperror)) # TODO: wait for HTTPError event to be processed and close the connection except BaseException: client = Client(Request(), Response(), socket, server) self._add_client(client) self.fire( self.default_internal_server_error(client, sys.exc_info())) raise else: for client in requests: self._add_client(client) client.events.routing = self.fire( RoutingEvent(client) ).event # TODO: fire routing event in on_headers_complete and wait for sending the request event until the request is parsed completely
def response(self): self.message = Response() status = self.message.status.code if self.arguments.status: status = int(self.arguments.status) if self.arguments.reason: status = (status, self.arguments.reason) self.message.status = status self.common()
def __init__(self, request=None, response=None, socket=None, server=None, *args, **kwargs): Client.__init__(self, request or Request(), response or Response(), socket, server) WSGI.__init__(self, *args, **kwargs)
def expect(self, client): for expect in client.request.headers.elements('Expect'): if expect.is_100_continue: if not self.expect_continue(client): raise EXPECTATION_FAILED() data = Response(status=CONTINUE().code) data = b'%s%s' % (data, data.headers) self.fire(write(data, client.socket), client.server.channel) else: raise EXPECTATION_FAILED('Unknown expect header: %r' % (expect, ))
def _on_response_failure(self, evt, error): client = evt.args[0] # Ignore failed "response" handlers (e.g. Loggers or Tools) if client.done: return # Ignore disconnected clients if client.socket not in self._buffers: client.response.body.close() return # creating a new response is better than removing all headers, etc. =) client.response = Response(status=500) client.done = True self._handle_exception(client, error)
def default_internal_server_error(self, client, error): client.request = Request() client.response = Response(status=500) client.response.headers['Content-Length'] = str( len(client.response.body)).encode('ASCII') return HTTPError(client, INTERNAL_SERVER_ERROR())