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

Side by Side Diff: third_party/WebKit/Source/platform/weborigin/KURL.cpp

Issue 2586253004: Revert of Optimize KURL protocols (Closed)
Patch Set: Created 4 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2004, 2007, 2008, 2011, 2012 Apple Inc. All rights reserved. 2 * Copyright (C) 2004, 2007, 2008, 2011, 2012 Apple Inc. All rights reserved.
3 * Copyright (C) 2012 Research In Motion Limited. All rights reserved. 3 * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
4 * Copyright (C) 2008, 2009, 2011 Google Inc. All rights reserved. 4 * Copyright (C) 2008, 2009, 2011 Google Inc. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 16 matching lines...) Expand all
27 27
28 #include "platform/weborigin/KURL.h" 28 #include "platform/weborigin/KURL.h"
29 29
30 #include "platform/weborigin/KnownPorts.h" 30 #include "platform/weborigin/KnownPorts.h"
31 #include "url/url_util.h" 31 #include "url/url_util.h"
32 #include "wtf/MathExtras.h" 32 #include "wtf/MathExtras.h"
33 #include "wtf/PtrUtil.h" 33 #include "wtf/PtrUtil.h"
34 #include "wtf/StdLibExtras.h" 34 #include "wtf/StdLibExtras.h"
35 #include "wtf/text/CString.h" 35 #include "wtf/text/CString.h"
36 #include "wtf/text/StringHash.h" 36 #include "wtf/text/StringHash.h"
37 #include "wtf/text/StringStatics.h"
38 #include "wtf/text/StringUTF8Adaptor.h" 37 #include "wtf/text/StringUTF8Adaptor.h"
39 #include "wtf/text/TextEncoding.h" 38 #include "wtf/text/TextEncoding.h"
40 #include <algorithm> 39 #include <algorithm>
41 #ifndef NDEBUG 40 #ifndef NDEBUG
42 #include <stdio.h> 41 #include <stdio.h>
43 #endif 42 #endif
44 43
45 namespace blink { 44 namespace blink {
46 45
47 static const int maximumValidPortNumber = 0xFFFE; 46 static const int maximumValidPortNumber = 0xFFFE;
48 static const int invalidPortNumber = 0xFFFF; 47 static const int invalidPortNumber = 0xFFFF;
49 48
50 static void assertProtocolIsGood(const char* protocol) { 49 static void assertProtocolIsGood(const char* protocol) {
51 #if ENABLE(ASSERT) 50 #if ENABLE(ASSERT)
52 DCHECK_NE(protocol, "");
53 const char* p = protocol; 51 const char* p = protocol;
54 while (*p) { 52 while (*p) {
55 ASSERT(*p > ' ' && *p < 0x7F && !(*p >= 'A' && *p <= 'Z')); 53 ASSERT(*p > ' ' && *p < 0x7F && !(*p >= 'A' && *p <= 'Z'));
56 ++p; 54 ++p;
57 } 55 }
58 #endif 56 #endif
59 } 57 }
60 58
61 // Note: You must ensure that |spec| is a valid canonicalized URL before calling 59 // Note: You must ensure that |spec| is a valid canonicalized URL before calling
62 // this function. 60 // this function.
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 init(base, relative, &encoding.encodingForFormSubmission()); 234 init(base, relative, &encoding.encodingForFormSubmission());
237 } 235 }
238 236
239 KURL::KURL(const AtomicString& canonicalString, 237 KURL::KURL(const AtomicString& canonicalString,
240 const url::Parsed& parsed, 238 const url::Parsed& parsed,
241 bool isValid) 239 bool isValid)
242 : m_isValid(isValid), 240 : m_isValid(isValid),
243 m_protocolIsInHTTPFamily(false), 241 m_protocolIsInHTTPFamily(false),
244 m_parsed(parsed), 242 m_parsed(parsed),
245 m_string(canonicalString) { 243 m_string(canonicalString) {
246 initProtocolMetadata(); 244 initProtocolIsInHTTPFamily();
247 initInnerURL(); 245 initInnerURL();
248 } 246 }
249 247
250 KURL::KURL(WTF::HashTableDeletedValueType) 248 KURL::KURL(WTF::HashTableDeletedValueType)
251 : m_isValid(false), 249 : m_isValid(false),
252 m_protocolIsInHTTPFamily(false), 250 m_protocolIsInHTTPFamily(false),
253 m_string(WTF::HashTableDeletedValue) {} 251 m_string(WTF::HashTableDeletedValue) {}
254 252
255 KURL::KURL(const KURL& other) 253 KURL::KURL(const KURL& other)
256 : m_isValid(other.m_isValid), 254 : m_isValid(other.m_isValid),
257 m_protocolIsInHTTPFamily(other.m_protocolIsInHTTPFamily), 255 m_protocolIsInHTTPFamily(other.m_protocolIsInHTTPFamily),
258 m_protocol(other.m_protocol),
259 m_parsed(other.m_parsed), 256 m_parsed(other.m_parsed),
260 m_string(other.m_string) { 257 m_string(other.m_string) {
261 if (other.m_innerURL.get()) 258 if (other.m_innerURL.get())
262 m_innerURL = WTF::wrapUnique(new KURL(other.m_innerURL->copy())); 259 m_innerURL = WTF::wrapUnique(new KURL(other.m_innerURL->copy()));
263 } 260 }
264 261
265 KURL::~KURL() {} 262 KURL::~KURL() {}
266 263
267 KURL& KURL::operator=(const KURL& other) { 264 KURL& KURL::operator=(const KURL& other) {
268 m_isValid = other.m_isValid; 265 m_isValid = other.m_isValid;
269 m_protocolIsInHTTPFamily = other.m_protocolIsInHTTPFamily; 266 m_protocolIsInHTTPFamily = other.m_protocolIsInHTTPFamily;
270 m_protocol = other.m_protocol;
271 m_parsed = other.m_parsed; 267 m_parsed = other.m_parsed;
272 m_string = other.m_string; 268 m_string = other.m_string;
273 if (other.m_innerURL) 269 if (other.m_innerURL)
274 m_innerURL = WTF::wrapUnique(new KURL(other.m_innerURL->copy())); 270 m_innerURL = WTF::wrapUnique(new KURL(other.m_innerURL->copy()));
275 else 271 else
276 m_innerURL.reset(); 272 m_innerURL.reset();
277 return *this; 273 return *this;
278 } 274 }
279 275
280 KURL KURL::copy() const { 276 KURL KURL::copy() const {
281 KURL result; 277 KURL result;
282 result.m_isValid = m_isValid; 278 result.m_isValid = m_isValid;
283 result.m_protocolIsInHTTPFamily = m_protocolIsInHTTPFamily; 279 result.m_protocolIsInHTTPFamily = m_protocolIsInHTTPFamily;
284 result.m_protocol = m_protocol.isolatedCopy();
285 result.m_parsed = m_parsed; 280 result.m_parsed = m_parsed;
286 result.m_string = m_string.isolatedCopy(); 281 result.m_string = m_string.isolatedCopy();
287 if (m_innerURL) 282 if (m_innerURL)
288 result.m_innerURL = WTF::wrapUnique(new KURL(m_innerURL->copy())); 283 result.m_innerURL = WTF::wrapUnique(new KURL(m_innerURL->copy()));
289 return result; 284 return result;
290 } 285 }
291 286
292 bool KURL::isNull() const { 287 bool KURL::isNull() const {
293 return m_string.isNull(); 288 return m_string.isNull();
294 } 289 }
(...skipping 15 matching lines...) Expand all
310 } 305 }
311 306
312 bool KURL::hasPath() const { 307 bool KURL::hasPath() const {
313 // Note that http://www.google.com/" has a path, the path is "/". This can 308 // Note that http://www.google.com/" has a path, the path is "/". This can
314 // return false only for invalid or nonstandard URLs. 309 // return false only for invalid or nonstandard URLs.
315 return m_parsed.path.len >= 0; 310 return m_parsed.path.len >= 0;
316 } 311 }
317 312
318 String KURL::lastPathComponent() const { 313 String KURL::lastPathComponent() const {
319 if (!m_isValid) 314 if (!m_isValid)
320 return stringViewForInvalidComponent().toString(); 315 return stringForInvalidComponent();
321 ASSERT(!m_string.isNull()); 316 ASSERT(!m_string.isNull());
322 317
323 // When the output ends in a slash, WebCore has different expectations than 318 // When the output ends in a slash, WebCore has different expectations than
324 // the GoogleURL library. For "/foo/bar/" the library will return the empty 319 // the GoogleURL library. For "/foo/bar/" the library will return the empty
325 // string, but WebCore wants "bar". 320 // string, but WebCore wants "bar".
326 url::Component path = m_parsed.path; 321 url::Component path = m_parsed.path;
327 if (path.len > 0 && m_string[path.end() - 1] == '/') 322 if (path.len > 0 && m_string[path.end() - 1] == '/')
328 path.len--; 323 path.len--;
329 324
330 url::Component file; 325 url::Component file;
331 if (m_string.is8Bit()) 326 if (m_string.is8Bit())
332 url::ExtractFileName(asURLChar8Subtle(m_string), path, &file); 327 url::ExtractFileName(asURLChar8Subtle(m_string), path, &file);
333 else 328 else
334 url::ExtractFileName(m_string.characters16(), path, &file); 329 url::ExtractFileName(m_string.characters16(), path, &file);
335 330
336 // Bug: https://bugs.webkit.org/show_bug.cgi?id=21015 this function returns 331 // Bug: https://bugs.webkit.org/show_bug.cgi?id=21015 this function returns
337 // a null string when the path is empty, which we duplicate here. 332 // a null string when the path is empty, which we duplicate here.
338 if (!file.is_nonempty()) 333 if (!file.is_nonempty())
339 return String(); 334 return String();
340 return componentString(file); 335 return componentString(file);
341 } 336 }
342 337
343 String KURL::protocol() const { 338 String KURL::protocol() const {
344 DCHECK_EQ(componentString(m_parsed.scheme), m_protocol); 339 return componentString(m_parsed.scheme);
345 return m_protocol;
346 } 340 }
347 341
348 String KURL::host() const { 342 String KURL::host() const {
349 return componentString(m_parsed.host); 343 return componentString(m_parsed.host);
350 } 344 }
351 345
352 // Returns 0 when there is no port. 346 // Returns 0 when there is no port.
353 // 347 //
354 // We treat URL's with out-of-range port numbers as invalid URLs, and they will 348 // We treat URL's with out-of-range port numbers as invalid URLs, and they will
355 // be rejected by the canonicalizer. KURL.cpp will allow them in parsing, but 349 // be rejected by the canonicalizer. KURL.cpp will allow them in parsing, but
356 // return invalidPortNumber from this port() function, so we mirror that 350 // return invalidPortNumber from this port() function, so we mirror that
357 // behavior here. 351 // behavior here.
358 unsigned short KURL::port() const { 352 unsigned short KURL::port() const {
359 if (!m_isValid || m_parsed.port.len <= 0) 353 if (!m_isValid || m_parsed.port.len <= 0)
360 return 0; 354 return 0;
361 ASSERT(!m_string.isNull()); 355 ASSERT(!m_string.isNull());
362 int port = m_string.is8Bit() 356 int port = m_string.is8Bit()
363 ? url::ParsePort(asURLChar8Subtle(m_string), m_parsed.port) 357 ? url::ParsePort(asURLChar8Subtle(m_string), m_parsed.port)
364 : url::ParsePort(m_string.characters16(), m_parsed.port); 358 : url::ParsePort(m_string.characters16(), m_parsed.port);
365 ASSERT(port != url::PORT_UNSPECIFIED); // Checked port.len <= 0 before. 359 ASSERT(port != url::PORT_UNSPECIFIED); // Checked port.len <= 0 before.
366 360
367 if (port == url::PORT_INVALID || 361 if (port == url::PORT_INVALID ||
368 port > maximumValidPortNumber) // Mimic KURL::port() 362 port > maximumValidPortNumber) // Mimic KURL::port()
369 port = invalidPortNumber; 363 port = invalidPortNumber;
370 364
371 return static_cast<unsigned short>(port); 365 return static_cast<unsigned short>(port);
372 } 366 }
373 367
374 // TODO(csharrison): Migrate pass() and user() to return a StringView. Most
375 // consumers just need to know if the string is empty.
376
377 String KURL::pass() const { 368 String KURL::pass() const {
378 // Bug: https://bugs.webkit.org/show_bug.cgi?id=21015 this function returns 369 // Bug: https://bugs.webkit.org/show_bug.cgi?id=21015 this function returns
379 // a null string when the password is empty, which we duplicate here. 370 // a null string when the password is empty, which we duplicate here.
380 if (!m_parsed.password.is_nonempty()) 371 if (!m_parsed.password.is_nonempty())
381 return String(); 372 return String();
382 return componentString(m_parsed.password); 373 return componentString(m_parsed.password);
383 } 374 }
384 375
385 String KURL::user() const { 376 String KURL::user() const {
386 return componentString(m_parsed.username); 377 return componentString(m_parsed.username);
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 // non-Atomic input as Atomic here, we will render the (const) input string 760 // non-Atomic input as Atomic here, we will render the (const) input string
770 // thread unsafe. 761 // thread unsafe.
771 if (!relative.isNull() && relative.impl()->isAtomic() && 762 if (!relative.isNull() && relative.impl()->isAtomic() &&
772 StringView(output.data(), static_cast<unsigned>(output.length())) == 763 StringView(output.data(), static_cast<unsigned>(output.length())) ==
773 relative) { 764 relative) {
774 m_string = relative; 765 m_string = relative;
775 } else { 766 } else {
776 m_string = AtomicString::fromUTF8(output.data(), output.length()); 767 m_string = AtomicString::fromUTF8(output.data(), output.length());
777 } 768 }
778 769
779 initProtocolMetadata(); 770 initProtocolIsInHTTPFamily();
780 initInnerURL(); 771 initInnerURL();
772 DCHECK_EQ(protocol(), protocol().lower());
781 } 773 }
782 774
783 void KURL::initInnerURL() { 775 void KURL::initInnerURL() {
784 if (!m_isValid) { 776 if (!m_isValid) {
785 m_innerURL.reset(); 777 m_innerURL.reset();
786 return; 778 return;
787 } 779 }
788 if (url::Parsed* innerParsed = m_parsed.inner_parsed()) 780 if (url::Parsed* innerParsed = m_parsed.inner_parsed())
789 m_innerURL = WTF::wrapUnique(new KURL( 781 m_innerURL = WTF::wrapUnique(new KURL(
790 ParsedURLString, 782 ParsedURLString,
791 m_string.substring(innerParsed->scheme.begin, 783 m_string.substring(innerParsed->scheme.begin,
792 innerParsed->Length() - innerParsed->scheme.begin))); 784 innerParsed->Length() - innerParsed->scheme.begin)));
793 else 785 else
794 m_innerURL.reset(); 786 m_innerURL.reset();
795 } 787 }
796 788
797 void KURL::initProtocolMetadata() { 789 template <typename CHAR>
790 bool internalProtocolIs(const url::Component& scheme,
791 const CHAR* spec,
792 const char* protocol) {
793 const CHAR* begin = spec + scheme.begin;
794 const CHAR* end = begin + scheme.len;
795
796 while (begin != end && *protocol) {
797 ASSERT(toASCIILower(*protocol) == *protocol);
798 if (toASCIILower(*begin++) != *protocol++)
799 return false;
800 }
801
802 // Both strings are equal (ignoring case) if and only if all of the characters
803 // were equal, and the end of both has been reached.
804 return begin == end && !*protocol;
805 }
806
807 template <typename CHAR>
808 bool checkIfProtocolIsInHTTPFamily(const url::Component& scheme,
809 const CHAR* spec) {
810 if (scheme.len == 4)
811 return internalProtocolIs(scheme, spec, "http");
812 if (scheme.len == 5)
813 return internalProtocolIs(scheme, spec, "https");
814 if (scheme.len == 7)
815 return internalProtocolIs(scheme, spec, "http-so");
816 if (scheme.len == 8)
817 return internalProtocolIs(scheme, spec, "https-so");
818 return false;
819 }
820
821 void KURL::initProtocolIsInHTTPFamily() {
798 if (!m_isValid) { 822 if (!m_isValid) {
799 m_protocolIsInHTTPFamily = false; 823 m_protocolIsInHTTPFamily = false;
800 m_protocol = componentString(m_parsed.scheme);
801 return; 824 return;
802 } 825 }
803 826
804 DCHECK(!m_string.isNull()); 827 ASSERT(!m_string.isNull());
805 StringView protocol = componentStringView(m_parsed.scheme); 828 m_protocolIsInHTTPFamily =
806 m_protocolIsInHTTPFamily = true; 829 m_string.is8Bit() ? checkIfProtocolIsInHTTPFamily(m_parsed.scheme,
807 if (protocol == WTF::httpsAtom) { 830 m_string.characters8())
808 m_protocol = WTF::httpsAtom; 831 : checkIfProtocolIsInHTTPFamily(
809 } else if (protocol == WTF::httpAtom) { 832 m_parsed.scheme, m_string.characters16());
810 m_protocol = WTF::httpAtom;
811 } else {
812 m_protocol = AtomicString(protocol.toString());
813 m_protocolIsInHTTPFamily =
814 m_protocol == "http-so" || m_protocol == "https-so";
815 }
816 DCHECK_EQ(m_protocol, m_protocol.lower());
817 } 833 }
818 834
819 bool KURL::protocolIs(const char* protocol) const { 835 bool KURL::protocolIs(const char* protocol) const {
820 assertProtocolIsGood(protocol); 836 assertProtocolIsGood(protocol);
821 837
822 // JavaScript URLs are "valid" and should be executed even if KURL decides 838 // JavaScript URLs are "valid" and should be executed even if KURL decides
823 // they are invalid. The free function protocolIsJavaScript() should be used 839 // they are invalid. The free function protocolIsJavaScript() should be used
824 // instead. 840 // instead.
825 // FIXME: Chromium code needs to be fixed for this assert to be enabled. 841 // FIXME: Chromium code needs to be fixed for this assert to be enabled.
826 // ASSERT(strcmp(protocol, "javascript")); 842 // ASSERT(strcmp(protocol, "javascript"));
827 return m_protocol == protocol; 843
844 if (m_string.isNull() || m_parsed.scheme.len <= 0)
845 return *protocol == '\0';
846
847 return m_string.is8Bit()
848 ? internalProtocolIs(m_parsed.scheme, m_string.characters8(),
849 protocol)
850 : internalProtocolIs(m_parsed.scheme, m_string.characters16(),
851 protocol);
828 } 852 }
829 853
830 StringView KURL::stringViewForInvalidComponent() const { 854 String KURL::stringForInvalidComponent() const {
831 return m_string.isNull() ? StringView() : StringView("", 0); 855 if (m_string.isNull())
856 return String();
857 return emptyString();
832 } 858 }
833 859
834 StringView KURL::componentStringView(const url::Component& component) const { 860 String KURL::componentString(const url::Component& component) const {
835 if (!m_isValid || component.len <= 0) 861 if (!m_isValid || component.len <= 0)
836 return stringViewForInvalidComponent(); 862 return stringForInvalidComponent();
837 // begin and len are in terms of bytes which do not match 863 // begin and len are in terms of bytes which do not match
838 // if string() is UTF-16 and input contains non-ASCII characters. 864 // if string() is UTF-16 and input contains non-ASCII characters.
839 // However, the only part in urlString that can contain non-ASCII 865 // However, the only part in urlString that can contain non-ASCII
840 // characters is 'ref' at the end of the string. In that case, 866 // characters is 'ref' at the end of the string. In that case,
841 // begin will always match the actual value and len (in terms of 867 // begin will always match the actual value and len (in terms of
842 // byte) will be longer than what's needed by 'mid'. However, mid 868 // byte) will be longer than what's needed by 'mid'. However, mid
843 // truncates len to avoid go past the end of a string so that we can 869 // truncates len to avoid go past the end of a string so that we can
844 // get away without doing anything here. 870 // get away without doing anything here.
845 871 return getString().substring(component.begin, component.len);
846 int maxLength = getString().length() - component.begin;
847 return StringView(getString(), component.begin,
848 component.len > maxLength ? maxLength : component.len);
849 }
850
851 String KURL::componentString(const url::Component& component) const {
852 return componentStringView(component).toString();
853 } 872 }
854 873
855 template <typename CHAR> 874 template <typename CHAR>
856 void KURL::replaceComponents(const url::Replacements<CHAR>& replacements) { 875 void KURL::replaceComponents(const url::Replacements<CHAR>& replacements) {
857 url::RawCanonOutputT<char> output; 876 url::RawCanonOutputT<char> output;
858 url::Parsed newParsed; 877 url::Parsed newParsed;
859 878
860 StringUTF8Adaptor utf8(m_string); 879 StringUTF8Adaptor utf8(m_string);
861 m_isValid = url::ReplaceComponents(utf8.data(), utf8.length(), m_parsed, 880 m_isValid = url::ReplaceComponents(utf8.data(), utf8.length(), m_parsed,
862 replacements, 0, &output, &newParsed); 881 replacements, 0, &output, &newParsed);
863 882
864 m_parsed = newParsed; 883 m_parsed = newParsed;
865 m_string = AtomicString::fromUTF8(output.data(), output.length()); 884 m_string = AtomicString::fromUTF8(output.data(), output.length());
866 initProtocolMetadata();
867 } 885 }
868 886
869 bool KURL::isSafeToSendToAnotherThread() const { 887 bool KURL::isSafeToSendToAnotherThread() const {
870 return m_string.isSafeToSendToAnotherThread() && 888 return m_string.isSafeToSendToAnotherThread() &&
871 (!m_innerURL || m_innerURL->isSafeToSendToAnotherThread()); 889 (!m_innerURL || m_innerURL->isSafeToSendToAnotherThread());
872 } 890 }
873 891
874 } // namespace blink 892 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/weborigin/KURL.h ('k') | third_party/WebKit/Source/platform/weborigin/KURLTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698