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

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

Issue 154473002: Support redirectUrl at onHeadersReceived in WebRequest / DWR API (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix WebRequestRulesRegistrySimpleTest.StageChecker test Created 6 years, 9 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_helpers.h" 5 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_number_conversions.h"
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 } 317 }
318 } 318 }
319 } 319 }
320 return result; 320 return result;
321 } 321 }
322 322
323 EventResponseDelta* CalculateOnHeadersReceivedDelta( 323 EventResponseDelta* CalculateOnHeadersReceivedDelta(
324 const std::string& extension_id, 324 const std::string& extension_id,
325 const base::Time& extension_install_time, 325 const base::Time& extension_install_time,
326 bool cancel, 326 bool cancel,
327 const GURL& new_url,
327 const net::HttpResponseHeaders* old_response_headers, 328 const net::HttpResponseHeaders* old_response_headers,
328 ResponseHeaders* new_response_headers) { 329 ResponseHeaders* new_response_headers) {
329 EventResponseDelta* result = 330 EventResponseDelta* result =
330 new EventResponseDelta(extension_id, extension_install_time); 331 new EventResponseDelta(extension_id, extension_install_time);
331 result->cancel = cancel; 332 result->cancel = cancel;
333 result->new_url = new_url;
332 334
333 if (!new_response_headers) 335 if (!new_response_headers)
334 return result; 336 return result;
335 337
336 // Find deleted headers (header keys are treated case insensitively). 338 // Find deleted headers (header keys are treated case insensitively).
337 { 339 {
338 void* iter = NULL; 340 void* iter = NULL;
339 std::string name; 341 std::string name;
340 std::string value; 342 std::string value;
341 while (old_response_headers->EnumerateHeaderLines(&iter, &name, &value)) { 343 while (old_response_headers->EnumerateHeaderLines(&iter, &name, &value)) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 if ((*i)->cancel) { 398 if ((*i)->cancel) {
397 *canceled = true; 399 *canceled = true;
398 net_log->AddEvent( 400 net_log->AddEvent(
399 net::NetLog::TYPE_CHROME_EXTENSION_ABORTED_REQUEST, 401 net::NetLog::TYPE_CHROME_EXTENSION_ABORTED_REQUEST,
400 CreateNetLogExtensionIdCallback(i->get())); 402 CreateNetLogExtensionIdCallback(i->get()));
401 break; 403 break;
402 } 404 }
403 } 405 }
404 } 406 }
405 407
406 // Helper function for MergeOnBeforeRequestResponses() that allows ignoring 408 // Helper function for MergeRedirectUrlOfResponses() that allows ignoring
407 // all redirects but those to data:// urls and about:blank. This is important 409 // all redirects but those to data:// urls and about:blank. This is important
408 // to treat these URLs as "cancel urls", i.e. URLs that extensions redirect 410 // to treat these URLs as "cancel urls", i.e. URLs that extensions redirect
409 // to if they want to express that they want to cancel a request. This reduces 411 // to if they want to express that they want to cancel a request. This reduces
410 // the number of conflicts that we need to flag, as canceling is considered 412 // the number of conflicts that we need to flag, as canceling is considered
411 // a higher precedence operation that redirects. 413 // a higher precedence operation that redirects.
412 // Returns whether a redirect occurred. 414 // Returns whether a redirect occurred.
413 static bool MergeOnBeforeRequestResponsesHelper( 415 static bool MergeRedirectUrlOfResponsesHelper(
414 const EventResponseDeltas& deltas, 416 const EventResponseDeltas& deltas,
415 GURL* new_url, 417 GURL* new_url,
416 extensions::ExtensionWarningSet* conflicting_extensions, 418 extensions::ExtensionWarningSet* conflicting_extensions,
417 const net::BoundNetLog* net_log, 419 const net::BoundNetLog* net_log,
418 bool consider_only_cancel_scheme_urls) { 420 bool consider_only_cancel_scheme_urls) {
419 bool redirected = false; 421 bool redirected = false;
420 422
421 // Extension that determines the |new_url|. 423 // Extension that determines the |new_url|.
422 std::string winning_extension_id; 424 std::string winning_extension_id;
423 EventResponseDeltas::const_iterator delta; 425 EventResponseDeltas::const_iterator delta;
(...skipping 21 matching lines...) Expand all
445 (*delta)->new_url, 447 (*delta)->new_url,
446 *new_url)); 448 *new_url));
447 net_log->AddEvent( 449 net_log->AddEvent(
448 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, 450 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT,
449 CreateNetLogExtensionIdCallback(delta->get())); 451 CreateNetLogExtensionIdCallback(delta->get()));
450 } 452 }
451 } 453 }
452 return redirected; 454 return redirected;
453 } 455 }
454 456
455 void MergeOnBeforeRequestResponses( 457 void MergeRedirectUrlOfResponses(
456 const EventResponseDeltas& deltas, 458 const EventResponseDeltas& deltas,
457 GURL* new_url, 459 GURL* new_url,
458 extensions::ExtensionWarningSet* conflicting_extensions, 460 extensions::ExtensionWarningSet* conflicting_extensions,
459 const net::BoundNetLog* net_log) { 461 const net::BoundNetLog* net_log) {
460 462
461 // First handle only redirects to data:// URLs and about:blank. These are a 463 // First handle only redirects to data:// URLs and about:blank. These are a
462 // special case as they represent a way of cancelling a request. 464 // special case as they represent a way of cancelling a request.
463 if (MergeOnBeforeRequestResponsesHelper( 465 if (MergeRedirectUrlOfResponsesHelper(
464 deltas, new_url, conflicting_extensions, net_log, true)) { 466 deltas, new_url, conflicting_extensions, net_log, true)) {
465 // If any extension cancelled a request by redirecting to a data:// URL or 467 // If any extension cancelled a request by redirecting to a data:// URL or
466 // about:blank, we don't consider the other redirects. 468 // about:blank, we don't consider the other redirects.
467 return; 469 return;
468 } 470 }
469 471
470 // Handle all other redirects. 472 // Handle all other redirects.
471 MergeOnBeforeRequestResponsesHelper( 473 MergeRedirectUrlOfResponsesHelper(
472 deltas, new_url, conflicting_extensions, net_log, false); 474 deltas, new_url, conflicting_extensions, net_log, false);
473 } 475 }
474 476
477 void MergeOnBeforeRequestResponses(
478 const EventResponseDeltas& deltas,
479 GURL* new_url,
480 extensions::ExtensionWarningSet* conflicting_extensions,
481 const net::BoundNetLog* net_log) {
482 MergeRedirectUrlOfResponses(deltas, new_url, conflicting_extensions, net_log);
483 }
484
475 // Assumes that |header_value| is the cookie header value of a HTTP Request 485 // Assumes that |header_value| is the cookie header value of a HTTP Request
476 // following the cookie-string schema of RFC 6265, section 4.2.1, and returns 486 // following the cookie-string schema of RFC 6265, section 4.2.1, and returns
477 // cookie name/value pairs. If cookie values are presented in double quotes, 487 // cookie name/value pairs. If cookie values are presented in double quotes,
478 // these will appear in |parsed| as well. We can assume that the cookie header 488 // these will appear in |parsed| as well. We can assume that the cookie header
479 // is written by Chromium and therefore, well-formed. 489 // is written by Chromium and therefore, well-formed.
480 static void ParseRequestCookieLine( 490 static void ParseRequestCookieLine(
481 const std::string& header_value, 491 const std::string& header_value,
482 ParsedRequestCookies* parsed_cookies) { 492 ParsedRequestCookies* parsed_cookies) {
483 std::string::const_iterator i = header_value.begin(); 493 std::string::const_iterator i = header_value.begin();
484 while (i != header_value.end()) { 494 while (i != header_value.end()) {
(...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after
1093 return (*delta)->extension_id; 1103 return (*delta)->extension_id;
1094 } 1104 }
1095 } 1105 }
1096 return std::string(); 1106 return std::string();
1097 } 1107 }
1098 1108
1099 void MergeOnHeadersReceivedResponses( 1109 void MergeOnHeadersReceivedResponses(
1100 const EventResponseDeltas& deltas, 1110 const EventResponseDeltas& deltas,
1101 const net::HttpResponseHeaders* original_response_headers, 1111 const net::HttpResponseHeaders* original_response_headers,
1102 scoped_refptr<net::HttpResponseHeaders>* override_response_headers, 1112 scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
1113 GURL* allowed_unsafe_redirect_url,
1103 extensions::ExtensionWarningSet* conflicting_extensions, 1114 extensions::ExtensionWarningSet* conflicting_extensions,
1104 const net::BoundNetLog* net_log) { 1115 const net::BoundNetLog* net_log) {
1105 EventResponseDeltas::const_iterator delta; 1116 EventResponseDeltas::const_iterator delta;
1106 1117
1107 // Here we collect which headers we have removed or added so far due to 1118 // Here we collect which headers we have removed or added so far due to
1108 // extensions of higher precedence. Header keys are always stored as 1119 // extensions of higher precedence. Header keys are always stored as
1109 // lower case. 1120 // lower case.
1110 std::set<ResponseHeader> removed_headers; 1121 std::set<ResponseHeader> removed_headers;
1111 std::set<ResponseHeader> added_headers; 1122 std::set<ResponseHeader> added_headers;
1112 1123
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1174 (*delta)->extension_id, winning_extension_id, 1185 (*delta)->extension_id, winning_extension_id,
1175 conflicting_header)); 1186 conflicting_header));
1176 net_log->AddEvent( 1187 net_log->AddEvent(
1177 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, 1188 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT,
1178 CreateNetLogExtensionIdCallback(delta->get())); 1189 CreateNetLogExtensionIdCallback(delta->get()));
1179 } 1190 }
1180 } 1191 }
1181 1192
1182 MergeCookiesInOnHeadersReceivedResponses(deltas, original_response_headers, 1193 MergeCookiesInOnHeadersReceivedResponses(deltas, original_response_headers,
1183 override_response_headers, conflicting_extensions, net_log); 1194 override_response_headers, conflicting_extensions, net_log);
1195
1196 GURL new_url;
1197 MergeRedirectUrlOfResponses(
1198 deltas, &new_url, conflicting_extensions, net_log);
1199 if (new_url.is_valid()) {
1200 // Only create a copy if we really want to modify the response headers.
1201 if (override_response_headers->get() == NULL) {
1202 *override_response_headers = new net::HttpResponseHeaders(
1203 original_response_headers->raw_headers());
1204 }
1205 (*override_response_headers)->ReplaceStatusLine("HTTP/1.1 302 Found");
1206 (*override_response_headers)->RemoveHeader("location");
1207 (*override_response_headers)->AddHeader("Location: " + new_url.spec());
1208 // Explicitly mark the URL as safe for redirection, to prevent the request
1209 // from being blocked because of net::ERR_UNSAFE_REDIRECT.
1210 *allowed_unsafe_redirect_url = new_url;
1211 }
1184 } 1212 }
1185 1213
1186 bool MergeOnAuthRequiredResponses( 1214 bool MergeOnAuthRequiredResponses(
1187 const EventResponseDeltas& deltas, 1215 const EventResponseDeltas& deltas,
1188 net::AuthCredentials* auth_credentials, 1216 net::AuthCredentials* auth_credentials,
1189 extensions::ExtensionWarningSet* conflicting_extensions, 1217 extensions::ExtensionWarningSet* conflicting_extensions,
1190 const net::BoundNetLog* net_log) { 1218 const net::BoundNetLog* net_log) {
1191 CHECK(auth_credentials); 1219 CHECK(auth_credentials);
1192 bool credentials_set = false; 1220 bool credentials_set = false;
1193 std::string winning_extension_id; 1221 std::string winning_extension_id;
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1286 return net::HttpUtil::IsToken(name); 1314 return net::HttpUtil::IsToken(name);
1287 } 1315 }
1288 1316
1289 bool IsValidHeaderValue(const std::string& value) { 1317 bool IsValidHeaderValue(const std::string& value) {
1290 // Just a sanity check: disallow NUL and CRLF. 1318 // Just a sanity check: disallow NUL and CRLF.
1291 return value.find('\0') == std::string::npos && 1319 return value.find('\0') == std::string::npos &&
1292 value.find("\r\n") == std::string::npos; 1320 value.find("\r\n") == std::string::npos;
1293 } 1321 }
1294 1322
1295 } // namespace extension_web_request_api_helpers 1323 } // namespace extension_web_request_api_helpers
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698