Ejemplo n.º 1
0
    def parse_headers(self):
        print('************* function parse_headers *************')
        self.num_headers[0] = 10

        result = lib.phr_parse_request(
            ffi.from_buffer(self.buffer),
            len(self.buffer),
            self.c_method,
            self.method_len,
            self.c_path,
            self.path_len,
            self.minor_version,
            self.c_headers,
            self.num_headers,
            0)

        """
        const char *buf, 
        size_t len, 
        const char **method, 
        size_t *method_len, 
        const char **path, 
        size_t *path_len,
        int *minor_version, 
        struct phr_header *headers, 
        size_t *num_headers, 
        size_t last_len
        """
        print('parse_headers-result: {}'.format(result))

        if result == -2:
            return result
        elif result == -1:
            self.on_error('malformed_headers')
            self._reset_state()
            self.buffer = bytearray()
            return result
        else:
            self._reset_state()

        method = ffi.string(self.c_method[0], self.method_len[0]).decode('ascii')
        path = ffi.string(self.c_path[0], self.path_len[0]).decode('ascii')
        version = "1." + str(self.minor_version[0])

        headers = {}
        for idx in range(self.num_headers[0]):
           header = self.c_headers[idx]
           name = ffi.string(header.name, header.name_len).decode('ascii').title()
           value = ffi.string(header.value, header.value_len).decode('latin1')
           headers[name] = value

        self.buffer = self.buffer[result:]
        print('len(self.buffer): {}'.format(len(self.buffer)))
        print('self.buffer: {}'.format(self.buffer))

        self.request = HttpRequest(method, path, version, headers)

        self.on_headers(self.request)

        return result
Ejemplo n.º 2
0
    def _parse_body(self):
        if self.content_length is None and self.request.method in NO_SEMANTICS:
            self.on_body(self.request)
            return 0
        elif self.content_length == 0:
            self.request.body = b""
            self.on_body(self.request)
            return 0
        elif self.content_length is not None:
            if self.content_length > len(self.buffer):
                return -2

            self.request.body = bytes(self.buffer[:self.content_length])
            self.on_body(self.request)
            self.buffer = self.buffer[self.content_length:]

            result = self.content_length

            return result
        elif self.transfer == 'identity':
            return -2
        elif self.transfer == 'chunked':
            if not self.chunked_decoder:
                self.chunked_decoder = ffi.new('struct phr_chunked_decoder*')
                self.chunked_decoder.consume_trailer = b'\x01'

            chunked_offset_start = self.chunked_offset[0]
            self.chunked_offset[0] = len(self.buffer) - self.chunked_offset[0]
            result = lib.phr_decode_chunked(
                self.chunked_decoder,
                ffi.from_buffer(self.buffer) + chunked_offset_start,
                self.chunked_offset)
            self.chunked_offset[
                0] = self.chunked_offset[0] + chunked_offset_start

            if result == -2:
                self.buffer = self.buffer[:self.chunked_offset[0]]
                return result
            elif result == -1:
                self.on_error('malformed_body')
                self._reset_state()
                self.buffer = bytearray()

                return result

            self.request.body = bytes(self.buffer[:self.chunked_offset[0]])
            self.on_body(self.request)
            self.buffer = self.buffer[self.chunked_offset[0]:self.
                                      chunked_offset[0] + result]
            self._reset_state()

            return result
Ejemplo n.º 3
0
    def parse_headers(self):
        self.num_headers[0] = 10

        result = lib.phr_parse_request(
            ffi.from_buffer(self.buffer), len(self.buffer),
            self.c_method, self.method_len,
            self.c_path, self.path_len,
            self.minor_version, self.c_headers, self.num_headers, 0)

        if result == -2:
            return result
        elif result == -1:
            self.on_error('malformed_headers')
            self._reset_state()
            self.buffer = bytearray()

            return result
        else:
            self._reset_state()

        method = ffi.string(self.c_method[0], self.method_len[0]).decode('ascii')
        path = ffi.string(self.c_path[0], self.path_len[0]).decode('ascii')
        version = "1." + str(self.minor_version[0])

        headers = {}
        for idx in range(self.num_headers[0]):
           header = self.c_headers[idx]
           name = ffi.string(header.name, header.name_len).decode('ascii').title()
           value = ffi.string(header.value, header.value_len).decode('latin1')
           headers[name] = value

        self.buffer = self.buffer[result:]

        self.request = HttpRequest(method, path, version, headers)

        self.on_headers(self.request)

        return result
Ejemplo n.º 4
0
    def _parse_headers(self):
        self.num_headers[0] = 10

        # FIXME: More than 10 headers

        result = lib.phr_parse_request(ffi.from_buffer(self.buffer),
                                       len(self.buffer), self.c_method,
                                       self.method_len, self.c_path,
                                       self.path_len, self.minor_version,
                                       self.c_headers, self.num_headers, 0)

        if result == -2:
            return result
        elif result == -1:
            self.on_error('malformed_headers')
            self._reset_state()
            self.buffer = bytearray()

            return result
        else:
            self._reset_state()

        method = ffi.string(self.c_method[0],
                            self.method_len[0]).decode('ascii')
        path = ffi.string(self.c_path[0], self.path_len[0]).decode('ascii')
        version = "1." + str(self.minor_version[0])

        headers = {}
        for idx in range(self.num_headers[0]):
            header = self.c_headers[idx]
            name = ffi.string(header.name,
                              header.name_len).decode('ascii').title()
            value = ffi.string(header.value, header.value_len).decode('latin1')
            headers[name] = value

        self.buffer = self.buffer[result:]

        if self.minor_version[0] == 0:
            self.connection = headers.get('Connection', 'close')
            self.transfer = 'identity'
        else:
            self.connection = headers.get('Connection', 'keep-alive')
            self.transfer = headers.get('Transfer-Encoding', 'chunked')

        self.content_length = headers.get('Content-Length')
        if self.content_length is not None:
            content_length_error = False

            if not self.content_length:
                content_length_error = True

            if not content_length_error and self.content_length[0] in '+-':
                content_length_error = True

            if not content_length_error:
                try:
                    self.content_length = int(self.content_length)
                except ValueError:
                    content_length_error = True

            if content_length_error:
                self.on_error('invalid_headers')
                self._reset_state()
                self.buffer = bytearray()

                return -1

        self.request = HttpRequest(method, path, version, headers)

        self.on_headers(self.request)

        return result