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

Side by Side Diff: url/gurl.cc

Issue 23835019: Support URL fragment resolution againt non-hierarchical schemes (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: brettw2 Created 7 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
« no previous file with comments | « url/gurl.h ('k') | url/gurl_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 #ifdef WIN32 5 #ifdef WIN32
6 #include <windows.h> 6 #include <windows.h>
7 #else 7 #else
8 #include <pthread.h> 8 #include <pthread.h>
9 #endif 9 #endif
10 10
11 #include <algorithm> 11 #include <algorithm>
12 #include <ostream> 12 #include <ostream>
13 13
14 #include "url/gurl.h" 14 #include "url/gurl.h"
15 15
16 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "url/url_canon_stdstring.h" 17 #include "url/url_canon_stdstring.h"
18 #include "url/url_util.h" 18 #include "url/url_util.h"
19 19
20 namespace { 20 namespace {
21 21
22 // External template that can handle initialization of either character type.
23 // The input spec is given, and the canonical version will be placed in
24 // |*canonical|, along with the parsing of the canonical spec in |*parsed|.
25 template<typename STR>
26 bool InitCanonical(const STR& input_spec,
27 std::string* canonical,
28 url_parse::Parsed* parsed) {
29 // Reserve enough room in the output for the input, plus some extra so that
30 // we have room if we have to escape a few things without reallocating.
31 canonical->reserve(input_spec.size() + 32);
32 url_canon::StdStringCanonOutput output(canonical);
33 bool success = url_util::Canonicalize(
34 input_spec.data(), static_cast<int>(input_spec.length()),
35 NULL, &output, parsed);
36
37 output.Complete(); // Must be done before using string.
38 return success;
39 }
40
41 static std::string* empty_string = NULL; 22 static std::string* empty_string = NULL;
42 static GURL* empty_gurl = NULL; 23 static GURL* empty_gurl = NULL;
43 24
44 #ifdef WIN32 25 #ifdef WIN32
45 26
46 // Returns a static reference to an empty string for returning a reference 27 // Returns a static reference to an empty string for returning a reference
47 // when there is no underlying string. 28 // when there is no underlying string.
48 const std::string& EmptyStringForGURL() { 29 const std::string& EmptyStringForGURL() {
49 // Avoid static object construction/destruction on startup/shutdown. 30 // Avoid static object construction/destruction on startup/shutdown.
50 if (!empty_string) { 31 if (!empty_string) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 : spec_(other.spec_), 68 : spec_(other.spec_),
88 is_valid_(other.is_valid_), 69 is_valid_(other.is_valid_),
89 parsed_(other.parsed_) { 70 parsed_(other.parsed_) {
90 if (other.inner_url_) 71 if (other.inner_url_)
91 inner_url_.reset(new GURL(*other.inner_url_)); 72 inner_url_.reset(new GURL(*other.inner_url_));
92 // Valid filesystem urls should always have an inner_url_. 73 // Valid filesystem urls should always have an inner_url_.
93 DCHECK(!is_valid_ || !SchemeIsFileSystem() || inner_url_); 74 DCHECK(!is_valid_ || !SchemeIsFileSystem() || inner_url_);
94 } 75 }
95 76
96 GURL::GURL(const std::string& url_string) { 77 GURL::GURL(const std::string& url_string) {
97 is_valid_ = InitCanonical(url_string, &spec_, &parsed_); 78 InitCanonical(url_string, true);
98 if (is_valid_ && SchemeIsFileSystem()) {
99 inner_url_.reset(
100 new GURL(spec_.data(), parsed_.Length(),
101 *parsed_.inner_parsed(), true));
102 }
103 } 79 }
104 80
105 GURL::GURL(const base::string16& url_string) { 81 GURL::GURL(const base::string16& url_string) {
106 is_valid_ = InitCanonical(url_string, &spec_, &parsed_); 82 InitCanonical(url_string, true);
107 if (is_valid_ && SchemeIsFileSystem()) { 83 }
108 inner_url_.reset( 84
109 new GURL(spec_.data(), parsed_.Length(), 85 GURL::GURL(const std::string& url_string, RetainWhiteSpaceSelector) {
110 *parsed_.inner_parsed(), true)); 86 InitCanonical(url_string, false);
111 }
112 } 87 }
113 88
114 GURL::GURL(const char* canonical_spec, size_t canonical_spec_len, 89 GURL::GURL(const char* canonical_spec, size_t canonical_spec_len,
115 const url_parse::Parsed& parsed, bool is_valid) 90 const url_parse::Parsed& parsed, bool is_valid)
116 : spec_(canonical_spec, canonical_spec_len), 91 : spec_(canonical_spec, canonical_spec_len),
117 is_valid_(is_valid), 92 is_valid_(is_valid),
118 parsed_(parsed) { 93 parsed_(parsed) {
119 InitializeFromCanonicalSpec(); 94 InitializeFromCanonicalSpec();
120 } 95 }
121 96
122 GURL::GURL(std::string canonical_spec, 97 GURL::GURL(std::string canonical_spec,
123 const url_parse::Parsed& parsed, bool is_valid) 98 const url_parse::Parsed& parsed, bool is_valid)
124 : is_valid_(is_valid), 99 : is_valid_(is_valid),
125 parsed_(parsed) { 100 parsed_(parsed) {
126 spec_.swap(canonical_spec); 101 spec_.swap(canonical_spec);
127 InitializeFromCanonicalSpec(); 102 InitializeFromCanonicalSpec();
128 } 103 }
129 104
105 template<typename STR>
106 void GURL::InitCanonical(const STR& input_spec, bool trim_path_end) {
107 // Reserve enough room in the output for the input, plus some extra so that
108 // we have room if we have to escape a few things without reallocating.
109 spec_.reserve(input_spec.size() + 32);
110 url_canon::StdStringCanonOutput output(&spec_);
111 is_valid_ = url_util::Canonicalize(
112 input_spec.data(), static_cast<int>(input_spec.length()), trim_path_end,
113 NULL, &output, &parsed_);
114
115 output.Complete(); // Must be done before using string.
116 if (is_valid_ && SchemeIsFileSystem()) {
117 inner_url_.reset(new GURL(spec_.data(), parsed_.Length(),
118 *parsed_.inner_parsed(), true));
119 }
120 }
121
130 void GURL::InitializeFromCanonicalSpec() { 122 void GURL::InitializeFromCanonicalSpec() {
131 if (is_valid_ && SchemeIsFileSystem()) { 123 if (is_valid_ && SchemeIsFileSystem()) {
132 inner_url_.reset( 124 inner_url_.reset(
133 new GURL(spec_.data(), parsed_.Length(), 125 new GURL(spec_.data(), parsed_.Length(),
134 *parsed_.inner_parsed(), true)); 126 *parsed_.inner_parsed(), true));
135 } 127 }
136 128
137 #ifndef NDEBUG 129 #ifndef NDEBUG
138 // For testing purposes, check that the parsed canonical URL is identical to 130 // For testing purposes, check that the parsed canonical URL is identical to
139 // what we would have produced. Skip checking for invalid URLs have no meaning 131 // what we would have produced. Skip checking for invalid URLs have no meaning
140 // and we can't always canonicalize then reproducabely. 132 // and we can't always canonicalize then reproducabely.
141 if (is_valid_) { 133 if (is_valid_) {
142 url_parse::Component scheme; 134 url_parse::Component scheme;
135 // We can't do this check on the inner_url of a filesystem URL, as
136 // canonical_spec actually points to the start of the outer URL, so we'd
137 // end up with infinite recursion in this constructor.
143 if (!url_util::FindAndCompareScheme(spec_.data(), spec_.length(), 138 if (!url_util::FindAndCompareScheme(spec_.data(), spec_.length(),
144 "filesystem", &scheme) || 139 "filesystem", &scheme) ||
145 scheme.begin == parsed_.scheme.begin) { 140 scheme.begin == parsed_.scheme.begin) {
146 // We can't do this check on the inner_url of a filesystem URL, as 141 // We need to retain trailing whitespace on path URLs, as the |parsed_|
147 // canonical_spec actually points to the start of the outer URL, so we'd 142 // spec we originally received may legitimately contain trailing white-
148 // end up with infinite recursion in this constructor. 143 // space on the path or components e.g. if the #ref has been
149 GURL test_url(spec_); 144 // removed from a "foo:hello #ref" URL (see http://crbug.com/291747).
145 GURL test_url(spec_, RETAIN_TRAILING_PATH_WHITEPACE);
150 146
151 DCHECK(test_url.is_valid_ == is_valid_); 147 DCHECK(test_url.is_valid_ == is_valid_);
152 DCHECK(test_url.spec_ == spec_); 148 DCHECK(test_url.spec_ == spec_);
153 149
154 DCHECK(test_url.parsed_.scheme == parsed_.scheme); 150 DCHECK(test_url.parsed_.scheme == parsed_.scheme);
155 DCHECK(test_url.parsed_.username == parsed_.username); 151 DCHECK(test_url.parsed_.username == parsed_.username);
156 DCHECK(test_url.parsed_.password == parsed_.password); 152 DCHECK(test_url.parsed_.password == parsed_.password);
157 DCHECK(test_url.parsed_.host == parsed_.host); 153 DCHECK(test_url.parsed_.host == parsed_.host);
158 DCHECK(test_url.parsed_.port == parsed_.port); 154 DCHECK(test_url.parsed_.port == parsed_.port);
159 DCHECK(test_url.parsed_.path == parsed_.path); 155 DCHECK(test_url.parsed_.path == parsed_.path);
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 void GURL::Swap(GURL* other) { 505 void GURL::Swap(GURL* other) {
510 spec_.swap(other->spec_); 506 spec_.swap(other->spec_);
511 std::swap(is_valid_, other->is_valid_); 507 std::swap(is_valid_, other->is_valid_);
512 std::swap(parsed_, other->parsed_); 508 std::swap(parsed_, other->parsed_);
513 inner_url_.swap(other->inner_url_); 509 inner_url_.swap(other->inner_url_);
514 } 510 }
515 511
516 std::ostream& operator<<(std::ostream& out, const GURL& url) { 512 std::ostream& operator<<(std::ostream& out, const GURL& url) {
517 return out << url.possibly_invalid_spec(); 513 return out << url.possibly_invalid_spec();
518 } 514 }
OLDNEW
« no previous file with comments | « url/gurl.h ('k') | url/gurl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698