예제 #1
0
파일: clients.py 프로젝트: noirbee/splicy
 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()
예제 #2
0
파일: backend.py 프로젝트: noirbee/splicy
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)
예제 #3
0
파일: backend.py 프로젝트: noirbee/splicy
 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
예제 #4
0
파일: clients.py 프로젝트: noirbee/splicy
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()