1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/prerender/prerender_util.h"
7 #include "base/logging.h"
8 #include "base/metrics/histogram.h"
9 #include "base/metrics/sparse_histogram.h"
10 #include "base/strings/string_util.h"
11 #include "content/public/browser/resource_request_info.h"
12 #include "content/public/common/resource_type.h"
13 #include "net/http/http_response_headers.h"
14 #include "net/url_request/url_request.h"
15 #include "url/third_party/mozilla/url_parse.h"
16 #include "url/url_canon.h"
17 #include "url/url_util.h"
19 using content::ResourceType
;
25 enum PrerenderSchemeCancelReason
{
26 PRERENDER_SCHEME_CANCEL_REASON_EXTERNAL_PROTOCOL
,
27 PRERENDER_SCHEME_CANCEL_REASON_DATA
,
28 PRERENDER_SCHEME_CANCEL_REASON_BLOB
,
29 PRERENDER_SCHEME_CANCEL_REASON_FILE
,
30 PRERENDER_SCHEME_CANCEL_REASON_FILESYSTEM
,
31 PRERENDER_SCHEME_CANCEL_REASON_WEBSOCKET
,
32 PRERENDER_SCHEME_CANCEL_REASON_FTP
,
33 PRERENDER_SCHEME_CANCEL_REASON_CHROME
,
34 PRERENDER_SCHEME_CANCEL_REASON_CHROME_EXTENSION
,
35 PRERENDER_SCHEME_CANCEL_REASON_ABOUT
,
36 PRERENDER_SCHEME_CANCEL_REASON_UNKNOWN
,
37 PRERENDER_SCHEME_CANCEL_REASON_MAX
,
40 void ReportPrerenderSchemeCancelReason(PrerenderSchemeCancelReason reason
) {
41 UMA_HISTOGRAM_ENUMERATION(
42 "Prerender.SchemeCancelReason", reason
,
43 PRERENDER_SCHEME_CANCEL_REASON_MAX
);
48 bool MaybeGetQueryStringBasedAliasURL(
49 const GURL
& url
, GURL
* alias_url
) {
52 url::ParseStandardURL(url
.spec().c_str(), url
.spec().length(), &parsed
);
53 url::Component query
= parsed
.query
;
54 url::Component key
, value
;
55 while (url::ExtractQueryKeyValue(url
.spec().c_str(), &query
, &key
, &value
)) {
56 if (key
.len
!= 3 || strncmp(url
.spec().c_str() + key
.begin
, "url", key
.len
))
58 // We found a url= query string component.
61 url::RawCanonOutputW
<1024> decoded_url
;
62 url::DecodeURLEscapeSequences(url
.spec().c_str() + value
.begin
, value
.len
,
64 GURL
new_url(base::string16(decoded_url
.data(), decoded_url
.length()));
65 if (!new_url
.is_empty() && new_url
.is_valid()) {
74 bool IsGoogleDomain(const GURL
& url
) {
75 return base::StartsWith(url
.host(), "www.google.",
76 base::CompareCase::SENSITIVE
);
79 bool IsGoogleSearchResultURL(const GURL
& url
) {
80 if (!IsGoogleDomain(url
))
82 return (url
.path().empty() ||
83 base::StartsWith(url
.path(), "/search",
84 base::CompareCase::SENSITIVE
) ||
85 (url
.path() == "/") ||
86 base::StartsWith(url
.path(), "/webhp", base::CompareCase::SENSITIVE
));
89 void ReportPrerenderExternalURL() {
90 ReportPrerenderSchemeCancelReason(
91 PRERENDER_SCHEME_CANCEL_REASON_EXTERNAL_PROTOCOL
);
94 void ReportUnsupportedPrerenderScheme(const GURL
& url
) {
95 if (url
.SchemeIs("data")) {
96 ReportPrerenderSchemeCancelReason(PRERENDER_SCHEME_CANCEL_REASON_DATA
);
97 } else if (url
.SchemeIs("blob")) {
98 ReportPrerenderSchemeCancelReason(PRERENDER_SCHEME_CANCEL_REASON_BLOB
);
99 } else if (url
.SchemeIsFile()) {
100 ReportPrerenderSchemeCancelReason(PRERENDER_SCHEME_CANCEL_REASON_FILE
);
101 } else if (url
.SchemeIsFileSystem()) {
102 ReportPrerenderSchemeCancelReason(
103 PRERENDER_SCHEME_CANCEL_REASON_FILESYSTEM
);
104 } else if (url
.SchemeIs("ws") || url
.SchemeIs("wss")) {
105 ReportPrerenderSchemeCancelReason(PRERENDER_SCHEME_CANCEL_REASON_WEBSOCKET
);
106 } else if (url
.SchemeIs("ftp")) {
107 ReportPrerenderSchemeCancelReason(PRERENDER_SCHEME_CANCEL_REASON_FTP
);
108 } else if (url
.SchemeIs("chrome")) {
109 ReportPrerenderSchemeCancelReason(PRERENDER_SCHEME_CANCEL_REASON_CHROME
);
110 } else if (url
.SchemeIs("chrome-extension")) {
111 ReportPrerenderSchemeCancelReason(
112 PRERENDER_SCHEME_CANCEL_REASON_CHROME_EXTENSION
);
113 } else if (url
.SchemeIs("about")) {
114 ReportPrerenderSchemeCancelReason(PRERENDER_SCHEME_CANCEL_REASON_ABOUT
);
116 ReportPrerenderSchemeCancelReason(PRERENDER_SCHEME_CANCEL_REASON_UNKNOWN
);
120 } // namespace prerender