def __init__(self, server, loop, sock, address_info): self.server = server self.loop = loop self.sock = sock self.sock.setblocking(0) self.address_info = address_info self.pipe_buffer = PipeBuffer() self.watchers = { 'recv': loop.io(sock.fileno(), EV_READ, self.recv_data), 'send': loop.io(sock.fileno(), EV_WRITE, self.send_data, 0), 'timeout': loop.timer(self.IO_TIMEOUT, self.IO_TIMEOUT, self.timeout), } self.http_parser = HTTPParser()
class BackendRequest(HTTPClient): def __init__(self, backend, request_parser, loop, url, headers=None, body=b"", addr_info=None, logger=None): HTTPClient.__init__(self, loop, url, headers, body, addr_info, logger) self.backend = backend self.request_parser = request_parser self.pipe_buffer = PipeBuffer() self.pipe_buffer_size = 0 def on_response_headers(self, response_parser, parsed_bytes, response_buffer): self.logger.debug("Parsed bytes = %d, body bytes = %d", parsed_bytes, len(response_parser.body)) header_bytes = response_buffer[:parsed_bytes] self.logger.debug("Headers: %s", header_bytes) self.pipe_buffer.write(header_bytes) self.pipe_buffer_size += len(header_bytes) def on_response_body(self, body): self.pipe_buffer.write(body) self.pipe_buffer.size = self.pipe_buffer_size + len(body) self.backend.server.logger.debug("Pipe buffer size: %d", self.pipe_buffer.size) def on_response(self, response_parser, body): self.backend.server.logger.info("Got response: %s, %s", response_parser, response_parser.headers) self.backend.publish_response(self.request_parser, response_parser, self.pipe_buffer)
def __init__(self, backend, request_parser, loop, url, headers=None, body=b"", addr_info=None, logger=None): HTTPClient.__init__(self, loop, url, headers, body, addr_info, logger) self.backend = backend self.request_parser = request_parser self.pipe_buffer = PipeBuffer() self.pipe_buffer_size = 0
class InboundClient(object): IO_TIMEOUT = 10 MAX_REQUEST_SIZE = 4096 def __init__(self, server, loop, sock, address_info): self.server = server self.loop = loop self.sock = sock self.sock.setblocking(0) self.address_info = address_info self.pipe_buffer = PipeBuffer() self.watchers = { 'recv': loop.io(sock.fileno(), EV_READ, self.recv_data), 'send': loop.io(sock.fileno(), EV_WRITE, self.send_data, 0), 'timeout': loop.timer(self.IO_TIMEOUT, self.IO_TIMEOUT, self.timeout), } self.http_parser = HTTPParser() def start(self): self.watchers['recv'].start() self.watchers['timeout'].start() # send is not started yet def stop(self): for watcher in self.watchers.values(): watcher.stop() self.sock.close() self.pipe_buffer.close() self.server.remove_client(self) self.server.logger.debug('Stopped client: %s', self) def recv_data(self, watcher, revents): try: data = self.sock.recv(self.MAX_REQUEST_SIZE, socket.MSG_PEEK) self.http_parser.execute(data) if self.http_parser.has_error(): self.stop() elif self.http_parser.is_finished(): # IO_TIMEOUT seconds at most for the response to come in self.watchers['timeout'].reset() data = self.sock.recv(self.MAX_REQUEST_SIZE) # We're not interested in any more data from this peer self.sock.shutdown(socket.SHUT_RD) watcher.stop() # Ask our server for the response, cached or not self.server.proxy(self, self.http_parser, data) except: self.server.logger.exception('While recv_data():') raise def start_sending(self): self.watchers['send'].start() def send_data(self, watcher, revents): self.watchers['timeout'].reset() self.server.logger.debug('Sending (%d - %d) = %d bytes to %s', self.pipe_buffer.size, watcher.data, self.pipe_buffer.size - watcher.data, self) watcher.data += splice(self.pipe_buffer.reader, None, self.sock.fileno(), None, self.pipe_buffer.size - watcher.data)[0] if watcher.data >= self.pipe_buffer.size: self.server.logger.debug('Done sending data to %s', self) self.stop() self.server.logger.debug('Sent %d bytes to %s', watcher.data, self) def timeout(self, watcher, revents): self.stop()