1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// Helper classes and functions used for the WebRequest API. 6 7#ifndef CHROME_BROWSER_EXTENSIONS_API_WEB_REQUEST_WEB_REQUEST_API_HELPERS_H_ 8#define CHROME_BROWSER_EXTENSIONS_API_WEB_REQUEST_WEB_REQUEST_API_HELPERS_H_ 9 10#include <list> 11#include <set> 12#include <string> 13 14#include "base/memory/linked_ptr.h" 15#include "base/memory/ref_counted.h" 16#include "base/memory/scoped_ptr.h" 17#include "base/time/time.h" 18#include "chrome/browser/extensions/extension_warning_set.h" 19#include "net/base/auth.h" 20#include "net/http/http_request_headers.h" 21#include "net/http/http_response_headers.h" 22#include "url/gurl.h" 23#include "webkit/common/resource_type.h" 24 25namespace base { 26class ListValue; 27class Value; 28} 29 30namespace extensions { 31class Extension; 32} 33 34namespace net { 35class BoundNetLog; 36class URLRequest; 37} 38 39namespace extension_web_request_api_helpers { 40 41typedef std::pair<std::string, std::string> ResponseHeader; 42typedef std::vector<ResponseHeader> ResponseHeaders; 43 44// Data container for RequestCookies as defined in the declarative WebRequest 45// API definition. 46struct RequestCookie { 47 RequestCookie(); 48 ~RequestCookie(); 49 scoped_ptr<std::string> name; 50 scoped_ptr<std::string> value; 51 private: 52 DISALLOW_COPY_AND_ASSIGN(RequestCookie); 53}; 54 55bool NullableEquals(const RequestCookie* a, const RequestCookie* b); 56 57// Data container for ResponseCookies as defined in the declarative WebRequest 58// API definition. 59struct ResponseCookie { 60 ResponseCookie(); 61 ~ResponseCookie(); 62 scoped_ptr<std::string> name; 63 scoped_ptr<std::string> value; 64 scoped_ptr<std::string> expires; 65 scoped_ptr<int> max_age; 66 scoped_ptr<std::string> domain; 67 scoped_ptr<std::string> path; 68 scoped_ptr<bool> secure; 69 scoped_ptr<bool> http_only; 70 private: 71 DISALLOW_COPY_AND_ASSIGN(ResponseCookie); 72}; 73 74bool NullableEquals(const ResponseCookie* a, const ResponseCookie* b); 75 76// Data container for FilterResponseCookies as defined in the declarative 77// WebRequest API definition. 78struct FilterResponseCookie : ResponseCookie { 79 FilterResponseCookie(); 80 ~FilterResponseCookie(); 81 scoped_ptr<int> age_lower_bound; 82 scoped_ptr<int> age_upper_bound; 83 scoped_ptr<bool> session_cookie; 84 private: 85 DISALLOW_COPY_AND_ASSIGN(FilterResponseCookie); 86}; 87 88bool NullableEquals(const FilterResponseCookie* a, 89 const FilterResponseCookie* b); 90 91enum CookieModificationType { 92 ADD, 93 EDIT, 94 REMOVE, 95}; 96 97struct RequestCookieModification { 98 RequestCookieModification(); 99 ~RequestCookieModification(); 100 CookieModificationType type; 101 // Used for EDIT and REMOVE. NULL for ADD. 102 scoped_ptr<RequestCookie> filter; 103 // Used for ADD and EDIT. NULL for REMOVE. 104 scoped_ptr<RequestCookie> modification; 105 private: 106 DISALLOW_COPY_AND_ASSIGN(RequestCookieModification); 107}; 108 109bool NullableEquals(const RequestCookieModification* a, 110 const RequestCookieModification* b); 111 112struct ResponseCookieModification { 113 ResponseCookieModification(); 114 ~ResponseCookieModification(); 115 CookieModificationType type; 116 // Used for EDIT and REMOVE. 117 scoped_ptr<FilterResponseCookie> filter; 118 // Used for ADD and EDIT. 119 scoped_ptr<ResponseCookie> modification; 120 private: 121 DISALLOW_COPY_AND_ASSIGN(ResponseCookieModification); 122}; 123 124bool NullableEquals(const ResponseCookieModification* a, 125 const ResponseCookieModification* b); 126 127typedef std::vector<linked_ptr<RequestCookieModification> > 128 RequestCookieModifications; 129typedef std::vector<linked_ptr<ResponseCookieModification> > 130 ResponseCookieModifications; 131 132// Contains the modification an extension wants to perform on an event. 133struct EventResponseDelta { 134 // ID of the extension that sent this response. 135 std::string extension_id; 136 137 // The time that the extension was installed. Used for deciding order of 138 // precedence in case multiple extensions respond with conflicting 139 // decisions. 140 base::Time extension_install_time; 141 142 // Response values. These are mutually exclusive. 143 bool cancel; 144 GURL new_url; 145 146 // Newly introduced or overridden request headers. 147 net::HttpRequestHeaders modified_request_headers; 148 149 // Keys of request headers to be deleted. 150 std::vector<std::string> deleted_request_headers; 151 152 // Headers that were added to the response. A modification of a header 153 // corresponds to a deletion and subsequent addition of the new header. 154 ResponseHeaders added_response_headers; 155 156 // Headers that were deleted from the response. 157 ResponseHeaders deleted_response_headers; 158 159 // Authentication Credentials to use. 160 scoped_ptr<net::AuthCredentials> auth_credentials; 161 162 // Modifications to cookies in request headers. 163 RequestCookieModifications request_cookie_modifications; 164 165 // Modifications to cookies in response headers. 166 ResponseCookieModifications response_cookie_modifications; 167 168 // Messages that shall be sent to the background/event/... pages of the 169 // extension. 170 std::set<std::string> messages_to_extension; 171 172 EventResponseDelta(const std::string& extension_id, 173 const base::Time& extension_install_time); 174 ~EventResponseDelta(); 175 176 DISALLOW_COPY_AND_ASSIGN(EventResponseDelta); 177}; 178 179typedef std::list<linked_ptr<EventResponseDelta> > EventResponseDeltas; 180 181// Comparison operator that returns true if the extension that caused 182// |a| was installed after the extension that caused |b|. 183bool InDecreasingExtensionInstallationTimeOrder( 184 const linked_ptr<EventResponseDelta>& a, 185 const linked_ptr<EventResponseDelta>& b); 186 187// Converts a string to a list of integers, each in 0..255. Ownership 188// of the created list is passed to the caller. 189base::ListValue* StringToCharList(const std::string& s); 190 191// Converts a list of integer values between 0 and 255 into a string |*out|. 192// Returns true if the conversion was successful. 193bool CharListToString(const base::ListValue* list, std::string* out); 194 195// The following functions calculate and return the modifications to requests 196// commanded by extension handlers. All functions take the id of the extension 197// that commanded a modification, the installation time of this extension (used 198// for defining a precedence in conflicting modifications) and whether the 199// extension requested to |cancel| the request. Other parameters depend on a 200// the signal handler. Ownership of the returned object is passed to the caller. 201 202EventResponseDelta* CalculateOnBeforeRequestDelta( 203 const std::string& extension_id, 204 const base::Time& extension_install_time, 205 bool cancel, 206 const GURL& new_url); 207EventResponseDelta* CalculateOnBeforeSendHeadersDelta( 208 const std::string& extension_id, 209 const base::Time& extension_install_time, 210 bool cancel, 211 net::HttpRequestHeaders* old_headers, 212 net::HttpRequestHeaders* new_headers); 213EventResponseDelta* CalculateOnHeadersReceivedDelta( 214 const std::string& extension_id, 215 const base::Time& extension_install_time, 216 bool cancel, 217 const net::HttpResponseHeaders* old_response_headers, 218 ResponseHeaders* new_response_headers); 219// Destructively moves the auth credentials from |auth_credentials| to the 220// returned EventResponseDelta. 221EventResponseDelta* CalculateOnAuthRequiredDelta( 222 const std::string& extension_id, 223 const base::Time& extension_install_time, 224 bool cancel, 225 scoped_ptr<net::AuthCredentials>* auth_credentials); 226 227// These functions merge the responses (the |deltas|) of request handlers. 228// The |deltas| need to be sorted in decreasing order of precedence of 229// extensions. In case extensions had |deltas| that could not be honored, their 230// IDs are reported in |conflicting_extensions|. NetLog events that shall be 231// reported will be stored in |event_log_entries|. 232 233// Stores in |canceled| whether any extension wanted to cancel the request. 234void MergeCancelOfResponses( 235 const EventResponseDeltas& deltas, 236 bool* canceled, 237 const net::BoundNetLog* net_log); 238// Stores in |*new_url| the redirect request of the extension with highest 239// precedence. Extensions that did not command to redirect the request are 240// ignored in this logic. 241void MergeOnBeforeRequestResponses( 242 const EventResponseDeltas& deltas, 243 GURL* new_url, 244 extensions::ExtensionWarningSet* conflicting_extensions, 245 const net::BoundNetLog* net_log); 246// Modifies the "Cookie" header in |request_headers| according to 247// |deltas.request_cookie_modifications|. Conflicts are currently ignored 248// silently. 249void MergeCookiesInOnBeforeSendHeadersResponses( 250 const EventResponseDeltas& deltas, 251 net::HttpRequestHeaders* request_headers, 252 extensions::ExtensionWarningSet* conflicting_extensions, 253 const net::BoundNetLog* net_log); 254// Modifies the headers in |request_headers| according to |deltas|. Conflicts 255// are tried to be resolved. 256void MergeOnBeforeSendHeadersResponses( 257 const EventResponseDeltas& deltas, 258 net::HttpRequestHeaders* request_headers, 259 extensions::ExtensionWarningSet* conflicting_extensions, 260 const net::BoundNetLog* net_log); 261// Modifies the "Set-Cookie" headers in |override_response_headers| according to 262// |deltas.response_cookie_modifications|. If |override_response_headers| is 263// NULL, a copy of |original_response_headers| is created. Conflicts are 264// currently ignored silently. 265void MergeCookiesInOnHeadersReceivedResponses( 266 const EventResponseDeltas& deltas, 267 const net::HttpResponseHeaders* original_response_headers, 268 scoped_refptr<net::HttpResponseHeaders>* override_response_headers, 269 extensions::ExtensionWarningSet* conflicting_extensions, 270 const net::BoundNetLog* net_log); 271// Stores a copy of |original_response_header| into |override_response_headers| 272// that is modified according to |deltas|. If |deltas| does not instruct to 273// modify the response headers, |override_response_headers| remains empty. 274void MergeOnHeadersReceivedResponses( 275 const EventResponseDeltas& deltas, 276 const net::HttpResponseHeaders* original_response_headers, 277 scoped_refptr<net::HttpResponseHeaders>* override_response_headers, 278 extensions::ExtensionWarningSet* conflicting_extensions, 279 const net::BoundNetLog* net_log); 280// Merge the responses of blocked onAuthRequired handlers. The first 281// registered listener that supplies authentication credentials in a response, 282// if any, will have its authentication credentials used. |request| must be 283// non-NULL, and contain |deltas| that are sorted in decreasing order of 284// precedence. 285// Returns whether authentication credentials are set. 286bool MergeOnAuthRequiredResponses( 287 const EventResponseDeltas& deltas, 288 net::AuthCredentials* auth_credentials, 289 extensions::ExtensionWarningSet* conflicting_extensions, 290 const net::BoundNetLog* net_log); 291 292// Returns whether |type| is a ResourceType that is handled by the web request 293// API. 294bool IsRelevantResourceType(ResourceType::Type type); 295 296// Returns a string representation of |type| or |other| if |type| is not handled 297// by the web request API. 298const char* ResourceTypeToString(ResourceType::Type type); 299 300// Stores a |ResourceType::Type| representation in |type| if |type_str| is 301// a resource type handled by the web request API. Returns true in case of 302// success. 303bool ParseResourceType(const std::string& type_str, 304 ResourceType::Type* type); 305 306// Triggers clearing each renderer's in-memory cache the next time it navigates. 307void ClearCacheOnNavigation(); 308 309// Tells renderer processes that the web request or declarative web request 310// API has been used by |extension| in profile |profile_id| to collect 311// UMA statistics on Page Load Times. Needs to be called on the UI thread. 312void NotifyWebRequestAPIUsed( 313 void* profile_id, 314 scoped_refptr<const extensions::Extension> extension); 315 316} // namespace extension_web_request_api_helpers 317 318#endif // CHROME_BROWSER_EXTENSIONS_API_WEB_REQUEST_WEB_REQUEST_API_HELPERS_H_ 319