Home | History | Annotate | Download | only in web_request
      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 GURL& new_url,
    218     const net::HttpResponseHeaders* old_response_headers,
    219     ResponseHeaders* new_response_headers);
    220 // Destructively moves the auth credentials from |auth_credentials| to the
    221 // returned EventResponseDelta.
    222 EventResponseDelta* CalculateOnAuthRequiredDelta(
    223     const std::string& extension_id,
    224     const base::Time& extension_install_time,
    225     bool cancel,
    226     scoped_ptr<net::AuthCredentials>* auth_credentials);
    227 
    228 // These functions merge the responses (the |deltas|) of request handlers.
    229 // The |deltas| need to be sorted in decreasing order of precedence of
    230 // extensions. In case extensions had |deltas| that could not be honored, their
    231 // IDs are reported in |conflicting_extensions|. NetLog events that shall be
    232 // reported will be stored in |event_log_entries|.
    233 
    234 // Stores in |canceled| whether any extension wanted to cancel the request.
    235 void MergeCancelOfResponses(
    236     const EventResponseDeltas& deltas,
    237     bool* canceled,
    238     const net::BoundNetLog* net_log);
    239 // Stores in |*new_url| the redirect request of the extension with highest
    240 // precedence. Extensions that did not command to redirect the request are
    241 // ignored in this logic.
    242 void MergeRedirectUrlOfResponses(
    243     const EventResponseDeltas& deltas,
    244     GURL* new_url,
    245     extensions::ExtensionWarningSet* conflicting_extensions,
    246     const net::BoundNetLog* net_log);
    247 // Stores in |*new_url| the redirect request of the extension with highest
    248 // precedence. Extensions that did not command to redirect the request are
    249 // ignored in this logic.
    250 void MergeOnBeforeRequestResponses(
    251     const EventResponseDeltas& deltas,
    252     GURL* new_url,
    253     extensions::ExtensionWarningSet* conflicting_extensions,
    254     const net::BoundNetLog* net_log);
    255 // Modifies the "Cookie" header in |request_headers| according to
    256 // |deltas.request_cookie_modifications|. Conflicts are currently ignored
    257 // silently.
    258 void MergeCookiesInOnBeforeSendHeadersResponses(
    259     const EventResponseDeltas& deltas,
    260     net::HttpRequestHeaders* request_headers,
    261     extensions::ExtensionWarningSet* conflicting_extensions,
    262     const net::BoundNetLog* net_log);
    263 // Modifies the headers in |request_headers| according to |deltas|. Conflicts
    264 // are tried to be resolved.
    265 void MergeOnBeforeSendHeadersResponses(
    266     const EventResponseDeltas& deltas,
    267     net::HttpRequestHeaders* request_headers,
    268     extensions::ExtensionWarningSet* conflicting_extensions,
    269     const net::BoundNetLog* net_log);
    270 // Modifies the "Set-Cookie" headers in |override_response_headers| according to
    271 // |deltas.response_cookie_modifications|. If |override_response_headers| is
    272 // NULL, a copy of |original_response_headers| is created. Conflicts are
    273 // currently ignored silently.
    274 void MergeCookiesInOnHeadersReceivedResponses(
    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 // Stores a copy of |original_response_header| into |override_response_headers|
    281 // that is modified according to |deltas|. If |deltas| does not instruct to
    282 // modify the response headers, |override_response_headers| remains empty.
    283 // Extension-initiated redirects are written to |override_response_headers|
    284 // (to request redirection) and |*allowed_unsafe_redirect_url| (to make sure
    285 // that the request is not cancelled with net::ERR_UNSAFE_REDIRECT).
    286 void MergeOnHeadersReceivedResponses(
    287     const EventResponseDeltas& deltas,
    288     const net::HttpResponseHeaders* original_response_headers,
    289     scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
    290     GURL* allowed_unsafe_redirect_url,
    291     extensions::ExtensionWarningSet* conflicting_extensions,
    292     const net::BoundNetLog* net_log);
    293 // Merge the responses of blocked onAuthRequired handlers. The first
    294 // registered listener that supplies authentication credentials in a response,
    295 // if any, will have its authentication credentials used. |request| must be
    296 // non-NULL, and contain |deltas| that are sorted in decreasing order of
    297 // precedence.
    298 // Returns whether authentication credentials are set.
    299 bool MergeOnAuthRequiredResponses(
    300     const EventResponseDeltas& deltas,
    301     net::AuthCredentials* auth_credentials,
    302     extensions::ExtensionWarningSet* conflicting_extensions,
    303     const net::BoundNetLog* net_log);
    304 
    305 // Returns whether |type| is a ResourceType that is handled by the web request
    306 // API.
    307 bool IsRelevantResourceType(ResourceType::Type type);
    308 
    309 // Returns a string representation of |type| or |other| if |type| is not handled
    310 // by the web request API.
    311 const char* ResourceTypeToString(ResourceType::Type type);
    312 
    313 // Stores a |ResourceType::Type| representation in |type| if |type_str| is
    314 // a resource type handled by the web request API. Returns true in case of
    315 // success.
    316 bool ParseResourceType(const std::string& type_str,
    317                        ResourceType::Type* type);
    318 
    319 // Triggers clearing each renderer's in-memory cache the next time it navigates.
    320 void ClearCacheOnNavigation();
    321 
    322 // Tells renderer processes that the web request or declarative web request
    323 // API has been used by |extension| in profile |profile_id| to collect
    324 // UMA statistics on Page Load Times. Needs to be called on the UI thread.
    325 void NotifyWebRequestAPIUsed(
    326     void* profile_id,
    327     scoped_refptr<const extensions::Extension> extension);
    328 
    329 // Whether a header is RFC 2616-compliant.
    330 bool IsValidHeaderName(const std::string& name);
    331 // Whether a header value does not contain NUL or CRLF.
    332 bool IsValidHeaderValue(const std::string& value);
    333 
    334 }  // namespace extension_web_request_api_helpers
    335 
    336 #endif  // CHROME_BROWSER_EXTENSIONS_API_WEB_REQUEST_WEB_REQUEST_API_HELPERS_H_
    337