1e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)/* 2e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) * Copyright (C) 2004, 2007, 2008, 2011, 2012 Apple Inc. All rights reserved. 3e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) * Copyright (C) 2012 Research In Motion Limited. All rights reserved. 4e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) * Copyright (C) 2008, 2009, 2011 Google Inc. All rights reserved. 5e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) * 6e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without 7e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) * modification, are permitted provided that the following conditions 8e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) * are met: 9e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 10e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) * notice, this list of conditions and the following disclaimer. 11e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 12e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 13e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) * documentation and/or other materials provided with the distribution. 14e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) * 15e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 16e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 19e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 20e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 23e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) */ 27e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 28e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#include "config.h" 2951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "platform/weborigin/KURL.h" 30e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 3151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "platform/weborigin/KnownPorts.h" 32e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#include "wtf/StdLibExtras.h" 33e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#include "wtf/text/CString.h" 34e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#include "wtf/text/StringHash.h" 3593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "wtf/text/StringUTF8Adaptor.h" 36e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#include "wtf/text/TextEncoding.h" 3793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include <algorithm> 38521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include <url/url_util.h> 398abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#ifndef NDEBUG 408abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#include <stdio.h> 418abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#endif 42e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 43c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 44e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 45f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)static const int maximumValidPortNumber = 0xFFFE; 46f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)static const int invalidPortNumber = 0xFFFF; 47e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 48e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)static void assertProtocolIsGood(const char* protocol) 49e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 50197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT) 51e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) const char* p = protocol; 52e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) while (*p) { 53e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) ASSERT(*p > ' ' && *p < 0x7F && !(*p >= 'A' && *p <= 'Z')); 54e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) ++p; 55e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) } 56e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#endif 57e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 58e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 59f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)// Note: You must ensure that |spec| is a valid canonicalized URL before calling this function. 6093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)static const char* asURLChar8Subtle(const String& spec) 6193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){ 6293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) ASSERT(spec.is8Bit()); 6393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // characters8 really return characters in Latin-1, but because we canonicalize 6493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // URL strings, we know that everything before the fragment identifier will 6593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // actually be ASCII, which means this cast is safe as long as you don't look 6693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // at the fragment component. 6793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return reinterpret_cast<const char*>(spec.characters8()); 6893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} 6993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 70e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)// Returns the characters for the given string, or a pointer to a static empty 71e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)// string if the input string is null. This will always ensure we have a non- 72e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)// null character pointer since ReplaceComponents has special meaning for null. 7393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)static const char* charactersOrEmpty(const StringUTF8Adaptor& string) 74e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 7593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) static const char zero = 0; 7693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return string.data() ? string.data() : &zero; 77e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 78e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 79e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)static bool isSchemeFirstChar(char c) 80e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 81e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); 82e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 83e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 84e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)static bool isSchemeChar(char c) 85e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 86e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return isSchemeFirstChar(c) || (c >= '0' && c <= '9') || c == '.' || c == '-' || c == '+'; 87e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 88e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 8993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)static bool isUnicodeEncoding(const WTF::TextEncoding* encoding) 9093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){ 9193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return encoding->encodingForFormSubmission() == UTF8Encoding(); 9293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} 9393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 9493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)namespace { 9593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 9610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdochclass KURLCharsetConverter FINAL : public url::CharsetConverter { 9793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)public: 9893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // The encoding parameter may be 0, but in this case the object must not be called. 9993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) explicit KURLCharsetConverter(const WTF::TextEncoding* encoding) 10093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) : m_encoding(encoding) 10193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) { 10293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 10393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 10410f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch virtual void ConvertFromUTF16(const url::UTF16Char* input, int inputLength, url::CanonOutput* output) OVERRIDE 10593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) { 10602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch CString encoded = m_encoding->normalizeAndEncode(String(input, inputLength), WTF::URLEncodedEntitiesForUnencodables); 10793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) output->Append(encoded.data(), static_cast<int>(encoded.length())); 10893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 10993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 11093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)private: 11193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) const WTF::TextEncoding* m_encoding; 11293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}; 11393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 11493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} // namespace 11593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 116e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)bool isValidProtocol(const String& protocol) 117e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 118e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // RFC3986: ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) 119e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) if (protocol.isEmpty()) 120e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return false; 121e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) if (!isSchemeFirstChar(protocol[0])) 122e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return false; 123e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) unsigned protocolLength = protocol.length(); 124e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) for (unsigned i = 1; i < protocolLength; i++) { 125e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) if (!isSchemeChar(protocol[i])) 126e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return false; 127e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) } 128e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return true; 129e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 130e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 131e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)String KURL::strippedForUseAsReferrer() const 132e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 13310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch if (protocolIsAbout() || protocolIs("data") || protocolIs("javascript")) 13409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return String(); 13509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 136323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) if (m_parsed.username.is_nonempty() || m_parsed.password.is_nonempty() || m_parsed.ref.is_nonempty()) { 137323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) KURL referrer(*this); 138323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) referrer.setUser(String()); 139323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) referrer.setPass(String()); 140323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) referrer.removeFragmentIdentifier(); 141323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) return referrer.string(); 142323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) } 143323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) return string(); 144e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 145e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 146e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)bool KURL::isLocalFile() const 147e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 148e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // Including feed here might be a bad idea since drag and drop uses this check 149e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // and including feed would allow feeds to potentially let someone's blog 150e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // read the contents of the clipboard on a drag, even without a drop. 151e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // Likewise with using the FrameLoader::shouldTreatURLAsLocal() function. 152e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return protocolIs("file"); 153e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 154e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 155e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)bool protocolIsJavaScript(const String& url) 156e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 157e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return protocolIs(url, "javascript"); 158e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 159e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 160e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)const KURL& blankURL() 161e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 162e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) DEFINE_STATIC_LOCAL(KURL, staticBlankURL, (ParsedURLString, "about:blank")); 163e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return staticBlankURL; 164e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 165e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 16610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdochbool KURL::isAboutBlankURL() const 167e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 16810f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch return *this == blankURL(); 169e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 170e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 171e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)String KURL::elidedString() const 172e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 173e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) if (string().length() <= 1024) 174e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return string(); 175e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 176e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return string().left(511) + "..." + string().right(510); 177e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 178e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 179f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)KURL::KURL() 180f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) : m_isValid(false) 181f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) , m_protocolIsInHTTPFamily(false) 182f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){ 183f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)} 184f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) 185e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)// Initializes with a string representing an absolute URL. No encoding 186e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)// information is specified. This generally happens when a KURL is converted 187e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)// to a string and then converted back. In this case, the URL is already 188e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)// canonical and in proper escaped form so needs no encoding. We treat it as 189e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)// UTF-8 just in case. 190e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)KURL::KURL(ParsedURLStringTag, const String& url) 191e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 192e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) if (!url.isNull()) 19393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) init(KURL(), url, 0); 194e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) else { 195e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // WebCore expects us to preserve the nullness of strings when this 196e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // constructor is used. In all other cases, it expects a non-null 197e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // empty string, which is what init() will create. 19893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) m_isValid = false; 19993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) m_protocolIsInHTTPFamily = false; 200e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) } 201e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 202e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 2035267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)KURL KURL::createIsolated(ParsedURLStringTag, const String& url) 2045267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles){ 2055267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) // FIXME: We should be able to skip this extra copy and created an 2065267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) // isolated KURL more efficiently. 2075267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) return KURL(ParsedURLString, url).copy(); 2085267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)} 2095267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 210e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)// Constructs a new URL given a base URL and a possibly relative input URL. 211e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)// This assumes UTF-8 encoding. 212e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)KURL::KURL(const KURL& base, const String& relative) 213e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 21493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) init(base, relative, 0); 215e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 216e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 217e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)// Constructs a new URL given a base URL and a possibly relative input URL. 218e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)// Any query portion of the relative URL will be encoded in the given encoding. 219e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)KURL::KURL(const KURL& base, const String& relative, const WTF::TextEncoding& encoding) 220e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 22193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) init(base, relative, &encoding.encodingForFormSubmission()); 222e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 223e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 22410f88d5669dbd969c059d61ba09fa37dd72ac559Ben MurdochKURL::KURL(const AtomicString& canonicalString, const url::Parsed& parsed, bool isValid) 22593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) : m_isValid(isValid) 22693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) , m_protocolIsInHTTPFamily(false) 22793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) , m_parsed(parsed) 228fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch , m_string(canonicalString) 22993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){ 23093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) initProtocolIsInHTTPFamily(); 23193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) initInnerURL(); 23293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} 23393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 23493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)KURL::KURL(WTF::HashTableDeletedValueType) 23593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) : m_isValid(false) 23693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) , m_protocolIsInHTTPFamily(false) 23793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) , m_string(WTF::HashTableDeletedValue) 238e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 23993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} 24093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 24193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)KURL::KURL(const KURL& other) 24293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) : m_isValid(other.m_isValid) 24393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) , m_protocolIsInHTTPFamily(other.m_protocolIsInHTTPFamily) 24493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) , m_parsed(other.m_parsed) 24593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) , m_string(other.m_string) 24693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){ 24793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (other.m_innerURL.get()) 24893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) m_innerURL = adoptPtr(new KURL(other.m_innerURL->copy())); 24993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} 25093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 25193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)KURL& KURL::operator=(const KURL& other) 25293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){ 25393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) m_isValid = other.m_isValid; 25493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) m_protocolIsInHTTPFamily = other.m_protocolIsInHTTPFamily; 25593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) m_parsed = other.m_parsed; 25693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) m_string = other.m_string; 25793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (other.m_innerURL) 25893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) m_innerURL = adoptPtr(new KURL(other.m_innerURL->copy())); 259e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) else 26093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) m_innerURL.clear(); 26193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return *this; 262e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 263e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 264d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) 265d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)KURL::KURL(KURL&& other) 266d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) : m_isValid(other.m_isValid) 267d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) , m_protocolIsInHTTPFamily(other.m_protocolIsInHTTPFamily) 268d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) , m_parsed(other.m_parsed) 269d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // FIXME: Instead of explicitly casting to String&& here, we should use std::move, but that requires us to 270d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // have a standard library that supports move semantics. 271d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) , m_string(static_cast<String&&>(other.m_string)) 272d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) , m_innerURL(other.m_innerURL.release()) 273d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){ 274d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)} 275d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 276d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)KURL& KURL::operator=(KURL&& other) 277d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){ 278d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) m_isValid = other.m_isValid; 279d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) m_protocolIsInHTTPFamily = other.m_protocolIsInHTTPFamily; 280d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) m_parsed = other.m_parsed; 281d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // FIXME: Instead of explicitly casting to String&& here, we should use std::move, but that requires us to 282d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) // have a standard library that supports move semantics. 283d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) m_string = static_cast<String&&>(other.m_string); 284d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) m_innerURL = other.m_innerURL.release(); 285d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) return *this; 286d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)} 287d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#endif 288d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 289e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)KURL KURL::copy() const 290e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 29193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) KURL result; 29293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) result.m_isValid = m_isValid; 29393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) result.m_protocolIsInHTTPFamily = m_protocolIsInHTTPFamily; 29493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) result.m_parsed = m_parsed; 29593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) result.m_string = m_string.isolatedCopy(); 2966f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch if (m_innerURL) 29793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) result.m_innerURL = adoptPtr(new KURL(m_innerURL->copy())); 298e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return result; 299e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 300e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 301e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)bool KURL::isNull() const 302e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 30393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return m_string.isNull(); 304e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 305e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 306e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)bool KURL::isEmpty() const 307e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 30893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return m_string.isEmpty(); 309e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 310e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 311e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)bool KURL::isValid() const 312e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 31393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return m_isValid; 314e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 315e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 316e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)bool KURL::hasPort() const 317e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 318e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return hostEnd() < pathStart(); 319e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 320e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 321e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)bool KURL::protocolIsInHTTPFamily() const 322e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 32393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return m_protocolIsInHTTPFamily; 324e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 325e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 326e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)bool KURL::hasPath() const 327e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 328e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // Note that http://www.google.com/" has a path, the path is "/". This can 329e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // return false only for invalid or nonstandard URLs. 33093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return m_parsed.path.len >= 0; 331e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 332e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 333e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)// We handle "parameters" separated by a semicolon, while KURL.cpp does not, 334e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)// which can lead to different results in some cases. 335e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)String KURL::lastPathComponent() const 336e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 337f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) if (!m_isValid) 338f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return stringForInvalidComponent(); 3399bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) ASSERT(!m_string.isNull()); 340f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) 341e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // When the output ends in a slash, WebCore has different expectations than 342e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // the GoogleURL library. For "/foo/bar/" the library will return the empty 343e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // string, but WebCore wants "bar". 34410f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::Component path = m_parsed.path; 34593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (path.len > 0 && m_string[path.end() - 1] == '/') 346e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) path.len--; 347e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 34810f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::Component file; 3499bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) if (m_string.is8Bit()) 35010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::ExtractFileName(asURLChar8Subtle(m_string), path, &file); 35193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) else 35210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::ExtractFileName(m_string.characters16(), path, &file); 353e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 354e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // Bug: https://bugs.webkit.org/show_bug.cgi?id=21015 this function returns 355e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // a null string when the path is empty, which we duplicate here. 356e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) if (!file.is_nonempty()) 357e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return String(); 35893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return componentString(file); 359e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 360e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 361e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)String KURL::protocol() const 362e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 36393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return componentString(m_parsed.scheme); 364e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 365e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 366e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)String KURL::host() const 367e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 36893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return componentString(m_parsed.host); 369e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 370e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 371e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)// Returns 0 when there is no port. 372e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)// 373e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)// We treat URL's with out-of-range port numbers as invalid URLs, and they will 374e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)// be rejected by the canonicalizer. KURL.cpp will allow them in parsing, but 375e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)// return invalidPortNumber from this port() function, so we mirror that behavior here. 376e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)unsigned short KURL::port() const 377e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 37893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (!m_isValid || m_parsed.port.len <= 0) 379e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return 0; 3809bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) ASSERT(!m_string.isNull()); 3819bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) int port = m_string.is8Bit() ? 38210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::ParsePort(asURLChar8Subtle(m_string), m_parsed.port) : 38310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::ParsePort(m_string.characters16(), m_parsed.port); 38410f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch ASSERT(port != url::PORT_UNSPECIFIED); // Checked port.len <= 0 before. 385e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 38610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch if (port == url::PORT_INVALID || port > maximumValidPortNumber) // Mimic KURL::port() 387e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) port = invalidPortNumber; 388e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 389e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return static_cast<unsigned short>(port); 390e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 391e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 392e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)String KURL::pass() const 393e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 394e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // Bug: https://bugs.webkit.org/show_bug.cgi?id=21015 this function returns 395e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // a null string when the password is empty, which we duplicate here. 39693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (!m_parsed.password.is_nonempty()) 397e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return String(); 39893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return componentString(m_parsed.password); 399e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 400e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 401e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)String KURL::user() const 402e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 40393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return componentString(m_parsed.username); 404e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 405e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 406e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)String KURL::fragmentIdentifier() const 407e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 408e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // Empty but present refs ("foo.com/bar#") should result in the empty 40993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // string, which componentString will produce. Nonexistent refs 410e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // should be the null string. 41193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (!m_parsed.ref.is_valid()) 412e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return String(); 41393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return componentString(m_parsed.ref); 414e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 415e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 416e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)bool KURL::hasFragmentIdentifier() const 417e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 41893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return m_parsed.ref.len >= 0; 419e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 420e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 421e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)String KURL::baseAsString() const 422e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 423e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // FIXME: There is probably a more efficient way to do this? 42493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return m_string.left(pathAfterLastSlash()); 425e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 426e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 427e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)String KURL::query() const 428e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 42993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (m_parsed.query.len >= 0) 43093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return componentString(m_parsed.query); 431e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 432e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // Bug: https://bugs.webkit.org/show_bug.cgi?id=21015 this function returns 433e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // an empty string when the query is empty rather than a null (not sure 434e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // which is right). 435e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // Returns a null if the query is not specified, instead of empty. 43693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (m_parsed.query.is_valid()) 43793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return emptyString(); 438e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return String(); 439e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 440e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 441e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)String KURL::path() const 442e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 44393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return componentString(m_parsed.path); 444e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 445e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 446e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)bool KURL::setProtocol(const String& protocol) 447e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 448e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // Firefox and IE remove everything after the first ':'. 449e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) int separatorPosition = protocol.find(':'); 450e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) String newProtocol = protocol.substring(0, separatorPosition); 45193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) StringUTF8Adaptor newProtocolUTF8(newProtocol); 452e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 453e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // If KURL is given an invalid scheme, it returns failure without modifying 454e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // the URL at all. This is in contrast to most other setters which modify 455e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // the URL and set "m_isValid." 45610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::RawCanonOutputT<char> canonProtocol; 45710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::Component protocolComponent; 45810f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch if (!url::CanonicalizeScheme(newProtocolUTF8.data(), url::Component(0, newProtocolUTF8.length()), &canonProtocol, &protocolComponent) 459e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) || !protocolComponent.is_nonempty()) 460e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return false; 461e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 46210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::Replacements<char> replacements; 46310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch replacements.SetScheme(charactersOrEmpty(newProtocolUTF8), url::Component(0, newProtocolUTF8.length())); 46493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) replaceComponents(replacements); 465e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 466e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // isValid could be false but we still return true here. This is because 467e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // WebCore or JS scripts can build up a URL by setting individual 468e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // components, and a JS exception is based on the return value of this 469e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // function. We want to throw the exception and stop the script only when 470e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // its trying to set a bad protocol, and not when it maybe just hasn't 471e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // finished building up its final scheme. 472e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return true; 473e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 474e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 475e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)void KURL::setHost(const String& host) 476e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 47793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) StringUTF8Adaptor hostUTF8(host); 47810f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::Replacements<char> replacements; 47910f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch replacements.SetHost(charactersOrEmpty(hostUTF8), url::Component(0, hostUTF8.length())); 48093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) replaceComponents(replacements); 481e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 482e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 483bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)static String parsePortFromStringPosition(const String& value, unsigned portStart) 484bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles){ 485bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) // "008080junk" needs to be treated as port "8080" and "000" as "0". 486bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) size_t length = value.length(); 487bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) unsigned portEnd = portStart; 488bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) while (isASCIIDigit(value[portEnd]) && portEnd < length) 489bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) ++portEnd; 490bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) while (value[portStart] == '0' && portStart < portEnd - 1) 491bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) ++portStart; 492bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 493bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) // Required for backwards compat. 494bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) // https://www.w3.org/Bugs/Public/show_bug.cgi?id=23463 495bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) if (portStart == portEnd) 496bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return "0"; 497bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 498bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return value.substring(portStart, portEnd - portStart); 499bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)} 500bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 50193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)void KURL::setHostAndPort(const String& hostAndPort) 502e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 503bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) size_t separator = hostAndPort.find(':'); 504bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) if (!separator) 505bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return; 506bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 507bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) if (separator == kNotFound) { 50810f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::Replacements<char> replacements; 509bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) StringUTF8Adaptor hostUTF8(hostAndPort); 51010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch replacements.SetHost(charactersOrEmpty(hostUTF8), url::Component(0, hostUTF8.length())); 511bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) replaceComponents(replacements); 512bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return; 513e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) } 514e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 515bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) String host = hostAndPort.substring(0, separator); 516bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) String port = parsePortFromStringPosition(hostAndPort, separator + 1); 517bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 51893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) StringUTF8Adaptor hostUTF8(host); 51993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) StringUTF8Adaptor portUTF8(port); 52093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 52110f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::Replacements<char> replacements; 52210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch replacements.SetHost(charactersOrEmpty(hostUTF8), url::Component(0, hostUTF8.length())); 52310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch replacements.SetPort(charactersOrEmpty(portUTF8), url::Component(0, portUTF8.length())); 52493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) replaceComponents(replacements); 525e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 526e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 527e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)void KURL::removePort() 528e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 529e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) if (!hasPort()) 530e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return; 53110f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::Replacements<char> replacements; 53293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) replacements.ClearPort(); 53393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) replaceComponents(replacements); 534e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 535e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 536bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)void KURL::setPort(const String& port) 537e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 538bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) String parsedPort = parsePortFromStringPosition(port, 0); 539bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) setPort(parsedPort.toUInt()); 540bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)} 541bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 542bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)void KURL::setPort(unsigned short port) 543bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles){ 544bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) if (isDefaultPortForProtocol(port, protocol())) { 545bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) removePort(); 546bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return; 547bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) } 548bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 549bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) String portString = String::number(port); 55093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) ASSERT(portString.is8Bit()); 551e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 55210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::Replacements<char> replacements; 55310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch replacements.SetPort(reinterpret_cast<const char*>(portString.characters8()), url::Component(0, portString.length())); 55493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) replaceComponents(replacements); 555e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 556e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 557e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)void KURL::setUser(const String& user) 558e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 559e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // This function is commonly called to clear the username, which we 560e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // normally don't have, so we optimize this case. 56193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (user.isEmpty() && !m_parsed.username.is_valid()) 562e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return; 563e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 564e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // The canonicalizer will clear any usernames that are empty, so we 565e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // don't have to explicitly call ClearUsername() here. 56693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) StringUTF8Adaptor userUTF8(user); 56710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::Replacements<char> replacements; 56810f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch replacements.SetUsername(charactersOrEmpty(userUTF8), url::Component(0, userUTF8.length())); 56993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) replaceComponents(replacements); 570e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 571e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 572e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)void KURL::setPass(const String& pass) 573e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 574e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // This function is commonly called to clear the password, which we 575e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // normally don't have, so we optimize this case. 57693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (pass.isEmpty() && !m_parsed.password.is_valid()) 577e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return; 578e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 579e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // The canonicalizer will clear any passwords that are empty, so we 580e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // don't have to explicitly call ClearUsername() here. 58193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) StringUTF8Adaptor passUTF8(pass); 58210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::Replacements<char> replacements; 58310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch replacements.SetPassword(charactersOrEmpty(passUTF8), url::Component(0, passUTF8.length())); 58493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) replaceComponents(replacements); 585e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 586e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 58793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)void KURL::setFragmentIdentifier(const String& fragment) 588e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 589e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // This function is commonly called to clear the ref, which we 590e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // normally don't have, so we optimize this case. 59193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (fragment.isNull() && !m_parsed.ref.is_valid()) 592e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return; 593e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 59493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) StringUTF8Adaptor fragmentUTF8(fragment); 59593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 59610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::Replacements<char> replacements; 59793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (fragment.isNull()) 598e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) replacements.ClearRef(); 599e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) else 60010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch replacements.SetRef(charactersOrEmpty(fragmentUTF8), url::Component(0, fragmentUTF8.length())); 60193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) replaceComponents(replacements); 602e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 603e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 604e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)void KURL::removeFragmentIdentifier() 605e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 60610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::Replacements<char> replacements; 607e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) replacements.ClearRef(); 60893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) replaceComponents(replacements); 609e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 610e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 611e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)void KURL::setQuery(const String& query) 612e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 61393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) StringUTF8Adaptor queryUTF8(query); 61410f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::Replacements<char> replacements; 615e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) if (query.isNull()) { 616e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // KURL.cpp sets to null to clear any query. 617e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) replacements.ClearQuery(); 618e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) } else if (query.length() > 0 && query[0] == '?') { 619e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // WebCore expects the query string to begin with a question mark, but 620e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // GoogleURL doesn't. So we trim off the question mark when setting. 62110f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch replacements.SetQuery(charactersOrEmpty(queryUTF8), url::Component(1, queryUTF8.length() - 1)); 622e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) } else { 623e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // When set with the empty string or something that doesn't begin with 624e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // a question mark, KURL.cpp will add a question mark for you. The only 625e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // way this isn't compatible is if you call this function with an empty 626e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // string. KURL.cpp will leave a '?' with nothing following it in the 627e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // URL, whereas we'll clear it. 628e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // FIXME We should eliminate this difference. 62910f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch replacements.SetQuery(charactersOrEmpty(queryUTF8), url::Component(0, queryUTF8.length())); 630e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) } 63193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) replaceComponents(replacements); 632e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 633e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 634e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)void KURL::setPath(const String& path) 635e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 636e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // Empty paths will be canonicalized to "/", so we don't have to worry 637e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // about calling ClearPath(). 63893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) StringUTF8Adaptor pathUTF8(path); 63910f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::Replacements<char> replacements; 64010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch replacements.SetPath(charactersOrEmpty(pathUTF8), url::Component(0, pathUTF8.length())); 64193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) replaceComponents(replacements); 642e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 643e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 644e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)String decodeURLEscapeSequences(const String& string) 645e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 646e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return decodeURLEscapeSequences(string, UTF8Encoding()); 647e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 648e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 649e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)// In KURL.cpp's implementation, this is called by every component getter. 650e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)// It will unescape every character, including '\0'. This is scary, and may 651e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)// cause security holes. We never call this function for components, and 652e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)// just return the ASCII versions instead. 653e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)// 654e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)// This function is also used to decode javascript: URLs and as a general 655e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)// purpose unescaping function. 656e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)// 657e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)// FIXME These should be merged to the KURL.cpp implementation. 658e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)String decodeURLEscapeSequences(const String& string, const WTF::TextEncoding& encoding) 659e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 660e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // FIXME We can probably use KURL.cpp's version of this function 661e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // without modification. However, I'm concerned about 662e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // https://bugs.webkit.org/show_bug.cgi?id=20559 so am keeping this old 663e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // custom code for now. Using their version will also fix the bug that 664e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // we ignore the encoding. 665e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // 666e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // FIXME b/1350291: This does not get called very often. We just convert 667e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // first to 8-bit UTF-8, then unescape, then back to 16-bit. This kind of 668e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // sucks, and we don't use the encoding properly, which will make some 669e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // obscure anchor navigations fail. 67093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) StringUTF8Adaptor stringUTF8(string); 67110f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::RawCanonOutputT<url::UTF16Char> unescaped; 67210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::DecodeURLEscapeSequences(stringUTF8.data(), stringUTF8.length(), &unescaped); 67393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return StringImpl::create8BitIfPossible(reinterpret_cast<UChar*>(unescaped.data()), unescaped.length()); 674e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 675e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 676e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)String encodeWithURLEscapeSequences(const String& notEncodedString) 677e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 67802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch CString utf8 = UTF8Encoding().normalizeAndEncode(notEncodedString, WTF::URLEncodedEntitiesForUnencodables); 679e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 68010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::RawCanonOutputT<char> buffer; 681e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) int inputLength = utf8.length(); 682e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) if (buffer.length() < inputLength * 3) 683e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) buffer.Resize(inputLength * 3); 684e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 68510f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::EncodeURIComponent(utf8.data(), inputLength, &buffer); 686e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) String escaped(buffer.data(), buffer.length()); 687e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // Unescape '/'; it's safe and much prettier. 688e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) escaped.replace("%2F", "/"); 689e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return escaped; 690e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 691e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 692e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)bool KURL::isHierarchical() const 693e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 6949bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) if (m_string.isNull() || !m_parsed.scheme.is_nonempty()) 695e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return false; 6969bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) return m_string.is8Bit() ? 69710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::IsStandard(asURLChar8Subtle(m_string), m_parsed.scheme) : 69810f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::IsStandard(m_string.characters16(), m_parsed.scheme); 699e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 700e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 701e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#ifndef NDEBUG 702e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)void KURL::print() const 703e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 70493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) printf("%s\n", m_string.utf8().data()); 705e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 706e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#endif 707e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 708e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)bool equalIgnoringFragmentIdentifier(const KURL& a, const KURL& b) 709e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 710e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // Compute the length of each URL without its ref. Note that the reference 711e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // begin (if it exists) points to the character *after* the '#', so we need 712e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) // to subtract one. 71393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) int aLength = a.m_string.length(); 71493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (a.m_parsed.ref.len >= 0) 71593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) aLength = a.m_parsed.ref.begin - 1; 716e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 71793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) int bLength = b.m_string.length(); 71893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (b.m_parsed.ref.len >= 0) 71993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) bLength = b.m_parsed.ref.begin - 1; 720e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 72193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (aLength != bLength) 72293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return false; 72393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 72493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) const String& aString = a.m_string; 72593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) const String& bString = b.m_string; 72693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // FIXME: Abstraction this into a function in WTFString.h. 72793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) for (int i = 0; i < aLength; ++i) { 72893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (aString[i] != bString[i]) 72993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return false; 73093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 73193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return true; 732e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 733e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 734e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)unsigned KURL::hostStart() const 735e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 73610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch return m_parsed.CountCharactersBefore(url::Parsed::HOST, false); 737e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 738e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 739e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)unsigned KURL::hostEnd() const 740e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 74110f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch return m_parsed.CountCharactersBefore(url::Parsed::PORT, true); 742e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 743e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 744e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)unsigned KURL::pathStart() const 745e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 74610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch return m_parsed.CountCharactersBefore(url::Parsed::PATH, false); 747e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 748e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 749e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)unsigned KURL::pathEnd() const 750e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 75110f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch return m_parsed.CountCharactersBefore(url::Parsed::QUERY, true); 752e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 753e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 754e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)unsigned KURL::pathAfterLastSlash() const 755e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 7569bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) if (m_string.isNull()) 7579bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) return 0; 758f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) if (!m_isValid || !m_parsed.path.is_valid()) 75910f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch return m_parsed.CountCharactersBefore(url::Parsed::PATH, false); 76010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::Component filename; 7619bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) if (m_string.is8Bit()) 76210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::ExtractFileName(asURLChar8Subtle(m_string), m_parsed.path, &filename); 76393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) else 76410f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::ExtractFileName(m_string.characters16(), m_parsed.path, &filename); 765e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) return filename.begin; 766e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 767e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 768e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)bool protocolIs(const String& url, const char* protocol) 769e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 770e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) assertProtocolIsGood(protocol); 77193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (url.isNull()) 77293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return false; 77393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (url.is8Bit()) 77410f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch return url::FindAndCompareScheme(asURLChar8Subtle(url), url.length(), protocol, 0); 77510f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch return url::FindAndCompareScheme(url.characters16(), url.length(), protocol, 0); 77693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} 77793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 77893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)void KURL::init(const KURL& base, const String& relative, const WTF::TextEncoding* queryEncoding) 77993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){ 78093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (!relative.isNull() && relative.is8Bit()) { 78193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) StringUTF8Adaptor relativeUTF8(relative); 78293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) init(base, relativeUTF8.data(), relativeUTF8.length(), queryEncoding); 78393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } else 78493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) init(base, relative.characters16(), relative.length(), queryEncoding); 78593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) initProtocolIsInHTTPFamily(); 78693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) initInnerURL(); 78793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} 78893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 78993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)template <typename CHAR> 79093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)void KURL::init(const KURL& base, const CHAR* relative, int relativeLength, const WTF::TextEncoding* queryEncoding) 79193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){ 79293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // As a performance optimization, we do not use the charset converter 79393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // if encoding is UTF-8 or other Unicode encodings. Note that this is 79493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // per HTML5 2.5.3 (resolving URL). The URL canonicalizer will be more 79593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // efficient with no charset converter object because it can do UTF-8 79693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // internally with no extra copies. 79793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 79893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // We feel free to make the charset converter object every time since it's 79993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // just a wrapper around a reference. 80093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) KURLCharsetConverter charsetConverterObject(queryEncoding); 80193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) KURLCharsetConverter* charsetConverter = (!queryEncoding || isUnicodeEncoding(queryEncoding)) ? 0 : &charsetConverterObject; 80293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 80393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) StringUTF8Adaptor baseUTF8(base.string()); 80493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 80510f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::RawCanonOutputT<char> output; 80610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch m_isValid = url::ResolveRelative(baseUTF8.data(), baseUTF8.length(), base.m_parsed, relative, relativeLength, charsetConverter, &output, &m_parsed); 80793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 80893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // See FIXME in KURLPrivate in the header. If canonicalization has not 80993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // changed the string, we can avoid an extra allocation by using assignment. 8105267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) m_string = AtomicString::fromUTF8(output.data(), output.length()); 81193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} 81293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 81393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)void KURL::initInnerURL() 81493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){ 81593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (!m_isValid) { 81693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) m_innerURL.clear(); 81793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return; 81893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 81910f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch if (url::Parsed* innerParsed = m_parsed.inner_parsed()) 82093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) m_innerURL = adoptPtr(new KURL(ParsedURLString, m_string.substring(innerParsed->scheme.begin, innerParsed->Length() - innerParsed->scheme.begin))); 82193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) else 82293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) m_innerURL.clear(); 82393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} 82493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 82593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)template<typename CHAR> 82610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdochbool internalProtocolIs(const url::Component& scheme, const CHAR* spec, const char* protocol) 82793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){ 82893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) const CHAR* begin = spec + scheme.begin; 82993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) const CHAR* end = begin + scheme.len; 83093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 83193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) while (begin != end && *protocol) { 83293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) ASSERT(toASCIILower(*protocol) == *protocol); 83393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (toASCIILower(*begin++) != *protocol++) 83493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return false; 83593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 83693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 83793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // Both strings are equal (ignoring case) if and only if all of the characters were equal, 83893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // and the end of both has been reached. 83993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return begin == end && !*protocol; 84093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} 84193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 84293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)template<typename CHAR> 84310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdochbool checkIfProtocolIsInHTTPFamily(const url::Component& scheme, const CHAR* spec) 84493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){ 84593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (scheme.len == 4) 84693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return internalProtocolIs(scheme, spec, "http"); 84793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (scheme.len == 5) 84893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return internalProtocolIs(scheme, spec, "https"); 84993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return false; 85093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} 85193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 85293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)void KURL::initProtocolIsInHTTPFamily() 85393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){ 85493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (!m_isValid) { 85593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) m_protocolIsInHTTPFamily = false; 85693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return; 85793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 85893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 8599bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) ASSERT(!m_string.isNull()); 8609bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) m_protocolIsInHTTPFamily = m_string.is8Bit() ? 8619bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) checkIfProtocolIsInHTTPFamily(m_parsed.scheme, m_string.characters8()) : 8629bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) checkIfProtocolIsInHTTPFamily(m_parsed.scheme, m_string.characters16()); 86393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} 86493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 86593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)bool KURL::protocolIs(const char* protocol) const 86693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){ 86793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) assertProtocolIsGood(protocol); 86893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 86993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // JavaScript URLs are "valid" and should be executed even if KURL decides they are invalid. 87093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // The free function protocolIsJavaScript() should be used instead. 87193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // FIXME: Chromium code needs to be fixed for this assert to be enabled. ASSERT(strcmp(protocol, "javascript")); 87293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 8739bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) if (m_string.isNull() || m_parsed.scheme.len <= 0) 8749bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) return *protocol == '\0'; 8759bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) 8769bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) return m_string.is8Bit() ? 8779bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) internalProtocolIs(m_parsed.scheme, m_string.characters8(), protocol) : 8789bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles) internalProtocolIs(m_parsed.scheme, m_string.characters16(), protocol); 87993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} 88093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 881f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)String KURL::stringForInvalidComponent() const 882f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles){ 883f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) if (m_string.isNull()) 884f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return String(); 885f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return emptyString(); 886f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)} 887f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) 88810f88d5669dbd969c059d61ba09fa37dd72ac559Ben MurdochString KURL::componentString(const url::Component& component) const 88993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){ 890f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) if (!m_isValid || component.len <= 0) 891f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return stringForInvalidComponent(); 89293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // begin and len are in terms of bytes which do not match 89393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // if string() is UTF-16 and input contains non-ASCII characters. 89493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // However, the only part in urlString that can contain non-ASCII 89593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // characters is 'ref' at the end of the string. In that case, 89693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // begin will always match the actual value and len (in terms of 89793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // byte) will be longer than what's needed by 'mid'. However, mid 89893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // truncates len to avoid go past the end of a string so that we can 89993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // get away without doing anything here. 90093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return string().substring(component.begin, component.len); 90193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} 90293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 90393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)template<typename CHAR> 90410f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdochvoid KURL::replaceComponents(const url::Replacements<CHAR>& replacements) 90593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){ 90610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::RawCanonOutputT<char> output; 90710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch url::Parsed newParsed; 90893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 90993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) StringUTF8Adaptor utf8(m_string); 91010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch m_isValid = url::ReplaceComponents(utf8.data(), utf8.length(), m_parsed, replacements, 0, &output, &newParsed); 91193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 91293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) m_parsed = newParsed; 9135267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) m_string = AtomicString::fromUTF8(output.data(), output.length()); 91493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} 91593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 91693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)bool KURL::isSafeToSendToAnotherThread() const 917e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles){ 91893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return m_string.isSafeToSendToAnotherThread() 91993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) && (!m_innerURL || m_innerURL->isSafeToSendToAnotherThread()); 920e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)} 921e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles) 922c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 923