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