URL::port should return Optional<uint16_t>
authorachristensen@apple.com <achristensen@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 24 Oct 2016 18:25:40 +0000 (18:25 +0000)
committerachristensen@apple.com <achristensen@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 24 Oct 2016 18:25:40 +0000 (18:25 +0000)
https://bugs.webkit.org/show_bug.cgi?id=163806

Reviewed by Darin Adler.

LayoutTests/imported/w3c:

* web-platform-tests/url/a-element-expected.txt:
* web-platform-tests/url/a-element-xhtml-expected.txt:
* web-platform-tests/url/url-constructor-expected.txt:

Source/WebCore:

A URL without a port is different than a URL with port 0.
This matches the spec, Chrome, and Firefox.

Covered by newly-passing web platform tests.

* Modules/indexeddb/IDBDatabaseIdentifier.h:
(WebCore::IDBDatabaseIdentifier::IDBDatabaseIdentifier):
(WebCore::IDBDatabaseIdentifier::isHashTableDeletedValue):
(WebCore::IDBDatabaseIdentifier::hash):
(WebCore::IDBDatabaseIdentifier::isValid):
(WebCore::IDBDatabaseIdentifier::isEmpty):
* Modules/websockets/WebSocket.cpp:
(WebCore::WebSocket::connect):
* Modules/websockets/WebSocketHandshake.cpp:
(WebCore::hostName):
* contentextensions/ContentExtensionsBackend.cpp:
(WebCore::ContentExtensions::ContentExtensionsBackend::processContentExtensionRulesForLoad):
(WebCore::ContentExtensions::applyBlockedStatusToRequest):
* html/HTMLPlugInImageElement.cpp:
(WebCore::HTMLPlugInImageElement::userDidClickSnapshot):
(WebCore::HTMLPlugInImageElement::subframeLoaderWillCreatePlugIn):
* html/URLUtils.h:
(WebCore::URLUtils<T>::protocol):
(WebCore::URLUtils<T>::host):
(WebCore::URLUtils<T>::port):
* loader/CrossOriginAccessControl.cpp:
(WebCore::isValidCrossOriginRedirectionURL):
* loader/DocumentLoader.cpp:
(WebCore::DocumentLoader::responseReceived):
(WebCore::isRemoteWebArchive):
(WebCore::DocumentLoader::maybeLoadEmpty):
* loader/DocumentThreadableLoader.cpp:
(WebCore::DocumentThreadableLoader::makeSimpleCrossOriginAccessRequest):
* loader/ResourceLoader.cpp:
(WebCore::ResourceLoader::didReceiveResponse):
* loader/cache/CachedResource.cpp:
(WebCore::shouldCacheSchemeIndefinitely):
(WebCore::CachedResource::freshnessLifetime):
* page/Location.cpp:
(WebCore::Location::protocol):
(WebCore::Location::host):
(WebCore::Location::port):
* page/Page.cpp:
(WebCore::Page::userStyleSheetLocationChanged):
* page/SecurityOrigin.cpp:
(WebCore::shouldTreatAsUniqueOrigin):
(WebCore::SecurityOrigin::SecurityOrigin):
(WebCore::SecurityOrigin::isSecure):
(WebCore::SecurityOrigin::canDisplay):
(WebCore::SecurityOrigin::toRawString):
(WebCore::SecurityOrigin::create):
(WebCore::SecurityOrigin::databaseIdentifier):
* page/SecurityOrigin.h:
(WebCore::SecurityOrigin::port):
* page/SecurityOriginData.cpp:
(WebCore::SecurityOriginData::debugString):
* page/SecurityOriginData.h:
(): Deleted.
* page/SecurityOriginHash.h:
(WebCore::SecurityOriginHash::hash):
* page/csp/ContentSecurityPolicy.cpp:
(WebCore::ContentSecurityPolicy::allowObjectFromSource):
(WebCore::ContentSecurityPolicy::allowChildFrameFromSource):
(WebCore::ContentSecurityPolicy::allowResourceFromSource):
(WebCore::ContentSecurityPolicy::allowConnectToSource):
(WebCore::ContentSecurityPolicy::allowBaseURI):
(WebCore::stripURLForUseInReport):
(WebCore::ContentSecurityPolicy::upgradeInsecureRequestIfNeeded):
* page/csp/ContentSecurityPolicySource.cpp:
(WebCore::ContentSecurityPolicySource::ContentSecurityPolicySource):
(WebCore::ContentSecurityPolicySource::portMatches):
* page/csp/ContentSecurityPolicySource.h:
* page/csp/ContentSecurityPolicySourceList.cpp:
(WebCore::ContentSecurityPolicySourceList::parse):
(WebCore::ContentSecurityPolicySourceList::parseSource):
(WebCore::ContentSecurityPolicySourceList::parsePort):
* page/csp/ContentSecurityPolicySourceList.h:
* platform/SchemeRegistry.h:
* platform/URL.cpp:
(WebCore::URL::protocol):
(WebCore::URL::port):
(WebCore::URL::serialize):
(WebCore::portAllowed):
(WebCore::defaultPortsMap): Deleted.
(WebCore::defaultPortForProtocol): Deleted.
(WebCore::isDefaultPortForProtocol): Deleted.
* platform/URL.h:
(WebCore::URL::hasPort): Deleted.
* platform/URLParser.cpp:
(WebCore::defaultPortForProtocol):
(WebCore::isDefaultPortForProtocol):
(WebCore::URLParser::parsePort):
(WebCore::isDefaultPort): Deleted.
* platform/network/CredentialStorage.cpp:
(WebCore::originStringFromURL):
* platform/network/ResourceHandle.cpp:
(WebCore::ResourceHandle::create):
(WebCore::ResourceHandle::loadResourceSynchronously):
* platform/network/cf/SocketStreamHandleImplCFNet.cpp:
(WebCore::SocketStreamHandleImpl::platformClose):
(WebCore::SocketStreamHandleImpl::port):
* workers/WorkerLocation.cpp:
(WebCore::WorkerLocation::protocol):
(WebCore::WorkerLocation::host):
(WebCore::WorkerLocation::port):

Source/WebKit/mac:

* WebCoreSupport/WebSecurityOrigin.mm:
(-[WebSecurityOrigin port]):

Source/WebKit2:

* NetworkProcess/mac/NetworkProcessMac.mm:
(WebKit::overrideSystemProxies):
* Shared/API/APISecurityOrigin.h:
(API::SecurityOrigin::create):
* Shared/API/APIURL.h:
(API::URL::protocol):
* Shared/API/c/WKSecurityOriginRef.cpp:
(WKSecurityOriginGetPort):
* UIProcess/API/Cocoa/WKSecurityOrigin.mm:
(-[WKSecurityOrigin port]):
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::canHandleRequest):
* WebProcess/cocoa/WebProcessCocoa.mm:
(WebKit::origin):

Tools:

* TestWebKitAPI/Tests/WebCore/URL.cpp:
(TestWebKitAPI::TEST_F):
* TestWebKitAPI/Tests/WebCore/URLParser.cpp:
(TestWebKitAPI::checkURL):
(TestWebKitAPI::checkRelativeURL):
(TestWebKitAPI::checkURLDifferences):
(TestWebKitAPI::checkRelativeURLDifferences):
(TestWebKitAPI::TEST_F):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207769 268f45cc-cd09-0410-ab3c-d52691b4dbfc

56 files changed:
LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/web-platform-tests/url/a-element-expected.txt
LayoutTests/imported/w3c/web-platform-tests/url/a-element-xhtml-expected.txt
LayoutTests/imported/w3c/web-platform-tests/url/url-constructor-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/IDBDatabaseIdentifier.h
Source/WebCore/Modules/websockets/WebSocket.cpp
Source/WebCore/Modules/websockets/WebSocketHandshake.cpp
Source/WebCore/contentextensions/ContentExtensionsBackend.cpp
Source/WebCore/editing/cocoa/DataDetection.mm
Source/WebCore/html/HTMLPlugInImageElement.cpp
Source/WebCore/html/URLUtils.h
Source/WebCore/loader/CrossOriginAccessControl.cpp
Source/WebCore/loader/DocumentLoader.cpp
Source/WebCore/loader/DocumentThreadableLoader.cpp
Source/WebCore/loader/ResourceLoader.cpp
Source/WebCore/loader/archive/mhtml/MHTMLArchive.cpp
Source/WebCore/loader/cache/CachedResource.cpp
Source/WebCore/page/Location.cpp
Source/WebCore/page/Page.cpp
Source/WebCore/page/SecurityOrigin.cpp
Source/WebCore/page/SecurityOrigin.h
Source/WebCore/page/SecurityOriginData.cpp
Source/WebCore/page/SecurityOriginData.h
Source/WebCore/page/SecurityOriginHash.h
Source/WebCore/page/csp/ContentSecurityPolicy.cpp
Source/WebCore/page/csp/ContentSecurityPolicySource.cpp
Source/WebCore/page/csp/ContentSecurityPolicySource.h
Source/WebCore/page/csp/ContentSecurityPolicySourceList.cpp
Source/WebCore/page/csp/ContentSecurityPolicySourceList.h
Source/WebCore/platform/SchemeRegistry.h
Source/WebCore/platform/URL.cpp
Source/WebCore/platform/URL.h
Source/WebCore/platform/URLParser.cpp
Source/WebCore/platform/network/CredentialStorage.cpp
Source/WebCore/platform/network/ResourceHandle.cpp
Source/WebCore/platform/network/cf/SocketStreamHandleImplCFNet.cpp
Source/WebCore/platform/network/curl/SocketStreamHandleImplCurl.cpp
Source/WebCore/platform/network/soup/ResourceRequestSoup.cpp
Source/WebCore/platform/network/soup/SocketStreamHandleImplSoup.cpp
Source/WebCore/workers/WorkerLocation.cpp
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/WebCoreSupport/WebSecurityOrigin.mm
Source/WebKit/win/WebSecurityOrigin.cpp
Source/WebKit/win/WebSecurityOrigin.h
Source/WebKit2/ChangeLog
Source/WebKit2/NetworkProcess/mac/NetworkProcessMac.mm
Source/WebKit2/Shared/API/APISecurityOrigin.h
Source/WebKit2/Shared/API/APIURL.h
Source/WebKit2/Shared/API/c/WKSecurityOriginRef.cpp
Source/WebKit2/UIProcess/API/Cocoa/WKSecurityOrigin.mm
Source/WebKit2/WebProcess/WebPage/WebPage.cpp
Source/WebKit2/WebProcess/cocoa/WebProcessCocoa.mm
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebCore/URL.cpp
Tools/TestWebKitAPI/Tests/WebCore/URLParser.cpp

index 935d17e..67ae326 100644 (file)
@@ -1,3 +1,14 @@
+2016-10-21  Alex Christensen  <achristensen@webkit.org>
+
+        URL::port should return Optional<uint16_t>
+        https://bugs.webkit.org/show_bug.cgi?id=163806
+
+        Reviewed by Darin Adler.
+
+        * web-platform-tests/url/a-element-expected.txt:
+        * web-platform-tests/url/a-element-xhtml-expected.txt:
+        * web-platform-tests/url/url-constructor-expected.txt:
+
 2016-10-24  Brady Eidson  <beidson@apple.com>
 
         IndexedDB 2.0: Support IDBIndex name assignment.
index ccc32e1..40a911f 100644 (file)
@@ -10,8 +10,8 @@ PASS Parsing: < foo.com  > against <http://example.org/foo/bar>
 FAIL Parsing: <a:       foo.com> against <http://example.org/foo/bar> assert_equals: origin expected "null" but got "a://"
 PASS Parsing: <http://f:21/ b ? d # e > against <http://example.org/foo/bar> 
 PASS Parsing: <http://f:/c> against <http://example.org/foo/bar> 
