Add a Generic WebSocket Server.
authorjocelyn.turcotte@nokia.com <jocelyn.turcotte@nokia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Apr 2012 13:24:11 +0000 (13:24 +0000)
committerjocelyn.turcotte@nokia.com <jocelyn.turcotte@nokia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Apr 2012 13:24:11 +0000 (13:24 +0000)
https://bugs.webkit.org/show_bug.cgi?id=73093

Reviewed by Simon Hausmann.

Source/WebCore:

Allow SocketStreamHandle for the Qt port to take an existing QTcpSocket in its constructor.

* platform/network/qt/SocketStreamHandle.h:
(WebCore::SocketStreamHandle::create):
(SocketStreamHandle):
* platform/network/qt/SocketStreamHandlePrivate.h:
(SocketStreamHandlePrivate):
* platform/network/qt/SocketStreamHandleQt.cpp:
(WebCore::SocketStreamHandlePrivate::SocketStreamHandlePrivate):
(WebCore):
(WebCore::SocketStreamHandlePrivate::initConnections):
(WebCore::SocketStreamHandlePrivate::close):
(WebCore::SocketStreamHandle::SocketStreamHandle):

Source/WebKit2:

The Inspector Server will be a WebSocket Server that also responds to
non-WebSocket-Upgrade HTTP Requests. This is a generic WebSocket server
that passes on what it doesn't know on to its client for extended
functionality. This code is wrapped in a new ENABLE(INSPECTOR_SERVER) flag.

There are no tests yet for a built-in WebSocket server.
This will be covered by API level tests in a later patch.

* Target.pri:

  WebSocketServer is a simple server. Calling listen, or close,
  multiple times is safe. Subclassing is expected.

* UIProcess/InspectorServer/WebSocketServer.cpp: Added.
(WebKit):
(WebKit::WebSocketServer::WebSocketServer):
(WebKit::WebSocketServer::~WebSocketServer):
(WebKit::WebSocketServer::listen):
(WebKit::WebSocketServer::close):
(WebKit::WebSocketServer::didAcceptConnection):
(WebKit::WebSocketServer::didCloseWebSocketServerConnection):
* UIProcess/InspectorServer/WebSocketServer.h: Added.
(WebKit):
(WebCore):
(WebSocketServer):
* UIProcess/InspectorServer/WebSocketServerClient.h: Added.
(WebCore):
(WebKit):
(WebSocketServerClient):
(WebKit::WebSocketServerClient::~WebSocketServerClient):
(WebKit::WebSocketServerClient::didReceiveUnrecognizedHTTPRequest):
(WebKit::WebSocketServerClient::didReceiveWebSocketUpgradeHTTPRequest):
(WebKit::WebSocketServerClient::didEstablishWebSocketConnection):
(WebKit::WebSocketServerClient::didReceiveWebSocketMessage):
(WebKit::WebSocketServerClient::didCloseWebSocketConnection):

  Each WebSocketConnection:

   - Passes unknown HTTP Requests to the server's client.
   - Handles WebSocket Upgrade Requests.
     - First ask the client if it is okay.
     - Later notify the client about a success.
   - Once upgraded the connection parses and passes WebSocket
     frames to the client.

* UIProcess/InspectorServer/WebSocketServerConnection.cpp: Added.
(WebKit):
(WebKit::WebSocketServerConnection::WebSocketServerConnection):
(WebKit::WebSocketServerConnection::~WebSocketServerConnection):
(WebKit::WebSocketServerConnection::shutdownNow):
(WebKit::WebSocketServerConnection::shutdownAfterSendOrNow): meant to shutdown after an HTTP response. Ensure all platforms work as expected.
(WebKit::WebSocketServerConnection::sendWebSocketMessage): send a text message (WebSocket message) over the connection.
(WebKit::WebSocketServerConnection::sendHTTPResponseHeader):
(WebKit::WebSocketServerConnection::sendRawData): send raw data (HTTP message) over the connection.
(WebKit::WebSocketServerConnection::didCloseSocketStream): handle socket closing scenarios.
(WebKit::WebSocketServerConnection::didReceiveSocketStreamData): parse the incoming data in HTTP / WebSocket modes.
(WebKit::WebSocketServerConnection::didFailSocketStream): log errors.
(WebKit::WebSocketServerConnection::readHTTPMessage): when starting, a web socket connection reads an HTTP message.
(WebKit::WebSocketServerConnection::upgradeToWebSocketServerConnection):
(WebKit::WebSocketServerConnection::readWebSocketFrames): parse our buffer for as many frames as possible.
(WebKit::WebSocketServerConnection::readWebSocketFrame): parse an individual frame.
* UIProcess/InspectorServer/WebSocketServerConnection.h: Added.
(WebCore):
(WebKit):
(WebSocketServerConnection):
(WebKit::WebSocketServerConnection::identifier):
(WebKit::WebSocketServerConnection::setIdentifier):

  Qt specific implementation.

* UIProcess/InspectorServer/qt/WebSocketServerQt.cpp: Added.
(WebKit):
(WebKit::WebSocketServer::platformInitialize):
(WebKit::WebSocketServer::platformListen):
(WebKit::WebSocketServer::platformClose):
(WebKit::QtTcpServerHandler::QtTcpServerHandler):
(WebKit::QtTcpServerHandler::handleNewConnection):
(WebKit::QtTcpServerHandler::listen):
(WebKit::QtTcpServerHandler::close):
* UIProcess/InspectorServer/qt/WebSocketServerQt.h: Added.
(WebKit):
(QtTcpServerHandler):

