Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(349)

Side by Side Diff: chrome/browser/extensions/api/web_request/web_request_api.cc

Issue 10694055: Add read-only access to POST data for webRequest's onBeforeRequest (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Windows, what's your problem with scoped_ptr? Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/api/web_request/web_request_api.h" 5 #include "chrome/browser/extensions/api/web_request/web_request_api.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/json/json_writer.h" 10 #include "base/json/json_writer.h"
11 #include "base/metrics/histogram.h" 11 #include "base/metrics/histogram.h"
12 #include "base/string_number_conversions.h" 12 #include "base/string_number_conversions.h"
13 #include "base/string_util.h" 13 #include "base/string_util.h"
14 #include "base/time.h" 14 #include "base/time.h"
15 #include "base/utf_string_conversions.h" 15 #include "base/utf_string_conversions.h"
16 #include "base/values.h" 16 #include "base/values.h"
17 #include "chrome/browser/browser_process.h" 17 #include "chrome/browser/browser_process.h"
18 #include "chrome/browser/chrome_content_browser_client.h" 18 #include "chrome/browser/chrome_content_browser_client.h"
19 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.h " 19 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.h "
20 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_ registry.h" 20 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_ registry.h"
21 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api_helper s.h" 21 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api_helper s.h"
22 #include "chrome/browser/extensions/api/web_request/post_data_parser.h"
22 #include "chrome/browser/extensions/api/web_request/web_request_api_constants.h" 23 #include "chrome/browser/extensions/api/web_request/web_request_api_constants.h"
23 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" 24 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h"
24 #include "chrome/browser/extensions/api/web_request/web_request_time_tracker.h" 25 #include "chrome/browser/extensions/api/web_request/web_request_time_tracker.h"
25 #include "chrome/browser/extensions/event_router.h" 26 #include "chrome/browser/extensions/event_router.h"
26 #include "chrome/browser/extensions/extension_info_map.h" 27 #include "chrome/browser/extensions/extension_info_map.h"
27 #include "chrome/browser/extensions/extension_prefs.h" 28 #include "chrome/browser/extensions/extension_prefs.h"
28 #include "chrome/browser/extensions/extension_service.h" 29 #include "chrome/browser/extensions/extension_service.h"
29 #include "chrome/browser/extensions/extension_tab_id_map.h" 30 #include "chrome/browser/extensions/extension_tab_id_map.h"
30 #include "chrome/browser/profiles/profile.h" 31 #include "chrome/browser/profiles/profile.h"
31 #include "chrome/browser/profiles/profile_manager.h" 32 #include "chrome/browser/profiles/profile_manager.h"
(...skipping 11 matching lines...) Expand all
43 #include "content/public/browser/render_process_host.h" 44 #include "content/public/browser/render_process_host.h"
44 #include "content/public/browser/resource_request_info.h" 45 #include "content/public/browser/resource_request_info.h"
45 #include "googleurl/src/gurl.h" 46 #include "googleurl/src/gurl.h"
46 #include "grit/generated_resources.h" 47 #include "grit/generated_resources.h"
47 #include "net/base/auth.h" 48 #include "net/base/auth.h"
48 #include "net/base/net_errors.h" 49 #include "net/base/net_errors.h"
49 #include "net/http/http_response_headers.h" 50 #include "net/http/http_response_headers.h"
50 #include "net/url_request/url_request.h" 51 #include "net/url_request/url_request.h"
51 #include "ui/base/l10n/l10n_util.h" 52 #include "ui/base/l10n/l10n_util.h"
52 53
54 using chrome::VersionInfo;
53 using content::BrowserMessageFilter; 55 using content::BrowserMessageFilter;
54 using content::BrowserThread; 56 using content::BrowserThread;
55 using content::ResourceRequestInfo; 57 using content::ResourceRequestInfo;
56 using extensions::Extension; 58 using extensions::Extension;
57 59
58 using extensions::web_navigation_api_helpers::GetFrameId; 60 using extensions::web_navigation_api_helpers::GetFrameId;
59 61
60 namespace helpers = extension_web_request_api_helpers; 62 namespace helpers = extension_web_request_api_helpers;
61 namespace keys = extension_web_request_api_constants; 63 namespace keys = extension_web_request_api_constants;
62 64
63 namespace { 65 namespace {
64 66
65 // List of all the webRequest events. 67 // List of all the webRequest events.
66 static const char* const kWebRequestEvents[] = { 68 static const char* const kWebRequestEvents[] = {
67 keys::kOnBeforeRedirect, 69 keys::kOnBeforeRedirect,
68 keys::kOnBeforeRequest, 70 keys::kOnBeforeRequest,
69 keys::kOnBeforeSendHeaders, 71 keys::kOnBeforeSendHeaders,
70 keys::kOnCompleted, 72 keys::kOnCompleted,
71 keys::kOnErrorOccurred, 73 keys::kOnErrorOccurred,
72 keys::kOnSendHeaders, 74 keys::kOnSendHeaders,
73 keys::kOnAuthRequired, 75 keys::kOnAuthRequired,
74 keys::kOnResponseStarted, 76 keys::kOnResponseStarted,
75 keys::kOnHeadersReceived, 77 keys::kOnHeadersReceived,
76 }; 78 };
77 79
78 #define ARRAYEND(array) (array + arraysize(array)) 80 #define ARRAYEND(array) (array + arraysize(array))
79 81
82 static bool g_channel_cached_ = false;
83 static VersionInfo::Channel g_channel_ = VersionInfo::CHANNEL_UNKNOWN;
84 static bool g_post_data_enabled_ = false;
wtc 2012/08/03 00:57:19 Nit: these three variables (and also the existing
vabr (Chromium) 2012/08/05 18:54:46 Done.
85
86 bool PostDataEnabledOnChannel() {
wtc 2012/08/03 00:57:19 Nit: This function operates on the global variable
vabr (Chromium) 2012/08/05 18:54:46 The function was removed in the meantime.
87 return g_channel_ == VersionInfo::CHANNEL_UNKNOWN ||
88 g_channel_ == VersionInfo::CHANNEL_CANARY ||
89 g_channel_ == VersionInfo::CHANNEL_DEV;
Matt Perry 2012/08/02 10:11:03 note: the channels go in increasing order of stabi
vabr (Chromium) 2012/08/05 18:54:46 Good to know! If that's the convention, then the t
90 }
91
92 // PostData feature (crbug.com/91191/) is currently only enabled in dev
93 // and canary channels. This function caches the release channel info from
94 // chrome::VersionInfo.
95 bool IsWebRequestPostDataEnabled() {
96 if (!g_channel_cached_) {
97 // Find out the correct channel and flip |g_post_data_enabled_| accordingly.
Matt Perry 2012/08/02 10:11:03 This comment is fairly obvious from the code. Take
vabr (Chromium) 2012/08/05 18:54:46 Comment removed.
98 g_channel_ = VersionInfo::GetChannel();
99 g_channel_cached_ = true;
100 g_post_data_enabled_ = PostDataEnabledOnChannel();
Matt Perry 2012/08/02 10:11:03 no need to cache this imo
wtc 2012/08/03 00:57:19 I agree that the result of PostDataEnabledOnChanne
vabr (Chromium) 2012/08/05 18:54:46 With switching to channel <= DEV instead of the th
101 }
102 return g_post_data_enabled_;
103 }
104
80 bool IsWebRequestEvent(const std::string& event_name) { 105 bool IsWebRequestEvent(const std::string& event_name) {
81 return std::find(kWebRequestEvents, ARRAYEND(kWebRequestEvents), 106 return std::find(kWebRequestEvents, ARRAYEND(kWebRequestEvents),
82 event_name) != ARRAYEND(kWebRequestEvents); 107 event_name) != ARRAYEND(kWebRequestEvents);
83 } 108 }
84 109
85 // Returns whether |request| has been triggered by an extension in 110 // Returns whether |request| has been triggered by an extension in
86 // |extension_info_map|. 111 // |extension_info_map|.
87 bool IsRequestFromExtension(const net::URLRequest* request, 112 bool IsRequestFromExtension(const net::URLRequest* request,
88 const ExtensionInfoMap* extension_info_map) { 113 const ExtensionInfoMap* extension_info_map) {
89 // |extension_info_map| is NULL for system-level requests. 114 // |extension_info_map| is NULL for system-level requests.
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 base::Uint64ToString(request->identifier())); 175 base::Uint64ToString(request->identifier()));
151 out->SetString(keys::kUrlKey, request->url().spec()); 176 out->SetString(keys::kUrlKey, request->url().spec());
152 out->SetString(keys::kMethodKey, request->method()); 177 out->SetString(keys::kMethodKey, request->method());
153 out->SetInteger(keys::kFrameIdKey, frame_id_for_extension); 178 out->SetInteger(keys::kFrameIdKey, frame_id_for_extension);
154 out->SetInteger(keys::kParentFrameIdKey, parent_frame_id_for_extension); 179 out->SetInteger(keys::kParentFrameIdKey, parent_frame_id_for_extension);
155 out->SetInteger(keys::kTabIdKey, tab_id); 180 out->SetInteger(keys::kTabIdKey, tab_id);
156 out->SetString(keys::kTypeKey, helpers::ResourceTypeToString(resource_type)); 181 out->SetString(keys::kTypeKey, helpers::ResourceTypeToString(resource_type));
157 out->SetDouble(keys::kTimeStampKey, base::Time::Now().ToDoubleT() * 1000); 182 out->SetDouble(keys::kTimeStampKey, base::Time::Now().ToDoubleT() * 1000);
158 } 183 }
159 184
185 // Extracts the POST data from |request| and writes the data into |out|.
186 // This can be expensive, so it's separated from ExtractRequestInfo().
187 void ExtractRequestInfoPost(const net::URLRequest* request,
188 DictionaryValue* out) {
189 if (request->method() != "POST")
190 return; // Need to exit without "out->Set(keys::kPostDataKey, ...);" .
191
192 DictionaryValue* post_data = new DictionaryValue();
193 out->Set(keys::kPostDataKey, post_data);
194
195 // Chunked encoding (defined in RFC 2616) is currently not supported.
196 std::string transfer_encoding;
197 if (request->extra_request_headers().GetHeader(
198 net::HttpRequestHeaders::kTransferEncoding, &transfer_encoding)) {
199 if (base::strcasecmp(transfer_encoding.c_str(), "chunked") == 0) {
200 post_data->SetString(keys::kPostDataErrorKey, "chunked_encoding");
201 return;
202 }
203 }
204
205 scoped_ptr<DictionaryValue> form_data =
206 extensions::PostDataParser::ParseURLRequestData(request);
207 if (form_data.get() != NULL)
208 post_data->Set(keys::kPostDataFormKey, form_data.release());
209 }
210
160 // Converts a HttpHeaders dictionary to a |name|, |value| pair. Returns 211 // Converts a HttpHeaders dictionary to a |name|, |value| pair. Returns
161 // true if successful. 212 // true if successful.
162 bool FromHeaderDictionary(const DictionaryValue* header_value, 213 bool FromHeaderDictionary(const DictionaryValue* header_value,
163 std::string* name, 214 std::string* name,
164 std::string* value) { 215 std::string* value) {
165 if (!header_value->GetString(keys::kHeaderNameKey, name)) 216 if (!header_value->GetString(keys::kHeaderNameKey, name))
166 return false; 217 return false;
167 218
168 // We require either a "value" or a "binaryValue" entry. 219 // We require either a "value" or a "binaryValue" entry.
169 if (!(header_value->HasKey(keys::kHeaderValueKey) ^ 220 if (!(header_value->HasKey(keys::kHeaderValueKey) ^
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 SendExtensionWebRequestStatusToHost(host); 295 SendExtensionWebRequestStatusToHost(host);
245 } 296 }
246 } 297 }
247 298
248 void ClearCacheOnNavigationOnUI() { 299 void ClearCacheOnNavigationOnUI() {
249 WebCacheManager::GetInstance()->ClearCacheOnNavigation(); 300 WebCacheManager::GetInstance()->ClearCacheOnNavigation();
250 } 301 }
251 302
252 } // namespace 303 } // namespace
253 304
305 // Sets the fake channel |c| and flips |g_post_data_enabled_| accordingly.
306 void SetChannelForTestingWebRequest(VersionInfo::Channel channel) {
wtc 2012/08/03 00:57:19 You name the argument |c| in the header file but n
vabr (Chromium) 2012/08/05 18:54:46 Header synced with implementation. Comment removed
307 g_channel_ = channel;
308 g_channel_cached_ = true;
309 g_post_data_enabled_ = PostDataEnabledOnChannel();
310 }
311
312 void ResetChannelForTestingWebRequest() {
313 g_channel_cached_ = false;
314 }
315
254 // Represents a single unique listener to an event, along with whatever filter 316 // Represents a single unique listener to an event, along with whatever filter
255 // parameters and extra_info_spec were specified at the time the listener was 317 // parameters and extra_info_spec were specified at the time the listener was
256 // added. 318 // added.
257 struct ExtensionWebRequestEventRouter::EventListener { 319 struct ExtensionWebRequestEventRouter::EventListener {
258 std::string extension_id; 320 std::string extension_id;
259 std::string extension_name; 321 std::string extension_name;
260 std::string sub_event_name; 322 std::string sub_event_name;
261 RequestFilter filter; 323 RequestFilter filter;
262 int extra_info_spec; 324 int extra_info_spec;
263 base::WeakPtr<IPC::Sender> ipc_sender; 325 base::WeakPtr<IPC::Sender> ipc_sender;
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 return false; 464 return false;
403 465
404 if (str == "requestHeaders") 466 if (str == "requestHeaders")
405 *extra_info_spec |= REQUEST_HEADERS; 467 *extra_info_spec |= REQUEST_HEADERS;
406 else if (str == "responseHeaders") 468 else if (str == "responseHeaders")
407 *extra_info_spec |= RESPONSE_HEADERS; 469 *extra_info_spec |= RESPONSE_HEADERS;
408 else if (str == "blocking") 470 else if (str == "blocking")
409 *extra_info_spec |= BLOCKING; 471 *extra_info_spec |= BLOCKING;
410 else if (str == "asyncBlocking") 472 else if (str == "asyncBlocking")
411 *extra_info_spec |= ASYNC_BLOCKING; 473 *extra_info_spec |= ASYNC_BLOCKING;
474 else if (str == "postData")
475 *extra_info_spec |= IsWebRequestPostDataEnabled() ? POST_DATA : 0;
412 else 476 else
413 return false; 477 return false;
414 478
415 // BLOCKING and ASYNC_BLOCKING are mutually exclusive. 479 // BLOCKING and ASYNC_BLOCKING are mutually exclusive.
416 if ((*extra_info_spec & BLOCKING) && (*extra_info_spec & ASYNC_BLOCKING)) 480 if ((*extra_info_spec & BLOCKING) && (*extra_info_spec & ASYNC_BLOCKING))
417 return false; 481 return false;
418 } 482 }
419 return true; 483 return true;
420 } 484 }
421 485
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 555
492 int extra_info_spec = 0; 556 int extra_info_spec = 0;
493 std::vector<const EventListener*> listeners = 557 std::vector<const EventListener*> listeners =
494 GetMatchingListeners(profile, extension_info_map, keys::kOnBeforeRequest, 558 GetMatchingListeners(profile, extension_info_map, keys::kOnBeforeRequest,
495 request, &extra_info_spec); 559 request, &extra_info_spec);
496 if (!listeners.empty() && 560 if (!listeners.empty() &&
497 !GetAndSetSignaled(request->identifier(), kOnBeforeRequest)) { 561 !GetAndSetSignaled(request->identifier(), kOnBeforeRequest)) {
498 ListValue args; 562 ListValue args;
499 DictionaryValue* dict = new DictionaryValue(); 563 DictionaryValue* dict = new DictionaryValue();
500 ExtractRequestInfo(request, dict); 564 ExtractRequestInfo(request, dict);
565 if (extra_info_spec & ExtraInfoSpec::POST_DATA)
566 ExtractRequestInfoPost(request, dict);
501 args.Append(dict); 567 args.Append(dict);
502 568
503 initialize_blocked_requests |= 569 initialize_blocked_requests |=
504 DispatchEvent(profile, request, listeners, args); 570 DispatchEvent(profile, request, listeners, args);
505 } 571 }
506 572
507 if (!initialize_blocked_requests) 573 if (!initialize_blocked_requests)
508 return net::OK; // Nobody saw a reason for modifying the request. 574 return net::OK; // Nobody saw a reason for modifying the request.
509 575
510 blocked_requests_[request->identifier()].event = kOnBeforeRequest; 576 blocked_requests_[request->identifier()].event = kOnBeforeRequest;
(...skipping 1309 matching lines...) Expand 10 before | Expand all | Expand 10 after
1820 } else if ((*it)->name().find("AdBlock") != std::string::npos) { 1886 } else if ((*it)->name().find("AdBlock") != std::string::npos) {
1821 adblock = true; 1887 adblock = true;
1822 } else { 1888 } else {
1823 other = true; 1889 other = true;
1824 } 1890 }
1825 } 1891 }
1826 } 1892 }
1827 1893
1828 host->Send(new ExtensionMsg_UsingWebRequestAPI(adblock, adblock_plus, other)); 1894 host->Send(new ExtensionMsg_UsingWebRequestAPI(adblock, adblock_plus, other));
1829 } 1895 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698