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

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: Merged with head. 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"
22 #include "chrome/browser/prerender/prerender_tracker.h" 23 #include "chrome/browser/prerender/prerender_tracker.h"
23 #include "chrome/browser/prerender/prerender_util.h" 24 #include "chrome/browser/prerender/prerender_util.h"
24 #include "chrome/browser/profiles/profile_io_data.h" 25 #include "chrome/browser/profiles/profile_io_data.h"
25 #include "chrome/browser/renderer_host/chrome_url_request_user_data.h" 26 #include "chrome/browser/renderer_host/chrome_url_request_user_data.h"
26 #include "chrome/browser/renderer_host/safe_browsing_resource_throttle_factory.h " 27 #include "chrome/browser/renderer_host/safe_browsing_resource_throttle_factory.h "
27 #include "chrome/browser/safe_browsing/safe_browsing_service.h" 28 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
28 #include "chrome/browser/ui/auto_login_prompter.h" 29 #include "chrome/browser/ui/auto_login_prompter.h"
29 #include "chrome/browser/ui/login/login_prompt.h" 30 #include "chrome/browser/ui/login/login_prompt.h"
30 #include "chrome/browser/ui/sync/one_click_signin_helper.h" 31 #include "chrome/browser/ui/sync/one_click_signin_helper.h"
31 #include "chrome/common/chrome_notification_types.h" 32 #include "chrome/common/chrome_notification_types.h"
32 #include "chrome/common/extensions/extension_constants.h" 33 #include "chrome/common/extensions/extension_constants.h"
33 #include "chrome/common/extensions/user_script.h" 34 #include "chrome/common/extensions/user_script.h"
34 #include "chrome/common/metrics/variations/variations_util.h"
35 #include "chrome/common/metrics/proto/chrome_experiments.pb.h"
36 #include "chrome/common/render_messages.h" 35 #include "chrome/common/render_messages.h"
37 #include "content/public/browser/browser_thread.h" 36 #include "content/public/browser/browser_thread.h"
38 #include "content/public/browser/notification_service.h" 37 #include "content/public/browser/notification_service.h"
39 #include "content/public/browser/render_view_host.h" 38 #include "content/public/browser/render_view_host.h"
40 #include "content/public/browser/resource_context.h" 39 #include "content/public/browser/resource_context.h"
41 #include "content/public/browser/resource_dispatcher_host.h" 40 #include "content/public/browser/resource_dispatcher_host.h"
42 #include "content/public/browser/resource_request_info.h" 41 #include "content/public/browser/resource_request_info.h"
43 #include "net/base/load_flags.h" 42 #include "net/base/load_flags.h"
44 #include "net/base/ssl_config_service.h" 43 #include "net/base/ssl_config_service.h"
45 #include "net/http/http_response_headers.h" 44 #include "net/http/http_response_headers.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 content::NotificationService::NoDetails()); 80 content::NotificationService::NoDetails());
82 } 81 }
83 82
84 } // end namespace 83 } // end namespace
85 84
86 ChromeResourceDispatcherHostDelegate::ChromeResourceDispatcherHostDelegate( 85 ChromeResourceDispatcherHostDelegate::ChromeResourceDispatcherHostDelegate(
87 prerender::PrerenderTracker* prerender_tracker) 86 prerender::PrerenderTracker* prerender_tracker)
88 : download_request_limiter_(g_browser_process->download_request_limiter()), 87 : download_request_limiter_(g_browser_process->download_request_limiter()),
89 safe_browsing_(g_browser_process->safe_browsing_service()), 88 safe_browsing_(g_browser_process->safe_browsing_service()),
90 user_script_listener_(new extensions::UserScriptListener()), 89 user_script_listener_(new extensions::UserScriptListener()),
91 prerender_tracker_(prerender_tracker), 90 prerender_tracker_(prerender_tracker) {
92 variation_ids_cache_initialized_(false) {
93 } 91 }
94 92
95 ChromeResourceDispatcherHostDelegate::~ChromeResourceDispatcherHostDelegate() { 93 ChromeResourceDispatcherHostDelegate::~ChromeResourceDispatcherHostDelegate() {
96 } 94 }
97 95
98 bool ChromeResourceDispatcherHostDelegate::ShouldBeginRequest( 96 bool ChromeResourceDispatcherHostDelegate::ShouldBeginRequest(
99 int child_id, 97 int child_id,
100 int route_id, 98 int route_id,
101 const std::string& method, 99 const std::string& method,
102 const GURL& url, 100 const GURL& url,
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 #endif 156 #endif
159 #if defined(OS_CHROMEOS) 157 #if defined(OS_CHROMEOS)
160 if (resource_type == ResourceType::MAIN_FRAME) { 158 if (resource_type == ResourceType::MAIN_FRAME) {
161 // We check offline first, then check safe browsing so that we still can 159 // We check offline first, then check safe browsing so that we still can
162 // block unsafe site after we remove offline page. 160 // block unsafe site after we remove offline page.
163 throttles->push_back(new OfflineResourceThrottle( 161 throttles->push_back(new OfflineResourceThrottle(
164 child_id, route_id, request, appcache_service)); 162 child_id, route_id, request, appcache_service));
165 } 163 }
166 #endif 164 #endif
167 165
168 AppendChromeMetricsHeaders(request, resource_context, resource_type); 166 // Don't attempt to append headers to requests that have already started.
167 // TODO(stevet): Remove this once the request ordering issues are resolved
168 // in crbug.com/128048.
169 if (!request->is_pending()) {
170 net::HttpRequestHeaders headers;
171 headers.CopyFrom(request->extra_request_headers());
172 ProfileIOData* io_data = ProfileIOData::FromResourceContext(
173 resource_context);
174 bool incognito = io_data->is_incognito();
175 ChromeMetricsHelper::GetInstance()->AppendHeaders(
176 request->url(), incognito,
177 !incognito && io_data->GetMetricsEnabledStateOnIOThread(), &headers);
178 request->SetExtraRequestHeaders(headers);
179 }
169 180
170 #if defined(ENABLE_ONE_CLICK_SIGNIN) 181 #if defined(ENABLE_ONE_CLICK_SIGNIN)
171 AppendChromeSyncGaiaHeader(request, resource_context); 182 AppendChromeSyncGaiaHeader(request, resource_context);
172 #endif 183 #endif
173 184
174 AppendStandardResourceThrottles(request, 185 AppendStandardResourceThrottles(request,
175 resource_context, 186 resource_context,
176 child_id, 187 child_id,
177 route_id, 188 route_id,
178 resource_type, 189 resource_type,
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 request, child_id, route_id, !is_subresource_request)); 317 request, child_id, route_id, !is_subresource_request));
307 #endif 318 #endif
308 319
309 content::ResourceThrottle* throttle = 320 content::ResourceThrottle* throttle =
310 user_script_listener_->CreateResourceThrottle(request->url(), 321 user_script_listener_->CreateResourceThrottle(request->url(),
311 resource_type); 322 resource_type);
312 if (throttle) 323 if (throttle)
313 throttles->push_back(throttle); 324 throttles->push_back(throttle);
314 } 325 }
315 326
316 void ChromeResourceDispatcherHostDelegate::AppendChromeMetricsHeaders(
317 net::URLRequest* request,
318 content::ResourceContext* resource_context,
319 ResourceType::Type resource_type) {
320 // Don't attempt to append headers to requests that have already started.
321 // TODO(stevet): Remove this once the request ordering issues are resolved
322 // in crbug.com/128048.
323 if (request->is_pending())
324 return;
325
326 // Note the criteria for attaching Chrome experiment headers:
327 // 1. We only transmit to *.google.<TLD> domains. NOTE that this use of
328 // google_util helpers to check this does not guarantee that the URL is
329 // Google-owned, only that it is of the form *.google.<TLD>. In the future
330 // we may choose to reinforce this check.
331 // 2. Only transmit for non-Incognito profiles.
332 // 3. For the X-Chrome-UMA-Enabled bit, only set it if UMA is in fact enabled
333 // for this install of Chrome.
334 // 4. For the X-Chrome-Variations, only include non-empty variation IDs.
335 ProfileIOData* io_data = ProfileIOData::FromResourceContext(resource_context);
336 if (io_data->is_incognito() ||
337 !google_util::IsGoogleDomainUrl(request->url().spec(),
338 google_util::ALLOW_SUBDOMAIN,
339 google_util::ALLOW_NON_STANDARD_PORTS))
340 return;
341
342 if (io_data->GetMetricsEnabledStateOnIOThread())
343 request->SetExtraRequestHeaderByName("X-Chrome-UMA-Enabled", "1", false);
344
345 // Lazily initialize the header, if not already done, before attempting to
346 // transmit it.
347 InitVariationIDsCacheIfNeeded();
348 if (!variation_ids_header_.empty()) {
349 request->SetExtraRequestHeaderByName("X-Chrome-Variations",
350 variation_ids_header_,
351 false);
352 }
353 }
354
355 #if defined(ENABLE_ONE_CLICK_SIGNIN) 327 #if defined(ENABLE_ONE_CLICK_SIGNIN)
356 void ChromeResourceDispatcherHostDelegate::AppendChromeSyncGaiaHeader( 328 void ChromeResourceDispatcherHostDelegate::AppendChromeSyncGaiaHeader(
357 net::URLRequest* request, 329 net::URLRequest* request,
358 content::ResourceContext* resource_context) { 330 content::ResourceContext* resource_context) {
359 static const char kAllowChromeSignIn[] = "Allow-Chrome-SignIn"; 331 static const char kAllowChromeSignIn[] = "Allow-Chrome-SignIn";
360 332
361 ProfileIOData* io_data = ProfileIOData::FromResourceContext(resource_context); 333 ProfileIOData* io_data = ProfileIOData::FromResourceContext(resource_context);
362 OneClickSigninHelper::Offer offer = 334 OneClickSigninHelper::Offer offer =
363 OneClickSigninHelper::CanOfferOnIOThread(request, io_data); 335 OneClickSigninHelper::CanOfferOnIOThread(request, io_data);
364 switch (offer) { 336 switch (offer) {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 OneClickSigninHelper::ShowInfoBarIfPossible(request, info->GetChildID(), 426 OneClickSigninHelper::ShowInfoBarIfPossible(request, info->GetChildID(),
455 info->GetRouteID()); 427 info->GetRouteID());
456 #endif 428 #endif
457 429
458 ProfileIOData* io_data = ProfileIOData::FromResourceContext(resource_context); 430 ProfileIOData* io_data = ProfileIOData::FromResourceContext(resource_context);
459 if (io_data->resource_prefetch_predictor_observer()) { 431 if (io_data->resource_prefetch_predictor_observer()) {
460 io_data->resource_prefetch_predictor_observer()->OnRequestRedirected( 432 io_data->resource_prefetch_predictor_observer()->OnRequestRedirected(
461 redirect_url, request); 433 redirect_url, request);
462 } 434 }
463 } 435 }
464
465 void ChromeResourceDispatcherHostDelegate::OnFieldTrialGroupFinalized(
466 const std::string& trial_name,
467 const std::string& group_name) {
468 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
469 chrome_variations::VariationID new_id =
470 chrome_variations::GetGoogleVariationID(
471 chrome_variations::GOOGLE_WEB_PROPERTIES, trial_name, group_name);
472 if (new_id == chrome_variations::kEmptyID)
473 return;
474 variation_ids_set_.insert(new_id);
475 UpdateVariationIDsHeaderValue();
476 }
477
478 void ChromeResourceDispatcherHostDelegate::InitVariationIDsCacheIfNeeded() {
479 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
480 if (variation_ids_cache_initialized_)
481 return;
482
483 // Register for additional cache updates. This is done first to avoid a race
484 // that could cause registered FieldTrials to be missed.
485 base::FieldTrialList::AddObserver(this);
486
487 base::FieldTrial::ActiveGroups initial_groups;
488 base::FieldTrialList::GetActiveFieldTrialGroups(&initial_groups);
489 for (base::FieldTrial::ActiveGroups::const_iterator it =
490 initial_groups.begin(); it != initial_groups.end(); ++it) {
491 const chrome_variations::VariationID id =
492 chrome_variations::GetGoogleVariationID(
493 chrome_variations::GOOGLE_WEB_PROPERTIES, it->trial_name,
494 it->group_name);
495 if (id != chrome_variations::kEmptyID)
496 variation_ids_set_.insert(id);
497 }
498 UpdateVariationIDsHeaderValue();
499
500 variation_ids_cache_initialized_ = true;
501 }
502
503 void ChromeResourceDispatcherHostDelegate::UpdateVariationIDsHeaderValue() {
504 // The header value is a serialized protobuffer of Variation IDs which is
505 // base64 encoded before transmitting as a string.
506 if (variation_ids_set_.empty())
507 return;
508
509 // This is the bottleneck for the creation of the header, so validate the size
510 // here. Force a hard maximum on the ID count in case the Variations server
511 // returns too many IDs and DOSs receiving servers with large requests.
512 DCHECK_LE(variation_ids_set_.size(), 10U);
513 if (variation_ids_set_.size() > 20) {
514 variation_ids_header_.clear();
515 return;
516 }
517
518 metrics::ChromeVariations proto;
519 for (std::set<chrome_variations::VariationID>::const_iterator it =
520 variation_ids_set_.begin(); it != variation_ids_set_.end(); ++it)
521 proto.add_variation_id(*it);
522
523 std::string serialized;
524 proto.SerializeToString(&serialized);
525
526 std::string hashed;
527 if (base::Base64Encode(serialized, &hashed)) {
528 // If successful, swap the header value with the new one.
529 // Note that the list of IDs and the header could be temporarily out of sync
530 // if IDs are added as the header is recreated. The receiving servers are OK
531 // with such descrepancies.
532 variation_ids_header_ = hashed;
533 } else {
534 DVLOG(1) << "Failed to base64 encode Variation IDs value: " << serialized;
535 }
536 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698