#ifndef EXTENSIONS_BROWSER_API_WEB_REQUEST_WEB_REQUEST_API_HELPERS_H_
#define EXTENSIONS_BROWSER_API_WEB_REQUEST_WEB_REQUEST_API_HELPERS_H_
#include <list>
#include <optional>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "base/memory/scoped_refptr.h"
#include "base/time/time.h"
#include "base/values.h"
#include "extensions/buildflags/buildflags.h"
#include "extensions/common/api/web_request.h"
#include "extensions/common/extension_id.h"
#include "net/base/auth.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "url/gurl.h"
static_assert(BUILDFLAG(ENABLE_EXTENSIONS_CORE));
namespace content {
class BrowserContext;
}
namespace extensions {
class Extension;
struct WebRequestInfo;
namespace declarative_net_request {
struct RequestAction;
}
}
namespace extension_web_request_api_helpers {
using ResponseHeader = std::pair<std::string, std::string>;
using ResponseHeaders = std::vector<ResponseHeader>;
enum class RequestHeaderType {
kNone = 0,
kOther = 1,
kAccept = 2,
kAcceptCharset = 3,
kAcceptEncoding = 4,
kAcceptLanguage = 5,
kAccessControlRequestHeaders = 6,
kAccessControlRequestMethod = 7,
kAuthorization = 8,
kCacheControl = 9,
kConnection = 10,
kContentEncoding = 11,
kContentLanguage = 12,
kContentLength = 13,
kContentLocation = 14,
kContentType = 15,
kCookie = 16,
kDate = 17,
kDnt = 18,
kEarlyData = 19,
kExpect = 20,
kForwarded = 21,
kFrom = 22,
kHost = 23,
kIfMatch = 24,
kIfModifiedSince = 25,
kIfNoneMatch = 26,
kIfRange = 27,
kIfUnmodifiedSince = 28,
kKeepAlive = 29,
kOrigin = 30,
kPragma = 31,
kProxyAuthorization = 32,
kProxyConnection = 33,
kRange = 34,
kReferer = 35,
kTe = 37,
kTransferEncoding = 38,
kUpgrade = 39,
kUpgradeInsecureRequests = 40,
kUserAgent = 41,
kVia = 42,
kWarning = 43,
kXForwardedFor = 44,
kXForwardedHost = 45,
kXForwardedProto = 46,
kMaxValue = kXForwardedProto,
};
enum class ResponseHeaderType {
kNone = 0,
kOther = 1,
kAcceptPatch = 2,
kAcceptRanges = 3,
kAccessControlAllowCredentials = 4,
kAccessControlAllowHeaders = 5,
kAccessControlAllowMethods = 6,
kAccessControlAllowOrigin = 7,
kAccessControlExposeHeaders = 8,
kAccessControlMaxAge = 9,
kAge = 10,
kAllow = 11,
kAltSvc = 12,
kCacheControl = 13,
kClearSiteData = 14,
kConnection = 15,
kContentDisposition = 16,
kContentEncoding = 17,
kContentLanguage = 18,
kContentLength = 19,
kContentLocation = 20,
kContentRange = 21,
kContentSecurityPolicy = 22,
kContentSecurityPolicyReportOnly = 23,
kContentType = 24,
kDate = 25,
kETag = 26,
kExpectCT = 27,
kExpires = 28,
kFeaturePolicy = 29,
kKeepAlive = 30,
kLargeAllocation = 31,
kLastModified = 32,
kLocation = 33,
kPragma = 34,
kProxyAuthenticate = 35,
kProxyConnection = 36,
kPublicKeyPins = 37,
kPublicKeyPinsReportOnly = 38,
kReferrerPolicy = 39,
kRefresh = 40,
kRetryAfter = 41,
kSecWebSocketAccept = 42,
kServer = 43,
kServerTiming = 44,
kSetCookie = 45,
kSourceMap = 46,
kStrictTransportSecurity = 47,
kTimingAllowOrigin = 48,
kTk = 49,
kTrailer = 50,
kTransferEncoding = 51,
kUpgrade = 52,
kVary = 53,
kVia = 54,
kWarning = 55,
kWWWAuthenticate = 56,
kXContentTypeOptions = 57,
kXDNSPrefetchControl = 58,
kXFrameOptions = 59,
kXXSSProtection = 60,
kMaxValue = kXXSSProtection
};
struct IgnoredAction {
IgnoredAction(extensions::ExtensionId extension_id,
extensions::api::web_request::IgnoredActionType action_type);
IgnoredAction(const IgnoredAction&) = delete;
IgnoredAction(IgnoredAction&& rhs);
IgnoredAction& operator=(const IgnoredAction&) = delete;
extensions::ExtensionId extension_id;
extensions::api::web_request::IgnoredActionType action_type;
};
using IgnoredActions = std::vector<IgnoredAction>;
struct ExtraInfoSpec {
enum Flags {
REQUEST_HEADERS = 1 << 0,
RESPONSE_HEADERS = 1 << 1,
BLOCKING = 1 << 2,
ASYNC_BLOCKING = 1 << 3,
REQUEST_BODY = 1 << 4,
EXTRA_HEADERS = 1 << 5,
SECURITY_INFO = 1 << 6,
SECURITY_INFO_RAW_DER = 1 << 7
};
static bool InitFromValue(const base::Value& value, int* extra_info_spec);
};
struct RequestCookie {
RequestCookie();
RequestCookie(const RequestCookie&) = delete;
RequestCookie(RequestCookie&& other);
RequestCookie& operator=(const RequestCookie&) = delete;
RequestCookie& operator=(RequestCookie&& other);
~RequestCookie();
auto operator<=>(const RequestCookie& rhs) const = default;
RequestCookie Clone() const;
std::optional<std::string> name;
std::optional<std::string> value;
};
struct ResponseCookie {
ResponseCookie();
ResponseCookie(const ResponseCookie&) = delete;
ResponseCookie(ResponseCookie&& other);
ResponseCookie& operator=(const ResponseCookie&) = delete;
ResponseCookie& operator=(ResponseCookie&& other);
~ResponseCookie();
auto operator<=>(const ResponseCookie& rhs) const = default;
ResponseCookie Clone() const;
std::optional<std::string> name;
std::optional<std::string> value;
std::optional<std::string> expires;
std::optional<int> max_age;
std::optional<std::string> domain;
std::optional<std::string> path;
std::optional<bool> secure;
std::optional<bool> http_only;
};
struct FilterResponseCookie : ResponseCookie {
FilterResponseCookie();
FilterResponseCookie(const FilterResponseCookie&) = delete;
FilterResponseCookie(FilterResponseCookie&& other);
FilterResponseCookie& operator=(const FilterResponseCookie&) = delete;
FilterResponseCookie& operator=(FilterResponseCookie&& other);
~FilterResponseCookie();
FilterResponseCookie Clone() const;
auto operator<=>(const FilterResponseCookie& rhs) const = default;
std::optional<int> age_lower_bound;
std::optional<int> age_upper_bound;
std::optional<bool> session_cookie;
};
enum CookieModificationType {
ADD,
EDIT,
REMOVE,
};
struct RequestCookieModification {
RequestCookieModification();
RequestCookieModification(const RequestCookieModification&) = delete;
RequestCookieModification(RequestCookieModification&& other);
RequestCookieModification& operator=(const RequestCookieModification&) =
delete;
RequestCookieModification& operator=(RequestCookieModification&& other);
~RequestCookieModification();
bool operator==(const RequestCookieModification& other) const;
RequestCookieModification Clone() const;
CookieModificationType type;
std::optional<RequestCookie> filter;
std::optional<RequestCookie> modification;
};
struct ResponseCookieModification {
ResponseCookieModification();
ResponseCookieModification(const ResponseCookieModification&) = delete;
ResponseCookieModification(ResponseCookieModification&& other);
ResponseCookieModification& operator=(const ResponseCookieModification&) =
delete;
ResponseCookieModification& operator=(ResponseCookieModification&& other);
~ResponseCookieModification();
bool operator==(const ResponseCookieModification& other) const;
ResponseCookieModification Clone() const;
CookieModificationType type;
std::optional<FilterResponseCookie> filter;
std::optional<ResponseCookie> modification;
};
using RequestCookieModifications = std::vector<RequestCookieModification>;
using ResponseCookieModifications = std::vector<ResponseCookieModification>;
struct EventResponseDelta {
EventResponseDelta(const extensions::ExtensionId& extension_id,
const base::Time& extension_install_time);
EventResponseDelta(const EventResponseDelta&) = delete;
EventResponseDelta(EventResponseDelta&& other);
EventResponseDelta& operator=(const EventResponseDelta&) = delete;
EventResponseDelta& operator=(EventResponseDelta&& other);
~EventResponseDelta();
extensions::ExtensionId extension_id;
base::Time extension_install_time;
bool cancel;
GURL new_url;
net::HttpRequestHeaders modified_request_headers;
std::vector<std::string> deleted_request_headers;
ResponseHeaders added_response_headers;
ResponseHeaders deleted_response_headers;
std::optional<net::AuthCredentials> auth_credentials;
RequestCookieModifications request_cookie_modifications;
ResponseCookieModifications response_cookie_modifications;
std::set<std::string> messages_to_extension;
};
using EventResponseDeltas = std::list<EventResponseDelta>;
bool InDecreasingExtensionInstallationTimeOrder(const EventResponseDelta& a,
const EventResponseDelta& b);
base::Value::List StringToCharList(const std::string& s);
bool CharListToString(const base::Value::List& list, std::string* out);
EventResponseDelta CalculateOnBeforeRequestDelta(
const extensions::ExtensionId& extension_id,
const base::Time& extension_install_time,
bool cancel,
const GURL& new_url);
EventResponseDelta CalculateOnBeforeSendHeadersDelta(
content::BrowserContext* browser_context,
const extensions::ExtensionId& extension_id,
const base::Time& extension_install_time,
bool cancel,
net::HttpRequestHeaders* old_headers,
net::HttpRequestHeaders* new_headers,
int extra_info_spec);
EventResponseDelta CalculateOnHeadersReceivedDelta(
const extensions::ExtensionId& extension_id,
const base::Time& extension_install_time,
bool cancel,
const GURL& old_url,
const GURL& new_url,
const net::HttpResponseHeaders* old_response_headers,
ResponseHeaders* new_response_headers,
int extra_info_spec);
EventResponseDelta CalculateOnAuthRequiredDelta(
const extensions::ExtensionId& extension_id,
const base::Time& extension_install_time,
bool cancel,
std::optional<net::AuthCredentials> auth_credentials);
void MergeCancelOfResponses(
const EventResponseDeltas& deltas,
std::optional<extensions::ExtensionId>* canceled_by_extension);
void MergeRedirectUrlOfResponses(
const GURL& url,
const EventResponseDeltas& deltas,
GURL* new_url,
std::optional<extensions::ExtensionId>* extension_id,
IgnoredActions* ignored_actions);
void MergeOnBeforeRequestResponses(
const GURL& url,
const EventResponseDeltas& deltas,
GURL* new_url,
std::optional<extensions::ExtensionId>* extension_id,
IgnoredActions* ignored_actions);
void MergeCookiesInOnBeforeSendHeadersResponses(
const GURL& gurl,
const EventResponseDeltas& deltas,
net::HttpRequestHeaders* request_headers);
void MergeOnBeforeSendHeadersResponses(
const extensions::WebRequestInfo& request,
const EventResponseDeltas& deltas,
net::HttpRequestHeaders* request_headers,
IgnoredActions* ignored_actions,
std::set<std::string>* removed_headers,
std::set<std::string>* set_headers,
bool* request_headers_modified,
std::vector<const extensions::declarative_net_request::RequestAction*>*
matched_dnr_actions);
void MergeCookiesInOnHeadersReceivedResponses(
const GURL& url,
const EventResponseDeltas& deltas,
const net::HttpResponseHeaders* original_response_headers,
scoped_refptr<net::HttpResponseHeaders>* override_response_headers);
void MergeOnHeadersReceivedResponses(
const extensions::WebRequestInfo& request,
const EventResponseDeltas& deltas,
const net::HttpResponseHeaders* original_response_headers,
scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
GURL* preserve_fragment_on_redirect_url,
std::optional<extensions::ExtensionId>* extenion_id,
IgnoredActions* ignored_actions,
bool* response_headers_modified,
std::vector<const extensions::declarative_net_request::RequestAction*>*
matched_dnr_actions);
bool MergeOnAuthRequiredResponses(const EventResponseDeltas& deltas,
net::AuthCredentials* auth_credentials,
IgnoredActions* ignored_actions);
void ClearCacheOnNavigation();
base::Value::Dict CreateHeaderDictionary(const std::string& name,
const std::string& value);
bool ShouldHideRequestHeader(content::BrowserContext* browser_context,
int extra_info_spec,
const std::string& name);
bool ShouldHideResponseHeader(int extra_info_spec, const std::string& name);
void RedirectRequestAfterHeadersReceived(
const GURL& new_url,
net::HttpResponseHeaders& override_response_headers,
GURL* preserve_fragment_on_redirect_url);
}
#endif