// Copyright 2012 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Helper classes and functions used for the WebRequest API. #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/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" namespace content { class BrowserContext; } namespace extensions { class Extension; struct WebRequestInfo; namespace declarative_net_request { struct RequestAction; } // namespace declarative_net_request } // namespace extensions namespace extension_web_request_api_helpers { ResponseHeader; ResponseHeaders; // These values are persisted to logs. Entries should not be renumbered and // numeric values should never be reused. enum class RequestHeaderType { … }; // These values are persisted to logs. Entries should not be renumbered and // numeric values should never be reused. enum class ResponseHeaderType { … }; struct IgnoredAction { … }; IgnoredActions; // Internal representation of the extraInfoSpec parameter on webRequest // events, used to specify extra information to be included with network // events. struct ExtraInfoSpec { … }; // Data container for RequestCookies as defined in the declarative WebRequest // API definition. struct RequestCookie { … }; // Data container for ResponseCookies as defined in the declarative WebRequest // API definition. struct ResponseCookie { … }; // Data container for FilterResponseCookies as defined in the declarative // WebRequest API definition. struct FilterResponseCookie : ResponseCookie { … }; enum CookieModificationType { … }; struct RequestCookieModification { … }; struct ResponseCookieModification { … }; RequestCookieModifications; ResponseCookieModifications; // Contains the modification an extension wants to perform on an event. struct EventResponseDelta { … }; EventResponseDeltas; // Comparison operator that returns true if the extension that caused // |a| was installed after the extension that caused |b|. bool InDecreasingExtensionInstallationTimeOrder(const EventResponseDelta& a, const EventResponseDelta& b); // Converts a string to a list of integers, each in 0..255. base::Value::List StringToCharList(const std::string& s); // Converts a list of integer values between 0 and 255 into a string |*out|. // Returns true if the conversion was successful. bool CharListToString(const base::Value::List& list, std::string* out); // The following functions calculate and return the modifications to requests // commanded by extension handlers. All functions take the id of the extension // that commanded a modification, the installation time of this extension (used // for defining a precedence in conflicting modifications) and whether the // extension requested to |cancel| the request. Other parameters depend on a // the signal handler. 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); // These functions merge the responses (the |deltas|) of request handlers. // The |deltas| need to be sorted in decreasing order of precedence of // extensions. In case extensions had |deltas| that could not be honored, their // IDs are reported in |conflicting_extensions|. // Stores in |*canceled_by_extension| whether any extension wanted to cancel the // request, std::nullopt if none did, the extension id otherwise. void MergeCancelOfResponses( const EventResponseDeltas& deltas, std::optional<extensions::ExtensionId>* canceled_by_extension); // Stores in |*new_url| the redirect request of the extension with highest // precedence. Extensions that did not command to redirect the request are // ignored in this logic. void MergeRedirectUrlOfResponses(const GURL& url, const EventResponseDeltas& deltas, GURL* new_url, IgnoredActions* ignored_actions); // Stores in |*new_url| the redirect request of the extension with highest // precedence. Extensions that did not command to redirect the request are // ignored in this logic. void MergeOnBeforeRequestResponses(const GURL& url, const EventResponseDeltas& deltas, GURL* new_url, IgnoredActions* ignored_actions); // Modifies the "Cookie" header in |request_headers| according to // |deltas.request_cookie_modifications|. Conflicts are currently ignored // silently. void MergeCookiesInOnBeforeSendHeadersResponses( const GURL& gurl, const EventResponseDeltas& deltas, net::HttpRequestHeaders* request_headers); // Modifies the headers in |request_headers| according to |deltas|. Conflicts // are tried to be resolved. // Stores in |request_headers_modified| whether the request headers were // modified. // Any actions within |request.dnr_actions| which result in headers being // modified are added to |matched_dnr_actions|. 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); // Modifies the "Set-Cookie" headers in |override_response_headers| according to // |deltas.response_cookie_modifications|. If |override_response_headers| is // NULL, a copy of |original_response_headers| is created. Conflicts are // currently ignored silently. void MergeCookiesInOnHeadersReceivedResponses( const GURL& url, const EventResponseDeltas& deltas, const net::HttpResponseHeaders* original_response_headers, scoped_refptr<net::HttpResponseHeaders>* override_response_headers); // Stores a copy of |original_response_header| into |override_response_headers| // that is modified according to |deltas|. If |deltas| does not instruct to // modify the response headers, |override_response_headers| remains empty. // Extension-initiated redirects are written to |override_response_headers| // (to request redirection) and |*preserve_fragment_on_redirect_url| (to make // sure that the URL provided by the extension isn't modified by having its // fragment overwritten by that of the original URL). Stores in // |response_headers_modified| whether the response headers were modified. // Any actions within |request.dnr_actions| which result in headers being // modified are added to |matched_dnr_actions|. 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, IgnoredActions* ignored_actions, bool* response_headers_modified, std::vector<const extensions::declarative_net_request::RequestAction*>* matched_dnr_actions); // Merge the responses of blocked onAuthRequired handlers. The first // registered listener that supplies authentication credentials in a response, // if any, will have its authentication credentials used. |request| must be // non-NULL, and contain |deltas| that are sorted in decreasing order of // precedence. // Returns whether authentication credentials are set. bool MergeOnAuthRequiredResponses(const EventResponseDeltas& deltas, net::AuthCredentials* auth_credentials, IgnoredActions* ignored_actions); // Triggers clearing any back-forward caches and each renderer's in-memory cache // the next time it navigates. void ClearCacheOnNavigation(); // Converts the |name|, |value| pair of a http header to a HttpHeaders // dictionary. base::Value::Dict CreateHeaderDictionary(const std::string& name, const std::string& value); // Returns whether a request header should be hidden from listeners. bool ShouldHideRequestHeader(content::BrowserContext* browser_context, int extra_info_spec, const std::string& name); // Returns whether a response header should be hidden from listeners. bool ShouldHideResponseHeader(int extra_info_spec, const std::string& name); // "Redirects" a request to `new_url` after the response has started by setting // the appropriate headers in `override_response_headers`. void RedirectRequestAfterHeadersReceived( const GURL& new_url, net::HttpResponseHeaders& override_response_headers, GURL* preserve_fragment_on_redirect_url); } // namespace extension_web_request_api_helpers #endif // EXTENSIONS_BROWSER_API_WEB_REQUEST_WEB_REQUEST_API_HELPERS_H_