-FAIL Parsing: <http://f:0/c> against <http://example.org/foo/bar> assert_equals: origin expected "http://f:0" but got "http://f"
-FAIL Parsing: <http://f:00000000000000/c> against <http://example.org/foo/bar> assert_equals: origin expected "http://f:0" but got "http://f"
+PASS Parsing: <http://f:0/c> against <http://example.org/foo/bar> 
+PASS Parsing: <http://f:00000000000000/c> against <http://example.org/foo/bar> 
 PASS Parsing: <http://f:00000000000000000000080/c> against <http://example.org/foo/bar> 
 PASS Parsing: <http://f:b/c> against <http://example.org/foo/bar> 
 PASS Parsing: <http://f: /c> against <http://example.org/foo/bar> 
index ccc32e1..40a911f 100644 (file)
@@ -10,8 +10,8 @@ PASS Parsing: < foo.com  > against <http://example.org/foo/bar>
 FAIL Parsing: <a:       foo.com> against <http://example.org/foo/bar> assert_equals: origin expected "null" but got "a://"
 PASS Parsing: <http://f:21/ b ? d # e > against <http://example.org/foo/bar> 
 PASS Parsing: <http://f:/c> against <http://example.org/foo/bar> 
-FAIL Parsing: <http://f:0/c> against <http://example.org/foo/bar> assert_equals: origin expected "http://f:0" but got "http://f"
-FAIL Parsing: <http://f:00000000000000/c> against <http://example.org/foo/bar> assert_equals: origin expected "http://f:0" but got "http://f"
+PASS Parsing: <http://f:0/c> against <http://example.org/foo/bar> 
+PASS Parsing: <http://f:00000000000000/c> against <http://example.org/foo/bar> 
 PASS Parsing: <http://f:00000000000000000000080/c> against <http://example.org/foo/bar> 
 PASS Parsing: <http://f:b/c> against <http://example.org/foo/bar> 
 PASS Parsing: <http://f: /c> against <http://example.org/foo/bar> 
index 882fd4f..64f6872 100644 (file)
@@ -14,8 +14,8 @@ PASS Parsing: < foo.com  > against <http://example.org/foo/bar>
 FAIL Parsing: <a:       foo.com> against <http://example.org/foo/bar> assert_equals: origin expected "null" but got "a://"
 PASS Parsing: <http://f:21/ b ? d # e > against <http://example.org/foo/bar> 
 PASS Parsing: <http://f:/c> against <http://example.org/foo/bar> 
-FAIL Parsing: <http://f:0/c> against <http://example.org/foo/bar> assert_equals: origin expected "http://f:0" but got "http://f"
-FAIL Parsing: <http://f:00000000000000/c> against <http://example.org/foo/bar> assert_equals: origin expected "http://f:0" but got "http://f"
+PASS Parsing: <http://f:0/c> against <http://example.org/foo/bar> 
+PASS Parsing: <http://f:00000000000000/c> against <http://example.org/foo/bar> 
 PASS Parsing: <http://f:00000000000000000000080/c> against <http://example.org/foo/bar> 
 PASS Parsing: <http://f:b/c> against <http://example.org/foo/bar> 
 PASS Parsing: <http://f: /c> against <http://example.org/foo/bar> 
index e6c3c3c..828ac92 100644 (file)
@@ -1,3 +1,116 @@
+2016-10-21  Alex Christensen  <achristensen@webkit.org>
+
+        URL::port should return Optional<uint16_t>
+        https://bugs.webkit.org/show_bug.cgi?id=163806
+
+        Reviewed by Darin Adler.
+
+        A URL without a port is different than a URL with port 0.
+        This matches the spec, Chrome, and Firefox.
+
+        Covered by newly-passing web platform tests.
+
+        * Modules/indexeddb/IDBDatabaseIdentifier.h:
+        (WebCore::IDBDatabaseIdentifier::IDBDatabaseIdentifier):
+        (WebCore::IDBDatabaseIdentifier::isHashTableDeletedValue):
+        (WebCore::IDBDatabaseIdentifier::hash):
+        (WebCore::IDBDatabaseIdentifier::isValid):
+        (WebCore::IDBDatabaseIdentifier::isEmpty):
+        * Modules/websockets/WebSocket.cpp:
+        (WebCore::WebSocket::connect):
+        * Modules/websockets/WebSocketHandshake.cpp:
+        (WebCore::hostName):
+        * contentextensions/ContentExtensionsBackend.cpp:
+        (WebCore::ContentExtensions::ContentExtensionsBackend::processContentExtensionRulesForLoad):
+        (WebCore::ContentExtensions::applyBlockedStatusToRequest):
+        * html/HTMLPlugInImageElement.cpp:
+        (WebCore::HTMLPlugInImageElement::userDidClickSnapshot):
+        (WebCore::HTMLPlugInImageElement::subframeLoaderWillCreatePlugIn):
+        * html/URLUtils.h:
+        (WebCore::URLUtils<T>::protocol):
+        (WebCore::URLUtils<T>::host):
+        (WebCore::URLUtils<T>::port):
+        * loader/CrossOriginAccessControl.cpp:
+        (WebCore::isValidCrossOriginRedirectionURL):
+        * loader/DocumentLoader.cpp:
+        (WebCore::DocumentLoader::responseReceived):
+        (WebCore::isRemoteWebArchive):
+        (WebCore::DocumentLoader::maybeLoadEmpty):
+        * loader/DocumentThreadableLoader.cpp:
+        (WebCore::DocumentThreadableLoader::makeSimpleCrossOriginAccessRequest):
+        * loader/ResourceLoader.cpp:
+        (WebCore::ResourceLoader::didReceiveResponse):
+        * loader/cache/CachedResource.cpp:
+        (WebCore::shouldCacheSchemeIndefinitely):
+        (WebCore::CachedResource::freshnessLifetime):
+        * page/Location.cpp:
+        (WebCore::Location::protocol):
+        (WebCore::Location::host):
+        (WebCore::Location::port):
+        * page/Page.cpp:
+        (WebCore::Page::userStyleSheetLocationChanged):
+        * page/SecurityOrigin.cpp:
+        (WebCore::shouldTreatAsUniqueOrigin):
+        (WebCore::SecurityOrigin::SecurityOrigin):
+        (WebCore::SecurityOrigin::isSecure):
+        (WebCore::SecurityOrigin::canDisplay):
+        (WebCore::SecurityOrigin::toRawString):
+        (WebCore::SecurityOrigin::create):
+        (WebCore::SecurityOrigin::databaseIdentifier):
+        * page/SecurityOrigin.h:
+        (WebCore::SecurityOrigin::port):
+        * page/SecurityOriginData.cpp:
+        (WebCore::SecurityOriginData::debugString):
+        * page/SecurityOriginData.h:
+        (): Deleted.
+        * page/SecurityOriginHash.h:
+        (WebCore::SecurityOriginHash::hash):
+        * page/csp/ContentSecurityPolicy.cpp:
+        (WebCore::ContentSecurityPolicy::allowObjectFromSource):
+        (WebCore::ContentSecurityPolicy::allowChildFrameFromSource):
+        (WebCore::ContentSecurityPolicy::allowResourceFromSource):
+        (WebCore::ContentSecurityPolicy::allowConnectToSource):
+        (WebCore::ContentSecurityPolicy::allowBaseURI):
+        (WebCore::stripURLForUseInReport):
+        (WebCore::ContentSecurityPolicy::upgradeInsecureRequestIfNeeded):
+        * page/csp/ContentSecurityPolicySource.cpp:
+        (WebCore::ContentSecurityPolicySource::ContentSecurityPolicySource):
+        (WebCore::ContentSecurityPolicySource::portMatches):
+        * page/csp/ContentSecurityPolicySource.h:
+        * page/csp/ContentSecurityPolicySourceList.cpp:
+        (WebCore::ContentSecurityPolicySourceList::parse):
+        (WebCore::ContentSecurityPolicySourceList::parseSource):
+        (WebCore::ContentSecurityPolicySourceList::parsePort):
+        * page/csp/ContentSecurityPolicySourceList.h:
+        * platform/SchemeRegistry.h:
+        * platform/URL.cpp:
+        (WebCore::URL::protocol):
+        (WebCore::URL::port):
+        (WebCore::URL::serialize):
+        (WebCore::portAllowed):
+        (WebCore::defaultPortsMap): Deleted.
+        (WebCore::defaultPortForProtocol): Deleted.
+        (WebCore::isDefaultPortForProtocol): Deleted.
+        * platform/URL.h:
+        (WebCore::URL::hasPort): Deleted.
+        * platform/URLParser.cpp:
+        (WebCore::defaultPortForProtocol):
+        (WebCore::isDefaultPortForProtocol):
+        (WebCore::URLParser::parsePort):
+        (WebCore::isDefaultPort): Deleted.
+        * platform/network/CredentialStorage.cpp:
+        (WebCore::originStringFromURL):
+        * platform/network/ResourceHandle.cpp:
+        (WebCore::ResourceHandle::create):
+        (WebCore::ResourceHandle::loadResourceSynchronously):
+        * platform/network/cf/SocketStreamHandleImplCFNet.cpp:
+        (WebCore::SocketStreamHandleImpl::platformClose):
+        (WebCore::SocketStreamHandleImpl::port):
+        * workers/WorkerLocation.cpp:
+        (WebCore::WorkerLocation::protocol):
+        (WebCore::WorkerLocation::host):
+        (WebCore::WorkerLocation::port):
+
 2016-10-24  Zan Dobersek  <zdobersek@igalia.com>
 
         [CodeGeneratorJS] Support enums for standalone dictionaries
index da929db..9cff7a2 100644 (file)
@@ -23,8 +23,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef IDBDatabaseIdentifier_h
-#define IDBDatabaseIdentifier_h
+#pragma once
 
 #if ENABLE(INDEXED_DATABASE)
 
@@ -39,23 +38,17 @@ class SecurityOrigin;
 
 class IDBDatabaseIdentifier {
 public:
-    IDBDatabaseIdentifier()
-    {
-        m_openingOrigin.port = -2;
-        m_mainFrameOrigin.port = -2;
-    }
-
+    IDBDatabaseIdentifier() { }
     IDBDatabaseIdentifier(WTF::HashTableDeletedValueType)
+        : m_databaseName(WTF::HashTableDeletedValue)
     {
-        m_openingOrigin.port = -1;
-        m_mainFrameOrigin.port = -1;
     }
 
     IDBDatabaseIdentifier isolatedCopy() const;
 
     bool isHashTableDeletedValue() const
     {
-        return m_openingOrigin.port == -1 && m_mainFrameOrigin.port == -1;
+        return m_databaseName.isHashTableDeletedValue();
     }
 
     unsigned hash() const
@@ -66,7 +59,7 @@ public:
         unsigned mainFrameProtocolHash = StringHash::hash(m_mainFrameOrigin.protocol);
         unsigned mainFrameHostHash = StringHash::hash(m_mainFrameOrigin.host);
         
-        unsigned hashCodes[7] = { nameHash, openingProtocolHash, openingHostHash, static_cast<unsigned>(m_openingOrigin.port), mainFrameProtocolHash, mainFrameHostHash, static_cast<unsigned>(m_mainFrameOrigin.port) };
+        unsigned hashCodes[7] = { nameHash, openingProtocolHash, openingHostHash, m_openingOrigin.port.valueOr(0), mainFrameProtocolHash, mainFrameHostHash, m_mainFrameOrigin.port.valueOr(0) };
         return StringHasher::hashMemory<sizeof(hashCodes)>(hashCodes);
     }
 
@@ -74,12 +67,13 @@ public:
 
     bool isValid() const
     {
-        return !m_databaseName.isNull() && m_openingOrigin.port >= 0 && m_mainFrameOrigin.port >= 0;
+        return !m_databaseName.isNull()
+            && !m_databaseName.isHashTableDeletedValue();
     }
 
     bool isEmpty() const
     {
-        return m_openingOrigin.port == -2 && m_mainFrameOrigin.port == -2;
+        return m_databaseName.isNull();
     }
 
     bool operator==(const IDBDatabaseIdentifier& other) const