* WebKit2.pri:
* config.h: Add ENABLE(INSPECTOR_SERVER) for WebKit2.

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

15 files changed:
Source/WebCore/ChangeLog
Source/WebCore/platform/network/qt/SocketStreamHandle.h
Source/WebCore/platform/network/qt/SocketStreamHandlePrivate.h
Source/WebCore/platform/network/qt/SocketStreamHandleQt.cpp
Source/WebKit2/ChangeLog
Source/WebKit2/Target.pri
Source/WebKit2/UIProcess/InspectorServer/WebSocketServer.cpp [new file with mode: 0644]
Source/WebKit2/UIProcess/InspectorServer/WebSocketServer.h [new file with mode: 0644]
Source/WebKit2/UIProcess/InspectorServer/WebSocketServerClient.h [new file with mode: 0644]
Source/WebKit2/UIProcess/InspectorServer/WebSocketServerConnection.cpp [new file with mode: 0644]
Source/WebKit2/UIProcess/InspectorServer/WebSocketServerConnection.h [new file with mode: 0644]
Source/WebKit2/UIProcess/InspectorServer/qt/WebSocketServerQt.cpp [new file with mode: 0644]
Source/WebKit2/UIProcess/InspectorServer/qt/WebSocketServerQt.h [new file with mode: 0644]
Source/WebKit2/WebKit2.pri
Source/WebKit2/config.h

index f835928..7c8e0b8 100644 (file)
@@ -1,3 +1,24 @@
+2012-03-29  Joseph Pecoraro  <joepeck@webkit.org> and Jocelyn Turcotte  <jocelyn.turcotte@nokia.com>
+
+        Add a Generic WebSocket Server.
+        https://bugs.webkit.org/show_bug.cgi?id=73093
+
+        Reviewed by Simon Hausmann.
+
+        Allow SocketStreamHandle for the Qt port to take an existing QTcpSocket in its constructor.
+
+        * platform/network/qt/SocketStreamHandle.h:
+        (WebCore::SocketStreamHandle::create):
+        (SocketStreamHandle):
+        * platform/network/qt/SocketStreamHandlePrivate.h:
+        (SocketStreamHandlePrivate):
+        * platform/network/qt/SocketStreamHandleQt.cpp:
+        (WebCore::SocketStreamHandlePrivate::SocketStreamHandlePrivate):
+        (WebCore):
+        (WebCore::SocketStreamHandlePrivate::initConnections):
+        (WebCore::SocketStreamHandlePrivate::close):
+        (WebCore::SocketStreamHandle::SocketStreamHandle):
+
 2012-04-01  Jocelyn Turcotte  <jocelyn.turcotte@nokia.com>
 
         Expose reusable WebSocket code for WebSocketServer.
index e725344..9e6eac0 100644 (file)
 #error This should only be built on Qt
 #endif
 
