Exemple #1
0
    def _handle(self, source, dest, to_backend, on_between_handle,
                **kwargs):
        # https://github.com/memcached/memcached/blob/master/doc/protocol.txt
        # Sending the query

        buffer = self._get_data(source)
        if not buffer:
            self._abort_handling(to_backend, dest)
            return

        # sending the first packet
        dest.sendall(buffer)
        on_between_handle()

        # finding the command we sent.
        cmd = RE_MEMCACHE_COMMAND.search(buffer)

        if cmd is None:
            # wat ?
            self._abort_handling(to_backend, dest)
            return

        # looking at the command
        cmd = cmd.groups()[0]
        buffer_size = self.option('buffer')

        cmd_parts = cmd.split()
        mcmd = cmd_parts[0]

        if mcmd in ('set', 'add', 'replace', 'append'):
            cmd_size = len(cmd) + len(CRLF)
            data_size = int(cmd_parts[-1])
            total_size = cmd_size + data_size

            # grabbing more data if needed
            left_to_read = total_size - len(buffer) + len(CRLF)
            if left_to_read > 0:
                for chunk in chunked(left_to_read, buffer_size):
                    data = source.recv(chunk)
                    buffer += data
                    dest.sendall(data)

        # Receiving the response now
        buffer = self._get_data(dest, buffer_size)
        source.sendall(buffer)

        if buffer.startswith('VALUE'):
            # we're getting back a value.
            EOW = 'END' + CRLF
        else:
            EOW = CRLF

        while not buffer.endswith(EOW):
            data = self._get_data(dest, buffer_size)
            buffer += data
            source.sendall(data)

        # we're done
        return True    # keeping connected
Exemple #2
0
    def _handle(self, source, dest, to_backend):
        buffer_size = self.option("buffer")

        # Getting the HTTP query
        data = self._get_data(source)

        if not data:
            self._abort_handling(to_backend, dest)
            return False

        # sending it to the backend
        dest.sendall(data)

        # Receiving the response
        buffer = self._get_data(dest, buffer_size)

        source.sendall(buffer)

        # Reading the HTTP Headers
        while EOH not in buffer:
            data = self._get_data(dest, buffer_size)
            buffer += data
            source.sendall(data)

        # keep alive header ?
        keep_alive = RE_KEEPALIVE.search(buffer) is not None

        # content-length header - to see if we need to suck more
        # data.
        match = RE_LEN.search(buffer)
        if match:
            resp_len = int(match.group(1))
            left_to_read = resp_len - len(buffer)
            if left_to_read > 0:
                for chunk in chunked(left_to_read, buffer_size):
                    data = self._get_data(dest, chunk)
                    buffer += data
                    source.sendall(data)
        else:
            # embarrassing...
            # just sucking until recv() returns ''
            while True:
                data = self._get_data(dest, buffer_size)
                if data == "":
                    break
                source.sendall(data)

        # do we close the client ?
        if not keep_alive and not self.option("keep_alive"):
            source.close()
            source._closed = True

        if not self.option("reuse_socket") and not self.option("keep_alive"):
            dest.close()
            dest._closed = True

        # we're done
        return keep_alive or self.option("keep_alive")
Exemple #3
0
    def _handle(self, source, dest, to_backend, on_between_handle):
        """ see http://redis.io/topics/protocol
        """
        # grabbing data
        bytepos, buffer = self._find(source, '', CRLF, dest)
        on_between_handle()
        if bytepos == -1:
            return False

        num_args = int(buffer[1:bytepos])

        for arg in range(num_args):
            # next CRLF
            buffer = buffer[bytepos + len(CRLF):]
            bytepos, buffer = self._find(source, buffer, CRLF, dest)

            # reading the number of bytes
            num_bytes = int(buffer[1:bytepos])
            data_start = bytepos + len(CRLF)

            # reading the data (next CRLF)
            buffer = buffer[data_start:]
            __, buffer = self._find(source, buffer, CRLF, dest)
            data = buffer[:num_bytes]
            bytepos = num_bytes

        # Getting the answer back and sending it over.
        buffer = self._get_data(dest)
        source.sendall(buffer)

        if buffer[0] in ('+', '-', ':'):
            # simple reply, we're good
            return False    # disconnect mode ?

        buffer_size = self.option('buffer')
        bytepos, buffer = self._find(dest, buffer, CRLF, source)

        if buffer[0] == '$':
            # bulk reply
            size = int(buffer[1:bytepos])
            left_to_read = (size - len(buffer) + len(buffer[:bytepos]) +
                            len(CRLF) * 2)

            if left_to_read > 0:
                for chunk in chunked(left_to_read, buffer_size):
                    data = self._get_data(dest, chunk)
                    buffer += data
                    source.sendall(data)

            return False  # disconnect mode ?

        if buffer[0] == '*':
            # multi-bulk reply
            raise NotImplementedError()

        raise NotImplementedError()
