Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/renderer/page_load_histograms.h" | 5 #include "chrome/renderer/page_load_histograms.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/metrics/field_trial.h" | 11 #include "base/metrics/field_trial.h" |
| 12 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
| 13 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
| 14 #include "base/strings/string_split.h" | |
| 14 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
| 15 #include "base/strings/stringprintf.h" | 16 #include "base/strings/stringprintf.h" |
| 16 #include "base/strings/utf_string_conversions.h" | 17 #include "base/strings/utf_string_conversions.h" |
| 17 #include "base/time/time.h" | 18 #include "base/time/time.h" |
| 18 #include "chrome/common/chrome_switches.h" | 19 #include "chrome/common/chrome_switches.h" |
| 19 #include "chrome/renderer/chrome_content_renderer_client.h" | 20 #include "chrome/renderer/chrome_content_renderer_client.h" |
| 20 #include "content/public/common/content_constants.h" | 21 #include "content/public/common/content_constants.h" |
| 21 #include "content/public/renderer/document_state.h" | 22 #include "content/public/renderer/document_state.h" |
| 22 #include "content/public/renderer/render_thread.h" | 23 #include "content/public/renderer/render_thread.h" |
| 23 #include "content/public/renderer/render_view.h" | 24 #include "content/public/renderer/render_view.h" |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 166 return static_cast<URLPattern::SchemeMasks>(0); | 167 return static_cast<URLPattern::SchemeMasks>(0); |
| 167 } | 168 } |
| 168 | 169 |
| 169 // Returns true if the data reduction proxy was used. Note, this function will | 170 // Returns true if the data reduction proxy was used. Note, this function will |
| 170 // produce a false positive if a page is fetched using SPDY and using a proxy, | 171 // produce a false positive if a page is fetched using SPDY and using a proxy, |
| 171 // and |kDatReductionProxyViaValue| is added to the Via header. | 172 // and |kDatReductionProxyViaValue| is added to the Via header. |
| 172 // TODO(bengr): Plumb the hostname of the proxy from |HttpNetworkTransaction| | 173 // TODO(bengr): Plumb the hostname of the proxy from |HttpNetworkTransaction| |
| 173 // and check if it matches |SPDY_PROXY_AUTH_ORIGIN|. | 174 // and check if it matches |SPDY_PROXY_AUTH_ORIGIN|. |
| 174 bool DataReductionProxyWasUsed(WebFrame* frame) { | 175 bool DataReductionProxyWasUsed(WebFrame* frame) { |
| 175 #if defined(SPDY_PROXY_AUTH_ORIGIN) | 176 #if defined(SPDY_PROXY_AUTH_ORIGIN) |
| 177 const char kDatReductionProxyViaValue[] = "1.1 Chrome Compression Proxy"; | |
| 178 return ViaHeaderContains(frame, kDatReductionProxyViaValue); | |
| 179 #endif | |
| 180 return false; | |
| 181 } | |
| 182 | |
| 183 // Helper function to check for string in 'via' header. This is used only for | |
| 184 // requests fetched via the proxy. | |
|
bengr
2014/01/10 17:40:04
"This is used only for requests fetched via the pr
ksimbili
2014/01/28 18:33:25
Done.
| |
| 185 bool ViaHeaderContains(WebFrame* frame, const std::string& via_value) { | |
|
bengr
2014/01/10 17:40:04
optional: you should check that |via_value| does n
| |
| 176 const char kViaHeaderName[] = "Via"; | 186 const char kViaHeaderName[] = "Via"; |
| 177 const char kDatReductionProxyViaValue[] = "1.1 Chrome Compression Proxy"; | |
| 178 | 187 |
| 179 DocumentState* document_state = | 188 DocumentState* document_state = |
| 180 DocumentState::FromDataSource(frame->dataSource()); | 189 DocumentState::FromDataSource(frame->dataSource()); |
| 181 if (!document_state->was_fetched_via_proxy()) | 190 if (!document_state->was_fetched_via_proxy()) |
| 182 return false; | 191 return false; |
| 183 | 192 |
| 184 std::string via_header(base::UTF16ToUTF8( | 193 std::vector<std::string> values; |
| 185 frame->dataSource()->response().httpHeaderField(kViaHeaderName))); | 194 // Multiple via headers have already been coalesced and hence each value |
| 186 return via_header.find(kDatReductionProxyViaValue) != std::string::npos; | 195 // seperated by a comma corresponds to a proxy. The value added by proxy is |
|
bengr
2014/01/10 17:40:04
seperated --> separated
by proxy --> by a proxy
ksimbili
2014/01/28 18:33:25
Done.
| |
| 187 #endif | 196 // not expected to contain any commas. |
| 188 return false; | 197 // Example., Via: 1.0 Compression proxy, 1.1 Google promise preview |
| 198 base::SplitString( | |
| 199 frame->dataSource()->response().httpHeaderField(kViaHeaderName).utf8(), | |
| 200 ',', &values); | |
| 201 return std::find(values.begin(), values.end(), via_value) != values.end(); | |
| 189 } | 202 } |
| 190 | 203 |
| 191 // Returns true if the provided URL is a referrer string that came from | 204 // Returns true if the provided URL is a referrer string that came from |
| 192 // a Google Web Search results page. This is a little non-deterministic | 205 // a Google Web Search results page. This is a little non-deterministic |
| 193 // because desktop and mobile websearch differ and sometimes just provide | 206 // because desktop and mobile websearch differ and sometimes just provide |
| 194 // http://www.google.com/ as the referrer. In the case of /url we can be sure | 207 // http://www.google.com/ as the referrer. In the case of /url we can be sure |
| 195 // that it came from websearch but we will be generous and allow for cases | 208 // that it came from websearch but we will be generous and allow for cases |
| 196 // where a non-Google URL was provided a bare Google URL as a referrer. | 209 // where a non-Google URL was provided a bare Google URL as a referrer. |
| 197 // The domain validation matches the code used by the prerenderer for similar | 210 // The domain validation matches the code used by the prerenderer for similar |
| 198 // purposes. | 211 // purposes. |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 222 return kNoExperiment; | 235 return kNoExperiment; |
| 223 | 236 |
| 224 int experiment_id; | 237 int experiment_id; |
| 225 if (!base::StringToInt(value, &experiment_id)) | 238 if (!base::StringToInt(value, &experiment_id)) |
| 226 return kNoExperiment; | 239 return kNoExperiment; |
| 227 if (0 < experiment_id && experiment_id <= kMaxExperimentID) | 240 if (0 < experiment_id && experiment_id <= kMaxExperimentID) |
| 228 return experiment_id; | 241 return experiment_id; |
| 229 return kNoExperiment; | 242 return kNoExperiment; |
| 230 } | 243 } |
| 231 | 244 |
| 232 // Appends "cerivrj_*" and "gcjeid" query parameters from preview_url to url. | |
| 233 // Returns true if "cerivrj_*" query is found. | |
| 234 // This will be used only for search results URLs. | |
| 235 bool AppendPreviewQueryFromURL(const GURL& preview_url, GURL* url) { | |
| 236 bool preview_query_found = false; | |
| 237 for (net::QueryIterator it(preview_url); !it.IsAtEnd(); it.Advance()) { | |
| 238 const std::string param_name = it.GetKey(); | |
| 239 bool is_preview = StartsWithASCII(param_name, "cerivrj_", true); | |
| 240 if (url && (is_preview || param_name == "gcjeid")) | |
| 241 net::AppendQueryParameter(*url, param_name, it.GetValue()); | |
| 242 preview_query_found = preview_query_found || is_preview; | |
| 243 } | |
| 244 return preview_query_found; | |
| 245 } | |
| 246 | |
| 247 // Returns true if the provided referrer URL is the preview URL of the current | |
| 248 // URL. Preview URL differs from original only with "cerivrj_*", "gcjeid" query | |
| 249 // parameters. | |
| 250 bool IsReferrerPreviewOfURL(const GURL& url, | |
| 251 const base::string16& referrer_str) { | |
| 252 GURL referrer(referrer_str); | |
| 253 if (referrer.is_valid()) { | |
| 254 GURL generated_preview_url(url); | |
| 255 // Now try to copy "cerivrj_*" and "gcjeid" paramters to url and check if | |
| 256 // they exactly match. | |
| 257 if (AppendPreviewQueryFromURL(referrer, &generated_preview_url)) | |
| 258 return generated_preview_url == referrer; | |
| 259 } | |
| 260 return false; | |
| 261 } | |
| 262 | |
| 263 // Returns preview state by looking at url and referer url. | 245 // Returns preview state by looking at url and referer url. |
| 264 void GetPreviewState(const GURL& url, | 246 void GetPreviewState(WebFrame* frame, |
| 265 const base::string16& referrer, | |
| 266 bool came_from_websearch, | 247 bool came_from_websearch, |
| 267 bool data_reduction_proxy_was_used, | 248 bool data_reduction_proxy_was_used, |
| 268 GwsPreviewState* preview_state, | 249 GwsPreviewState* preview_state, |
| 269 int* preview_experiment_id) { | 250 int* preview_experiment_id) { |
| 270 // Conditions for GWS preview are, | 251 // Conditions for GWS preview are, |
| 271 // 1. Data reduction proxy was used. | 252 // 1. Data reduction proxy was used. |
| 272 // 2. URL is loaded from web search. | 253 // 2. URL is loaded from web search. |
|
bengr
2014/01/10 17:40:04
2. is misleading because you set state even when c
ksimbili
2014/01/28 18:33:25
Done.
| |
| 273 // If the URL contains "cerivrj_*' query parameter record under | 254 // Based on via header PREVIEW/PREVIEW_WAS_SHOWN/PREVIEW_NOT_USED is |
|
bengr
2014/01/10 17:40:04
// Determine the preview state (PREVIEW, PREVIEW_W
ksimbili
2014/01/28 18:33:25
Done.
| |
| 274 // "Preview". | 255 // determined. |
| 275 if (data_reduction_proxy_was_used) { | 256 if (data_reduction_proxy_was_used) { |
| 276 if (came_from_websearch) { | 257 if (came_from_websearch) { |
| 277 *preview_state = | 258 *preview_state = |
| 278 AppendPreviewQueryFromURL(url, NULL) ? PREVIEW : PREVIEW_NOT_USED; | 259 ViaHeaderContains(frame, "1.1 Google Promise Preview") ? PREVIEW : |
| 279 } else if (IsReferrerPreviewOfURL(url, referrer)) { | 260 PREVIEW_NOT_USED; |
|
bengr
2014/01/10 17:40:04
I'd move "frame,..." down to the next line and ind
ksimbili
2014/01/28 18:33:25
Done.
| |
| 261 } else if (ViaHeaderContains(frame, "1.1 Google Promise Original")) { | |
| 280 *preview_state = PREVIEW_WAS_SHOWN; | 262 *preview_state = PREVIEW_WAS_SHOWN; |
| 281 *preview_experiment_id = GetQueryStringBasedExperiment(GURL(referrer)); | 263 *preview_experiment_id = GetQueryStringBasedExperiment( |
| 264 GURL(frame->document().referrer())); | |
| 282 } | 265 } |
| 283 } | 266 } |
| 284 } | 267 } |
| 285 | 268 |
| 286 void DumpPerformanceTiming(const WebPerformance& performance, | 269 void DumpPerformanceTiming(const WebPerformance& performance, |
| 287 DocumentState* document_state, | 270 DocumentState* document_state, |
| 288 bool data_reduction_proxy_was_used, | 271 bool data_reduction_proxy_was_used, |
| 289 bool came_from_websearch, | 272 bool came_from_websearch, |
| 290 int websearch_chrome_joint_experiment_id, | 273 int websearch_chrome_joint_experiment_id, |
| 291 GwsPreviewState preview_state, | 274 GwsPreviewState preview_state, |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 553 IsFromGoogleSearchResult(frame->document().url(), | 536 IsFromGoogleSearchResult(frame->document().url(), |
| 554 GURL(frame->document().referrer())); | 537 GURL(frame->document().referrer())); |
| 555 int websearch_chrome_joint_experiment_id = kNoExperiment; | 538 int websearch_chrome_joint_experiment_id = kNoExperiment; |
| 556 if (came_from_websearch) { | 539 if (came_from_websearch) { |
| 557 websearch_chrome_joint_experiment_id = | 540 websearch_chrome_joint_experiment_id = |
| 558 GetQueryStringBasedExperiment(GURL(frame->document().referrer())); | 541 GetQueryStringBasedExperiment(GURL(frame->document().referrer())); |
| 559 } | 542 } |
| 560 | 543 |
| 561 GwsPreviewState preview_state = PREVIEW_NONE; | 544 GwsPreviewState preview_state = PREVIEW_NONE; |
| 562 int preview_experiment_id = websearch_chrome_joint_experiment_id; | 545 int preview_experiment_id = websearch_chrome_joint_experiment_id; |
| 563 GetPreviewState(frame->document().url(), frame->document().referrer(), | 546 GetPreviewState(frame, came_from_websearch, data_reduction_proxy_was_used, |
| 564 came_from_websearch, data_reduction_proxy_was_used, | |
| 565 &preview_state, &preview_experiment_id); | 547 &preview_state, &preview_experiment_id); |
| 566 | 548 |
| 567 // Times based on the Web Timing metrics. | 549 // Times based on the Web Timing metrics. |
| 568 // http://www.w3.org/TR/navigation-timing/ | 550 // http://www.w3.org/TR/navigation-timing/ |
| 569 // TODO(tonyg, jar): We are in the process of vetting these metrics against | 551 // TODO(tonyg, jar): We are in the process of vetting these metrics against |
| 570 // the existing ones. Once we understand any differences, we will standardize | 552 // the existing ones. Once we understand any differences, we will standardize |
| 571 // on a single set of metrics. | 553 // on a single set of metrics. |
| 572 DumpPerformanceTiming(frame->performance(), document_state, | 554 DumpPerformanceTiming(frame->performance(), document_state, |
| 573 data_reduction_proxy_was_used, | 555 data_reduction_proxy_was_used, |
| 574 came_from_websearch, | 556 came_from_websearch, |
| (...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1047 | 1029 |
| 1048 DCHECK(document_state); | 1030 DCHECK(document_state); |
| 1049 DCHECK(ds); | 1031 DCHECK(ds); |
| 1050 GURL url(ds->request().url()); | 1032 GURL url(ds->request().url()); |
| 1051 Time start = document_state->start_load_time(); | 1033 Time start = document_state->start_load_time(); |
| 1052 Time finish = document_state->finish_load_time(); | 1034 Time finish = document_state->finish_load_time(); |
| 1053 // TODO(mbelshe): should we log more stats? | 1035 // TODO(mbelshe): should we log more stats? |
| 1054 VLOG(1) << "PLT: " << (finish - start).InMilliseconds() << "ms " | 1036 VLOG(1) << "PLT: " << (finish - start).InMilliseconds() << "ms " |
| 1055 << url.spec(); | 1037 << url.spec(); |
| 1056 } | 1038 } |
| OLD | NEW |