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
+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.
#error This should only be built on Qt
#endif
+QT_BEGIN_NAMESPACE
+class QTcpSocket;
+QT_END_NAMESPACE
+
namespace WebCore {
class AuthenticationChallenge;
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();
private:
SocketStreamHandle(const KURL&, SocketStreamHandleClient*);
+ SocketStreamHandle(QTcpSocket*, SocketStreamHandleClient*);
// No authentication for streams per se, but proxy may ask for credentials.
void didReceiveAuthenticationChallenge(const AuthenticationChallenge&);
Q_OBJECT
public:
SocketStreamHandlePrivate(SocketStreamHandle*, const KURL&);
+ SocketStreamHandlePrivate(SocketStreamHandle*, QTcpSocket*);
~SocketStreamHandlePrivate();
public slots:
void socketSslErrors(const QList<QSslError>&);
#endif
public:
+ void initConnections();
QTcpSocket* m_socket;
SocketStreamHandle* m_streamHandle;
};
namespace WebCore {
-SocketStreamHandlePrivate::SocketStreamHandlePrivate(SocketStreamHandle* streamHandle, const KURL& url) : QObject()
+SocketStreamHandlePrivate::SocketStreamHandlePrivate(SocketStreamHandle* streamHandle, const KURL& url)
{
m_streamHandle = streamHandle;
m_socket = 0;
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);
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()) {
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;
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);
+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.
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 \
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 \
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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"
--- /dev/null
+/*
+ * 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
$$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 \
#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