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
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
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
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