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

Side by Side Diff: chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc

Issue 11522009: X-Chrome-Variations logic refactoring (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Created 8 years 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 | Annotate | Revision Log
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/renderer_host/chrome_resource_dispatcher_host_delegate. h" 5 #include "chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate. h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/base64.h" 9 #include "base/base64.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "chrome/browser/browser_process.h" 11 #include "chrome/browser/browser_process.h"
12 #include "chrome/browser/chrome_metrics_helper.h"
12 #include "chrome/browser/content_settings/host_content_settings_map.h" 13 #include "chrome/browser/content_settings/host_content_settings_map.h"
13 #include "chrome/browser/download/download_request_limiter.h" 14 #include "chrome/browser/download/download_request_limiter.h"
14 #include "chrome/browser/download/download_resource_throttle.h" 15 #include "chrome/browser/download/download_resource_throttle.h"
15 #include "chrome/browser/download/download_util.h" 16 #include "chrome/browser/download/download_util.h"
16 #include "chrome/browser/extensions/user_script_listener.h" 17 #include "chrome/browser/extensions/user_script_listener.h"
17 #include "chrome/browser/external_protocol/external_protocol_handler.h" 18 #include "chrome/browser/external_protocol/external_protocol_handler.h"
18 #include "chrome/browser/google/google_util.h" 19 #include "chrome/browser/google/google_util.h"
19 #include "chrome/browser/net/load_timing_observer.h" 20 #include "chrome/browser/net/load_timing_observer.h"
20 #include "chrome/browser/net/resource_prefetch_predictor_observer.h" 21 #include "chrome/browser/net/resource_prefetch_predictor_observer.h"
21 #include "chrome/browser/prerender/prerender_manager.h" 22 #include "chrome/browser/prerender/prerender_manager.h"
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 content::NotificationService::NoDetails()); 81 content::NotificationService::NoDetails());
81 } 82 }
82 83
83 } // end namespace 84 } // end namespace
84 85
85 ChromeResourceDispatcherHostDelegate::ChromeResourceDispatcherHostDelegate( 86 ChromeResourceDispatcherHostDelegate::ChromeResourceDispatcherHostDelegate(
86 prerender::PrerenderTracker* prerender_tracker) 87 prerender::PrerenderTracker* prerender_tracker)
87 : download_request_limiter_(g_browser_process->download_request_limiter()), 88 : download_request_limiter_(g_browser_process->download_request_limiter()),
88 safe_browsing_(g_browser_process->safe_browsing_service()), 89 safe_browsing_(g_browser_process->safe_browsing_service()),
89 user_script_listener_(new extensions::UserScriptListener()), 90 user_script_listener_(new extensions::UserScriptListener()),
90 prerender_tracker_(prerender_tracker), 91 prerender_tracker_(prerender_tracker) {
91 variation_ids_cache_initialized_(false) {
92 } 92 }
93 93
94 ChromeResourceDispatcherHostDelegate::~ChromeResourceDispatcherHostDelegate() { 94 ChromeResourceDispatcherHostDelegate::~ChromeResourceDispatcherHostDelegate() {
95 } 95 }
96 96
97 bool ChromeResourceDispatcherHostDelegate::ShouldBeginRequest( 97 bool ChromeResourceDispatcherHostDelegate::ShouldBeginRequest(
98 int child_id, 98 int child_id,
99 int route_id, 99 int route_id,
100 const std::string& method, 100 const std::string& method,
101 const GURL& url, 101 const GURL& url,
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 #endif 157 #endif
158 #if defined(OS_CHROMEOS) 158 #if defined(OS_CHROMEOS)
159 if (resource_type == ResourceType::MAIN_FRAME) { 159 if (resource_type == ResourceType::MAIN_FRAME) {
160 // We check offline first, then check safe browsing so that we still can 160 // We check offline first, then check safe browsing so that we still can
161 // block unsafe site after we remove offline page. 161 // block unsafe site after we remove offline page.
162 throttles->push_back(new OfflineResourceThrottle( 162 throttles->push_back(new OfflineResourceThrottle(
163 child_id, route_id, request, appcache_service)); 163 child_id, route_id, request, appcache_service));
164 } 164 }
165 #endif 165 #endif
166 166
167 AppendChromeMetricsHeaders(request, resource_context, resource_type); 167 ChromeMetricsHelper::GetInstance()->AppendHeadersToRequest(request,
168 resource_context);
168 169
169 #if defined(ENABLE_ONE_CLICK_SIGNIN) 170 #if defined(ENABLE_ONE_CLICK_SIGNIN)
170 AppendChromeSyncGaiaHeader(request, resource_context); 171 AppendChromeSyncGaiaHeader(request, resource_context);
171 #endif 172 #endif
172 173
173 AppendStandardResourceThrottles(request, 174 AppendStandardResourceThrottles(request,
174 resource_context, 175 resource_context,
175 child_id, 176 child_id,
176 route_id, 177 route_id,
177 resource_type, 178 resource_type,
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 request, child_id, route_id, !is_subresource_request)); 306 request, child_id, route_id, !is_subresource_request));
306 #endif 307 #endif
307 308
308 content::ResourceThrottle* throttle = 309 content::ResourceThrottle* throttle =
309 user_script_listener_->CreateResourceThrottle(request->url(), 310 user_script_listener_->CreateResourceThrottle(request->url(),
310 resource_type); 311 resource_type);
311 if (throttle) 312 if (throttle)
312 throttles->push_back(throttle); 313 throttles->push_back(throttle);
313 } 314 }
314 315
315 void ChromeResourceDispatcherHostDelegate::AppendChromeMetricsHeaders(
316 net::URLRequest* request,
317 content::ResourceContext* resource_context,
318 ResourceType::Type resource_type) {
319 // Don't attempt to append headers to requests that have already started.
320 // TODO(stevet): Remove this once the request ordering issues are resolved
321 // in crbug.com/128048.
322 if (request->is_pending())
323 return;
324
325 // Note the criteria for attaching Chrome experiment headers:
326 // 1. We only transmit to *.google.<TLD> domains. NOTE that this use of
327 // google_util helpers to check this does not guarantee that the URL is
328 // Google-owned, only that it is of the form *.google.<TLD>. In the future
329 // we may choose to reinforce this check.
330 // 2. Only transmit for non-Incognito profiles.
331 // 3. For the X-Chrome-UMA-Enabled bit, only set it if UMA is in fact enabled
332 // for this install of Chrome.
333 // 4. For the X-Chrome-Variations, only include non-empty variation IDs.
334 ProfileIOData* io_data = ProfileIOData::FromResourceContext(resource_context);
335 if (io_data->is_incognito() ||
336 !google_util::IsGoogleDomainUrl(request->url().spec(),
337 google_util::ALLOW_SUBDOMAIN,
338 google_util::ALLOW_NON_STANDARD_PORTS))
339 return;
340
341 if (io_data->GetMetricsEnabledStateOnIOThread())
342 request->SetExtraRequestHeaderByName("X-Chrome-UMA-Enabled", "1", false);
343
344 // Lazily initialize the header, if not already done, before attempting to
345 // transmit it.
346 InitVariationIDsCacheIfNeeded();
347 if (!variation_ids_header_.empty()) {
348 request->SetExtraRequestHeaderByName("X-Chrome-Variations",
349 variation_ids_header_,
350 false);
351 }
352 }
353
354 #if defined(ENABLE_ONE_CLICK_SIGNIN) 316 #if defined(ENABLE_ONE_CLICK_SIGNIN)
355 void ChromeResourceDispatcherHostDelegate::AppendChromeSyncGaiaHeader( 317 void ChromeResourceDispatcherHostDelegate::AppendChromeSyncGaiaHeader(
356 net::URLRequest* request, 318 net::URLRequest* request,
357 content::ResourceContext* resource_context) { 319 content::ResourceContext* resource_context) {
358 static const char kAllowChromeSignIn[] = "Allow-Chrome-SignIn"; 320 static const char kAllowChromeSignIn[] = "Allow-Chrome-SignIn";
359 321
360 ProfileIOData* io_data = ProfileIOData::FromResourceContext(resource_context); 322 ProfileIOData* io_data = ProfileIOData::FromResourceContext(resource_context);
361 OneClickSigninHelper::Offer offer = 323 OneClickSigninHelper::Offer offer =
362 OneClickSigninHelper::CanOfferOnIOThread(request, io_data); 324 OneClickSigninHelper::CanOfferOnIOThread(request, io_data);
363 switch (offer) { 325 switch (offer) {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 OneClickSigninHelper::ShowInfoBarIfPossible(request, info->GetChildID(), 413 OneClickSigninHelper::ShowInfoBarIfPossible(request, info->GetChildID(),
452 info->GetRouteID()); 414 info->GetRouteID());
453 #endif 415 #endif
454 416
455 ProfileIOData* io_data = ProfileIOData::FromResourceContext(resource_context); 417 ProfileIOData* io_data = ProfileIOData::FromResourceContext(resource_context);
456 if (io_data->resource_prefetch_predictor_observer()) { 418 if (io_data->resource_prefetch_predictor_observer()) {
457 io_data->resource_prefetch_predictor_observer()->OnRequestRedirected( 419 io_data->resource_prefetch_predictor_observer()->OnRequestRedirected(
458 redirect_url, request); 420 redirect_url, request);
459 } 421 }
460 } 422 }
461
462 void ChromeResourceDispatcherHostDelegate::OnFieldTrialGroupFinalized(
463 const std::string& trial_name,
464 const std::string& group_name) {
465 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
466 chrome_variations::VariationID new_id =
467 chrome_variations::GetGoogleVariationID(
468 chrome_variations::GOOGLE_WEB_PROPERTIES, trial_name, group_name);
469 if (new_id == chrome_variations::kEmptyID)
470 return;
471 variation_ids_set_.insert(new_id);
472 UpdateVariationIDsHeaderValue();
473 }
474
475 void ChromeResourceDispatcherHostDelegate::InitVariationIDsCacheIfNeeded() {
476 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
477 if (variation_ids_cache_initialized_)
478 return;
479
480 // Register for additional cache updates. This is done first to avoid a race
481 // that could cause registered FieldTrials to be missed.
482 base::FieldTrialList::AddObserver(this);
483
484 base::FieldTrial::ActiveGroups initial_groups;
485 base::FieldTrialList::GetActiveFieldTrialGroups(&initial_groups);
486 for (base::FieldTrial::ActiveGroups::const_iterator it =
487 initial_groups.begin(); it != initial_groups.end(); ++it) {
488 const chrome_variations::VariationID id =
489 chrome_variations::GetGoogleVariationID(
490 chrome_variations::GOOGLE_WEB_PROPERTIES, it->trial_name,
491 it->group_name);
492 if (id != chrome_variations::kEmptyID)
493 variation_ids_set_.insert(id);
494 }
495 UpdateVariationIDsHeaderValue();
496
497 variation_ids_cache_initialized_ = true;
498 }
499
500 void ChromeResourceDispatcherHostDelegate::UpdateVariationIDsHeaderValue() {
501 // The header value is a serialized protobuffer of Variation IDs which is
502 // base64 encoded before transmitting as a string.
503 if (variation_ids_set_.empty())
504 return;
505
506 // This is the bottleneck for the creation of the header, so validate the size
507 // here. Force a hard maximum on the ID count in case the Variations server
508 // returns too many IDs and DOSs receiving servers with large requests.
509 DCHECK_LE(variation_ids_set_.size(), 10U);
510 if (variation_ids_set_.size() > 20) {
511 variation_ids_header_.clear();
512 return;
513 }
514
515 metrics::ChromeVariations proto;
516 for (std::set<chrome_variations::VariationID>::const_iterator it =
517 variation_ids_set_.begin(); it != variation_ids_set_.end(); ++it)
518 proto.add_variation_id(*it);
519
520 std::string serialized;
521 proto.SerializeToString(&serialized);
522
523 std::string hashed;
524 if (base::Base64Encode(serialized, &hashed)) {
525 // If successful, swap the header value with the new one.
526 // Note that the list of IDs and the header could be temporarily out of sync
527 // if IDs are added as the header is recreated. The receiving servers are OK
528 // with such descrepancies.
529 variation_ids_header_ = hashed;
530 } else {
531 DVLOG(1) << "Failed to base64 encode Variation IDs value: " << serialized;
532 }
533 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698