• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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