[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

ap at apple.com ap at apple.com
Wed Apr 7 23:39:17 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit 77959bec2d22fd9fbc53d38f5ad4e1e866a10ce4
Author: ap at apple.com <ap at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Nov 13 18:14:59 2009 +0000

            Reviewed by Darin Adler.
    
            https://bugs.webkit.org/show_bug.cgi?id=31441
            Implement SocketStreamHandleCFNet
    
            Existing WebSocket tests now pass on Mac. No proxy support yet.
    
            * platform/network/SocketStreamHandleClient.h:
            * platform/network/cf/SocketStreamHandle.h:
            (WebCore::SocketStreamHandle::shouldUseSSL):
            (WebCore::SocketStreamHandle::refAuthenticationClient):
            (WebCore::SocketStreamHandle::derefAuthenticationClient):
            (WebCore::SocketStreamHandle::):
            * platform/network/cf/SocketStreamHandleCFNet.cpp:
            (WebCore::SocketStreamHandle::SocketStreamHandle):
            (WebCore::SocketStreamHandle::chooseProxy):
            (WebCore::SocketStreamHandle::createStreams):
            (WebCore::SocketStreamHandle::copyCFStreamDescription):
            (WebCore::SocketStreamHandle::readStreamCallback):
            (WebCore::SocketStreamHandle::writeStreamCallback):
            (WebCore::SocketStreamHandle::~SocketStreamHandle):
            (WebCore::SocketStreamHandle::platformSend):
            (WebCore::SocketStreamHandle::platformClose):
            (WebCore::SocketStreamHandle::receivedCredential):
            (WebCore::SocketStreamHandle::receivedRequestToContinueWithoutCredential):
            (WebCore::SocketStreamHandle::receivedCancellation):
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@50951 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 2da2b0a..ce32c78 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,14 @@
+2009-11-12  Alexey Proskuryakov  <ap at apple.com>
+
+        Reviewed by Darin Adler.
+
+        https://bugs.webkit.org/show_bug.cgi?id=31441
+        Implement SocketStreamCFNet
+
+        * platform/mac/Skipped:
+        * platform/win/Skipped:
+        Enables tests in websocket directory.
+
 2009-11-13  Dmitry Titov  <dimich at chromium.org>
 
         Reviewed by Darin Adler.
diff --git a/LayoutTests/platform/mac/Skipped b/LayoutTests/platform/mac/Skipped
index 2d61bf8..18b6421 100644
--- a/LayoutTests/platform/mac/Skipped
+++ b/LayoutTests/platform/mac/Skipped
@@ -96,8 +96,5 @@ media/video-empty-source.html
 # Ruby layout tests somehow cause http/tests/security/mixedContent/about-blank-iframe-in-main-frame.html to fail
 fast/ruby
 
-# Missing SocketStreamHandle implementation
-websocket/tests
-
 # Accessibility tests without results
 accessibility/document-attributes.html
diff --git a/LayoutTests/platform/win/Skipped b/LayoutTests/platform/win/Skipped
index 5bfbf05..82b8f44 100644
--- a/LayoutTests/platform/win/Skipped
+++ b/LayoutTests/platform/win/Skipped
@@ -687,9 +687,6 @@ fast/ruby
 # https://bugs.webkit.org/show_bug.cgi?id=31315
 fast/dom/HTMLObjectElement/children-changed.html
 
-# Missing SocketStreamHandle implementation
-websocket/tests
-
 # Need rebaseline: https://bugs.webkit.org/show_bug.cgi?id=26830
 fast/multicol/single-line.html
 
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 931418d..57aedfb 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,32 @@
+2009-11-12  Alexey Proskuryakov  <ap at apple.com>
+
+        Reviewed by Darin Adler.
+
+        https://bugs.webkit.org/show_bug.cgi?id=31441
+        Implement SocketStreamHandleCFNet
+
+        Existing WebSocket tests now pass on Mac. No proxy support yet.
+
+        * platform/network/SocketStreamHandleClient.h:
+        * platform/network/cf/SocketStreamHandle.h:
+        (WebCore::SocketStreamHandle::shouldUseSSL):
+        (WebCore::SocketStreamHandle::refAuthenticationClient):
+        (WebCore::SocketStreamHandle::derefAuthenticationClient):
+        (WebCore::SocketStreamHandle::):
+        * platform/network/cf/SocketStreamHandleCFNet.cpp:
+        (WebCore::SocketStreamHandle::SocketStreamHandle):
+        (WebCore::SocketStreamHandle::chooseProxy):
+        (WebCore::SocketStreamHandle::createStreams):
+        (WebCore::SocketStreamHandle::copyCFStreamDescription):
+        (WebCore::SocketStreamHandle::readStreamCallback):
+        (WebCore::SocketStreamHandle::writeStreamCallback):
+        (WebCore::SocketStreamHandle::~SocketStreamHandle):
+        (WebCore::SocketStreamHandle::platformSend):
+        (WebCore::SocketStreamHandle::platformClose):
+        (WebCore::SocketStreamHandle::receivedCredential):
+        (WebCore::SocketStreamHandle::receivedRequestToContinueWithoutCredential):
+        (WebCore::SocketStreamHandle::receivedCancellation):
+
 2009-11-12  Pavel Feldman  <pfeldman at chromium.org>
 
         Reviewed by Timothy Hatcher.
diff --git a/WebCore/platform/network/SocketStreamHandleClient.h b/WebCore/platform/network/SocketStreamHandleClient.h
index 1586334..5d97ec0 100644
--- a/WebCore/platform/network/SocketStreamHandleClient.h
+++ b/WebCore/platform/network/SocketStreamHandleClient.h
@@ -49,6 +49,7 @@ namespace WebCore {
 
         virtual void didFail(SocketStreamHandle*, const SocketStreamError&) { }
 
+        // No authentication for streams per se, but proxy may ask for credentials.
         virtual void didReceiveAuthenticationChallenge(SocketStreamHandle*, const AuthenticationChallenge&) { }
         virtual void didCancelAuthenticationChallenge(SocketStreamHandle*, const AuthenticationChallenge&) { }
     };
diff --git a/WebCore/platform/network/cf/SocketStreamHandle.h b/WebCore/platform/network/cf/SocketStreamHandle.h
index 64139e5..30b9571 100644
--- a/WebCore/platform/network/cf/SocketStreamHandle.h
+++ b/WebCore/platform/network/cf/SocketStreamHandle.h
@@ -32,10 +32,9 @@
 #ifndef SocketStreamHandle_h
 #define SocketStreamHandle_h
 
+#include "AuthenticationClient.h"
 #include "SocketStreamHandleBase.h"
-
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
+#include <wtf/RetainPtr.h>
 
 namespace WebCore {
 
@@ -43,24 +42,53 @@ namespace WebCore {
     class Credential;
     class SocketStreamHandleClient;
 
-    class SocketStreamHandle : public RefCounted<SocketStreamHandle>, public SocketStreamHandleBase {
+    class SocketStreamHandle : public RefCounted<SocketStreamHandle>, public SocketStreamHandleBase, public AuthenticationClient {
     public:
         static PassRefPtr<SocketStreamHandle> create(const KURL& url, SocketStreamHandleClient* client) { return adoptRef(new SocketStreamHandle(url, client)); }
 
         virtual ~SocketStreamHandle();
 
-    protected:
+        using RefCounted<SocketStreamHandle>::ref;
+        using RefCounted<SocketStreamHandle>::deref;
+
+    private:
         virtual int platformSend(const char* data, int length);
         virtual void platformClose();
 
-    private:
         SocketStreamHandle(const KURL&, SocketStreamHandleClient*);
+        void createStreams();
+        void chooseProxy();
+
+        bool shouldUseSSL() const { return m_url.protocolIs("wss"); }
+
+        static CFStringRef copyCFStreamDescription(void* streamInfo);
+        static void readStreamCallback(CFReadStreamRef, CFStreamEventType, void* clientCallBackInfo);
+        static void writeStreamCallback(CFWriteStreamRef, CFStreamEventType, void* clientCallBackInfo);
+
+        void readStreamCallback(CFStreamEventType);
+        void writeStreamCallback(CFStreamEventType);
 
         // No authentication for streams per se, but proxy may ask for credentials.
-        void didReceiveAuthenticationChallenge(const AuthenticationChallenge&);
-        void receivedCredential(const AuthenticationChallenge&, const Credential&);
-        void receivedRequestToContinueWithoutCredential(const AuthenticationChallenge&);
-        void receivedCancellation(const AuthenticationChallenge&);
+        virtual void receivedCredential(const AuthenticationChallenge&, const Credential&);
+        virtual void receivedRequestToContinueWithoutCredential(const AuthenticationChallenge&);
+        virtual void receivedCancellation(const AuthenticationChallenge&);
+
+        virtual void refAuthenticationClient() { ref(); }
+        virtual void derefAuthenticationClient() { deref(); }
+
+        enum ConnectingSubstate { New, FetchingProxyAutoConfigurationFile, WaitingForCredentials, WaitingForConnect, Connected };
+        ConnectingSubstate m_connectingSubstate;
+
+        enum ConnectionType { Unknown, Direct, SOCKSProxy, CONNECTProxy };
+        ConnectionType m_connectionType;
+        RetainPtr<CFStringRef> m_proxyHost;
+        RetainPtr<CFNumberRef> m_proxyPort;
+
+        RetainPtr<CFHTTPMessageRef> m_proxyResponseMessage;
+        RetainPtr<CFReadStreamRef> m_readStream;
+        RetainPtr<CFWriteStreamRef> m_writeStream;
+
+        RetainPtr<CFURLRef> m_httpURL; // ws(s): replaced with http(s):
     };
 
 }  // namespace WebCore
diff --git a/WebCore/platform/network/cf/SocketStreamHandleCFNet.cpp b/WebCore/platform/network/cf/SocketStreamHandleCFNet.cpp
index 6aa33fc..24cbcda 100644
--- a/WebCore/platform/network/cf/SocketStreamHandleCFNet.cpp
+++ b/WebCore/platform/network/cf/SocketStreamHandleCFNet.cpp
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2009 Apple Inc.  All rights reserved.
  * Copyright (C) 2009 Google Inc.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,58 +32,235 @@
 #include "config.h"
 #include "SocketStreamHandle.h"
 
-#include "KURL.h"
 #include "Logging.h"
-#include "NotImplemented.h"
+#include "SocketStreamError.h"
 #include "SocketStreamHandleClient.h"
 
 namespace WebCore {
 
 SocketStreamHandle::SocketStreamHandle(const KURL& url, SocketStreamHandleClient* client)
     : SocketStreamHandleBase(url, client)
+    , m_connectingSubstate(New)
+    , m_connectionType(Unknown)
 {
     LOG(Network, "SocketStreamHandle %p new client %p", this, m_client);
-    notImplemented();
+
+    ASSERT(url.protocolIs("ws") || url.protocolIs("wss"));
+
+    if (!m_url.port())
+        m_url.setPort(shouldUseSSL() ? 443 : 80);
+
+    KURL httpURL(KURL(), (shouldUseSSL() ? "https://" : "http://") + m_url.host());
+    m_httpURL.adoptCF(httpURL.createCFURL());
+
+    createStreams();
+    ASSERT(!m_readStream == !m_writeStream);
+    if (!m_readStream) // Doing asynchronous PAC file processing, streams will be created later.
+        return;
+
+    CFStreamClientContext clientContext = { 0, this, 0, 0, copyCFStreamDescription };
+    // FIXME: Pass specific events we're interested in instead of -1.
+    CFReadStreamSetClient(m_readStream.get(), -1, readStreamCallback, &clientContext);
+    CFWriteStreamSetClient(m_writeStream.get(), -1, writeStreamCallback, &clientContext);
+
+    CFReadStreamScheduleWithRunLoop(m_readStream.get(), CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
+    CFWriteStreamScheduleWithRunLoop(m_writeStream.get(), CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
+    
+    CFReadStreamOpen(m_readStream.get());
+    CFWriteStreamOpen(m_writeStream.get());
+
+    m_connectingSubstate = WaitingForConnect;
+}
+
+void SocketStreamHandle::chooseProxy()
+{
+    // FIXME: Retrieve proxy information.
+    m_connectionType = Direct;
+}
+
+void SocketStreamHandle::createStreams()
+{
+    if (m_connectionType == Unknown)
+        chooseProxy();
+
+    // If it's still unknown, then we're resolving a PAC file asynchronously.
+    if (m_connectionType == Unknown)
+        return;
+
+    RetainPtr<CFStringRef> host(AdoptCF, m_url.host().createCFString());
+
+    // Creating streams to final destination, not to proxy.
+    CFReadStreamRef readStream = 0;
+    CFWriteStreamRef writeStream = 0;
+    CFStreamCreatePairWithSocketToHost(0, host.get(), m_url.port(), &readStream, &writeStream);
+
+    m_readStream.adoptCF(readStream);
+    m_writeStream.adoptCF(writeStream);
+
+    // FIXME: Apply proxy information to streams.
+
+    if (shouldUseSSL()) {
+        const void* keys[] = { kCFStreamSSLPeerName, kCFStreamSSLLevel };
+        const void* values[] = { host.get(), kCFStreamSocketSecurityLevelNegotiatedSSL };
+        RetainPtr<CFDictionaryRef> settings(AdoptCF, CFDictionaryCreate(0, keys, values, sizeof(keys) / sizeof(*keys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+        CFReadStreamSetProperty(m_readStream.get(), kCFStreamPropertySSLSettings, settings.get());
+        CFWriteStreamSetProperty(m_writeStream.get(), kCFStreamPropertySSLSettings, settings.get());
+    }
+}
+
+CFStringRef SocketStreamHandle::copyCFStreamDescription(void* info)
+{
+    SocketStreamHandle* handle = static_cast<SocketStreamHandle*>(info);
+    return ("WebKit socket stream, " + handle->m_url.string()).createCFString();
+}
+
+void SocketStreamHandle::readStreamCallback(CFReadStreamRef stream, CFStreamEventType type, void* clientCallBackInfo)
+{
+    SocketStreamHandle* handle = static_cast<SocketStreamHandle*>(clientCallBackInfo);
+    ASSERT(stream == handle->m_readStream.get());
+    handle->readStreamCallback(type);
+}
+
+void SocketStreamHandle::writeStreamCallback(CFWriteStreamRef stream, CFStreamEventType type, void* clientCallBackInfo)
+{
+    SocketStreamHandle* handle = static_cast<SocketStreamHandle*>(clientCallBackInfo);
+    ASSERT(stream == handle->m_writeStream.get());
+    handle->writeStreamCallback(type);
+}
+
+void SocketStreamHandle::readStreamCallback(CFStreamEventType type)
+{
+    switch(type) {
+    case kCFStreamEventNone:
+        break;
+    case kCFStreamEventOpenCompleted:
+        break;
+    case kCFStreamEventHasBytesAvailable: {
+        if (m_connectingSubstate == WaitingForConnect) {
+            // FIXME: Handle CONNECT proxy credentials here.
+        } else if (m_connectingSubstate == WaitingForCredentials)
+            break;
+
+        if (m_connectingSubstate == WaitingForConnect) {
+            m_connectingSubstate = Connected;
+            m_state = Open;
+            m_client->didOpen(this);
+            // Fall through.
+        } else if (m_state == Closed)
+            break;
+
+        ASSERT(m_state == Open);
+        ASSERT(m_connectingSubstate == Connected);
+
+        CFIndex length;
+        UInt8 localBuffer[1024]; // Used if CFReadStreamGetBuffer couldn't return anything.
+        const UInt8* ptr = CFReadStreamGetBuffer(m_readStream.get(), 0, &length);
+        if (!ptr) {
+            length = CFReadStreamRead(m_readStream.get(), localBuffer, sizeof(localBuffer));
+            ptr = localBuffer;
+        }
+
+        m_client->didReceiveData(this, reinterpret_cast<const char*>(ptr), length);
+
+        break;
+    }
+    case kCFStreamEventCanAcceptBytes:
+        ASSERT_NOT_REACHED();
+        break;
+    case kCFStreamEventErrorOccurred: {
+        CFStreamError error = CFReadStreamGetError(m_readStream.get());
+        m_client->didFail(this, SocketStreamError(error.error)); // FIXME: Provide a sensible error.
+        break;
+    }
+    case kCFStreamEventEndEncountered:
+        m_client->didClose(this);
+        break;
+    }
+}
+
+void SocketStreamHandle::writeStreamCallback(CFStreamEventType type)
+{
+    switch(type) {
+    case kCFStreamEventNone:
+        break;
+    case kCFStreamEventOpenCompleted:
+        break;
+    case kCFStreamEventHasBytesAvailable:
+        ASSERT_NOT_REACHED();
+        break;
+    case kCFStreamEventCanAcceptBytes: {
+        // Possibly, a spurious event from CONNECT handshake.
+        if (!CFWriteStreamCanAcceptBytes(m_writeStream.get()))
+            return;
+
+        if (m_connectingSubstate == WaitingForCredentials)
+            break;
+
+        if (m_connectingSubstate == WaitingForConnect) {
+            m_connectingSubstate = Connected;
+            m_state = Open;
+            m_client->didOpen(this);
+            break;
+        }
+
+        ASSERT(m_state = Open);
+        ASSERT(m_connectingSubstate == Connected);
+
+        sendPendingData();
+        break;
+    }
+    case kCFStreamEventErrorOccurred: {
+        CFStreamError error = CFWriteStreamGetError(m_writeStream.get());
+        m_client->didFail(this, SocketStreamError(error.error)); // FIXME: Provide a sensible error.
+        break;
+    }
+    case kCFStreamEventEndEncountered:
+        // FIXME: Currently, we call didClose from read callback, but these can come independently (e.g. a server can stop listening, but keep sending data).
+        break;
+    }
 }
 
 SocketStreamHandle::~SocketStreamHandle()
 {
-    LOG(Network, "SocketStreamHandle %p delete", this);
-    setClient(0);
-    notImplemented();
+    LOG(Network, "SocketStreamHandle %p dtor", this);
 }
 
-int SocketStreamHandle::platformSend(const char*, int)
+int SocketStreamHandle::platformSend(const char* data, int length)
 {
-    LOG(Network, "SocketStreamHandle %p platformSend", this);
-    notImplemented();
-    return 0;
+    if (!CFWriteStreamCanAcceptBytes(m_writeStream.get()))
+        return 0;
+
+    return CFWriteStreamWrite(m_writeStream.get(), reinterpret_cast<const UInt8*>(data), length);
 }
 
 void SocketStreamHandle::platformClose()
 {
     LOG(Network, "SocketStreamHandle %p platformClose", this);
-    notImplemented();
-}
 
-void SocketStreamHandle::didReceiveAuthenticationChallenge(const AuthenticationChallenge&)
-{
-    notImplemented();
+    ASSERT(!m_readStream == !m_writeStream);
+    if (!m_readStream)
+        return;
+
+    CFReadStreamUnscheduleFromRunLoop(m_readStream.get(), CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
+    CFWriteStreamUnscheduleFromRunLoop(m_writeStream.get(), CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
+
+    CFReadStreamClose(m_readStream.get());
+    CFWriteStreamClose(m_writeStream.get());
+    
+    m_readStream = 0;
+    m_writeStream = 0;
 }
 
 void SocketStreamHandle::receivedCredential(const AuthenticationChallenge&, const Credential&)
 {
-    notImplemented();
 }
 
 void SocketStreamHandle::receivedRequestToContinueWithoutCredential(const AuthenticationChallenge&)
 {
-    notImplemented();
 }
 
 void SocketStreamHandle::receivedCancellation(const AuthenticationChallenge&)
 {
-    notImplemented();
 }
 
 }  // namespace WebCore

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list