Exemple #4
0
    def _handle(self, source, dest, to_backend, on_between_handle):
        """ see http://redis.io/topics/protocol
        """
        # grabbing data
        bytepos, buffer = self._find(source, '', CRLF, dest)
        on_between_handle()
        if bytepos == -1:
            return False

        num_args = int(buffer[1:bytepos])

        for arg in range(num_args):
            # next CRLF
            buffer = buffer[bytepos + len(CRLF):]
            bytepos, buffer = self._find(source, buffer, CRLF, dest)

            # reading the number of bytes
            num_bytes = int(buffer[1:bytepos])
            data_start = bytepos + len(CRLF)

            # reading the data (next CRLF)
            buffer = buffer[data_start:]
            __, buffer = self._find(source, buffer, CRLF, dest)
            data = buffer[:num_bytes]
            bytepos = num_bytes

        # Getting the answer back and sending it over.
        buffer = self._get_data(dest)
        source.sendall(buffer)

        if buffer[0] in ('+', '-', ':'):
            # simple reply, we're good
            return False  # disconnect mode ?

        buffer_size = self.option('buffer')
        bytepos, buffer = self._find(dest, buffer, CRLF, source)

        if buffer[0] == '$':
            # bulk reply
            size = int(buffer[1:bytepos])
            left_to_read = (size - len(buffer) + len(buffer[:bytepos]) +
                            len(CRLF) * 2)

            if left_to_read > 0:
                for chunk in chunked(left_to_read, buffer_size):
                    data = self._get_data(dest, chunk)
                    buffer += data
                    source.sendall(data)

            return False  # disconnect mode ?

        if buffer[0] == '*':
            # multi-bulk reply
            raise NotImplementedError()

        raise NotImplementedError()
Exemple #5
0
    def handle(self, client_sock, address):
        client_sock.setblocking(0)
        dest = None
        try:
            # getting the query
            data = get_data(client_sock)

            if not data:
                return

            # finding out what backend we want
            data = data.split('\r\n')

            PATH = data[0].split()
            elmts = PATH[1].split('/')
            try:
                port = int(elmts[1])
            except ValueError:
                client_sock.sendall(http_error(404, 'Not Found'))
                return

            NEW_PATH = '/'.join(elmts[0:1] + elmts[2:])
            data[0] = ' '.join(PATH[0:1] + [NEW_PATH] + PATH[2:])

            try:
                dest = create_connection((self.host, port))
            except error:
                client_sock.sendall(http_error(503, '%d not responding' %
                                    port))
                return

            # sending it to the backend
            dest.sendall('\r\n'.join(data))

            # Receiving the response
            buffer = get_data(dest)

            client_sock.sendall(buffer)

            # Reading the HTTP Headers
            while EOH not in buffer:
                data = get_data(dest)
                buffer += data
                client_sock.sendall(data)

            # content-length header - to see if we need to suck more
            # data.
            match = RE_LEN.search(buffer)
            if match:
                resp_len = int(match.group(1))
                left_to_read = resp_len - len(buffer)
                if left_to_read > 0:
                    for chunk in chunked(left_to_read, 1024):
                        data = get_data(dest, chunk)
                        buffer += data
                        client_sock.sendall(data)
            else:
                # embarrassing...
                # just sucking until recv() returns ''
                while True:
                    data = get_data(dest)
                    if data == '':
                        break
                    client_sock.sendall(data)
        finally:
            client_sock.close()
            if dest is not None:
                dest.close()
Exemple #6
0
 def test_chunked(self):
     self.assertEqual(sum(list(chunked(7634, 2049))), 7634)
Exemple #7
0
 def test_chunked(self):
     self.assertEqual(sum(list(chunked(7634, 2049))), 7634)
Exemple #8
0
    def handle(self, client_sock, address):
        client_sock.setblocking(0)
        dest = None
        try:
            # getting the query
            data = get_data(client_sock)

            if not data:
                return

            # finding out what backend we want
            data = data.split('\r\n')

            PATH = data[0].split()
            elmts = PATH[1].split('/')
            try:
                port = int(elmts[1])
            except ValueError:
                client_sock.sendall(http_error(404, 'Not Found'))
                return

            NEW_PATH = '/'.join(elmts[0:1] + elmts[2:])
            data[0] = ' '.join(PATH[0:1] + [NEW_PATH] + PATH[2:])

            try:
                dest = create_connection((self.host, port))
            except error:
                client_sock.sendall(http_error(503,
                                               '%d not responding' % port))
                return

            # sending it to the backend
            dest.sendall('\r\n'.join(data))

            # Receiving the response
            buffer = get_data(dest)

            client_sock.sendall(buffer)

            # Reading the HTTP Headers
            while EOH not in buffer:
                data = get_data(dest)
                buffer += data
                client_sock.sendall(data)

            # content-length header - to see if we need to suck more
            # data.
            match = RE_LEN.search(buffer)
            if match:
                resp_len = int(match.group(1))
                left_to_read = resp_len - len(buffer)
                if left_to_read > 0:
                    for chunk in chunked(left_to_read, 1024):
                        data = get_data(dest, chunk)
                        buffer += data
                        client_sock.sendall(data)
            else:
                # embarrassing...
                # just sucking until recv() returns ''
                while True:
                    data = get_data(dest)
                    if data == '':
                        break
                    client_sock.sendall(data)
        finally:
            client_sock.close()
            if dest is not None:
                dest.close()