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 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