1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/prerender/prerender_util.h"
#include "base/logging.h"
#include "base/metrics/sparse_histogram.h"
#include "base/strings/string_util.h"
#include "content/public/browser/resource_request_info.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request.h"
#include "url/url_canon.h"
#include "url/url_parse.h"
#include "url/url_util.h"
namespace prerender {
bool MaybeGetQueryStringBasedAliasURL(
const GURL& url, GURL* alias_url) {
DCHECK(alias_url);
url_parse::Parsed parsed;
url_parse::ParseStandardURL(url.spec().c_str(), url.spec().length(),
&parsed);
url_parse::Component query = parsed.query;
url_parse::Component key, value;
while (url_parse::ExtractQueryKeyValue(url.spec().c_str(), &query, &key,
&value)) {
if (key.len != 3 || strncmp(url.spec().c_str() + key.begin, "url", key.len))
continue;
// We found a url= query string component.
if (value.len < 1)
continue;
url_canon::RawCanonOutputW<1024> decoded_url;
url_util::DecodeURLEscapeSequences(url.spec().c_str() + value.begin,
value.len, &decoded_url);
GURL new_url(string16(decoded_url.data(), decoded_url.length()));
if (!new_url.is_empty() && new_url.is_valid()) {
*alias_url = new_url;
return true;
}
return false;
}
return false;
}
uint8 GetQueryStringBasedExperiment(const GURL& url) {
url_parse::Parsed parsed;
url_parse::ParseStandardURL(url.spec().c_str(), url.spec().length(),
&parsed);
url_parse::Component query = parsed.query;
url_parse::Component key, value;
while (url_parse::ExtractQueryKeyValue(url.spec().c_str(), &query, &key,
&value)) {
if (key.len != 3 || strncmp(url.spec().c_str() + key.begin, "lpe", key.len))
continue;
// We found a lpe= query string component.
if (value.len != 1)
continue;
uint8 exp = *(url.spec().c_str() + value.begin) - '0';
if (exp < 1 || exp > 9)
continue;
return exp;
}
return kNoExperiment;
}
bool IsGoogleDomain(const GURL& url) {
return StartsWithASCII(url.host(), std::string("www.google."), true);
}
bool IsGoogleSearchResultURL(const GURL& url) {
if (!IsGoogleDomain(url))
return false;
return (url.path().empty() ||
StartsWithASCII(url.path(), std::string("/search"), true) ||
(url.path() == "/") ||
StartsWithASCII(url.path(), std::string("/webhp"), true));
}
bool IsNoSwapInExperiment(uint8 experiment_id) {
// Currently, experiments 5 and 6 fall in this category.
return experiment_id == 5 || experiment_id == 6;
}
bool IsControlGroupExperiment(uint8 experiment_id) {
// Currently, experiments 7 and 8 fall in this category.
return experiment_id == 7 || experiment_id == 8;
}
void URLRequestResponseStarted(net::URLRequest* request) {
static const char* kModPagespeedHeader = "X-Mod-Pagespeed";
static const char* kModPagespeedHistogram = "Prerender.ModPagespeedHeader";
const content::ResourceRequestInfo* info =
content::ResourceRequestInfo::ForRequest(request);
// Gather histogram information about the X-Mod-Pagespeed header.
if (info->GetResourceType() == ResourceType::MAIN_FRAME &&
request->url().SchemeIsHTTPOrHTTPS()) {
UMA_HISTOGRAM_SPARSE_SLOWLY(kModPagespeedHistogram, 0);
if (request->response_headers() &&
request->response_headers()->HasHeader(kModPagespeedHeader)) {
UMA_HISTOGRAM_SPARSE_SLOWLY(kModPagespeedHistogram, 1);
// Attempt to parse the version number, and encode it in buckets
// 2 through 99. 0 and 1 are used to store all pageviews and
// # pageviews with the MPS header (see above).
void* iter = NULL;
std::string mps_version;
if (request->response_headers()->EnumerateHeader(
&iter, kModPagespeedHeader, &mps_version) &&
!mps_version.empty()) {
// Mod Pagespeed versions are of the form a.b.c.d-e
int a, b, c, d, e;
int num_parsed = sscanf(mps_version.c_str(), "%d.%d.%d.%d-%d",
&a, &b, &c, &d, &e);
if (num_parsed == 5) {
int output = 2;
if (c > 10)
output += 2 * (c - 10);
if (d > 1)
output++;
if (output < 2 || output >= 99)
output = 99;
UMA_HISTOGRAM_SPARSE_SLOWLY(kModPagespeedHistogram, output);
}
}
}
}
}
} // namespace prerender
|