#ifndef SERVICES_NETWORK_CORS_PREFLIGHT_RESULT_H_
#define SERVICES_NETWORK_CORS_PREFLIGHT_RESULT_H_
#include <memory>
#include <optional>
#include <string>
#include "base/component_export.h"
#include "base/containers/flat_set.h"
#include "base/time/time.h"
#include "base/types/strong_alias.h"
#include "base/values.h"
#include "services/network/public/cpp/cors/cors_error_status.h"
#include "services/network/public/mojom/cors.mojom-shared.h"
#include "services/network/public/mojom/fetch_api.mojom-shared.h"
namespace base {
class TickClock;
}
namespace net {
class HttpRequestHeaders;
}
namespace network {
namespace cors {
using NonWildcardRequestHeadersSupport =
base::StrongAlias<class NonWildcardRequestHeadersSupportTag, bool>;
class COMPONENT_EXPORT(NETWORK_SERVICE) PreflightResult final {
public:
static void SetTickClockForTesting(const base::TickClock* tick_clock);
static std::unique_ptr<PreflightResult> Create(
const mojom::CredentialsMode credentials_mode,
const std::optional<std::string>& allow_methods_header,
const std::optional<std::string>& allow_headers_header,
const std::optional<std::string>& max_age_header,
std::optional<mojom::CorsError>* detected_error);
PreflightResult(const PreflightResult&) = delete;
PreflightResult& operator=(const PreflightResult&) = delete;
~PreflightResult();
std::optional<CorsErrorStatus> EnsureAllowedCrossOriginMethod(
const std::string& method,
bool acam_preflight_spec_conformant) const;
std::optional<CorsErrorStatus> EnsureAllowedCrossOriginHeaders(
const net::HttpRequestHeaders& headers,
bool is_revalidating,
NonWildcardRequestHeadersSupport
with_non_wildcard_request_headers_support) const;
bool IsExpired() const;
bool EnsureAllowedRequest(mojom::CredentialsMode credentials_mode,
const std::string& method,
const net::HttpRequestHeaders& headers,
bool is_revalidating,
NonWildcardRequestHeadersSupport
with_non_wildcard_request_headers_support,
bool acam_preflight_spec_conformant) const;
bool HasAuthorizationCoveredByWildcard(
const net::HttpRequestHeaders& headers) const;
base::TimeTicks absolute_expiry_time() const { return absolute_expiry_time_; }
base::Value::Dict NetLogParams() const;
protected:
explicit PreflightResult(const mojom::CredentialsMode credentials_mode);
std::optional<mojom::CorsError> Parse(
const std::optional<std::string>& allow_methods_header,
const std::optional<std::string>& allow_headers_header,
const std::optional<std::string>& max_age_header);
private:
std::optional<CorsErrorStatus>
EnsureAllowedCrossOriginHeadersWithAuthorizationCoveredByWildcard(
const net::HttpRequestHeaders& headers,
bool is_revalidating) const;
std::optional<CorsErrorStatus>
EnsureAllowedCrossOriginHeadersWithAuthorizationNotCoveredByWildcard(
const net::HttpRequestHeaders& headers,
bool is_revalidating) const;
base::TimeTicks absolute_expiry_time_;
bool credentials_;
base::flat_set<std::string> methods_;
base::flat_set<std::string> headers_;
};
}
}
#endif