Exemplo 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
Exemplo n.º 2
0
    def parse_headers(self, data):
        c_method = ffi.new('char **')
        method_len = ffi.new('size_t *')
        c_path = ffi.new('char **')
        path_len = ffi.new('size_t *')
        minor_version = ffi.new('int *')
        c_headers = ffi.new('struct phr_header[10]')
        num_headers = ffi.new('size_t *')
        num_headers[0] = 10

        result = lib.phr_parse_request(self.buffer, self.buffer_len, c_method,
                                       method_len, c_path, path_len,
                                       minor_version, c_headers, num_headers,
                                       0)
        print('parse_headers:result: {}'.format(
            result))  # parse_headers:result: 679

        if result == -2:
            if self.buffer == data:
                self.buffer = ffi.new('char[8192]')
                self.buffer_owned = True
                ffi.memmove(self.buffer, data, len(data))

            return result
        if result == -1:
            self.on_error()
            self._reset()

            return result

        self.buffer_consumed += result

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

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

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

        self.on_headers(self.request)

        return result
Exemplo 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
Exemplo 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