private function execute_callback(
		callable $callback, array $args, bool $is_raw=null
	) {
		$method = strtolower($this->request_method);

		if (in_array($method, ['head', 'get', 'options']))
			return $this->finish_callback($callback, $args);

		if ($method == 'post') {
			$args['post'] = $is_raw ?
				file_get_contents("php://input") : $_POST;
			if (isset($_FILES) && !empty($_FILES))
				$args['files'] = $_FILES;
			return $this->finish_callback($callback, $args);
		}

		if (in_array($method, ['put', 'delete', 'patch'])) {
			$args[$method] = file_get_contents("php://input");
			return $this->finish_callback($callback, $args);
		}

		# TRACE, CONNECT, etc. is not supported, in case web server
		# hasn't disabled them
		self::$logger->warning(sprintf(
			"Router: %s not supported in '%s'.",
			$this->request_method, $this->request_path));
		$this->abort(405);

		# always return self for chaining even if aborted
		return $this;
	}