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

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: One more static RE2 object made non-static Created 8 years, 3 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/upload_data_presenter.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"
32 #include "chrome/browser/renderer_host/chrome_render_message_filter.h" 33 #include "chrome/browser/renderer_host/chrome_render_message_filter.h"
33 #include "chrome/browser/renderer_host/web_cache_manager.h" 34 #include "chrome/browser/renderer_host/web_cache_manager.h"
34 #include "chrome/common/extensions/api/web_request.h" 35 #include "chrome/common/extensions/api/web_request.h"
35 #include "chrome/common/extensions/event_filtering_info.h" 36 #include "chrome/common/extensions/event_filtering_info.h"
36 #include "chrome/common/extensions/extension.h" 37 #include "chrome/common/extensions/extension.h"
37 #include "chrome/common/extensions/extension_constants.h" 38 #include "chrome/common/extensions/extension_constants.h"
38 #include "chrome/common/extensions/extension_error_utils.h" 39 #include "chrome/common/extensions/extension_error_utils.h"
39 #include "chrome/common/extensions/extension_messages.h" 40 #include "chrome/common/extensions/extension_messages.h"
41 #include "chrome/common/extensions/features/feature.h"
40 #include "chrome/common/extensions/url_pattern.h" 42 #include "chrome/common/extensions/url_pattern.h"
41 #include "chrome/common/url_constants.h" 43 #include "chrome/common/url_constants.h"
42 #include "content/public/browser/browser_message_filter.h" 44 #include "content/public/browser/browser_message_filter.h"
43 #include "content/public/browser/browser_thread.h" 45 #include "content/public/browser/browser_thread.h"
44 #include "content/public/browser/render_process_host.h" 46 #include "content/public/browser/render_process_host.h"
45 #include "content/public/browser/resource_request_info.h" 47 #include "content/public/browser/resource_request_info.h"
46 #include "googleurl/src/gurl.h" 48 #include "googleurl/src/gurl.h"
47 #include "grit/generated_resources.h" 49 #include "grit/generated_resources.h"
48 #include "net/base/auth.h" 50 #include "net/base/auth.h"
49 #include "net/base/net_errors.h" 51 #include "net/base/net_errors.h"
52 #include "net/base/upload_data.h"
53 #include "net/base/upload_element.h"
50 #include "net/http/http_response_headers.h" 54 #include "net/http/http_response_headers.h"
51 #include "net/url_request/url_request.h" 55 #include "net/url_request/url_request.h"
52 #include "ui/base/l10n/l10n_util.h" 56 #include "ui/base/l10n/l10n_util.h"
53 57
58 using base::DictionaryValue;
59 using base::ListValue;
60 using base::StringValue;
61 using chrome::VersionInfo;
54 using content::BrowserMessageFilter; 62 using content::BrowserMessageFilter;
55 using content::BrowserThread; 63 using content::BrowserThread;
56 using content::ResourceRequestInfo; 64 using content::ResourceRequestInfo;
57 using extensions::Extension; 65 using extensions::Extension;
66 using extensions::Feature;
58 67
59 using extensions::web_navigation_api_helpers::GetFrameId; 68 using extensions::web_navigation_api_helpers::GetFrameId;
60 69
61 namespace helpers = extension_web_request_api_helpers; 70 namespace helpers = extension_web_request_api_helpers;
62 namespace keys = extension_web_request_api_constants; 71 namespace keys = extension_web_request_api_constants;
63 namespace web_request = extensions::api::web_request; 72 namespace web_request = extensions::api::web_request;
64 73
65 namespace { 74 namespace {
66 75
67 // List of all the webRequest events. 76 // List of all the webRequest events.
68 static const char* const kWebRequestEvents[] = { 77 const char* const kWebRequestEvents[] = {
69 keys::kOnBeforeRedirect, 78 keys::kOnBeforeRedirect,
70 keys::kOnBeforeRequest, 79 keys::kOnBeforeRequest,
71 keys::kOnBeforeSendHeaders, 80 keys::kOnBeforeSendHeaders,
72 keys::kOnCompleted, 81 keys::kOnCompleted,
73 keys::kOnErrorOccurred, 82 keys::kOnErrorOccurred,
74 keys::kOnSendHeaders, 83 keys::kOnSendHeaders,
75 keys::kOnAuthRequired, 84 keys::kOnAuthRequired,
76 keys::kOnResponseStarted, 85 keys::kOnResponseStarted,
77 keys::kOnHeadersReceived, 86 keys::kOnHeadersReceived,
78 }; 87 };
79 88
80 #define ARRAYEND(array) (array + arraysize(array)) 89 #define ARRAYEND(array) (array + arraysize(array))
81 90
91 // Access to request body (crbug.com/91191/) is currently only enabled in dev
92 // and canary channels. This function caches the release channel info from
93 // chrome::VersionInfo. Don't use this outside IO thread.
94 bool IsWebRequestBodyDataAccessEnabled() {
95 return Feature::GetCurrentChannel() <= VersionInfo::CHANNEL_DEV;
96 }
97
82 bool IsWebRequestEvent(const std::string& event_name) { 98 bool IsWebRequestEvent(const std::string& event_name) {
83 return std::find(kWebRequestEvents, ARRAYEND(kWebRequestEvents), 99 return std::find(kWebRequestEvents, ARRAYEND(kWebRequestEvents),
84 event_name) != ARRAYEND(kWebRequestEvents); 100 event_name) != ARRAYEND(kWebRequestEvents);
85 } 101 }
86 102
87 // Returns whether |request| has been triggered by an extension in 103 // Returns whether |request| has been triggered by an extension in
88 // |extension_info_map|. 104 // |extension_info_map|.
89 bool IsRequestFromExtension(const net::URLRequest* request, 105 bool IsRequestFromExtension(const net::URLRequest* request,
90 const ExtensionInfoMap* extension_info_map) { 106 const ExtensionInfoMap* extension_info_map) {
91 // |extension_info_map| is NULL for system-level requests. 107 // |extension_info_map| is NULL for system-level requests.
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 base::Uint64ToString(request->identifier())); 168 base::Uint64ToString(request->identifier()));
153 out->SetString(keys::kUrlKey, request->url().spec()); 169 out->SetString(keys::kUrlKey, request->url().spec());
154 out->SetString(keys::kMethodKey, request->method()); 170 out->SetString(keys::kMethodKey, request->method());
155 out->SetInteger(keys::kFrameIdKey, frame_id_for_extension); 171 out->SetInteger(keys::kFrameIdKey, frame_id_for_extension);
156 out->SetInteger(keys::kParentFrameIdKey, parent_frame_id_for_extension); 172 out->SetInteger(keys::kParentFrameIdKey, parent_frame_id_for_extension);
157 out->SetInteger(keys::kTabIdKey, tab_id); 173 out->SetInteger(keys::kTabIdKey, tab_id);
158 out->SetString(keys::kTypeKey, helpers::ResourceTypeToString(resource_type)); 174 out->SetString(keys::kTypeKey, helpers::ResourceTypeToString(resource_type));
159 out->SetDouble(keys::kTimeStampKey, base::Time::Now().ToDoubleT() * 1000); 175 out->SetDouble(keys::kTimeStampKey, base::Time::Now().ToDoubleT() * 1000);
160 } 176 }
161 177
178 // Extracts the body from |request| and writes the data into |out|.
179 void ExtractRequestInfoBody(const net::URLRequest* request,
180 DictionaryValue* out) {
181 if (request->method() != "POST" && request->method() != "PUT")
182 return; // Need to exit without "out->Set(keys::kRequestBodyKey, ...);" .
183
184 DictionaryValue* requestBody = new DictionaryValue();
185 out->Set(keys::kRequestBodyKey, requestBody);
186
187 // Get the data presenters, ordered by being interesting.
188 extensions::RawDataPresenter raw_data_presenter;
189 extensions::ParsedDataPresenter parsed_data_presenter(request);
190 extensions::UploadDataPresenter* const presenters[] = {
191 &parsed_data_presenter, // Second -- any parseable forms?
192 &raw_data_presenter // Third -- any data at all?
193 };
194 // Keys for the results of the corresponding presenters.
195 static const char* const kKeys[] = {
196 keys::kRequestBodyFormDataKey,
197 keys::kRequestBodyRawKey
198 };
199
200 const std::vector<net::UploadElement>* elements =
201 request->get_upload()->elements();
202 bool some_succeeded = false;
203 for (size_t i = 0; !some_succeeded && i < arraysize(presenters); ++i) {
204 std::vector<net::UploadElement>::const_iterator element;
205 for (element = elements->begin(); element != elements->end(); ++element)
206 presenters[i]->FeedNext(*element);
207 if (presenters[i]->Succeeded()) {
208 requestBody->Set(kKeys[i], presenters[i]->Result().release());
209 some_succeeded = true;
210 }
211 }
212 if (!some_succeeded)
213 requestBody->SetString(keys::kRequestBodyErrorKey, "Unknown error.");
214 }
215
162 // Converts a HttpHeaders dictionary to a |name|, |value| pair. Returns 216 // Converts a HttpHeaders dictionary to a |name|, |value| pair. Returns
163 // true if successful. 217 // true if successful.
164 bool FromHeaderDictionary(const DictionaryValue* header_value, 218 bool FromHeaderDictionary(const DictionaryValue* header_value,
165 std::string* name, 219 std::string* name,
166 std::string* value) { 220 std::string* value) {
167 if (!header_value->GetString(keys::kHeaderNameKey, name)) 221 if (!header_value->GetString(keys::kHeaderNameKey, name))
168 return false; 222 return false;
169 223
170 // We require either a "value" or a "binaryValue" entry. 224 // We require either a "value" or a "binaryValue" entry.
171 if (!(header_value->HasKey(keys::kHeaderValueKey) ^ 225 if (!(header_value->HasKey(keys::kHeaderValueKey) ^
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 return false; 458 return false;
405 459
406 if (str == "requestHeaders") 460 if (str == "requestHeaders")
407 *extra_info_spec |= REQUEST_HEADERS; 461 *extra_info_spec |= REQUEST_HEADERS;
408 else if (str == "responseHeaders") 462 else if (str == "responseHeaders")
409 *extra_info_spec |= RESPONSE_HEADERS; 463 *extra_info_spec |= RESPONSE_HEADERS;
410 else if (str == "blocking") 464 else if (str == "blocking")
411 *extra_info_spec |= BLOCKING; 465 *extra_info_spec |= BLOCKING;
412 else if (str == "asyncBlocking") 466 else if (str == "asyncBlocking")
413 *extra_info_spec |= ASYNC_BLOCKING; 467 *extra_info_spec |= ASYNC_BLOCKING;
468 else if (str == "requestBody")
469 *extra_info_spec |=
470 IsWebRequestBodyDataAccessEnabled() ? REQUEST_BODY : 0;
414 else 471 else
415 return false; 472 return false;
416 473
417 // BLOCKING and ASYNC_BLOCKING are mutually exclusive. 474 // BLOCKING and ASYNC_BLOCKING are mutually exclusive.
418 if ((*extra_info_spec & BLOCKING) && (*extra_info_spec & ASYNC_BLOCKING)) 475 if ((*extra_info_spec & BLOCKING) && (*extra_info_spec & ASYNC_BLOCKING))
419 return false; 476 return false;
420 } 477 }
421 return true; 478 return true;
422 } 479 }
423 480
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 551
495 int extra_info_spec = 0; 552 int extra_info_spec = 0;
496 std::vector<const EventListener*> listeners = 553 std::vector<const EventListener*> listeners =
497 GetMatchingListeners(profile, extension_info_map, keys::kOnBeforeRequest, 554 GetMatchingListeners(profile, extension_info_map, keys::kOnBeforeRequest,
498 request, &extra_info_spec); 555 request, &extra_info_spec);
499 if (!listeners.empty() && 556 if (!listeners.empty() &&
500 !GetAndSetSignaled(request->identifier(), kOnBeforeRequest)) { 557 !GetAndSetSignaled(request->identifier(), kOnBeforeRequest)) {
501 ListValue args; 558 ListValue args;
502 DictionaryValue* dict = new DictionaryValue(); 559 DictionaryValue* dict = new DictionaryValue();
503 ExtractRequestInfo(request, dict); 560 ExtractRequestInfo(request, dict);
561 if (extra_info_spec & ExtraInfoSpec::REQUEST_BODY)
562 ExtractRequestInfoBody(request, dict);
504 args.Append(dict); 563 args.Append(dict);
505 564
506 initialize_blocked_requests |= 565 initialize_blocked_requests |=
507 DispatchEvent(profile, request, listeners, args); 566 DispatchEvent(profile, request, listeners, args);
508 } 567 }
509 568
510 if (!initialize_blocked_requests) 569 if (!initialize_blocked_requests)
511 return net::OK; // Nobody saw a reason for modifying the request. 570 return net::OK; // Nobody saw a reason for modifying the request.
512 571
513 blocked_requests_[request->identifier()].event = kOnBeforeRequest; 572 blocked_requests_[request->identifier()].event = kOnBeforeRequest;
(...skipping 1334 matching lines...) Expand 10 before | Expand all | Expand 10 after
1848 } else if ((*it)->name().find("AdBlock") != std::string::npos) { 1907 } else if ((*it)->name().find("AdBlock") != std::string::npos) {
1849 adblock = true; 1908 adblock = true;
1850 } else { 1909 } else {
1851 other = true; 1910 other = true;
1852 } 1911 }
1853 } 1912 }
1854 } 1913 }
1855 1914
1856 host->Send(new ExtensionMsg_UsingWebRequestAPI(adblock, adblock_plus, other)); 1915 host->Send(new ExtensionMsg_UsingWebRequestAPI(adblock, adblock_plus, other));
1857 } 1916 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698