+QT_BEGIN_NAMESPACE
+class QTcpSocket;
+QT_END_NAMESPACE
+
 namespace WebCore {
 
     class AuthenticationChallenge;
@@ -52,6 +56,7 @@ namespace WebCore {
     class SocketStreamHandle : public RefCounted<SocketStreamHandle>, public SocketStreamHandleBase {
     public:
         static PassRefPtr<SocketStreamHandle> create(const KURL& url, SocketStreamHandleClient* client) { return adoptRef(new SocketStreamHandle(url, client)); }
+        static PassRefPtr<SocketStreamHandle> create(QTcpSocket* socket, SocketStreamHandleClient* client) { return adoptRef(new SocketStreamHandle(socket, client)); }
 
         virtual ~SocketStreamHandle();
 
@@ -61,6 +66,7 @@ namespace WebCore {
 
     private:
         SocketStreamHandle(const KURL&, SocketStreamHandleClient*);
+        SocketStreamHandle(QTcpSocket*, SocketStreamHandleClient*);
 
         // No authentication for streams per se, but proxy may ask for credentials.
         void didReceiveAuthenticationChallenge(const AuthenticationChallenge&);
index d074f42..3019279 100644 (file)
@@ -47,6 +47,7 @@ class SocketStreamHandlePrivate : public QObject {
     Q_OBJECT
 public:
     SocketStreamHandlePrivate(SocketStreamHandle*, const KURL&);
+    SocketStreamHandlePrivate(SocketStreamHandle*, QTcpSocket*);
     ~SocketStreamHandlePrivate();
 
 public slots:
@@ -63,6 +64,7 @@ public slots:
     void socketSslErrors(const QList<QSslError>&);
 #endif
 public:
+    void initConnections();
     QTcpSocket* m_socket;
     SocketStreamHandle* m_streamHandle;
 };
index d463909..28101a6 100644 (file)
@@ -40,7 +40,7 @@
 
 namespace WebCore {
 
-SocketStreamHandlePrivate::SocketStreamHandlePrivate(SocketStreamHandle* streamHandle, const KURL& url) : QObject()
+SocketStreamHandlePrivate::SocketStreamHandlePrivate(SocketStreamHandle* streamHandle, const KURL& url)
 {
     m_streamHandle = streamHandle;
     m_socket = 0;
@@ -56,12 +56,7 @@ SocketStreamHandlePrivate::SocketStreamHandlePrivate(SocketStreamHandle* streamH
     if (!m_socket)
         return;
 
-    connect(m_socket, SIGNAL(connected()), this, SLOT(socketConnected()));
-    connect(m_socket, SIGNAL(readyRead()), this, SLOT(socketReadyRead()));
-    connect(m_socket, SIGNAL(disconnected()), this, SLOT(socketClosed()));
-    connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError)));
-    if (isSecure)
-        connect(m_socket, SIGNAL(sslErrors(const QList<QSslError>&)), this, SLOT(socketSslErrors(const QList<QSslError>&)));
+    initConnections();
 
     unsigned int port = url.hasPort() ? url.port() : (isSecure ? 443 : 80);
 
@@ -74,11 +69,36 @@ SocketStreamHandlePrivate::SocketStreamHandlePrivate(SocketStreamHandle* streamH
         m_socket->connectToHost(host, port);
 }
 
+SocketStreamHandlePrivate::SocketStreamHandlePrivate(SocketStreamHandle* streamHandle, QTcpSocket* socket)
+{
+    m_streamHandle = streamHandle;
+    m_socket = socket;
+    initConnections();
+}
+
 SocketStreamHandlePrivate::~SocketStreamHandlePrivate()
 {
     Q_ASSERT(!(m_socket && m_socket->state() == QAbstractSocket::ConnectedState));
 }
 
+void SocketStreamHandlePrivate::initConnections()
+{
+    connect(m_socket, SIGNAL(connected()), this, SLOT(socketConnected()));
+    connect(m_socket, SIGNAL(readyRead()), this, SLOT(socketReadyRead()));
+    connect(m_socket, SIGNAL(disconnected()), this, SLOT(socketClosed()));
+    connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError)));
+#ifndef QT_NO_OPENSSL
+    if (qobject_cast<QSslSocket*>(m_socket))
+        connect(m_socket, SIGNAL(sslErrors(const QList<QSslError>&)), this, SLOT(socketSslErrors(const QList<QSslError>&)));
+#endif
+
+    // Check for missed signals and call the slots asynchronously to allow a client to be set first.
+    if (m_socket->state() >= QAbstractSocket::ConnectedState)
+        QMetaObject::invokeMethod(this, "socketConnected", Qt::QueuedConnection);
+    if (m_socket->bytesAvailable())
+        QMetaObject::invokeMethod(this, "socketReadyRead", Qt::QueuedConnection);
+}
+
 void SocketStreamHandlePrivate::socketConnected()
 {
     if (m_streamHandle && m_streamHandle->client()) {
@@ -106,7 +126,7 @@ int SocketStreamHandlePrivate::send(const char* data, int len)
 
 void SocketStreamHandlePrivate::close()
 {
-    if (m_streamHandle->m_state == SocketStreamHandleBase::Connecting) {
+    if (m_streamHandle && m_streamHandle->m_state == SocketStreamHandleBase::Connecting) {
         m_socket->abort();
         m_streamHandle->client()->didCloseSocketStream(m_streamHandle);
         return;
@@ -166,6 +186,13 @@ SocketStreamHandle::SocketStreamHandle(const KURL& url, SocketStreamHandleClient
     m_p = new SocketStreamHandlePrivate(this, url);
 }
 
+SocketStreamHandle::SocketStreamHandle(QTcpSocket* socket, SocketStreamHandleClient* client)
+    : SocketStreamHandleBase(KURL(), client)
+{
+    LOG(Network, "SocketStreamHandle %p new client %p", this, m_client);
+    m_p = new SocketStreamHandlePrivate(this, socket);
+}
+
 SocketStreamHandle::~SocketStreamHandle()
 {
     LOG(Network, "SocketStreamHandle %p delete", this);
index 71a5344..d9dceb4 100644 (file)
@@ -1,3 +1,96 @@
+2012-03-29  Joseph Pecoraro  <joepeck@webkit.org> and Jocelyn Turcotte  <jocelyn.turcotte@nokia.com>
+
+        Add a Generic WebSocket Server.
+        https://bugs.webkit.org/show_bug.cgi?id=73093
+
+        Reviewed by Simon Hausmann.
+
+        The Inspector Server will be a WebSocket Server that also responds to
+        non-WebSocket-Upgrade HTTP Requests. This is a generic WebSocket server
+        that passes on what it doesn't know on to its client for extended
+        functionality. This code is wrapped in a new ENABLE(INSPECTOR_SERVER) flag.
+
+        There are no tests yet for a built-in WebSocket server.
+        This will be covered by API level tests in a later patch.
+
+        * Target.pri:
+
+          WebSocketServer is a simple server. Calling listen, or close,
+          multiple times is safe. Subclassing is expected.
+
+        * UIProcess/InspectorServer/WebSocketServer.cpp: Added.
+        (WebKit):
+        (WebKit::WebSocketServer::WebSocketServer):
+        (WebKit::WebSocketServer::~WebSocketServer):
+        (WebKit::WebSocketServer::listen):
+        (WebKit::WebSocketServer::close):
+        (WebKit::WebSocketServer::didAcceptConnection):
+        (WebKit::WebSocketServer::didCloseWebSocketServerConnection):
+        * UIProcess/InspectorServer/WebSocketServer.h: Added.
+        (WebKit):
+        (WebCore):
+        (WebSocketServer):
+        * UIProcess/InspectorServer/WebSocketServerClient.h: Added.
+        (WebCore):
+        (WebKit):
+        (WebSocketServerClient):
+        (WebKit::WebSocketServerClient::~WebSocketServerClient):
+        (WebKit::WebSocketServerClient::didReceiveUnrecognizedHTTPRequest):
+        (WebKit::WebSocketServerClient::didReceiveWebSocketUpgradeHTTPRequest):
+        (WebKit::WebSocketServerClient::didEstablishWebSocketConnection):
+        (WebKit::WebSocketServerClient::didReceiveWebSocketMessage):
+        (WebKit::WebSocketServerClient::didCloseWebSocketConnection):
+
+          Each WebSocketConnection:
+
+           - Passes unknown HTTP Requests to the server's client.
+           - Handles WebSocket Upgrade Requests.
+             - First ask the client if it is okay.
+             - Later notify the client about a success.
+           - Once upgraded the connection parses and passes WebSocket
+             frames to the client.
+
+        * UIProcess/InspectorServer/WebSocketServerConnection.cpp: Added.
+        (WebKit):
+        (WebKit::WebSocketServerConnection::WebSocketServerConnection):
+        (WebKit::WebSocketServerConnection::~WebSocketServerConnection):
+        (WebKit::WebSocketServerConnection::shutdownNow):
+        (WebKit::WebSocketServerConnection::shutdownAfterSendOrNow): meant to shutdown after an HTTP response. Ensure all platforms work as expected.
+        (WebKit::WebSocketServerConnection::sendWebSocketMessage): send a text message (WebSocket message) over the connection.
+        (WebKit::WebSocketServerConnection::sendHTTPResponseHeader):
+        (WebKit::WebSocketServerConnection::sendRawData): send raw data (HTTP message) over the connection.
+        (WebKit::WebSocketServerConnection::didCloseSocketStream): handle socket closing scenarios.
+        (WebKit::WebSocketServerConnection::didReceiveSocketStreamData): parse the incoming data in HTTP / WebSocket modes.
+        (WebKit::WebSocketServerConnection::didFailSocketStream): log errors.
+        (WebKit::WebSocketServerConnection::readHTTPMessage): when starting, a web socket connection reads an HTTP message.
+        (WebKit::WebSocketServerConnection::upgradeToWebSocketServerConnection):
+        (WebKit::WebSocketServerConnection::readWebSocketFrames): parse our buffer for as many frames as possible.
+        (WebKit::WebSocketServerConnection::readWebSocketFrame): parse an individual frame.
+        * UIProcess/InspectorServer/WebSocketServerConnection.h: Added.
+        (WebCore):
+        (WebKit):
+        (WebSocketServerConnection):
+        (WebKit::WebSocketServerConnection::identifier):
+        (WebKit::WebSocketServerConnection::setIdentifier):
+
+          Qt specific implementation.
+
+        * UIProcess/InspectorServer/qt/WebSocketServerQt.cpp: Added.
+        (WebKit):
+        (WebKit::WebSocketServer::platformInitialize):
+        (WebKit::WebSocketServer::platformListen):
+        (WebKit::WebSocketServer::platformClose):
+        (WebKit::QtTcpServerHandler::QtTcpServerHandler):
+        (WebKit::QtTcpServerHandler::handleNewConnection):
+        (WebKit::QtTcpServerHandler::listen):
+        (WebKit::QtTcpServerHandler::close):
+        * UIProcess/InspectorServer/qt/WebSocketServerQt.h: Added.
+        (WebKit):
+        (QtTcpServerHandler):
+
+        * WebKit2.pri:
+        * config.h: Add ENABLE(INSPECTOR_SERVER) for WebKit2.
+
 2012-04-03  Jocelyn Turcotte  <jocelyn.turcotte@nokia.com>
 
         [Qt] Add developerExtrasEnabled to QWebPreferences.
index 0749738..498c469 100644 (file)
@@ -204,6 +204,10 @@ HEADERS += \
     UIProcess/GenericCallback.h \
     UIProcess/GeolocationPermissionRequestManagerProxy.h \
     UIProcess/GeolocationPermissionRequestProxy.h \
+    UIProcess/InspectorServer/WebSocketServer.h \
+    UIProcess/InspectorServer/WebSocketServerClient.h \
+    UIProcess/InspectorServer/WebSocketServerConnection.h \
+    UIProcess/InspectorServer/qt/WebSocketServerQt.h \
     UIProcess/Launcher/ProcessLauncher.h \
     UIProcess/Launcher/ThreadLauncher.h \
     UIProcess/LayerTreeHostProxy.h \
@@ -541,6 +545,9 @@ SOURCES += \
     UIProcess/FindIndicator.cpp \
     UIProcess/GeolocationPermissionRequestManagerProxy.cpp \
     UIProcess/GeolocationPermissionRequestProxy.cpp \
+    UIProcess/InspectorServer/WebSocketServer.cpp \
+    UIProcess/InspectorServer/WebSocketServerConnection.cpp \
+    UIProcess/InspectorServer/qt/WebSocketServerQt.cpp \
     UIProcess/Launcher/ProcessLauncher.cpp \
     UIProcess/Launcher/ThreadLauncher.cpp \
     UIProcess/Launcher/qt/ProcessLauncherQt.cpp \
diff --git a/Source/WebKit2/UIProcess/InspectorServer/WebSocketServer.cpp b/Source/WebKit2/UIProcess/InspectorServer/WebSocketServer.cpp
new file mode 100644 (file)
index 0000000..1ccdbc8
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(INSPECTOR_SERVER)
+
+#include "WebSocketServer.h"
+
+#include "WebSocketServerConnection.h"
+#include <WebCore/SocketStreamHandle.h>
+#include <wtf/PassOwnPtr.h>
+
+#if PLATFORM(QT)
+#include "WebSocketServerQt.h"
+#endif
+
+using namespace WebCore;
+
+namespace WebKit {
+
+WebSocketServer::WebSocketServer(WebSocketServerClient* client)
+    : m_state(Closed)
+    , m_client(client)
+{
+    platformInitialize();
+}
+
+WebSocketServer::~WebSocketServer()
+{
+    close();
+}
+
+bool WebSocketServer::listen(const String& bindAddress, unsigned short port)
+{
+    ASSERT(port);
+
+    if (m_state == Listening)
+        return false;
+
+    bool isNowListening = platformListen(bindAddress, port);
+    m_state = isNowListening ? Listening : Closed;
+    return isNowListening;
+}
+
+void WebSocketServer::close()
+{
+    if (m_state == Closed)
+        return;
+
+    platformClose();
+}
+
+void WebSocketServer::didAcceptConnection(PassRefPtr<SocketStreamHandle> socketHandle)
+{
+    m_connections.append(adoptPtr(new WebSocketServerConnection(socketHandle, m_client, this)));
+}
+
+void WebSocketServer::didCloseWebSocketServerConnection(WebSocketServerConnection* connection)
+{
+    Deque<OwnPtr<WebSocketServerConnection> >::iterator end = m_connections.end();
+    for (Deque<OwnPtr<WebSocketServerConnection> >::iterator it = m_connections.begin(); it != end; ++it) {
+        if (it->get() == connection) {
+            m_connections.remove(it);
+            return;
+        }
+    }
+    ASSERT_NOT_REACHED();
+}
+
+}
+
+#endif // ENABLE(INSPECTOR_SERVER)
diff --git a/Source/WebKit2/UIProcess/InspectorServer/WebSocketServer.h b/Source/WebKit2/UIProcess/InspectorServer/WebSocketServer.h
new file mode 100644 (file)
index 0000000..d60820e
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebSocketServer_h
+#define WebSocketServer_h
+
+#if ENABLE(INSPECTOR_SERVER)
+
+#include <wtf/Deque.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/text/WTFString.h>
+
+#if PLATFORM(QT)
+namespace WebKit {
+class QtTcpServerHandler;
+}
+#endif
+
+namespace WebCore {
+class SocketStreamHandle;
+}
+
+namespace WebKit {
+
+class WebSocketServerClient;
+class WebSocketServerConnection;
+
+class WebSocketServer {
+public:
+    enum ServerState { Closed, Listening };
+    WebSocketServer(WebSocketServerClient*);
+    virtual ~WebSocketServer();
+
+    // Server operations.
+    bool listen(const String& bindAddress, unsigned short port);
+    void close();
+
+    void didAcceptConnection(PassRefPtr<WebCore::SocketStreamHandle>);
+
+private:
+    void didCloseWebSocketServerConnection(WebSocketServerConnection*);
+
+    void platformInitialize();
+    bool platformListen(const String& bindAddress, unsigned short port);
+    void platformClose();
+
+    ServerState m_state;
+    Deque<OwnPtr<WebSocketServerConnection> > m_connections;
+    WebSocketServerClient* m_client;
+#if PLATFORM(QT)
+    OwnPtr<QtTcpServerHandler> m_tcpServerHandler;
+#endif
+    friend class WebSocketServerConnection;
+};
+
+}
+
+#endif // ENABLE(INSPECTOR_SERVER)
+
+#endif // WebSocketServer_h
diff --git a/Source/WebKit2/UIProcess/InspectorServer/WebSocketServerClient.h b/Source/WebKit2/UIProcess/InspectorServer/WebSocketServerClient.h
new file mode 100644 (file)
index 0000000..e7be3ab
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebSocketServerClient_h
+#define WebSocketServerClient_h
+
+#if ENABLE(INSPECTOR_SERVER)
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+class HTTPRequest;
+}
+
+namespace WebKit {
+
+class WebSocketServerConnection;
+
+class WebSocketServerClient {
+public:
+    virtual ~WebSocketServerClient() { }
+
+    // Received an HTTP request but didn't know what to do with it.
+    virtual void didReceiveUnrecognizedHTTPRequest(WebSocketServerConnection*, PassRefPtr<WebCore::HTTPRequest>) { }
+
+    // Received a WebSocket Upgrade HTTP request. Ask if we should handle it and upgrade.
+    virtual bool didReceiveWebSocketUpgradeHTTPRequest(WebSocketServerConnection*, PassRefPtr<WebCore::HTTPRequest>) { return true; }
+
+    // Established a WebSocket Connection.
+    virtual void didEstablishWebSocketConnection(WebSocketServerConnection*, PassRefPtr<WebCore::HTTPRequest>) { }
+
+    // Received a WebSocket message.
+    virtual void didReceiveWebSocketMessage(WebSocketServerConnection*, const String&) { }
+
+    // WebSocket Connection closed.
+    virtual void didCloseWebSocketConnection(WebSocketServerConnection*) { }
+};
+
+}
+
+#endif // ENABLE(INSPECTOR_SERVER)
+
+#endif // WebSocketServerClient_h
diff --git a/Source/WebKit2/UIProcess/InspectorServer/WebSocketServerConnection.cpp b/Source/WebKit2/UIProcess/InspectorServer/WebSocketServerConnection.cpp
new file mode 100644 (file)
index 0000000..9ffbbbe
--- /dev/null
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(INSPECTOR_SERVER)
+
+#include "WebSocketServerConnection.h"
+
+#include "WebSocketServer.h"
+#include "WebSocketServerClient.h"
+#include <WebCore/HTTPRequest.h>
+#include <WebCore/NotImplemented.h>
+#include <WebCore/SocketStreamError.h>
+#include <WebCore/SocketStreamHandle.h>
+#include <WebCore/WebSocketChannel.h>
+#include <WebCore/WebSocketHandshake.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/StringBuilder.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+WebSocketServerConnection::WebSocketServerConnection(PassRefPtr<SocketStreamHandle> socket, WebSocketServerClient* client, WebSocketServer* server)
+    : m_identifier(0)
+    , m_mode(HTTP)
+    , m_socket(socket)
+    , m_server(server)
+    , m_client(client)
+{
+    m_socket->setClient(this);
+}
+
+WebSocketServerConnection::~WebSocketServerConnection()
+{
+    shutdownNow();
+}
+
+void WebSocketServerConnection::shutdownNow()
+{
+    if (!m_socket)
+        return;
+    RefPtr<SocketStreamHandle> socket = m_socket.release();
+    socket->close();
+}
+
+void WebSocketServerConnection::shutdownAfterSendOrNow()
+{
+    // If this ASSERT happens on any platform then their SocketStreamHandle::send
+    // followed by a SocketStreamHandle::close is not guarenteed to have sent all
+    // data. If this happens, we need to slightly change the design to include a
+    // SocketStreamHandleClient::didSend, handle it here, and add an m_shutdownAfterSend
+    // state on this WebSocketServerConnection.
+    ASSERT(!m_socket->bufferedAmount());
+
+    shutdownNow();
+}
+
+void WebSocketServerConnection::sendWebSocketMessage(const String& message)
+{
+    CString payload = message.utf8();
+    const bool final = true, compress = false, masked = false;
+    WebSocketFrame frame(WebSocketFrame::OpCodeText, final, compress, masked, payload.data(), payload.length());
+
+    Vector<char> frameData;
+    frame.makeFrameData(frameData);
+
+    m_socket->send(frameData.data(), frameData.size());
+}
+
+void WebSocketServerConnection::sendHTTPResponseHeader(int statusCode, const String& statusText, const HTTPHeaderMap& headerFields)
+{
+    StringBuilder builder;
+    builder.append("HTTP/1.1 ");
+    builder.append(String::number(statusCode));
+    builder.append(" ");
+    builder.append(statusText);
+    builder.append("\r\n");
+    HTTPHeaderMap::const_iterator end = headerFields.end();
+    for (HTTPHeaderMap::const_iterator it = headerFields.begin(); it != end; ++it) {
+        builder.append(it->first);
+        builder.append(": ");
+        builder.append(it->second + "\r\n");
+    }
+    builder.append("\r\n");
+
+    CString header = builder.toString().latin1();
+    m_socket->send(header.data(), header.length());
+}
+
+void WebSocketServerConnection::sendRawData(const char* data, size_t length)
+{
+    m_socket->send(data, length);
+}
+
+void WebSocketServerConnection::didCloseSocketStream(SocketStreamHandle*)
+{
+    // Web Socket Mode.
+    if (m_mode == WebSocket)
+        m_client->didCloseWebSocketConnection(this);
+
+    // Tell the server to get rid of this.
+    m_server->didCloseWebSocketServerConnection(this);
+}
+
+void WebSocketServerConnection::didReceiveSocketStreamData(SocketStreamHandle*, const char* data, int length)
+{
+    // Each didReceiveData call adds more data to our buffer.
+    // We clear the buffer when we have handled data from it.
+    m_bufferedData.append(data, length);
+
+    switch (m_mode) {
+    case HTTP:
+        readHTTPMessage();
+        break;
+    case WebSocket:
+        readWebSocketFrames();
+        break;
+    default:
+        // For any new modes added in the future.
+        ASSERT_NOT_REACHED();
+    }
+}
+
+void WebSocketServerConnection::didFailSocketStream(SocketStreamHandle*, const SocketStreamError&)
+{
+    // Possible read or write error.
+}
+
+void WebSocketServerConnection::readHTTPMessage()
+{
+    String failureReason;
+    RefPtr<HTTPRequest> request = HTTPRequest::parseHTTPRequestFromBuffer(m_bufferedData.data(), m_bufferedData.size(), failureReason);
+    if (!request)
+        return;
+
+    // Assume all the input has been read if we are reading an HTTP Request.
+    m_bufferedData.clear();
+
+    // If this is a WebSocket request, perform the WebSocket Handshake.
+    const HTTPHeaderMap& headers = request->headerFields();
+    String upgradeHeaderValue = headers.get("Upgrade");
+    if (upgradeHeaderValue == "websocket") {
+        upgradeToWebSocketServerConnection(request);
+        return;
+    }
+    if (upgradeHeaderValue == "WebSocket") {
+        LOG_ERROR("WebSocket protocol version < Hybi-10 not supported. Upgrade your client.");
+        return;
+    }
+
+    // Otherwise, this is an HTTP Request we don't know how to deal with.
+    m_client->didReceiveUnrecognizedHTTPRequest(this, request);
+}
+
+void WebSocketServerConnection::upgradeToWebSocketServerConnection(PassRefPtr<HTTPRequest> request)
+{
+    ASSERT(request);
+    ASSERT(m_mode == HTTP);
+    m_mode = WebSocket;
+    RefPtr<HTTPRequest> protectedRequest(request);
+
+    // Ask the client if we should upgrade for this or not.
+    if (!m_client->didReceiveWebSocketUpgradeHTTPRequest(this, protectedRequest)) {
+        shutdownNow();
+        return;
+    }
+
+    // Build and send the WebSocket handshake response.
+    const HTTPHeaderMap& requestHeaders = protectedRequest->headerFields();
+    String accept = WebSocketHandshake::getExpectedWebSocketAccept(requestHeaders.get("Sec-WebSocket-Key"));
+    HTTPHeaderMap responseHeaders;
+    responseHeaders.add("Upgrade", requestHeaders.get("Upgrade"));
+    responseHeaders.add("Connection", requestHeaders.get("Connection"));
+    responseHeaders.add("Sec-WebSocket-Accept", accept);
+
+    sendHTTPResponseHeader(101, "WebSocket Protocol Handshake", responseHeaders);
+
+    m_client->didEstablishWebSocketConnection(this, protectedRequest);
+}
+
+void WebSocketServerConnection::readWebSocketFrames()
+{
+    while (true) {
+        bool didReadOneFrame = readWebSocketFrame();
+        if (!didReadOneFrame)
+            break;
+        if (m_bufferedData.isEmpty())
+            break;
+    }
+}
+
+bool WebSocketServerConnection::readWebSocketFrame()
+{
+    WebSocketFrame frame;
+    const char* frameEnd;
+    String errorString;
+    WebSocketFrame::ParseFrameResult result = WebSocketFrame::parseFrame(m_bufferedData.data(), m_bufferedData.size(), frame, frameEnd, errorString);
+
+    // Incomplete frame. Wait to receive more data.
+    if (result == WebSocketFrame::FrameIncomplete)
+        return false;
+
+    if (result == WebSocketFrame::FrameError) {
+        shutdownNow();
+    } else if (frame.opCode == WebSocketFrame::OpCodeText) {
+        // Delegate Text frames to our client.
+        String msg = String::fromUTF8(frame.payload, frame.payloadLength);
+        m_client->didReceiveWebSocketMessage(this, msg);
+    } else
+        notImplemented();
+
+    // Remove the frame from our buffer.
+    m_bufferedData.remove(0, frameEnd - m_bufferedData.data());
+
+    return true;
+}
+
+}
+
+#endif // ENABLE(INSPECTOR_SERVER)
diff --git a/Source/WebKit2/UIProcess/InspectorServer/WebSocketServerConnection.h b/Source/WebKit2/UIProcess/InspectorServer/WebSocketServerConnection.h
new file mode 100644 (file)
index 0000000..6cc7701
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebSocketServerConnection_h
+#define WebSocketServerConnection_h
+
+#if ENABLE(INSPECTOR_SERVER)
+
+#include <WebCore/SocketStreamHandleClient.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+class HTTPHeaderMap;
+class HTTPRequest;
+class SocketStreamHandle;
+}
+
+namespace WebKit {
+
+class WebSocketServer;
+class WebSocketServerClient;
+
+class WebSocketServerConnection : public WebCore::SocketStreamHandleClient {
+public:
+    enum WebSocketServerMode { HTTP, WebSocket };
+    WebSocketServerConnection(PassRefPtr<WebCore::SocketStreamHandle>, WebSocketServerClient*, WebSocketServer*);
+    virtual ~WebSocketServerConnection();
+
+    unsigned identifier() const { return m_identifier; }
+    void setIdentifier(unsigned id) { m_identifier = id; }
+
+    // Sending data over the connection.
+    void sendWebSocketMessage(const String& message);
+    void sendHTTPResponseHeader(int statusCode, const String& statusText, const WebCore::HTTPHeaderMap& headerFields);
+    void sendRawData(const char* data, size_t length);
+
+    // Terminating the connection.
+    void shutdownNow();
+    void shutdownAfterSendOrNow();
+
+    // SocketStreamHandleClient implementation.
+    virtual void didCloseSocketStream(WebCore::SocketStreamHandle*);
+    virtual void didReceiveSocketStreamData(WebCore::SocketStreamHandle*, const char* data, int length);
+    virtual void didFailSocketStream(WebCore::SocketStreamHandle*, const WebCore::SocketStreamError&);
+
+private:
+    // HTTP Mode.
+    void readHTTPMessage();
+
+    // WebSocket Mode.
+    void upgradeToWebSocketServerConnection(PassRefPtr<WebCore::HTTPRequest>);
+    void readWebSocketFrames();
+    bool readWebSocketFrame();
+
+protected:
+    unsigned m_identifier;
+    Vector<char> m_bufferedData;
+    WebSocketServerMode m_mode;
+    RefPtr<WebCore::SocketStreamHandle> m_socket;
+    WebSocketServer* m_server;
+    WebSocketServerClient* m_client;
+};
+
+}
+
+#endif // ENABLE(INSPECTOR_SERVER)
+
+#endif // WebSocketServerConnection_h
diff --git a/Source/WebKit2/UIProcess/InspectorServer/qt/WebSocketServerQt.cpp b/Source/WebKit2/UIProcess/InspectorServer/qt/WebSocketServerQt.cpp
new file mode 100644 (file)
index 0000000..6a9c5b3
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this program; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#include "config.h"
+#include "WebSocketServerQt.h"
+
+#include "WebSocketServer.h"
+#include <WebCore/SocketStreamHandle.h>
+#include <wtf/PassOwnPtr.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+void WebSocketServer::platformInitialize()
+{
+    m_tcpServerHandler = adoptPtr(new QtTcpServerHandler(this));
+}
+
+bool WebSocketServer::platformListen(const String& bindAddress, unsigned short port)
+{
+    return m_tcpServerHandler->listen(bindAddress, port);
+}
+
+void WebSocketServer::platformClose()
+{
+    m_tcpServerHandler->close();
+}
+
+QtTcpServerHandler::QtTcpServerHandler(WebSocketServer* webSocketServer)
+: m_webSocketServer(webSocketServer)
+{
+    connect(&m_serverSocket, SIGNAL(newConnection()), SLOT(handleNewConnection()));
+}
+
+void QtTcpServerHandler::handleNewConnection()
+{
+    QTcpSocket* socket = m_serverSocket.nextPendingConnection();
+    ASSERT(socket);
+    m_webSocketServer->didAcceptConnection(SocketStreamHandle::create(socket, 0));
+}
+
+bool QtTcpServerHandler::listen(const String& bindAddress, unsigned short port)
+{
+    ASSERT(!bindAddress.isEmpty());
+    ASSERT(port);
+    bool success = m_serverSocket.listen(QHostAddress(bindAddress), port);
+    if (!success)
+        LOG_ERROR("Can't open server socket on %s:%d [%s]", qPrintable(bindAddress), port, qPrintable(m_serverSocket.errorString()));
+    return success;
+}
+
+void QtTcpServerHandler::close()
+{
+    m_serverSocket.close();
+}
+
+}
+
+#include "moc_WebSocketServerQt.cpp"
diff --git a/Source/WebKit2/UIProcess/InspectorServer/qt/WebSocketServerQt.h b/Source/WebKit2/UIProcess/InspectorServer/qt/WebSocketServerQt.h
new file mode 100644 (file)
index 0000000..d565977
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebSocketServerQt_h
+#define WebSocketServerQt_h
+
+#include <QTcpServer>
+#include <wtf/text/WTFString.h>
+
+namespace WebKit {
+
+class WebSocketServer;
+
+class QtTcpServerHandler : public QObject {
+    Q_OBJECT
+public:
+    QtTcpServerHandler(WebSocketServer*);
+    bool listen(const String& bindAddress, unsigned short port);
+    void close();
+
+private slots:
+    void handleNewConnection();
+
+private:
+    QTcpServer m_serverSocket;
+    WebSocketServer* m_webSocketServer;
+};
+
+}
+
+#endif // WebSocketServerQt_h
index 648f4dc..24cc5a2 100644 (file)
@@ -27,6 +27,8 @@ INCLUDEPATH += \
     $$SOURCE_DIR/UIProcess/API/qt \
     $$SOURCE_DIR/UIProcess/Authentication \
     $$SOURCE_DIR/UIProcess/Downloads \
+    $$SOURCE_DIR/UIProcess/InspectorServer \
+    $$SOURCE_DIR/UIProcess/InspectorServer/qt \
     $$SOURCE_DIR/UIProcess/Launcher \
     $$SOURCE_DIR/UIProcess/Notifications \
     $$SOURCE_DIR/UIProcess/Plugins \
index 7db76c0..ff38f30 100644 (file)
@@ -135,3 +135,9 @@ static const type& name() \
 #endif
 
 #define PLUGIN_ARCHITECTURE(ARCH) (defined PLUGIN_ARCHITECTURE_##ARCH && PLUGIN_ARCHITECTURE_##ARCH)
+
+#ifndef ENABLE_INSPECTOR_SERVER
+#if PLATFORM(QT)
+#define ENABLE_INSPECTOR_SERVER 1
+#endif
+#endif