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

Side by Side Diff: gurl.cc

Issue 2029803003: Update to Chromium //url at Chromium commit 79dc59ac7602413181079ecb463873e29a1d7d0a. (Closed) Base URL: https://chromium.googlesource.com/external/github.com/domokit/gurl@master
Patch Set: Created 4 years, 6 months 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
« no previous file with comments | « gurl.h ('k') | 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 "base/strings/string_piece.h"
18 #include "base/strings/string_util.h"
17 #include "url/url_canon_stdstring.h" 19 #include "url/url_canon_stdstring.h"
18 #include "url/url_util.h" 20 #include "url/url_util.h"
19 21
20 namespace { 22 namespace {
21 23
22 static std::string* empty_string = NULL; 24 static std::string* empty_string = NULL;
23 static GURL* empty_gurl = NULL; 25 static GURL* empty_gurl = NULL;
24 26
25 #ifdef WIN32 27 #ifdef WIN32
26 28
(...skipping 25 matching lines...) Expand all
52 } 54 }
53 55
54 const std::string& EmptyStringForGURL() { 56 const std::string& EmptyStringForGURL() {
55 // Avoid static object construction/destruction on startup/shutdown. 57 // Avoid static object construction/destruction on startup/shutdown.
56 pthread_once(&empty_string_once, EmptyStringForGURLOnce); 58 pthread_once(&empty_string_once, EmptyStringForGURLOnce);
57 return *empty_string; 59 return *empty_string;
58 } 60 }
59 61
60 #endif // WIN32 62 #endif // WIN32
61 63
62 } // namespace 64 } // namespace
63 65
64 GURL::GURL() : is_valid_(false) { 66 GURL::GURL() : is_valid_(false) {
65 } 67 }
66 68
67 GURL::GURL(const GURL& other) 69 GURL::GURL(const GURL& other)
68 : spec_(other.spec_), 70 : spec_(other.spec_),
69 is_valid_(other.is_valid_), 71 is_valid_(other.is_valid_),
70 parsed_(other.parsed_) { 72 parsed_(other.parsed_) {
71 if (other.inner_url_) 73 if (other.inner_url_)
72 inner_url_.reset(new GURL(*other.inner_url_)); 74 inner_url_.reset(new GURL(*other.inner_url_));
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 void GURL::InitializeFromCanonicalSpec() { 125 void GURL::InitializeFromCanonicalSpec() {
124 if (is_valid_ && SchemeIsFileSystem()) { 126 if (is_valid_ && SchemeIsFileSystem()) {
125 inner_url_.reset( 127 inner_url_.reset(
126 new GURL(spec_.data(), parsed_.Length(), 128 new GURL(spec_.data(), parsed_.Length(),
127 *parsed_.inner_parsed(), true)); 129 *parsed_.inner_parsed(), true));
128 } 130 }
129 131
130 #ifndef NDEBUG 132 #ifndef NDEBUG
131 // For testing purposes, check that the parsed canonical URL is identical to 133 // For testing purposes, check that the parsed canonical URL is identical to
132 // what we would have produced. Skip checking for invalid URLs have no meaning 134 // what we would have produced. Skip checking for invalid URLs have no meaning
133 // and we can't always canonicalize then reproducabely. 135 // and we can't always canonicalize then reproducibly.
134 if (is_valid_) { 136 if (is_valid_) {
135 url::Component scheme; 137 url::Component scheme;
136 // We can't do this check on the inner_url of a filesystem URL, as 138 // We can't do this check on the inner_url of a filesystem URL, as
137 // canonical_spec actually points to the start of the outer URL, so we'd 139 // canonical_spec actually points to the start of the outer URL, so we'd
138 // end up with infinite recursion in this constructor. 140 // end up with infinite recursion in this constructor.
139 if (!url::FindAndCompareScheme(spec_.data(), spec_.length(), 141 if (!url::FindAndCompareScheme(spec_.data(), spec_.length(),
140 url::kFileSystemScheme, &scheme) || 142 url::kFileSystemScheme, &scheme) ||
141 scheme.begin == parsed_.scheme.begin) { 143 scheme.begin == parsed_.scheme.begin) {
142 // We need to retain trailing whitespace on path URLs, as the |parsed_| 144 // We need to retain trailing whitespace on path URLs, as the |parsed_|
143 // spec we originally received may legitimately contain trailing white- 145 // spec we originally received may legitimately contain trailing white-
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 } 188 }
187 189
188 bool GURL::operator<(const GURL& other) const { 190 bool GURL::operator<(const GURL& other) const {
189 return spec_ < other.spec_; 191 return spec_ < other.spec_;
190 } 192 }
191 193
192 bool GURL::operator>(const GURL& other) const { 194 bool GURL::operator>(const GURL& other) const {
193 return spec_ > other.spec_; 195 return spec_ > other.spec_;
194 } 196 }
195 197
198 // Note: code duplicated below (it's inconvenient to use a template here).
196 GURL GURL::Resolve(const std::string& relative) const { 199 GURL GURL::Resolve(const std::string& relative) const {
197 return ResolveWithCharsetConverter(relative, NULL);
198 }
199 GURL GURL::Resolve(const base::string16& relative) const {
200 return ResolveWithCharsetConverter(relative, NULL);
201 }
202
203 // Note: code duplicated below (it's inconvenient to use a template here).
204 GURL GURL::ResolveWithCharsetConverter(
205 const std::string& relative,
206 url::CharsetConverter* charset_converter) const {
207 // Not allowed for invalid URLs. 200 // Not allowed for invalid URLs.
208 if (!is_valid_) 201 if (!is_valid_)
209 return GURL(); 202 return GURL();
210 203
211 GURL result; 204 GURL result;
212 205
213 // Reserve enough room in the output for the input, plus some extra so that 206 // Reserve enough room in the output for the input, plus some extra so that
214 // we have room if we have to escape a few things without reallocating. 207 // we have room if we have to escape a few things without reallocating.
215 result.spec_.reserve(spec_.size() + 32); 208 result.spec_.reserve(spec_.size() + 32);
216 url::StdStringCanonOutput output(&result.spec_); 209 url::StdStringCanonOutput output(&result.spec_);
217 210
218 if (!url::ResolveRelative(spec_.data(), static_cast<int>(spec_.length()), 211 if (!url::ResolveRelative(spec_.data(), static_cast<int>(spec_.length()),
219 parsed_, relative.data(), 212 parsed_, relative.data(),
220 static_cast<int>(relative.length()), 213 static_cast<int>(relative.length()),
221 charset_converter, &output, &result.parsed_)) { 214 nullptr, &output, &result.parsed_)) {
222 // Error resolving, return an empty URL. 215 // Error resolving, return an empty URL.
223 return GURL(); 216 return GURL();
224 } 217 }
225 218
226 output.Complete(); 219 output.Complete();
227 result.is_valid_ = true; 220 result.is_valid_ = true;
228 if (result.SchemeIsFileSystem()) { 221 if (result.SchemeIsFileSystem()) {
229 result.inner_url_.reset( 222 result.inner_url_.reset(
230 new GURL(result.spec_.data(), result.parsed_.Length(), 223 new GURL(result.spec_.data(), result.parsed_.Length(),
231 *result.parsed_.inner_parsed(), true)); 224 *result.parsed_.inner_parsed(), true));
232 } 225 }
233 return result; 226 return result;
234 } 227 }
235 228
236 // Note: code duplicated above (it's inconvenient to use a template here). 229 // Note: code duplicated above (it's inconvenient to use a template here).
237 GURL GURL::ResolveWithCharsetConverter( 230 GURL GURL::Resolve(const base::string16& relative) const {
238 const base::string16& relative,
239 url::CharsetConverter* charset_converter) const {
240 // Not allowed for invalid URLs. 231 // Not allowed for invalid URLs.
241 if (!is_valid_) 232 if (!is_valid_)
242 return GURL(); 233 return GURL();
243 234
244 GURL result; 235 GURL result;
245 236
246 // Reserve enough room in the output for the input, plus some extra so that 237 // Reserve enough room in the output for the input, plus some extra so that
247 // we have room if we have to escape a few things without reallocating. 238 // we have room if we have to escape a few things without reallocating.
248 result.spec_.reserve(spec_.size() + 32); 239 result.spec_.reserve(spec_.size() + 32);
249 url::StdStringCanonOutput output(&result.spec_); 240 url::StdStringCanonOutput output(&result.spec_);
250 241
251 if (!url::ResolveRelative(spec_.data(), static_cast<int>(spec_.length()), 242 if (!url::ResolveRelative(spec_.data(), static_cast<int>(spec_.length()),
252 parsed_, relative.data(), 243 parsed_, relative.data(),
253 static_cast<int>(relative.length()), 244 static_cast<int>(relative.length()),
254 charset_converter, &output, &result.parsed_)) { 245 nullptr, &output, &result.parsed_)) {
255 // Error resolving, return an empty URL. 246 // Error resolving, return an empty URL.
256 return GURL(); 247 return GURL();
257 } 248 }
258 249
259 output.Complete(); 250 output.Complete();
260 result.is_valid_ = true; 251 result.is_valid_ = true;
261 if (result.SchemeIsFileSystem()) { 252 if (result.SchemeIsFileSystem()) {
262 result.inner_url_.reset( 253 result.inner_url_.reset(
263 new GURL(result.spec_.data(), result.parsed_.Length(), 254 new GURL(result.spec_.data(), result.parsed_.Length(),
264 *result.parsed_.inner_parsed(), true)); 255 *result.parsed_.inner_parsed(), true));
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 output.Complete(); 304 output.Complete();
314 if (result.is_valid_ && result.SchemeIsFileSystem()) { 305 if (result.is_valid_ && result.SchemeIsFileSystem()) {
315 result.inner_url_.reset(new GURL(spec_.data(), result.parsed_.Length(), 306 result.inner_url_.reset(new GURL(spec_.data(), result.parsed_.Length(),
316 *result.parsed_.inner_parsed(), true)); 307 *result.parsed_.inner_parsed(), true));
317 } 308 }
318 return result; 309 return result;
319 } 310 }
320 311
321 GURL GURL::GetOrigin() const { 312 GURL GURL::GetOrigin() const {
322 // This doesn't make sense for invalid or nonstandard URLs, so return 313 // This doesn't make sense for invalid or nonstandard URLs, so return
323 // the empty URL 314 // the empty URL.
324 if (!is_valid_ || !IsStandard()) 315 if (!is_valid_ || !IsStandard())
325 return GURL(); 316 return GURL();
326 317
327 if (SchemeIsFileSystem()) 318 if (SchemeIsFileSystem())
328 return inner_url_->GetOrigin(); 319 return inner_url_->GetOrigin();
329 320
330 url::Replacements<char> replacements; 321 url::Replacements<char> replacements;
331 replacements.ClearUsername(); 322 replacements.ClearUsername();
332 replacements.ClearPassword(); 323 replacements.ClearPassword();
333 replacements.ClearPath(); 324 replacements.ClearPath();
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 return other; 366 return other;
376 } 367 }
377 368
378 bool GURL::IsStandard() const { 369 bool GURL::IsStandard() const {
379 return url::IsStandard(spec_.data(), parsed_.scheme); 370 return url::IsStandard(spec_.data(), parsed_.scheme);
380 } 371 }
381 372
382 bool GURL::SchemeIs(const char* lower_ascii_scheme) const { 373 bool GURL::SchemeIs(const char* lower_ascii_scheme) const {
383 if (parsed_.scheme.len <= 0) 374 if (parsed_.scheme.len <= 0)
384 return lower_ascii_scheme == NULL; 375 return lower_ascii_scheme == NULL;
385 return url::LowerCaseEqualsASCII(spec_.data() + parsed_.scheme.begin, 376 return base::LowerCaseEqualsASCII(
386 spec_.data() + parsed_.scheme.end(), 377 base::StringPiece(spec_.data() + parsed_.scheme.begin,
387 lower_ascii_scheme); 378 parsed_.scheme.len),
379 lower_ascii_scheme);
388 } 380 }
389 381
390 bool GURL::SchemeIsHTTPOrHTTPS() const { 382 bool GURL::SchemeIsHTTPOrHTTPS() const {
391 return SchemeIs(url::kHttpScheme) || SchemeIs(url::kHttpsScheme); 383 return SchemeIs(url::kHttpScheme) || SchemeIs(url::kHttpsScheme);
392 } 384 }
393 385
394 bool GURL::SchemeIsWSOrWSS() const { 386 bool GURL::SchemeIsWSOrWSS() const {
395 return SchemeIs(url::kWsScheme) || SchemeIs(url::kWssScheme); 387 return SchemeIs(url::kWsScheme) || SchemeIs(url::kWssScheme);
396 } 388 }
397 389
(...skipping 11 matching lines...) Expand all
409 return int_port; 401 return int_port;
410 } 402 }
411 403
412 std::string GURL::ExtractFileName() const { 404 std::string GURL::ExtractFileName() const {
413 url::Component file_component; 405 url::Component file_component;
414 url::ExtractFileName(spec_.data(), parsed_.path, &file_component); 406 url::ExtractFileName(spec_.data(), parsed_.path, &file_component);
415 return ComponentString(file_component); 407 return ComponentString(file_component);
416 } 408 }
417 409
418 std::string GURL::PathForRequest() const { 410 std::string GURL::PathForRequest() const {
419 DCHECK(parsed_.path.len > 0) << "Canonical path for requests should be non-emp ty"; 411 DCHECK(parsed_.path.len > 0)
412 << "Canonical path for requests should be non-empty";
420 if (parsed_.ref.len >= 0) { 413 if (parsed_.ref.len >= 0) {
421 // Clip off the reference when it exists. The reference starts after the # 414 // Clip off the reference when it exists. The reference starts after the
422 // sign, so we have to subtract one to also remove it. 415 // #-sign, so we have to subtract one to also remove it.
423 return std::string(spec_, parsed_.path.begin, 416 return std::string(spec_, parsed_.path.begin,
424 parsed_.ref.begin - parsed_.path.begin - 1); 417 parsed_.ref.begin - parsed_.path.begin - 1);
425 } 418 }
426 // Compute the actual path length, rather than depending on the spec's 419 // Compute the actual path length, rather than depending on the spec's
427 // terminator. If we're an inner_url, our spec continues on into our outer 420 // terminator. If we're an inner_url, our spec continues on into our outer
428 // url's path/query/ref. 421 // URL's path/query/ref.
429 int path_len = parsed_.path.len; 422 int path_len = parsed_.path.len;
430 if (parsed_.query.is_valid()) 423 if (parsed_.query.is_valid())
431 path_len = parsed_.query.end() - parsed_.path.begin; 424 path_len = parsed_.query.end() - parsed_.path.begin;
432 425
433 return std::string(spec_, parsed_.path.begin, path_len); 426 return std::string(spec_, parsed_.path.begin, path_len);
434 } 427 }
435 428
436 std::string GURL::HostNoBrackets() const { 429 std::string GURL::HostNoBrackets() const {
437 // If host looks like an IPv6 literal, strip the square brackets. 430 // If host looks like an IPv6 literal, strip the square brackets.
438 url::Component h(parsed_.host); 431 url::Component h(parsed_.host);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 } 476 }
484 477
485 const GURL& GURL::EmptyGURL() { 478 const GURL& GURL::EmptyGURL() {
486 // Avoid static object construction/destruction on startup/shutdown. 479 // Avoid static object construction/destruction on startup/shutdown.
487 pthread_once(&empty_gurl_once, EmptyGURLOnce); 480 pthread_once(&empty_gurl_once, EmptyGURLOnce);
488 return *empty_gurl; 481 return *empty_gurl;
489 } 482 }
490 483
491 #endif // WIN32 484 #endif // WIN32
492 485
493 bool GURL::DomainIs(const char* lower_ascii_domain, 486 bool GURL::DomainIs(base::StringPiece lower_ascii_domain) const {
494 int domain_len) const { 487 if (!is_valid_ || lower_ascii_domain.empty())
495 // Return false if this URL is not valid or domain is empty.
496 if (!is_valid_ || !domain_len)
497 return false; 488 return false;
498 489
499 // FileSystem URLs have empty parsed_.host, so check this first. 490 // FileSystem URLs have empty parsed_.host, so check this first.
500 if (SchemeIsFileSystem() && inner_url_) 491 if (SchemeIsFileSystem() && inner_url_)
501 return inner_url_->DomainIs(lower_ascii_domain, domain_len); 492 return inner_url_->DomainIs(lower_ascii_domain);
502 493
503 if (!parsed_.host.is_nonempty()) 494 if (!parsed_.host.is_nonempty())
504 return false; 495 return false;
505 496
506 // Check whether the host name is end with a dot. If yes, treat it 497 // If the host name ends with a dot but the input domain doesn't,
507 // the same as no-dot unless the input comparison domain is end 498 // then we ignore the dot in the host name.
508 // with dot. 499 const char* host_last_pos = spec_.data() + parsed_.host.end() - 1;
509 const char* last_pos = spec_.data() + parsed_.host.end() - 1;
510 int host_len = parsed_.host.len; 500 int host_len = parsed_.host.len;
511 if ('.' == *last_pos && '.' != lower_ascii_domain[domain_len - 1]) { 501 int domain_len = lower_ascii_domain.length();
512 last_pos--; 502 if ('.' == *host_last_pos && '.' != lower_ascii_domain[domain_len - 1]) {
503 host_last_pos--;
513 host_len--; 504 host_len--;
514 } 505 }
515 506
516 // Return false if host's length is less than domain's length.
517 if (host_len < domain_len) 507 if (host_len < domain_len)
518 return false; 508 return false;
519 509
520 // Compare this url whether belong specific domain. 510 // |host_first_pos| is the start of the compared part of the host name, not
521 const char* start_pos = spec_.data() + parsed_.host.begin + 511 // start of the whole host name.
522 host_len - domain_len; 512 const char* host_first_pos = spec_.data() + parsed_.host.begin +
513 host_len - domain_len;
523 514
524 if (!url::LowerCaseEqualsASCII(start_pos, 515 if (!base::LowerCaseEqualsASCII(
525 last_pos + 1, 516 base::StringPiece(host_first_pos, domain_len), lower_ascii_domain))
526 lower_ascii_domain,
527 lower_ascii_domain + domain_len))
528 return false; 517 return false;
529 518
530 // Check whether host has right domain start with dot, make sure we got 519 // Make sure there aren't extra characters in host before the compared part;
531 // right domain range. For example www.google.com has domain 520 // if the host name is longer than the input domain name, then the character
532 // "google.com" but www.iamnotgoogle.com does not. 521 // immediately before the compared part should be a dot. For example,
522 // www.google.com has domain "google.com", but www.iamnotgoogle.com does not.
533 if ('.' != lower_ascii_domain[0] && host_len > domain_len && 523 if ('.' != lower_ascii_domain[0] && host_len > domain_len &&
534 '.' != *(start_pos - 1)) 524 '.' != *(host_first_pos - 1))
535 return false; 525 return false;
536 526
537 return true; 527 return true;
538 } 528 }
539 529
540 void GURL::Swap(GURL* other) { 530 void GURL::Swap(GURL* other) {
541 spec_.swap(other->spec_); 531 spec_.swap(other->spec_);
542 std::swap(is_valid_, other->is_valid_); 532 std::swap(is_valid_, other->is_valid_);
543 std::swap(parsed_, other->parsed_); 533 std::swap(parsed_, other->parsed_);
544 inner_url_.swap(other->inner_url_); 534 inner_url_.swap(other->inner_url_);
545 } 535 }
546 536
547 std::ostream& operator<<(std::ostream& out, const GURL& url) { 537 std::ostream& operator<<(std::ostream& out, const GURL& url) {
548 return out << url.possibly_invalid_spec(); 538 return out << url.possibly_invalid_spec();
549 } 539 }
OLDNEW
« no previous file with comments | « gurl.h ('k') | gurl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698