@@ -157,4 +151,3 @@ template<> struct DefaultHash<WebCore::IDBDatabaseIdentifier> {
 } // namespace WTF
 
 #endif // ENABLE(INDEXED_DATABASE)
-#endif // IDBDatabaseIdentifier_h
index 71a279a..7b2f894 100644 (file)
@@ -225,7 +225,12 @@ ExceptionOr<void> WebSocket::connect(const String& url, const Vector<String>& pr
     contentSecurityPolicy.upgradeInsecureRequestIfNeeded(m_url, ContentSecurityPolicy::InsecureRequestType::Load);
 
     if (!portAllowed(m_url)) {
-        context.addConsoleMessage(MessageSource::JS, MessageLevel::Error, "WebSocket port " + String::number(m_url.port()) + " blocked");
+        String message;
+        if (m_url.port())
+            message = makeString("WebSocket port ", String::number(m_url.port().value()), " blocked");
+        else
+            message = ASCIILiteral("WebSocket without port blocked");
+        context.addConsoleMessage(MessageSource::JS, MessageLevel::Error, message);
         m_state = CLOSED;
         return Exception { SECURITY_ERR };
     }
index 25812a7..6a7ca67 100644 (file)
@@ -84,9 +84,9 @@ static String hostName(const URL& url, bool secure)
     ASSERT(url.protocolIs("wss") == secure);
     StringBuilder builder;
     builder.append(url.host().convertToASCIILowercase());
-    if (url.port() && ((!secure && url.port() != 80) || (secure && url.port() != 443))) {
+    if (url.port() && ((!secure && url.port().value() != 80) || (secure && url.port().value() != 443))) {
         builder.append(':');
-        builder.appendNumber(url.port());
+        builder.appendNumber(url.port().value());
     }
     return builder.toString();
 }
index 9e5b436..83ea96e 100644 (file)
@@ -197,7 +197,7 @@ BlockedStatus ContentExtensionsBackend::processContentExtensionRulesForLoad(cons
         }
         case ContentExtensions::ActionType::MakeHTTPS: {
             if ((url.protocolIs("http") || url.protocolIs("ws"))
-                && (!url.hasPort() || isDefaultPortForProtocol(url.port(), url.protocol())))
+                && (!url.port() || isDefaultPortForProtocol(url.port().value(), url.protocol())))
                 willMakeHTTPS = true;
             break;
         }
@@ -233,12 +233,12 @@ void applyBlockedStatusToRequest(const BlockedStatus& status, ResourceRequest& r
     if (status.madeHTTPS) {
         const URL& originalURL = request.url();
         ASSERT(originalURL.protocolIs("http"));
-        ASSERT(!originalURL.hasPort() || isDefaultPortForProtocol(originalURL.port(), originalURL.protocol()));
+        ASSERT(!originalURL.port() || isDefaultPortForProtocol(originalURL.port().value(), originalURL.protocol()));
 
         URL newURL = originalURL;
         newURL.setProtocol("https");
-        if (originalURL.hasPort())
-            newURL.setPort(defaultPortForProtocol("https"));
+        if (originalURL.port())
+            newURL.setPort(defaultPortForProtocol("https").value());
         request.setURL(newURL);
     }
 }
index e5a214e..a513d06 100644 (file)
@@ -156,7 +156,7 @@ bool DataDetection::isDataDetectorLink(Element& element)
         return false;
 
 #if __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000
-    return [softLink_DataDetectorsCore_DDURLTapAndHoldSchemes() containsObject:(NSString *)downcast<HTMLAnchorElement>(element).href().protocol().convertToASCIILowercase()];
+    return [softLink_DataDetectorsCore_DDURLTapAndHoldSchemes() containsObject:(NSString *)downcast<HTMLAnchorElement>(element).href().protocol().toStringWithoutCopying().convertToASCIILowercase()];
 #else
     if (equalIgnoringASCIICase(element.attributeWithoutSynchronization(x_apple_data_detectorsAttr), "true"))
         return true;
index 4bcc8b4..1968700 100644 (file)
@@ -482,7 +482,7 @@ void HTMLPlugInImageElement::userDidClickSnapshot(PassRefPtr<MouseEvent> event,
         m_pendingClickEventFromSnapshot = event;
 
     String plugInOrigin = m_loadedUrl.host();
-    if (document().page() && !SchemeRegistry::shouldTreatURLSchemeAsLocal(document().page()->mainFrame().document()->baseURL().protocol()) && document().page()->settings().autostartOriginPlugInSnapshottingEnabled())
+    if (document().page() && !SchemeRegistry::shouldTreatURLSchemeAsLocal(document().page()->mainFrame().document()->baseURL().protocol().toStringWithoutCopying()) && document().page()->settings().autostartOriginPlugInSnapshottingEnabled())
         document().page()->plugInClient()->didStartFromOrigin(document().page()->mainFrame().document()->baseURL().host(), plugInOrigin, loadedMimeType(), document().page()->sessionID());
 
     LOG(Plugins, "%p User clicked on snapshotted plug-in. Restart.", this);
@@ -701,7 +701,7 @@ void HTMLPlugInImageElement::subframeLoaderWillCreatePlugIn(const URL& url)
         return;
     }
 
