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 25 namespace base { 26 class ListValue; 27 class Value; 28 } 29 30 namespace extensions { 31 class Extension; 32 } 33 34 namespace net { 35 class BoundNetLog; 36 class URLRequest; 37 } 38 39 namespace extension_web_request_api_helpers { 40 41 typedef std::pair<std::string, std::string> ResponseHeader; 42 typedef std::vector<ResponseHeader> ResponseHeaders; 43 44 // Data container for RequestCookies as defined in the declarative WebRequest 45 // API definition. 46 struct 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 55 bool NullableEquals(const RequestCookie* a, const RequestCookie* b); 56 57 // Data container for ResponseCookies as defined in the declarative WebRequest 58 // API definition. 59 struct 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 74 bool NullableEquals(const ResponseCookie* a, const ResponseCookie* b); 75 76 // Data container for FilterResponseCookies as defined in the declarative 77 // WebRequest API definition. 78 struct 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 88 bool NullableEquals(const FilterResponseCookie* a, 89 const FilterResponseCookie* b); 90 91 enum CookieModificationType { 92 ADD, 93 EDIT, 94 REMOVE, 95 }; 96 97 struct 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 109 bool NullableEquals(const RequestCookieModification* a, 110 const RequestCookieModification* b); 111 112 struct 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 124 bool NullableEquals(const ResponseCookieModification* a, 125 const ResponseCookieModification* b); 126 127 typedef std::vector<linked_ptr<RequestCookieModification> > 128 RequestCookieModifications; 129 typedef std::vector<linked_ptr<ResponseCookieModification> > 130 ResponseCookieModifications; 131 132 // Contains the modification an extension wants to perform on an event. 133 struct 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 179 typedef 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|. 183 bool 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. 189 base::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. 193 bool 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 202 EventResponseDelta* CalculateOnBeforeRequestDelta( 203 const std::string& extension_id, 204 const base::Time& extension_install_time, 205 bool cancel, 206 const GURL& new_url); 207 EventResponseDelta* 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); 213 EventResponseDelta* 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. 221 EventResponseDelta* 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. 234 void 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. 241 void 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. 249 void 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. 256 void 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. 265 void 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. 274 void 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. 286 bool 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. 294 bool 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. 298 const 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. 303 bool 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. 307 void 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. 312 void 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