-    if (!SchemeRegistry::shouldTreatURLSchemeAsLocal(m_loadedUrl.protocol()) && !m_loadedUrl.host().isEmpty() && m_loadedUrl.host() == document().page()->mainFrame().document()->baseURL().host()) {
+    if (!SchemeRegistry::shouldTreatURLSchemeAsLocal(m_loadedUrl.protocol().toStringWithoutCopying()) && !m_loadedUrl.host().isEmpty() && m_loadedUrl.host() == document().page()->mainFrame().document()->baseURL().host()) {
         LOG(Plugins, "%p Plug-in is served from page's domain, set to play", this);
         m_snapshotDecision = NeverSnapshot;
         return;
index 38f6a28..5bc6341 100644 (file)
@@ -83,7 +83,7 @@ String URLUtils<T>::origin() const
 template <typename T>
 String URLUtils<T>::protocol() const
 {
-    return href().protocol() + ':';
+    return makeString(href().protocol(), ':');
 }
 
 template <typename T>
@@ -128,9 +128,9 @@ String URLUtils<T>::host() const
     const URL& url = href();
     if (url.hostEnd() == url.pathStart())
         return url.host();
-    if (isDefaultPortForProtocol(url.port(), url.protocol()))
+    if (!url.port() || isDefaultPortForProtocol(url.port().value(), url.protocol()))
         return url.host();
-    return url.host() + ':' + String::number(url.port());
+    return url.host() + ':' + String::number(url.port().value());
 }
 
 // This function does not allow leading spaces before the port number.
@@ -205,8 +205,8 @@ void URLUtils<T>::setHostname(const String& value)
 template <typename T>
 String URLUtils<T>::port() const
 {
-    if (href().hasPort())
-        return String::number(href().port());
+    if (href().port())
+        return String::number(href().port().value());
 
     return emptyString();
 }
index 4fedc4a..f72916f 100644 (file)
@@ -145,7 +145,7 @@ ResourceRequest createAccessControlPreflightRequest(const ResourceRequest& reque
 
 bool isValidCrossOriginRedirectionURL(const URL& redirectURL)
 {
-    return SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(redirectURL.protocol())
+    return SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(redirectURL.protocol().toStringWithoutCopying())
         && redirectURL.user().isEmpty()
         && redirectURL.pass().isEmpty();
 }
index 9f1886d..c76979f 100644 (file)
@@ -734,7 +734,7 @@ void DocumentLoader::responseReceived(const ResourceResponse& response)
     if (m_response.isHttpVersion0_9()) {
         // Non-HTTP responses are interpreted as HTTP/0.9 which may allow exfiltration of data
         // from non-HTTP services. Therefore cancel if the request was to a non-default port.
-        if (!isDefaultPortForProtocol(url.port(), url.protocol())) {
+        if (url.port() && !isDefaultPortForProtocol(url.port().value(), url.protocol())) {
             String message = "Stopped document load from '" + url.string() + "' because it is using HTTP/0.9 on a non-default port.";
             m_frame->document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, message, identifier);
             stopLoading();
@@ -777,7 +777,7 @@ static bool isRemoteWebArchive(const DocumentLoader& documentLoader)
         return false;
 #endif
 
-    return !documentLoader.substituteData().isValid() && !SchemeRegistry::shouldTreatURLSchemeAsLocal(documentLoader.request().url().protocol());
+    return !documentLoader.substituteData().isValid() && !SchemeRegistry::shouldTreatURLSchemeAsLocal(documentLoader.request().url().protocol().toStringWithoutCopying());
 }
 
 void DocumentLoader::continueAfterContentPolicy(PolicyAction policy)
@@ -1485,8 +1485,8 @@ bool DocumentLoader::isMultipartReplacingLoad() const
 
 bool DocumentLoader::maybeLoadEmpty()
 {
-    bool shouldLoadEmpty = !m_substituteData.isValid() && (m_request.url().isEmpty() || SchemeRegistry::shouldLoadURLSchemeAsEmptyDocument(m_request.url().protocol()));
-    if (!shouldLoadEmpty && !frameLoader()->client().representationExistsForURLScheme(m_request.url().protocol()))
+    bool shouldLoadEmpty = !m_substituteData.isValid() && (m_request.url().isEmpty() || SchemeRegistry::shouldLoadURLSchemeAsEmptyDocument(m_request.url().protocol().toStringWithoutCopying()));
+    if (!shouldLoadEmpty && !frameLoader()->client().representationExistsForURLScheme(m_request.url().protocol().toStringWithoutCopying()))
         return false;
 
     if (m_request.url().isEmpty() && !frameLoader()->stateMachine().creatingInitialEmptyDocument()) {
@@ -1495,7 +1495,7 @@ bool DocumentLoader::maybeLoadEmpty()
             frameLoader()->client().dispatchDidChangeProvisionalURL();
     }
 
-    String mimeType = shouldLoadEmpty ? "text/html" : frameLoader()->client().generatedMIMETypeForURLScheme(m_request.url().protocol());
+    String mimeType = shouldLoadEmpty ? "text/html" : frameLoader()->client().generatedMIMETypeForURLScheme(m_request.url().protocol().toStringWithoutCopying());
     m_response = ResourceResponse(m_request.url(), mimeType, 0, String());
     finishedLoading(monotonicallyIncreasingTime());
     return true;
index df328f3..21c69c2 100644 (file)
@@ -145,7 +145,7 @@ void DocumentThreadableLoader::makeSimpleCrossOriginAccessRequest(ResourceReques
     ASSERT(m_options.preflightPolicy == PreventPreflight || isSimpleCrossOriginAccessRequest(request.httpMethod(), request.httpHeaderFields()));
 
     // Cross-origin requests are only allowed for HTTP and registered schemes. We would catch this when checking response headers later, but there is no reason to send a request that's guaranteed to be denied.
-    if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(request.url().protocol())) {
+    if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(request.url().protocol().toStringWithoutCopying())) {
         m_client->didFail(ResourceError(errorDomainWebKitInternal, 0, request.url(), "Cross origin requests are only supported for HTTP.", ResourceError::Type::AccessControl));
         return;
     }
index 6620a56..4f63478 100644 (file)
@@ -450,7 +450,7 @@ void ResourceLoader::didReceiveResponse(const ResourceResponse& r)
             didFail(error);
             return;
         }
-        if (!isDefaultPortForProtocol(url.port(), url.protocol())) {
+        if (url.port() && !isDefaultPortForProtocol(url.port().value(), url.protocol())) {
             String message = "Cancelled resource load from '" + url.string() + "' because it is using HTTP/0.9 on a non-default port.";
             m_frame->document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, message, identifier());
             ResourceError error(emptyString(), 0, url, message);
index b0e4fb8..e1f3ad0 100644 (file)
@@ -109,7 +109,7 @@ Ref<MHTMLArchive> MHTMLArchive::create()
 RefPtr<MHTMLArchive> MHTMLArchive::create(const URL& url, SharedBuffer& data)
 {
     // For security reasons we only load MHTML pages from local URLs.
-    if (!SchemeRegistry::shouldTreatURLSchemeAsLocal(url.protocol()))
+    if (!SchemeRegistry::shouldTreatURLSchemeAsLocal(url.protocol().toString()))
         return nullptr;
 
     MHTMLParser parser(&data);
index 09d8738..5b75576 100644 (file)
@@ -440,7 +440,7 @@ bool CachedResource::isExpired() const
     return computeCurrentAge(m_response, m_responseTimestamp) > freshnessLifetime(m_response);
 }
 
-static inline bool shouldCacheSchemeIndefinitely(const String& scheme)
+static inline bool shouldCacheSchemeIndefinitely(StringView scheme)
 {
 #if PLATFORM(COCOA)
     if (equalLettersIgnoringASCIICase(scheme, "applewebdata"))
@@ -456,12 +456,12 @@ static inline bool shouldCacheSchemeIndefinitely(const String& scheme)
 std::chrono::microseconds CachedResource::freshnessLifetime(const ResourceResponse& response) const
 {
     if (!response.url().protocolIsInHTTPFamily()) {
-        String protocol = response.url().protocol();
+        StringView protocol = response.url().protocol();
         if (!shouldCacheSchemeIndefinitely(protocol)) {
             // Don't cache non-HTTP main resources since we can't check for freshness.
             // FIXME: We should not cache subresources either, but when we tried this
             // it caused performance and flakiness issues in our test infrastructure.
-            if (m_type == MainResource || SchemeRegistry::shouldAlwaysRevalidateURLScheme(protocol))
+            if (m_type == MainResource || SchemeRegistry::shouldAlwaysRevalidateURLScheme(protocol.toStringWithoutCopying()))
                 return 0us;
         }
 
index 39f82eb..b06fa8d 100644 (file)
@@ -76,7 +76,7 @@ String Location::protocol() const
     if (!m_frame)
         return String();
 
-    return url().protocol() + ":";
+    return makeString(url().protocol(), ":");
 }
 
 String Location::host() const
@@ -87,7 +87,7 @@ String Location::host() const
     // Note: this is the IE spec. The NS spec swaps the two, it says
     // "The hostname property is the concatenation of the host and port properties, separated by a colon."
     const URL& url = this->url();
-    return url.hasPort() ? url.host() + ":" + String::number(url.port()) : url.host();
+    return url.port() ? url.host() + ":" + String::number(url.port().value()) : url.host();
 }
 
 String Location::hostname() const
@@ -104,7 +104,7 @@ String Location::port() const
         return String();
 
     const URL& url = this->url();
-    return url.hasPort() ? String::number(url.port()) : emptyString();
+    return url.port() ? String::number(url.port().value()) : emptyString();
 }
 
 String Location::pathname() const
index 782886f..a898092 100644 (file)
@@ -1070,7 +1070,7 @@ void Page::userStyleSheetLocationChanged()
     URL url = m_settings->userStyleSheetLocation();
     
     // Allow any local file URL scheme to be loaded.
-    if (SchemeRegistry::shouldTreatURLSchemeAsLocal(url.protocol()))
+    if (SchemeRegistry::shouldTreatURLSchemeAsLocal(url.protocol().toStringWithoutCopying()))
         m_userStyleSheetPath = url.fileSystemPath();
     else
         m_userStyleSheetPath = String();
index e9cac03..e1ae74e 100644 (file)
@@ -42,8 +42,7 @@
 
 namespace WebCore {
 
-const int InvalidPort = 0;
-const int MaxAllowedPort = 65535;
+const int MaxAllowedPort = std::numeric_limits<uint16_t>::max();
 
 static bool schemeRequiresHost(const URL& url)
 {
@@ -95,7 +94,7 @@ static bool shouldTreatAsUniqueOrigin(const URL& url)
     if (schemeRequiresHost(innerURL) && innerURL.host().isEmpty())
         return true;
 
-    if (SchemeRegistry::shouldTreatURLSchemeAsNoAccess(innerURL.protocol()))
+    if (SchemeRegistry::shouldTreatURLSchemeAsNoAccess(innerURL.protocol().toStringWithoutCopying()))
         return true;
 
     // This is the common case.
@@ -103,7 +102,7 @@ static bool shouldTreatAsUniqueOrigin(const URL& url)
 }
 
 SecurityOrigin::SecurityOrigin(const URL& url)
-    : m_protocol(url.protocol().isNull() ? emptyString() : url.protocol().convertToASCIILowercase())
+    : m_protocol(url.protocol().isNull() ? emptyString() : url.protocol().toString().convertToASCIILowercase())
     , m_host(url.host().isNull() ? emptyString() : url.host().convertToASCIILowercase())
     , m_port(url.port())
     , m_isUnique(false)
@@ -116,8 +115,8 @@ SecurityOrigin::SecurityOrigin(const URL& url)
     // document.domain starts as m_host, but can be set by the DOM.
     m_domain = m_host;
 
-    if (isDefaultPortForProtocol(m_port, m_protocol))
-        m_port = InvalidPort;
+    if (m_port && isDefaultPortForProtocol(m_port.value(), m_protocol))
+        m_port = Nullopt;
 
     // By default, only local SecurityOrigins can load local resources.
     m_canLoadLocalResources = isLocal();
@@ -130,7 +129,6 @@ SecurityOrigin::SecurityOrigin()
     : m_protocol(emptyString())
     , m_host(emptyString())
     , m_domain(emptyString())
-    , m_port(InvalidPort)
     , m_isUnique(true)
     , m_universalAccess(false)
     , m_domainWasSetInDOM(false)
@@ -203,11 +201,11 @@ void SecurityOrigin::setDomainFromDOM(const String& newDomain)
 bool SecurityOrigin::isSecure(const URL& url)
 {
     // Invalid URLs are secure, as are URLs which have a secure protocol.
-    if (!url.isValid() || SchemeRegistry::shouldTreatURLSchemeAsSecure(url.protocol()))
+    if (!url.isValid() || SchemeRegistry::shouldTreatURLSchemeAsSecure(url.protocol().toStringWithoutCopying()))
         return true;
 
     // URLs that wrap inner URLs are secure if those inner URLs are secure.
-    if (shouldUseInnerURL(url) && SchemeRegistry::shouldTreatURLSchemeAsSecure(extractInnerURL(url).protocol()))
+    if (shouldUseInnerURL(url) && SchemeRegistry::shouldTreatURLSchemeAsSecure(extractInnerURL(url).protocol().toStringWithoutCopying()))
         return true;
 
     return false;
@@ -334,7 +332,7 @@ bool SecurityOrigin::canDisplay(const URL& url) const
     if (isFeedWithNestedProtocolInHTTPFamily(url))
         return true;
 
-    String protocol = url.protocol();
+    String protocol = url.protocol().toString();
 
     if (SchemeRegistry::canDisplayOnlyIfCanRequest(protocol))
         return canRequest(url);
@@ -458,7 +456,7 @@ String SecurityOrigin::toRawString() const
 
     if (m_port) {
         result.append(':');
-        result.appendNumber(m_port);
+        result.appendNumber(m_port.value());
     }
 
     return result.toString();
@@ -515,10 +513,8 @@ Ref<SecurityOrigin> SecurityOrigin::createFromDatabaseIdentifier(const String& d
     return create(URL());
 }
 
-Ref<SecurityOrigin> SecurityOrigin::create(const String& protocol, const String& host, int port)
+Ref<SecurityOrigin> SecurityOrigin::create(const String& protocol, const String& host, Optional<uint16_t> port)
 {
-    if (port < 0 || port > MaxAllowedPort)
-        return createUnique();
     String decodedHost = decodeURLEscapeSequences(host);
     auto origin = create(URL(URL(), protocol + "://" + host + "/"));
     origin->m_port = port;
@@ -540,7 +536,7 @@ String SecurityOrigin::databaseIdentifier() const
     stringBuilder.append(separatorCharacter);
     stringBuilder.append(encodeForFileName(m_host));
     stringBuilder.append(separatorCharacter);
-    stringBuilder.appendNumber(m_port);
+    stringBuilder.appendNumber(m_port.valueOr(0));
 
     return stringBuilder.toString();
 }
index 9e33cb0..011d20e 100644 (file)
@@ -26,8 +26,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef SecurityOrigin_h
-#define SecurityOrigin_h
+#pragma once
 
 #include <wtf/ThreadSafeRefCounted.h>
 #include <wtf/text/WTFString.h>
@@ -60,7 +59,7 @@ public:
     WEBCORE_EXPORT static RefPtr<SecurityOrigin> maybeCreateFromDatabaseIdentifier(const String&);
 
     WEBCORE_EXPORT static Ref<SecurityOrigin> createFromString(const String&);
-    WEBCORE_EXPORT static Ref<SecurityOrigin> create(const String& protocol, const String& host, int port);
+    WEBCORE_EXPORT static Ref<SecurityOrigin> create(const String& protocol, const String& host, Optional<uint16_t> port);
 
     // Some URL schemes use nested URLs for their security context. For example,
     // filesystem URLs look like the following:
@@ -88,7 +87,7 @@ public:
     String protocol() const { return m_protocol; }
     String host() const { return m_host; }
     String domain() const { return m_domain; }
-    unsigned short port() const { return m_port; }
+    Optional<uint16_t> port() const { return m_port; }
 
     // Returns true if a given URL is secure, based either directly on its
     // own protocol, or, when relevant, on the protocol of its "inner URL"
@@ -226,7 +225,7 @@ private:
     String m_host;
     String m_domain;
     String m_filePath;
-    unsigned short m_port;
+    Optional<uint16_t> m_port;
     bool m_isUnique;
     bool m_universalAccess;
     bool m_domainWasSetInDOM;
@@ -237,5 +236,3 @@ private:
 };
 
 } // namespace WebCore
-
-#endif // SecurityOrigin_h
index 41ec5f4..b5d899b 100644 (file)
@@ -49,7 +49,7 @@ SecurityOriginData SecurityOriginData::fromSecurityOrigin(const SecurityOrigin&
 #if !LOG_DISABLED
 String SecurityOriginData::debugString() const
 {
-    return makeString(protocol, "://", host, ":", String::number(port));
+    return makeString(protocol, "://", host, ":", String::number(port.valueOr(0)));
 }
 #endif
 
index 03811f9..31ec1f6 100644 (file)
@@ -23,8 +23,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef SecurityOriginData_h
-#define SecurityOriginData_h
+#pragma once
 
 #include <wtf/text/WTFString.h>
 
@@ -43,7 +42,7 @@ struct SecurityOriginData {
 
     String protocol;
     String host;
-    int port { 0 };
+    Optional<uint16_t> port;
 
     WEBCORE_EXPORT SecurityOriginData isolatedCopy() const;
 
@@ -79,5 +78,3 @@ bool SecurityOriginData::decode(Decoder& decoder, SecurityOriginData& securityOr
 }
 
 } // namespace WebCore
-
-#endif // SecurityOriginData_h
index 05efef7..50eb295 100644 (file)
@@ -26,8 +26,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef SecurityOriginHash_h
-#define SecurityOriginHash_h
+#pragma once
 
 #include "URL.h"
 #include "SecurityOrigin.h"
@@ -41,7 +40,7 @@ struct SecurityOriginHash {
         unsigned hashCodes[3] = {
             origin->protocol().impl() ? origin->protocol().impl()->hash() : 0,
             origin->host().impl() ? origin->host().impl()->hash() : 0,
-            origin->port()
+            origin->port().valueOr(0)
         };
         return StringHasher::hashMemory<sizeof(hashCodes)>(hashCodes);
     }
@@ -82,5 +81,3 @@ namespace WTF {
     };
 
 } // namespace WTF
-
-#endif // SecurityOriginHash_h
index c9f0afc..4dd67e1 100644 (file)
@@ -453,7 +453,7 @@ bool ContentSecurityPolicy::allowPluginType(const String& type, const String& ty
 
 bool ContentSecurityPolicy::allowObjectFromSource(const URL& url, RedirectResponseReceived redirectResponseReceived) const
 {
-    if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
+    if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol().toStringWithoutCopying()))
         return true;
     // As per section object-src of the Content Security Policy Level 3 spec., <http://w3c.github.io/webappsec-csp> (Editor's Draft, 29 February 2016),
     // "If plugin content is loaded without an associated URL (perhaps an object element lacks a data attribute, but loads some default plugin based
@@ -469,7 +469,7 @@ bool ContentSecurityPolicy::allowObjectFromSource(const URL& url, RedirectRespon
 
 bool ContentSecurityPolicy::allowChildFrameFromSource(const URL& url, RedirectResponseReceived redirectResponseReceived) const
 {
-    if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
+    if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol().toStringWithoutCopying()))
         return true;
     String sourceURL;
     TextPosition sourcePosition(WTF::OrdinalNumber::beforeFirst(), WTF::OrdinalNumber());
@@ -483,7 +483,7 @@ bool ContentSecurityPolicy::allowChildFrameFromSource(const URL& url, RedirectRe
 
 bool ContentSecurityPolicy::allowResourceFromSource(const URL& url, RedirectResponseReceived redirectResponseReceived, const char* name, ResourcePredicate resourcePredicate) const
 {
-    if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
+    if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol().toStringWithoutCopying()))
         return true;
     String sourceURL;
     TextPosition sourcePosition(WTF::OrdinalNumber::beforeFirst(), WTF::OrdinalNumber());
@@ -526,7 +526,7 @@ bool ContentSecurityPolicy::allowMediaFromSource(const URL& url, RedirectRespons
 
 bool ContentSecurityPolicy::allowConnectToSource(const URL& url, RedirectResponseReceived redirectResponseReceived) const
 {
-    if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
+    if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol().toStringWithoutCopying()))
         return true;
     String sourceURL;
     TextPosition sourcePosition(WTF::OrdinalNumber::beforeFirst(), WTF::OrdinalNumber());
@@ -546,7 +546,7 @@ bool ContentSecurityPolicy::allowBaseURI(const URL& url, bool overrideContentSec
 {
     if (overrideContentSecurityPolicy)
         return true;
-    if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
+    if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol().toStringWithoutCopying()))
         return true;
     String sourceURL;
     TextPosition sourcePosition(WTF::OrdinalNumber::beforeFirst(), WTF::OrdinalNumber());
@@ -562,7 +562,7 @@ static String stripURLForUseInReport(Document& document, const URL& url)
     if (!url.isValid())
         return String();
     if (!url.isHierarchical() || url.protocolIs("file"))
-        return url.protocol();
+        return url.protocol().toString();
     return document.securityOrigin()->canRequest(url) ? url.strippedForUseAsReferrer() : SecurityOrigin::create(url).get().toString();
 }
 
@@ -797,7 +797,7 @@ void ContentSecurityPolicy::upgradeInsecureRequestIfNeeded(URL& url, InsecureReq
     else
         return;
     
-    if (url.port() == 80)
+    if (url.port() && url.port().value() == 80)
         url.setPort(443);
 }
 
index ef91b26..ea6ff92 100644 (file)
@@ -32,7 +32,7 @@
 
 namespace WebCore {
 
-ContentSecurityPolicySource::ContentSecurityPolicySource(const ContentSecurityPolicy& policy, const String& scheme, const String& host, int port, const String& path, bool hostHasWildcard, bool portHasWildcard)
+ContentSecurityPolicySource::ContentSecurityPolicySource(const ContentSecurityPolicy& policy, const String& scheme, const String& host, Optional<uint16_t> port, const String& path, bool hostHasWildcard, bool portHasWildcard)
     : m_policy(policy)
     , m_scheme(scheme)
     , m_host(host)
@@ -86,16 +86,16 @@ bool ContentSecurityPolicySource::portMatches(const URL& url) const
     if (m_portHasWildcard)
         return true;
 
-    int port = url.port();
+    Optional<uint16_t> port = url.port();
 
     if (port == m_port)
         return true;
 
     if (!port)
-        return isDefaultPortForProtocol(m_port, url.protocol());
+        return isDefaultPortForProtocol(m_port.value(), url.protocol());
 
     if (!m_port)
-        return isDefaultPortForProtocol(port, url.protocol());
+        return isDefaultPortForProtocol(port.value(), url.protocol());
 
     return false;
 }
index 76b9e04..abaae96 100644 (file)
@@ -24,8 +24,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef ContentSecurityPolicySource_h
-#define ContentSecurityPolicySource_h
+#pragma once
 
 #include <wtf/text/WTFString.h>
 
@@ -37,7 +36,7 @@ class URL;
 class ContentSecurityPolicySource {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    ContentSecurityPolicySource(const ContentSecurityPolicy&, const String& scheme, const String& host, int port, const String& path, bool hostHasWildcard, bool portHasWildcard);
+    ContentSecurityPolicySource(const ContentSecurityPolicy&, const String& scheme, const String& host, Optional<uint16_t> port, const String& path, bool hostHasWildcard, bool portHasWildcard);
 
     bool matches(const URL&, bool didReceiveRedirectResponse = false) const;
 
@@ -51,7 +50,7 @@ private:
     const ContentSecurityPolicy& m_policy;
     String m_scheme;
     String m_host;
-    int m_port;
+    Optional<uint16_t> m_port;
     String m_path;
 
     bool m_hostHasWildcard;
@@ -59,5 +58,3 @@ private:
 };
 
 } // namespace WebCore
-
-#endif /* ContentSecurityPolicySource_h */
index 3a8f3eb..0963f42 100644 (file)
@@ -173,7 +173,7 @@ void ContentSecurityPolicySourceList::parse(const UChar* begin, const UChar* end
         skipWhile<UChar, isSourceCharacter>(position, end);
 
         String scheme, host, path;
-        int port = 0;
+        Optional<uint16_t> port;
         bool hostHasWildcard = false;
         bool portHasWildcard = false;
 
@@ -203,7 +203,7 @@ void ContentSecurityPolicySourceList::parse(const UChar* begin, const UChar* end
 //                   / ( [ scheme "://" ] host [ port ] [ path ] )
 //                   / "'self'"
 //
-bool ContentSecurityPolicySourceList::parseSource(const UChar* begin, const UChar* end, String& scheme, String& host, int& port, String& path, bool& hostHasWildcard, bool& portHasWildcard)
+bool ContentSecurityPolicySourceList::parseSource(const UChar* begin, const UChar* end, String& scheme, String& host, Optional<uint16_t>& port, String& path, bool& hostHasWildcard, bool& portHasWildcard)
 {
     if (begin == end)
         return false;
@@ -292,7 +292,7 @@ bool ContentSecurityPolicySourceList::parseSource(const UChar* begin, const UCha
         return false;
 
     if (!beginPort)
-        port = 0;
+        port = Nullopt;
     else {
         if (!parsePort(beginPort, beginPath, port, portHasWildcard))
             return false;
@@ -394,7 +394,7 @@ bool ContentSecurityPolicySourceList::parsePath(const UChar* begin, const UChar*
 
 // port              = ":" ( 1*DIGIT / "*" )
 //
-bool ContentSecurityPolicySourceList::parsePort(const UChar* begin, const UChar* end, int& port, bool& portHasWildcard)
+bool ContentSecurityPolicySourceList::parsePort(const UChar* begin, const UChar* end, Optional<uint16_t>& port, bool& portHasWildcard)
 {
     ASSERT(begin <= end);
     ASSERT(!port);
@@ -407,7 +407,7 @@ bool ContentSecurityPolicySourceList::parsePort(const UChar* begin, const UChar*
         return false;
     
     if (end - begin == 1 && *begin == '*') {
-        port = 0;
+        port = Nullopt;
         portHasWildcard = true;
         return true;
     }
@@ -419,7 +419,10 @@ bool ContentSecurityPolicySourceList::parsePort(const UChar* begin, const UChar*
         return false;
     
     bool ok;
-    port = charactersToIntStrict(begin, end - begin, &ok);
+    int portInt = charactersToIntStrict(begin, end - begin, &ok);
+    if (portInt < 0 || portInt > std::numeric_limits<uint16_t>::max())
+        return false;
+    port = portInt;
     return ok;
 }
 
index 58b0dd6..bfeb854 100644 (file)
@@ -24,8 +24,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef ContentSecurityPolicySourceList_h
-#define ContentSecurityPolicySourceList_h
+#pragma once
 
 #include "ContentSecurityPolicyHash.h"
 #include "ContentSecurityPolicySource.h"
@@ -59,10 +58,10 @@ public:
 private:
     void parse(const UChar* begin, const UChar* end);
 
-    bool parseSource(const UChar* begin, const UChar* end, String& scheme, String& host, int& port, String& path, bool& hostHasWildcard, bool& portHasWildcard);
+    bool parseSource(const UChar* begin, const UChar* end, String& scheme, String& host, Optional<uint16_t>& port, String& path, bool& hostHasWildcard, bool& portHasWildcard);
     bool parseScheme(const UChar* begin, const UChar* end, String& scheme);
     bool parseHost(const UChar* begin, const UChar* end, String& host, bool& hostHasWildcard);
-    bool parsePort(const UChar* begin, const UChar* end, int& port, bool& portHasWildcard);
+    bool parsePort(const UChar* begin, const UChar* end, Optional<uint16_t>& port, bool& portHasWildcard);
     bool parsePath(const UChar* begin, const UChar* end, String& path);
 
     bool parseNonceSource(const UChar* begin, const UChar* end);
@@ -85,5 +84,3 @@ private:
 };
 
 } // namespace WebCore
-
-#endif /* ContentSecurityPolicySourceList_h */
index 79b1593..ec041b1 100644 (file)
@@ -23,8 +23,8 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  *
  */
-#ifndef SchemeRegistry_h
-#define SchemeRegistry_h
+
+#pragma once
 
 #include <wtf/HashSet.h>
 #include <wtf/text/StringHash.h>
@@ -32,7 +32,8 @@
 
 namespace WebCore {
 
-typedef HashSet<String, ASCIICaseInsensitiveHash> URLSchemesMap;
+// FIXME: Make HashSet<String>::contains(StringView) work and use StringViews here.
+using URLSchemesMap = HashSet<String, ASCIICaseInsensitiveHash>;
 
 class SchemeRegistry {
 public:
@@ -101,5 +102,3 @@ public:
 };
 
 } // namespace WebCore
-
-#endif // SchemeRegistry_h
index 29dab7c..b319049 100644 (file)
@@ -53,7 +53,6 @@ namespace WebCore {
 typedef Vector<char, 512> CharBuffer;
 typedef Vector<UChar, 512> UCharBuffer;
 
-static const unsigned maximumValidPortNumber = 0xFFFE;
 static const unsigned invalidPortNumber = 0xFFFF;
 
 static inline bool isLetterMatchIgnoringCase(UChar character, char lowercaseLetter)
@@ -702,9 +701,9 @@ String URL::lastPathComponent() const
     return m_string.substring(start, end - start + 1);
 }
 
-String URL::protocol() const
+StringView URL::protocol() const
 {
-    return m_string.left(m_schemeEnd);
+    return StringView(m_string).substring(0, m_schemeEnd);
 }
 
 String URL::host() const
@@ -713,13 +712,10 @@ String URL::host() const
     return m_string.substring(start, m_hostEnd - start);
 }
 
-unsigned short URL::port() const
+Optional<uint16_t> URL::port() const
 {
-    // We return a port of 0 if there is no port specified. This can happen in two situations:
-    // 1) The URL contains no colon after the host name and before the path component of the URL.
-    // 2) The URL contains a colon but there's no port number before the path component of the URL begins.
-    if (m_hostEnd == m_portEnd || m_hostEnd == m_portEnd - 1)
-        return 0;
+    if (!m_portEnd || m_hostEnd >= m_portEnd - 1)
+        return Nullopt;
 
     bool ok = false;
     unsigned number;
@@ -727,8 +723,8 @@ unsigned short URL::port() const
         number = charactersToUIntStrict(m_string.characters8() + m_hostEnd + 1, m_portEnd - m_hostEnd - 1, &ok);
     else
         number = charactersToUIntStrict(m_string.characters16() + m_hostEnd + 1, m_portEnd - m_hostEnd - 1, &ok);
-    if (!ok || number > maximumValidPortNumber)
-        return invalidPortNumber;
+    if (!ok || number > std::numeric_limits<uint16_t>::max())
+        return Nullopt;
     return number;
 }
 
@@ -1336,9 +1332,9 @@ String URL::serialize(bool omitFragment) const
         }
         // FIXME: Serialize host according https://url.spec.whatwg.org/#concept-host-serializer for IPv4 and IPv6 addresses.
         urlBuilder.append(m_string, start, m_hostEnd - start);
-        if (hasPort()) {
+        if (port()) {
             urlBuilder.appendLiteral(":");
-            urlBuilder.appendNumber(port());
+            urlBuilder.appendNumber(port().value());
         }
     } else if (protocolIs("file"))
         urlBuilder.appendLiteral("//");
@@ -2236,33 +2232,9 @@ bool URL::isBlankURL() const
     return protocolIs("about");
 }
 
-typedef HashMap<String, unsigned short, ASCIICaseInsensitiveHash> DefaultPortsMap;
-static const DefaultPortsMap& defaultPortsMap()
-{
-    static NeverDestroyed<const DefaultPortsMap> defaultPortsMap(DefaultPortsMap({
-        { "http", 80 },
-        { "https", 443 },
-        { "ftp", 21 },
-        { "ftps", 990 }
-    }));
-    return defaultPortsMap.get();
-}
-unsigned short defaultPortForProtocol(const String& protocol)
-{
-    return defaultPortsMap().get(protocol);
-}
-
-bool isDefaultPortForProtocol(unsigned short port, const String& protocol)
-{
-    if (protocol.isEmpty())
-        return false;
-
-    return defaultPortForProtocol(protocol) == port;
-}
-
 bool portAllowed(const URL& url)
 {
-    unsigned short port = url.port();
+    Optional<uint16_t> port = url.port();
 
     // Since most URLs don't have a port, return early for the "no port" case.
     if (!port)
@@ -2270,7 +2242,7 @@ bool portAllowed(const URL& url)
 
     // This blocked port list matches the port blocking that Mozilla implements.
     // See http://www.mozilla.org/projects/netlib/PortBanning.html for more information.
-    static const unsigned short blockedPortList[] = {
+    static const uint16_t blockedPortList[] = {
         1,    // tcpmux
         7,    // echo
         9,    // discard
@@ -2351,11 +2323,11 @@ bool portAllowed(const URL& url)
 #endif
 
     // If the port is not in the blocked port list, allow it.
-    if (!std::binary_search(blockedPortList, blockedPortListEnd, port))
+    if (!std::binary_search(blockedPortList, blockedPortListEnd, port.value()))
         return true;
 
     // Allow ports 21 and 22 for FTP URLs, as Mozilla does.
-    if ((port == 21 || port == 22) && url.protocolIs("ftp"))
+    if ((port.value() == 21 || port.value() == 22) && url.protocolIs("ftp"))
         return true;
 
     // Allow any port number in a file URL, since the port number is ignored.
index cd6f9ba..710ea51 100644 (file)
@@ -100,10 +100,9 @@ public:
 
     String stringCenterEllipsizedToLength(unsigned length = 1024) const;
 
-    WEBCORE_EXPORT String protocol() const;
+    WEBCORE_EXPORT StringView protocol() const;
     WEBCORE_EXPORT String host() const;
-    WEBCORE_EXPORT unsigned short port() const;
-    bool hasPort() const;
+    WEBCORE_EXPORT Optional<uint16_t> port() const;
     WEBCORE_EXPORT String user() const;
     WEBCORE_EXPORT String pass() const;
     WEBCORE_EXPORT String path() const;
@@ -312,8 +311,8 @@ WEBCORE_EXPORT bool protocolIs(const String& url, const char* protocol);
 WEBCORE_EXPORT bool protocolIsJavaScript(const String& url);
 WEBCORE_EXPORT bool protocolIsInHTTPFamily(const String& url);
 
-unsigned short defaultPortForProtocol(const String& protocol);
-WEBCORE_EXPORT bool isDefaultPortForProtocol(unsigned short port, const String& protocol);
+Optional<uint16_t> defaultPortForProtocol(StringView protocol);
+WEBCORE_EXPORT bool isDefaultPortForProtocol(uint16_t port, StringView protocol);
 WEBCORE_EXPORT bool portAllowed(const URL&); // Blacklist ports that should never be used for Web resources.
 
 bool isValidProtocol(const String&);
@@ -389,11 +388,6 @@ inline bool URL::hasPath() const
     return m_pathEnd != m_portEnd;
 }
 
-inline bool URL::hasPort() const
-{
-    return m_hostEnd < m_portEnd;
-}
-
 inline bool URL::hasUsername() const
 {
     return m_userEnd > m_userStart;
index 2e20be9..a4f55e4 100644 (file)
@@ -624,7 +624,7 @@ void URLParser::encodeQuery(const Vector<UChar>& source, const TextEncoding& enc
     }
 }
 
-ALWAYS_INLINE static bool isDefaultPort(StringView scheme, uint16_t port)
+Optional<uint16_t> defaultPortForProtocol(StringView scheme)
 {
     static const uint16_t ftpPort = 21;
     static const uint16_t gopherPort = 70;
@@ -635,55 +635,65 @@ ALWAYS_INLINE static bool isDefaultPort(StringView scheme, uint16_t port)
     
     auto length = scheme.length();
     if (!length)
-        return false;
+        return Nullopt;
     switch (scheme[0]) {
     case 'w':
         switch (length) {
         case 2:
-            return scheme[1] == 's'
-                && port == wsPort;
+            if (scheme[1] == 's')
+                return wsPort;
+            return Nullopt;
         case 3:
-            return scheme[1] == 's'
-                && scheme[2] == 's'
-                && port == wssPort;
+            if (scheme[1] == 's'
+                && scheme[2] == 's')
+                return wssPort;
+            return Nullopt;
         default:
             return false;
         }
     case 'h':
         switch (length) {
         case 4:
-            return scheme[1] == 't'
+            if (scheme[1] == 't'
                 && scheme[2] == 't'
-                && scheme[3] == 'p'
-                && port == httpPort;
+                && scheme[3] == 'p')
+                return httpPort;
+            return Nullopt;
         case 5:
-            return scheme[1] == 't'
+            if (scheme[1] == 't'
                 && scheme[2] == 't'
                 && scheme[3] == 'p'
-                && scheme[4] == 's'
-                && port == httpsPort;
+                && scheme[4] == 's')
+                return httpsPort;
+            return Nullopt;
         default:
-            return false;
+            return Nullopt;
         }
     case 'g':
-        return length == 6
+        if (length == 6
             && scheme[1] == 'o'
             && scheme[2] == 'p'
             && scheme[3] == 'h'
             && scheme[4] == 'e'
-            && scheme[5] == 'r'
-            && port == gopherPort;
+            && scheme[5] == 'r')
+            return gopherPort;
+        return Nullopt;
     case 'f':
-        return length == 3
+        if (length == 3
             && scheme[1] == 't'
-            && scheme[2] == 'p'
-            && port == ftpPort;
-        return false;
+            && scheme[2] == 'p')
+            return ftpPort;
+        return Nullopt;
     default:
-        return false;
+        return Nullopt;
     }
 }
 
+bool isDefaultPortForProtocol(uint16_t port, StringView protocol)
+{
+    return defaultPortForProtocol(protocol) == port;
+}
+
 enum class Scheme {
     WS,
     WSS,
@@ -2589,7 +2599,7 @@ bool URLParser::parsePort(CodePointIterator<CharacterType>& iterator)
     if (!port && digitCount > 1)
         syntaxViolation(colonIterator);
 
-    if (UNLIKELY(isDefaultPort(parsedDataView(0, m_url.m_schemeEnd), port)))
+    if (UNLIKELY(isDefaultPortForProtocol(port, parsedDataView(0, m_url.m_schemeEnd))))
         syntaxViolation(colonIterator);
     else {
         appendToASCIIBuffer(':');
index 7f90efa..d49236d 100644 (file)
@@ -43,9 +43,9 @@ CredentialStorage& CredentialStorage::defaultCredentialStorage()
 static String originStringFromURL(const URL& url)
 {
     if (url.port())
-        return url.protocol() + "://" + url.host() + ':' + String::number(url.port()) + '/';
+        return makeString(url.protocol(), "://", url.host(), ':', String::number(url.port().value()), '/');
 
-    return url.protocol() + "://" + url.host() + '/';
+    return makeString(url.protocol(), "://", url.host(), '/');
 }
 
 static String protectionSpaceMapKeyFromURL(const URL& url)
index 69553ff..60434ca 100644 (file)
@@ -88,10 +88,8 @@ ResourceHandle::ResourceHandle(NetworkingContext* context, const ResourceRequest
 
 RefPtr<ResourceHandle> ResourceHandle::create(NetworkingContext* context, const ResourceRequest& request, ResourceHandleClient* client, bool defersLoading, bool shouldContentSniff)
 {
-    BuiltinResourceHandleConstructorMap::iterator protocolMapItem = builtinResourceHandleConstructorMap().find(request.url().protocol());
-
-    if (protocolMapItem != builtinResourceHandleConstructorMap().end())
-        return protocolMapItem->value(request, client);
+    if (auto constructor = builtinResourceHandleConstructorMap().get(request.url().protocol().toStringWithoutCopying()))
+        return constructor(request, client);
 
     auto newHandle = adoptRef(*new ResourceHandle(context, request, client, defersLoading, shouldContentSniff));
 
@@ -134,10 +132,8 @@ void ResourceHandle::failureTimerFired()
 
 void ResourceHandle::loadResourceSynchronously(NetworkingContext* context, const ResourceRequest& request, StoredCredentials storedCredentials, ResourceError& error, ResourceResponse& response, Vector<char>& data)
 {
-    BuiltinResourceHandleSynchronousLoaderMap::iterator protocolMapItem = builtinResourceHandleSynchronousLoaderMap().find(request.url().protocol());
-
-    if (protocolMapItem != builtinResourceHandleSynchronousLoaderMap().end()) {
-        protocolMapItem->value(context, request, storedCredentials, error, response, data);
+    if (auto constructor = builtinResourceHandleSynchronousLoaderMap().get(request.url().protocol().toStringWithoutCopying())) {
+        constructor(context, request, storedCredentials, error, response, data);
         return;
     }
 
index b3c6d34..ba39cdb 100644 (file)
@@ -691,16 +691,16 @@ void SocketStreamHandleImpl::platformClose()
     CFReadStreamClose(m_readStream.get());
     CFWriteStreamClose(m_writeStream.get());
     
-    m_readStream = 0;
-    m_writeStream = 0;
+    m_readStream = nullptr;
+    m_writeStream = nullptr;
 
     m_client.didCloseSocketStream(*this);
 }
 
 unsigned short SocketStreamHandleImpl::port() const
 {
-    if (unsigned short urlPort = m_url.port())
-        return urlPort;
+    if (auto urlPort = m_url.port())
+        return urlPort.value();
     if (shouldUseSSL())
         return 443;
     return 80;
index 6b75762..57a6a73 100644 (file)
@@ -209,7 +209,8 @@ void SocketStreamHandleImpl::startThread()
             return;
 
         curl_easy_setopt(curlHandle, CURLOPT_URL, m_url.host().utf8().data());
-        curl_easy_setopt(curlHandle, CURLOPT_PORT, m_url.port());
+        if (m_url.port())
+            curl_easy_setopt(curlHandle, CURLOPT_PORT, m_url.port().value());
         curl_easy_setopt(curlHandle, CURLOPT_CONNECT_ONLY, 1L);
 
         // Connect to host
index 755e4c1..c5767e8 100644 (file)
@@ -144,7 +144,7 @@ void ResourceRequest::updateSoupMessage(SoupMessage* soupMessage) const
 
 void ResourceRequest::updateFromSoupMessage(SoupMessage* soupMessage)
 {
-    bool shouldPortBeResetToZero = m_url.hasPort() && !m_url.port();
+    bool shouldPortBeResetToZero = m_url.port() && !m_url.port().value();
     m_url = URL(soup_message_get_uri(soupMessage));
 
     // SoupURI cannot differeniate between an explicitly specified port 0 and
index 11cca7a..087dafd 100644 (file)
@@ -52,7 +52,7 @@ Ref<SocketStreamHandleImpl> SocketStreamHandleImpl::create(const URL& url, Socke
 {
     Ref<SocketStreamHandleImpl> socket = adoptRef(*new SocketStreamHandleImpl(url, client));
 
-    unsigned port = url.hasPort() ? url.port() : (url.protocolIs("wss") ? 443 : 80);
+    unsigned port = url.port() ? url.port().value() : (url.protocolIs("wss") ? 443 : 80);
     GRefPtr<GSocketClient> socketClient = adoptGRef(g_socket_client_new());
     if (url.protocolIs("wss"))
         g_socket_client_set_tls(socketClient.get(), TRUE);
index 6f228ec..214ac75 100644 (file)
@@ -38,12 +38,12 @@ String WorkerLocation::href() const
 
 String WorkerLocation::protocol() const
 {
-    return m_url.protocol() + ":";
+    return makeString(m_url.protocol(), ":");
 }
 
 String WorkerLocation::host() const
 {
-    return m_url.port() ? m_url.host() + ":" + String::number(m_url.port()) : m_url.host();
+    return m_url.port() ? m_url.host() + ":" + String::number(m_url.port().value()) : m_url.host();
 }
 
 String WorkerLocation::hostname() const
@@ -53,7 +53,7 @@ String WorkerLocation::hostname() const
 
 String WorkerLocation::port() const
 {
-    return m_url.port() ? String::number(m_url.port()) : "";
+    return m_url.port() ? String::number(m_url.port().value()) : emptyString();
 }
 
 String WorkerLocation::pathname() const
index b6b3eb9..0c15f09 100644 (file)
@@ -1,3 +1,13 @@
+2016-10-21  Alex Christensen  <achristensen@webkit.org>
+
+        URL::port should return Optional<uint16_t>
+        https://bugs.webkit.org/show_bug.cgi?id=163806
+
+        Reviewed by Darin Adler.
+
+        * WebCoreSupport/WebSecurityOrigin.mm:
+        (-[WebSecurityOrigin port]):
+
 2016-10-24  Dave Hyatt  <hyatt@apple.com>
 
         Remove CSSCharsetRule from the CSS OM
index a3dbf4a..48bbd30 100644 (file)
@@ -90,7 +90,7 @@ using namespace WebCore;
 
 - (unsigned short)port
 {
-    return reinterpret_cast<SecurityOrigin*>(_private)->port();
+    return reinterpret_cast<SecurityOrigin*>(_private)->port().valueOr(0);
 }
 
 // FIXME: Overriding isEqual: without overriding hash will cause trouble if this ever goes into an NSSet or is the key in an NSDictionary,
index d6756d3..784aacd 100644 (file)
@@ -119,7 +119,7 @@ HRESULT WebSecurityOrigin::port(_Out_ unsigned short* result)
     if (!result)
         return E_POINTER;
 
-    *result = m_securityOrigin->port();
+    *result = m_securityOrigin->port().valueOr(0);
 
     return S_OK;
 }
index d74f643..05059c5 100644 (file)
@@ -26,8 +26,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef WebSecurityOrigin_h
-#define WebSecurityOrigin_h
+#pragma once
 
 #include "WebKit.h"
 #include <WebCore/SecurityOrigin.h>
@@ -62,5 +61,3 @@ private:
     ULONG m_refCount { 0 };
     RefPtr<WebCore::SecurityOrigin> m_securityOrigin;
 };
-
-#endif // WebSecurityOrigin_h
index 300d69b..f901e59 100644 (file)
@@ -1,3 +1,25 @@
+2016-10-21  Alex Christensen  <achristensen@webkit.org>
+
+        URL::port should return Optional<uint16_t>
+        https://bugs.webkit.org/show_bug.cgi?id=163806
+
+        Reviewed by Darin Adler.
+
+        * NetworkProcess/mac/NetworkProcessMac.mm:
+        (WebKit::overrideSystemProxies):
+        * Shared/API/APISecurityOrigin.h:
+        (API::SecurityOrigin::create):
+        * Shared/API/APIURL.h:
+        (API::URL::protocol):
+        * Shared/API/c/WKSecurityOriginRef.cpp:
+        (WKSecurityOriginGetPort):
+        * UIProcess/API/Cocoa/WKSecurityOrigin.mm:
+        (-[WKSecurityOrigin port]):
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::canHandleRequest):
+        * WebProcess/cocoa/WebProcessCocoa.mm:
+        (WebKit::origin):
+
 2016-10-24  Eric Carlson  <eric.carlson@apple.com>
 
         [MediaStream] Separate media capture and audio playback muting
index 35e2b07..4efaffa 100644 (file)
@@ -70,8 +70,8 @@ static void overrideSystemProxies(const String& httpProxy, const String& httpsPr
         URL httpProxyURL(URL(), httpProxy);
         if (httpProxyURL.isValid()) {
             [proxySettings setObject:nsStringFromWebCoreString(httpProxyURL.host()) forKey:(NSString *)kCFNetworkProxiesHTTPProxy];
-            if (httpProxyURL.hasPort()) {
-                NSNumber *port = [NSNumber numberWithInt:httpProxyURL.port()];
+            if (httpProxyURL.port()) {
+                NSNumber *port = [NSNumber numberWithInt:httpProxyURL.port().value()];
                 [proxySettings setObject:port forKey:(NSString *)kCFNetworkProxiesHTTPPort];
             }
         }
@@ -83,8 +83,8 @@ static void overrideSystemProxies(const String& httpProxy, const String& httpsPr
         URL httpsProxyURL(URL(), httpsProxy);
         if (httpsProxyURL.isValid()) {
             [proxySettings setObject:nsStringFromWebCoreString(httpsProxyURL.host()) forKey:(NSString *)kCFNetworkProxiesHTTPSProxy];
-            if (httpsProxyURL.hasPort()) {
-                NSNumber *port = [NSNumber numberWithInt:httpsProxyURL.port()];
+            if (httpsProxyURL.port()) {
+                NSNumber *port = [NSNumber numberWithInt:httpsProxyURL.port().value()];
                 [proxySettings setObject:port forKey:(NSString *)kCFNetworkProxiesHTTPSPort];
             }
         } else
index 077ac64..7bc3c6f 100644 (file)
@@ -23,8 +23,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef APISecurityOrigin_h
-#define APISecurityOrigin_h
+#pragma once
 
 #include "APIObject.h"
 #include <WebCore/SecurityOrigin.h>
@@ -39,7 +38,7 @@ public:
         return create(WebCore::SecurityOrigin::createFromString(string));
     }
 
-    static RefPtr<SecurityOrigin> create(const WTF::String& protocol, const WTF::String& host, int port)
+    static RefPtr<SecurityOrigin> create(const WTF::String& protocol, const WTF::String& host, Optional<uint16_t> port)
     {
         return create(WebCore::SecurityOrigin::create(protocol, host, port));
     }
@@ -66,5 +65,3 @@ private:
 };
 
 }
-
-#endif
index 57251aa..7e0fae1 100644 (file)
@@ -70,7 +70,7 @@ public:
     WTF::String protocol() const
     {
         parseURLIfNecessary();
-        return m_parsedURL->isValid() ? m_parsedURL->protocol() : WTF::String();
+        return m_parsedURL->isValid() ? m_parsedURL->protocol().toString() : WTF::String();
     }
 
     WTF::String path() const
index 48cc0b2..d4aa013 100644 (file)
@@ -74,7 +74,7 @@ WKStringRef WKSecurityOriginCopyHost(WKSecurityOriginRef securityOrigin)
 
 unsigned short WKSecurityOriginGetPort(WKSecurityOriginRef securityOrigin)
 {
-    return toImpl(securityOrigin)->securityOrigin().port();
+    return toImpl(securityOrigin)->securityOrigin().port().valueOr(0);
 }
 
 // For backwards ABI compatibility.
index bb0ee60..c5543a2 100644 (file)
@@ -58,7 +58,7 @@
 
 - (NSInteger)port
 {
-    return _securityOrigin->securityOrigin().port();
+    return _securityOrigin->securityOrigin().port().valueOr(0);
 }
 
 #pragma mark WKObject protocol implementation
index 8a51c13..519f5de 100644 (file)
@@ -4434,7 +4434,7 @@ void WebPage::runModal()
 
 bool WebPage::canHandleRequest(const WebCore::ResourceRequest& request)
 {
-    if (SchemeRegistry::shouldLoadURLSchemeAsEmptyDocument(request.url().protocol()))
+    if (SchemeRegistry::shouldLoadURLSchemeAsEmptyDocument(request.url().protocol().toStringWithoutCopying()))
         return true;
 
     if (request.url().protocolIsBlob())
index fd2f49d..0a60493 100644 (file)
@@ -316,7 +316,7 @@ static NSURL *origin(WebPage& page)
     if (!mainFrameOrigin->isUnique())
         mainFrameOriginString = mainFrameOrigin->toRawString();
     else
-        mainFrameOriginString = mainFrameURL.protocol() + ':'; // toRawString() is not supposed to work with unique origins, and would just return "://".
+        mainFrameOriginString = makeString(mainFrameURL.protocol(), ':'); // toRawString() is not supposed to work with unique origins, and would just return "://".
 
     // +[NSURL URLWithString:] returns nil when its argument is malformed. It's unclear when we would have a malformed URL here,
     // but it happens in practice according to <rdar://problem/14173389>. Leaving an assertion in to catch a reproducible case.
index 7b5fb22..7674fb8 100644 (file)
@@ -1,3 +1,19 @@
+2016-10-21  Alex Christensen  <achristensen@webkit.org>
+
+        URL::port should return Optional<uint16_t>
+        https://bugs.webkit.org/show_bug.cgi?id=163806
+
+        Reviewed by Darin Adler.
+
+        * TestWebKitAPI/Tests/WebCore/URL.cpp:
+        (TestWebKitAPI::TEST_F):
+        * TestWebKitAPI/Tests/WebCore/URLParser.cpp:
+        (TestWebKitAPI::checkURL):
+        (TestWebKitAPI::checkRelativeURL):
+        (TestWebKitAPI::checkURLDifferences):
+        (TestWebKitAPI::checkRelativeURLDifferences):
+        (TestWebKitAPI::TEST_F):
+
 2016-10-24  Youenn Fablet  <youenn@apple.com>
 
         Activate WEB_RTC compilation flags for Mac bots
index 4a7f539..9033f64 100644 (file)
@@ -57,10 +57,10 @@ TEST_F(URLTest, URLConstructorConstChar)
     EXPECT_FALSE(kurl.isNull());
     EXPECT_TRUE(kurl.isValid());
 
-    EXPECT_EQ(String("http"), kurl.protocol());
+    EXPECT_EQ(kurl.protocol() == "http", true);
     EXPECT_EQ(String("www.example.com"), kurl.host());
-    EXPECT_TRUE(kurl.hasPort());
-    EXPECT_EQ(8080, kurl.port());
+    EXPECT_TRUE(!!kurl.port());
+    EXPECT_EQ(8080, kurl.port().value());
     EXPECT_EQ(String("username"), kurl.user());
     EXPECT_EQ(String("password"), kurl.pass());
     EXPECT_EQ(String("/index.html"), kurl.path());
index 777fe33..f3dcddf 100644 (file)
@@ -94,21 +94,21 @@ static void checkURL(const String& urlString, const ExpectedParts& parts, TestTa
     auto oldURL = URL(URL(), urlString);
     URLParser::setEnabled(wasEnabled);
     
-    EXPECT_TRUE(eq(parts.protocol, url.protocol()));
+    EXPECT_TRUE(eq(parts.protocol, url.protocol().toString()));
     EXPECT_TRUE(eq(parts.user, url.user()));
     EXPECT_TRUE(eq(parts.password, url.pass()));
     EXPECT_TRUE(eq(parts.host, url.host()));
-    EXPECT_EQ(parts.port, url.port());
+    EXPECT_EQ(parts.port, url.port().valueOr(0));
     EXPECT_TRUE(eq(parts.path, url.path()));
     EXPECT_TRUE(eq(parts.query, url.query()));
     EXPECT_TRUE(eq(parts.fragment, url.fragmentIdentifier()));
     EXPECT_TRUE(eq(parts.string, url.string()));
     
-    EXPECT_TRUE(eq(parts.protocol, oldURL.protocol()));
+    EXPECT_TRUE(eq(parts.protocol, oldURL.protocol().toString()));
     EXPECT_TRUE(eq(parts.user, oldURL.user()));
     EXPECT_TRUE(eq(parts.password, oldURL.pass()));
     EXPECT_TRUE(eq(parts.host, oldURL.host()));
-    EXPECT_EQ(parts.port, oldURL.port());
+    EXPECT_EQ(parts.port, oldURL.port().valueOr(0));
     EXPECT_TRUE(eq(parts.path, oldURL.path()));
     EXPECT_TRUE(eq(parts.query, oldURL.query()));
     EXPECT_TRUE(eq(parts.fragment, oldURL.fragmentIdentifier()));
@@ -350,21 +350,21 @@ static void checkRelativeURL(const String& urlString, const String& baseURLStrin
     auto oldURL = URL(URL(URL(), baseURLString), urlString);
     URLParser::setEnabled(wasEnabled);
 
-    EXPECT_TRUE(eq(parts.protocol, url.protocol()));
+    EXPECT_TRUE(eq(parts.protocol, url.protocol().toString()));
     EXPECT_TRUE(eq(parts.user, url.user()));
     EXPECT_TRUE(eq(parts.password, url.pass()));
     EXPECT_TRUE(eq(parts.host, url.host()));
-    EXPECT_EQ(parts.port, url.port());
+    EXPECT_EQ(parts.port, url.port().valueOr(0));
     EXPECT_TRUE(eq(parts.path, url.path()));
     EXPECT_TRUE(eq(parts.query, url.query()));
     EXPECT_TRUE(eq(parts.fragment, url.fragmentIdentifier()));
     EXPECT_TRUE(eq(parts.string, url.string()));
 
-    EXPECT_TRUE(eq(parts.protocol, oldURL.protocol()));
+    EXPECT_TRUE(eq(parts.protocol, oldURL.protocol().toString()));
     EXPECT_TRUE(eq(parts.user, oldURL.user()));
     EXPECT_TRUE(eq(parts.password, oldURL.pass()));
     EXPECT_TRUE(eq(parts.host, oldURL.host()));
-    EXPECT_EQ(parts.port, oldURL.port());
+    EXPECT_EQ(parts.port, oldURL.port().valueOr(0));
     EXPECT_TRUE(eq(parts.path, oldURL.path()));
     EXPECT_TRUE(eq(parts.query, oldURL.query()));
     EXPECT_TRUE(eq(parts.fragment, oldURL.fragmentIdentifier()));
@@ -476,21 +476,21 @@ static void checkURLDifferences(const String& urlString, const ExpectedParts& pa
     auto oldURL = URL(URL(), urlString);
     URLParser::setEnabled(wasEnabled);
 
-    EXPECT_TRUE(eq(partsNew.protocol, url.protocol()));
+    EXPECT_TRUE(eq(partsNew.protocol, url.protocol().toString()));
     EXPECT_TRUE(eq(partsNew.user, url.user()));
     EXPECT_TRUE(eq(partsNew.password, url.pass()));
     EXPECT_TRUE(eq(partsNew.host, url.host()));
-    EXPECT_EQ(partsNew.port, url.port());
+    EXPECT_EQ(partsNew.port, url.port().valueOr(0));
     EXPECT_TRUE(eq(partsNew.path, url.path()));
     EXPECT_TRUE(eq(partsNew.query, url.query()));
     EXPECT_TRUE(eq(partsNew.fragment, url.fragmentIdentifier()));
     EXPECT_TRUE(eq(partsNew.string, url.string()));
     
-    EXPECT_TRUE(eq(partsOld.protocol, oldURL.protocol()));
+    EXPECT_TRUE(eq(partsOld.protocol, oldURL.protocol().toString()));
     EXPECT_TRUE(eq(partsOld.user, oldURL.user()));
     EXPECT_TRUE(eq(partsOld.password, oldURL.pass()));
     EXPECT_TRUE(eq(partsOld.host, oldURL.host()));
-    EXPECT_EQ(partsOld.port, oldURL.port());
+    EXPECT_EQ(partsOld.port, oldURL.port().valueOr(0));
     EXPECT_TRUE(eq(partsOld.path, oldURL.path()));
     EXPECT_TRUE(eq(partsOld.query, oldURL.query()));
     EXPECT_TRUE(eq(partsOld.fragment, oldURL.fragmentIdentifier()));
@@ -521,21 +521,21 @@ static void checkRelativeURLDifferences(const String& urlString, const String& b
     auto oldURL = URL(URL(URL(), baseURLString), urlString);
     URLParser::setEnabled(wasEnabled);
 
-    EXPECT_TRUE(eq(partsNew.protocol, url.protocol()));
+    EXPECT_TRUE(eq(partsNew.protocol, url.protocol().toString()));
     EXPECT_TRUE(eq(partsNew.user, url.user()));
     EXPECT_TRUE(eq(partsNew.password, url.pass()));
     EXPECT_TRUE(eq(partsNew.host, url.host()));
-    EXPECT_EQ(partsNew.port, url.port());
+    EXPECT_EQ(partsNew.port, url.port().valueOr(0));
     EXPECT_TRUE(eq(partsNew.path, url.path()));
     EXPECT_TRUE(eq(partsNew.query, url.query()));
     EXPECT_TRUE(eq(partsNew.fragment, url.fragmentIdentifier()));
     EXPECT_TRUE(eq(partsNew.string, url.string()));
     
-    EXPECT_TRUE(eq(partsOld.protocol, oldURL.protocol()));
+    EXPECT_TRUE(eq(partsOld.protocol, oldURL.protocol().toString()));
     EXPECT_TRUE(eq(partsOld.user, oldURL.user()));
     EXPECT_TRUE(eq(partsOld.password, oldURL.pass()));
     EXPECT_TRUE(eq(partsOld.host, oldURL.host()));
-    EXPECT_EQ(partsOld.port, oldURL.port());
+    EXPECT_EQ(partsOld.port, oldURL.port().valueOr(0));
     EXPECT_TRUE(eq(partsOld.path, oldURL.path()));
     EXPECT_TRUE(eq(partsOld.query, oldURL.query()));
     EXPECT_TRUE(eq(partsOld.fragment, oldURL.fragmentIdentifier()));
@@ -643,16 +643,16 @@ TEST_F(URLParserTest, ParserDifferences)
         {"https", "", "", "", 0, "/", "", "", "https:/"});
     checkURLDifferences("http://127.0.0.1:65536/path",
         {"", "", "", "", 0, "", "", "", "http://127.0.0.1:65536/path"},
-        {"http", "", "", "127.0.0.1", 65535, "/path", "", "", "http://127.0.0.1:65536/path"});
+        {"http", "", "", "127.0.0.1", 0, "/path", "", "", "http://127.0.0.1:65536/path"});
     checkURLDifferences("http://host:65536",
         {"", "", "", "", 0, "", "", "", "http://host:65536"},
-        {"http", "", "", "host", 65535, "/", "", "", "http://host:65536/"});
+        {"http", "", "", "host", 0, "/", "", "", "http://host:65536/"});
     checkURLDifferences("http://127.0.0.1:65536",
         {"", "", "", "", 0, "", "", "", "http://127.0.0.1:65536"},
-        {"http", "", "", "127.0.0.1", 65535, "/", "", "", "http://127.0.0.1:65536/"});
+        {"http", "", "", "127.0.0.1", 0, "/", "", "", "http://127.0.0.1:65536/"});
     checkURLDifferences("http://[0:f::f:f:0:0]:65536",
         {"", "", "", "", 0, "", "", "", "http://[0:f::f:f:0:0]:65536"},
-        {"http", "", "", "[0:f::f:f:0:0]", 65535, "/", "", "", "http://[0:f::f:f:0:0]:65536/"});
+        {"http", "", "", "[0:f::f:f:0:0]", 0, "/", "", "", "http://[0:f::f:f:0:0]:65536/"});
     checkRelativeURLDifferences(":foo.com\\", "notspecial://example.org/foo/bar",
         {"notspecial", "", "", "example.org", 0, "/foo/:foo.com\\", "", "", "notspecial://example.org/foo/:foo.com\\"},
         {"notspecial", "", "", "example.org", 0, "/foo/:foo.com/", "", "", "notspecial://example.org/foo/:foo.com/"});
@@ -1174,11 +1174,11 @@ static void checkURL(const String& urlString, const TextEncoding& encoding, cons
 {
     URLParser parser(urlString, { }, encoding);
     auto url = parser.result();
-    EXPECT_TRUE(eq(parts.protocol, url.protocol()));
+    EXPECT_TRUE(eq(parts.protocol, url.protocol().toString()));
     EXPECT_TRUE(eq(parts.user, url.user()));
     EXPECT_TRUE(eq(parts.password, url.pass()));
     EXPECT_TRUE(eq(parts.host, url.host()));
-    EXPECT_EQ(parts.port, url.port());
+    EXPECT_EQ(parts.port, url.port().valueOr(0));
     EXPECT_TRUE(eq(parts.path, url.path()));
     EXPECT_TRUE(eq(parts.query, url.query()));
     EXPECT_TRUE(eq(parts.fragment, url.fragmentIdentifier()));
@@ -1200,11 +1200,11 @@ static void checkURL(const String& urlString, const String& baseURLString, const
     URLParser baseParser(baseURLString, { }, encoding);
     URLParser parser(urlString, baseParser.result(), encoding);
     auto url = parser.result();
-    EXPECT_TRUE(eq(parts.protocol, url.protocol()));
+    EXPECT_TRUE(eq(parts.protocol, url.protocol().toString()));
     EXPECT_TRUE(eq(parts.user, url.user()));
     EXPECT_TRUE(eq(parts.password, url.pass()));
     EXPECT_TRUE(eq(parts.host, url.host()));
-    EXPECT_EQ(parts.port, url.port());
+    EXPECT_EQ(parts.port, url.port().valueOr(0));
     EXPECT_TRUE(eq(parts.path, url.path()));
     EXPECT_TRUE(eq(parts.query, url.query()));
     EXPECT_TRUE(eq(parts.fragment, url.fragmentIdentifier()));