[WinCairo] Implement and enable RemoteInspector Server.
authorBasuke.Suzuki@sony.com <Basuke.Suzuki@sony.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 3 May 2019 21:03:34 +0000 (21:03 +0000)
committerBasuke.Suzuki@sony.com <Basuke.Suzuki@sony.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 3 May 2019 21:03:34 +0000 (21:03 +0000)
https://bugs.webkit.org/show_bug.cgi?id=197432

Reviewed by Ross Kirsling.

.:

Add new build flag USE_INSPECTOR_SOCKET_SERVER to indicate using Socket implementation for RemoteInspector
protocol. Currently PlayStation is the only platform which uses this. WinCairo is the second one.

* Source/cmake/OptionsPlayStation.cmake:
* Source/cmake/OptionsWin.cmake:
* Source/cmake/OptionsWinCairo.cmake:

Source/JavaScriptCore:

Implement Windows implementation for Socket Backend of RemoteInspector and enable it on WinCairo
for experimental feature.

Also add listener interface for connection between RemoteInspector and RemoteInspectorServer
for flexible configuration.

* PlatformWin.cmake:
* inspector/remote/RemoteInspector.h:
* inspector/remote/socket/RemoteInspectorConnectionClient.h:
(Inspector::RemoteInspectorConnectionClient::didAccept):
* inspector/remote/socket/RemoteInspectorServer.cpp:
(Inspector::RemoteInspectorServer::connect):
(Inspector::RemoteInspectorServer::listenForTargets):
(Inspector::RemoteInspectorServer::didAccept):
(Inspector::RemoteInspectorServer::dispatchMap):
(Inspector::RemoteInspectorServer::start):
(Inspector::RemoteInspectorServer::addServerConnection): Deleted.
* inspector/remote/socket/RemoteInspectorServer.h:
(Inspector::RemoteInspectorServer::RemoteInspectorServer):
* inspector/remote/socket/RemoteInspectorSocket.cpp:
(Inspector::RemoteInspector::RemoteInspector):
(Inspector::RemoteInspector::dispatchMap):
(Inspector::RemoteInspector::start):
(Inspector::RemoteInspector::stopInternal):
(Inspector::RemoteInspector::setServerPort):
* inspector/remote/socket/RemoteInspectorSocket.h:
* inspector/remote/socket/RemoteInspectorSocketEndpoint.cpp:
(Inspector::RemoteInspectorSocketEndpoint::listenInet):
(Inspector::RemoteInspectorSocketEndpoint::getPort const):
(Inspector::RemoteInspectorSocketEndpoint::acceptInetSocketIfEnabled):
* inspector/remote/socket/RemoteInspectorSocketEndpoint.h:
* inspector/remote/socket/posix/RemoteInspectorSocketPOSIX.cpp:
(Inspector::Socket::init): Added.
(Inspector::Socket::listen): Signature changed.
(Inspector::Socket::getPort): Added.
* inspector/remote/socket/win/RemoteInspectorSocketWin.cpp: Added.
(Inspector::Socket::init):
(Inspector::Socket::Socket::Socket):
(Inspector::Socket::Socket::~Socket):
(Inspector::Socket::Socket::close):
(Inspector::Socket::Socket::operator PlatformSocketType const):
(Inspector::Socket::Socket::operator bool const):
(Inspector::Socket::Socket::leak):
(Inspector::Socket::Socket::create):
(Inspector::Socket::setOpt):
(Inspector::Socket::setOptEnabled):
(Inspector::Socket::enableOpt):
(Inspector::Socket::connectTo):
(Inspector::Socket::bindAndListen):
(Inspector::Socket::connect):
(Inspector::Socket::listen):
(Inspector::Socket::accept):
(Inspector::Socket::createPair):
(Inspector::Socket::setup):
(Inspector::Socket::isValid):
(Inspector::Socket::isListening):
(Inspector::Socket::getPort):
(Inspector::Socket::read):
(Inspector::Socket::write):
(Inspector::Socket::close):
(Inspector::Socket::preparePolling):
(Inspector::Socket::poll):
(Inspector::Socket::isReadable):
(Inspector::Socket::isWritable):
(Inspector::Socket::markWaitingWritable):
(Inspector::Socket::clearWaitingWritable):

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

16 files changed:
ChangeLog
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/PlatformWin.cmake
Source/JavaScriptCore/inspector/remote/RemoteInspector.h
Source/JavaScriptCore/inspector/remote/socket/RemoteInspectorConnectionClient.h
Source/JavaScriptCore/inspector/remote/socket/RemoteInspectorServer.cpp
Source/JavaScriptCore/inspector/remote/socket/RemoteInspectorServer.h
Source/JavaScriptCore/inspector/remote/socket/RemoteInspectorSocket.cpp
Source/JavaScriptCore/inspector/remote/socket/RemoteInspectorSocket.h
Source/JavaScriptCore/inspector/remote/socket/RemoteInspectorSocketEndpoint.cpp
Source/JavaScriptCore/inspector/remote/socket/RemoteInspectorSocketEndpoint.h
Source/JavaScriptCore/inspector/remote/socket/posix/RemoteInspectorSocketPOSIX.cpp
Source/JavaScriptCore/inspector/remote/socket/win/RemoteInspectorSocketWin.cpp [new file with mode: 0644]
Source/cmake/OptionsPlayStation.cmake
Source/cmake/OptionsWin.cmake
Source/cmake/OptionsWinCairo.cmake

index 35c5607..4921060 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2019-05-03  Basuke Suzuki  <Basuke.Suzuki@sony.com>
+
+        [WinCairo] Implement and enable RemoteInspector Server.
+        https://bugs.webkit.org/show_bug.cgi?id=197432
+
+        Reviewed by Ross Kirsling.
+
+        Add new build flag USE_INSPECTOR_SOCKET_SERVER to indicate using Socket implementation for RemoteInspector
+        protocol. Currently PlayStation is the only platform which uses this. WinCairo is the second one.
+
+        * Source/cmake/OptionsPlayStation.cmake:
+        * Source/cmake/OptionsWin.cmake:
+        * Source/cmake/OptionsWinCairo.cmake:
+
 2019-05-03  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r244881.
index 9daa654..f416d56 100644 (file)
@@ -1,3 +1,77 @@
+2019-05-03  Basuke Suzuki  <Basuke.Suzuki@sony.com>
+
+        [WinCairo] Implement and enable RemoteInspector Server.
+        https://bugs.webkit.org/show_bug.cgi?id=197432
+
+        Reviewed by Ross Kirsling.
+
+        Implement Windows implementation for Socket Backend of RemoteInspector and enable it on WinCairo
+        for experimental feature.
+
+        Also add listener interface for connection between RemoteInspector and RemoteInspectorServer
+        for flexible configuration.
+
+        * PlatformWin.cmake:
+        * inspector/remote/RemoteInspector.h:
+        * inspector/remote/socket/RemoteInspectorConnectionClient.h:
+        (Inspector::RemoteInspectorConnectionClient::didAccept):
+        * inspector/remote/socket/RemoteInspectorServer.cpp:
+        (Inspector::RemoteInspectorServer::connect):
+        (Inspector::RemoteInspectorServer::listenForTargets):
+        (Inspector::RemoteInspectorServer::didAccept):
+        (Inspector::RemoteInspectorServer::dispatchMap):
+        (Inspector::RemoteInspectorServer::start):
+        (Inspector::RemoteInspectorServer::addServerConnection): Deleted.
+        * inspector/remote/socket/RemoteInspectorServer.h:
+        (Inspector::RemoteInspectorServer::RemoteInspectorServer):
+        * inspector/remote/socket/RemoteInspectorSocket.cpp:
+        (Inspector::RemoteInspector::RemoteInspector):
+        (Inspector::RemoteInspector::dispatchMap):
+        (Inspector::RemoteInspector::start):
+        (Inspector::RemoteInspector::stopInternal):
+        (Inspector::RemoteInspector::setServerPort):
+        * inspector/remote/socket/RemoteInspectorSocket.h:
+        * inspector/remote/socket/RemoteInspectorSocketEndpoint.cpp:
+        (Inspector::RemoteInspectorSocketEndpoint::listenInet):
+        (Inspector::RemoteInspectorSocketEndpoint::getPort const):
+        (Inspector::RemoteInspectorSocketEndpoint::acceptInetSocketIfEnabled):
+        * inspector/remote/socket/RemoteInspectorSocketEndpoint.h:
+        * inspector/remote/socket/posix/RemoteInspectorSocketPOSIX.cpp:
+        (Inspector::Socket::init): Added.
+        (Inspector::Socket::listen): Signature changed.
+        (Inspector::Socket::getPort): Added.
+        * inspector/remote/socket/win/RemoteInspectorSocketWin.cpp: Added.
+        (Inspector::Socket::init):
+        (Inspector::Socket::Socket::Socket):
+        (Inspector::Socket::Socket::~Socket):
+        (Inspector::Socket::Socket::close):
+        (Inspector::Socket::Socket::operator PlatformSocketType const):
+        (Inspector::Socket::Socket::operator bool const):
+        (Inspector::Socket::Socket::leak):
+        (Inspector::Socket::Socket::create):
+        (Inspector::Socket::setOpt):
+        (Inspector::Socket::setOptEnabled):
+        (Inspector::Socket::enableOpt):
+        (Inspector::Socket::connectTo):
+        (Inspector::Socket::bindAndListen):
+        (Inspector::Socket::connect):
+        (Inspector::Socket::listen):
+        (Inspector::Socket::accept):
+        (Inspector::Socket::createPair):
+        (Inspector::Socket::setup):
+        (Inspector::Socket::isValid):
+        (Inspector::Socket::isListening):
+        (Inspector::Socket::getPort):
+        (Inspector::Socket::read):
+        (Inspector::Socket::write):
+        (Inspector::Socket::close):
+        (Inspector::Socket::preparePolling):
+        (Inspector::Socket::poll):
+        (Inspector::Socket::isReadable):
+        (Inspector::Socket::isWritable):
+        (Inspector::Socket::markWaitingWritable):
+        (Inspector::Socket::clearWaitingWritable):
+
 2019-05-03  Yusuke Suzuki  <ysuzuki@apple.com>
 
         [JSC] Generator CodeBlock generation should be idempotent
index 4730e56..425b97e 100644 (file)
@@ -32,9 +32,51 @@ if (NOT WTF_PLATFORM_WIN_CAIRO)
     )
 endif ()
 
-list(REMOVE_ITEM JavaScriptCore_SOURCES
-    inspector/JSGlobalObjectInspectorController.cpp
-)
+if (ENABLE_REMOTE_INSPECTOR)
+    list(APPEND JavaScriptCore_PRIVATE_INCLUDE_DIRECTORIES
+        "${JAVASCRIPTCORE_DIR}/inspector/remote/socket"
+    )
+
+    list(APPEND JavaScriptCore_PRIVATE_FRAMEWORK_HEADERS
+        inspector/remote/RemoteAutomationTarget.h
+        inspector/remote/RemoteConnectionToTarget.h
+        inspector/remote/RemoteControllableTarget.h
+        inspector/remote/RemoteInspectionTarget.h
+        inspector/remote/RemoteInspector.h
+
+        inspector/remote/socket/RemoteInspectorConnectionClient.h
+        inspector/remote/socket/RemoteInspectorMessageParser.h
+        inspector/remote/socket/RemoteInspectorServer.h
+        inspector/remote/socket/RemoteInspectorSocket.h
+        inspector/remote/socket/RemoteInspectorSocketEndpoint.h
+    )
+
+    list(APPEND JavaScriptCore_SOURCES
+        API/JSRemoteInspector.cpp
+
+        inspector/remote/RemoteAutomationTarget.cpp
+        inspector/remote/RemoteConnectionToTarget.cpp
+        inspector/remote/RemoteControllableTarget.cpp
+        inspector/remote/RemoteInspectionTarget.cpp
+        inspector/remote/RemoteInspector.cpp
+
+        inspector/remote/socket/RemoteInspectorConnectionClient.cpp
+        inspector/remote/socket/RemoteInspectorMessageParser.cpp
+        inspector/remote/socket/RemoteInspectorServer.cpp
+        inspector/remote/socket/RemoteInspectorSocket.cpp
+        inspector/remote/socket/RemoteInspectorSocketEndpoint.cpp
+
+        inspector/remote/socket/win/RemoteInspectorSocketWin.cpp
+    )
+
+    list(APPEND JavaScriptCore_LIBRARIES
+        wsock32 ws2_32
+    )
+else ()
+    list(REMOVE_ITEM JavaScriptCore_SOURCES
+        inspector/JSGlobalObjectInspectorController.cpp
+    )
+endif ()
 
 file(COPY
     "${JAVASCRIPTCORE_DIR}/JavaScriptCore.vcxproj/JavaScriptCore.resources"
index 3cf93c3..2b9315e 100644 (file)
@@ -53,7 +53,7 @@ typedef struct _GDBusConnection GDBusConnection;
 typedef struct _GDBusInterfaceVTable GDBusInterfaceVTable;
 #endif
 
-#if PLATFORM(PLAYSTATION)
+#if USE(INSPECTOR_SOCKET_SERVER)
 #include "RemoteConnectionToTarget.h"
 #include "RemoteInspectorConnectionClient.h"
 #include "RemoteInspectorSocketEndpoint.h"
@@ -77,7 +77,7 @@ class RemoteInspectorClient;
 class JS_EXPORT_PRIVATE RemoteInspector final
 #if PLATFORM(COCOA)
     : public RemoteInspectorXPCConnection::Client
-#elif PLATFORM(PLAYSTATION)
+#elif USE(INSPECTOR_SOCKET_SERVER)
     : public RemoteInspectorConnectionClient
 #endif
 {
@@ -146,12 +146,13 @@ public:
 #if USE(GLIB)
     void requestAutomationSession(const char* sessionID, const Client::SessionCapabilities&);
 #endif
-#if USE(GLIB) || PLATFORM(PLAYSTATION)
+#if USE(GLIB) || USE(INSPECTOR_SOCKET_SERVER)
     void setup(TargetID);
     void sendMessageToTarget(TargetID, const char* message);
 #endif
-#if PLATFORM(PLAYSTATION)
+#if USE(INSPECTOR_SOCKET_SERVER)
     static void setConnectionIdentifier(PlatformSocketType);
+    static void setServerPort(uint16_t);
 #endif
 
 private:
@@ -208,7 +209,7 @@ private:
     void receivedAutomaticInspectionRejectMessage(NSDictionary *userInfo);
     void receivedAutomationSessionRequestMessage(NSDictionary *userInfo);
 #endif
-#if PLATFORM(PLAYSTATION)
+#if USE(INSPECTOR_SOCKET_SERVER)
     HashMap<String, CallHandler>& dispatchMap() override;
     void didClose(ConnectionID) override;
 
@@ -239,9 +240,10 @@ private:
     GRefPtr<GCancellable> m_cancellable;
 #endif
 
-#if PLATFORM(PLAYSTATION)
+#if USE(INSPECTOR_SOCKET_SERVER)
     std::unique_ptr<RemoteInspectorSocketEndpoint> m_socketConnection;
     static PlatformSocketType s_connectionIdentifier;
+    static uint16_t s_serverPort;
     Optional<ConnectionID> m_clientID;
 #endif
 
index 348e391..9b1142f 100644 (file)
@@ -27,6 +27,7 @@
 
 #if ENABLE(REMOTE_INSPECTOR)
 
+#include "RemoteControllableTarget.h"
 #include "RemoteInspectorSocketEndpoint.h"
 #include <wtf/WeakPtr.h>
 #include <wtf/text/WTFString.h>
@@ -36,7 +37,7 @@ namespace Inspector {
 class RemoteInspectorConnectionClient : public CanMakeWeakPtr<RemoteInspectorConnectionClient> {
 public:
     void didReceiveWebInspectorEvent(ConnectionID, Vector<uint8_t>&&);
-    virtual void didAccept(ConnectionID, Socket::Domain) { };
+    virtual void didAccept(ConnectionID acceptedID, ConnectionID listenerID, Socket::Domain) { };
     virtual void didClose(ConnectionID) = 0;
 
     struct Event {
index e60fc52..8935089 100644 (file)
 
 namespace Inspector {
 
-void RemoteInspectorServer::addServerConnection(PlatformSocketType identifier)
+Optional<PlatformSocketType> RemoteInspectorServer::connect()
 {
-    if (!m_server)
-        return;
+    if (!m_server) {
+        LOG_ERROR("Inspector server is not running");
+        return WTF::nullopt;
+    }
 
-    if (auto id = m_server->createClient(identifier)) {
-        LockHolder lock(m_connectionsLock);
-        m_inspectorConnections.append(id.value());
+    if (auto sockets = Socket::createPair()) {
+        if (auto id = m_server->createClient(sockets->at(0))) {
+            LockHolder lock(m_connectionsLock);
+            m_inspectorConnections.append(id.value());
+
+            return sockets->at(1);
+        }
     }
+
+    return WTF::nullopt;
 }
 
-void RemoteInspectorServer::didAccept(ConnectionID id, Socket::Domain type)
+Optional<uint16_t> RemoteInspectorServer::listenForTargets()
+{
+    if (!m_server) {
+        LOG_ERROR("Inspector server is not running");
+        return WTF::nullopt;
+    }
+
+    if (m_inspectorListener) {
+        LOG_ERROR("Inspector server is already listening for targets.");
+        return WTF::nullopt;
+    }
+
+    if (auto connection = m_server->listenInet("127.0.0.1", 0)) {
+        m_inspectorListener = connection;
+        return m_server->getPort(*connection);
+    }
+
+    return WTF::nullopt;
+}
+
+void RemoteInspectorServer::didAccept(ConnectionID acceptedID, ConnectionID listenerID, Socket::Domain type)
 {
     ASSERT(!isMainThread());
 
-    if (type == Socket::Domain::Network) {
+    if (type == Socket::Domain::Local || (m_inspectorListener && listenerID == *m_inspectorListener)) {
+        LockHolder lock(m_connectionsLock);
+        m_inspectorConnections.append(acceptedID);
+    } else if (type == Socket::Domain::Network) {
         if (m_clientConnection) {
             LOG_ERROR("Inspector server can accept only 1 client");
             return;
         }
-        m_clientConnection = id;
-    } else if (type == Socket::Domain::Local) {
-        LockHolder lock(m_connectionsLock);
-        m_inspectorConnections.append(id);
+        m_clientConnection = acceptedID;
     }
 }
 
@@ -81,12 +109,12 @@ void RemoteInspectorServer::didClose(ConnectionID id)
 HashMap<String, RemoteInspectorConnectionClient::CallHandler>& RemoteInspectorServer::dispatchMap()
 {
     static NeverDestroyed<HashMap<String, CallHandler>> dispatchMap = HashMap<String, CallHandler>({
-        {"SetTargetList"_s, &RemoteInspectorServer::setTargetList},
-        {"SetupInspectorClient"_s, &RemoteInspectorServer::setupInspectorClient},
-        {"Setup"_s, &RemoteInspectorServer::setup},
-        {"FrontendDidClose"_s, &RemoteInspectorServer::close},
-        {"SendMessageToFrontend"_s, &RemoteInspectorServer::sendMessageToFrontend},
-        {"SendMessageToBackend"_s, &RemoteInspectorServer::sendMessageToBackend},
+        { "SetTargetList"_s, reinterpret_cast<CallHandler>(&RemoteInspectorServer::setTargetList) },
+        { "SetupInspectorClient"_s, reinterpret_cast<CallHandler>(&RemoteInspectorServer::setupInspectorClient) },
+        { "Setup"_s, reinterpret_cast<CallHandler>(&RemoteInspectorServer::setup) },
+        { "FrontendDidClose"_s, reinterpret_cast<CallHandler>(&RemoteInspectorServer::close) },
+        { "SendMessageToFrontend"_s, reinterpret_cast<CallHandler>(&RemoteInspectorServer::sendMessageToFrontend) },
+        { "SendMessageToBackend"_s, reinterpret_cast<CallHandler>(&RemoteInspectorServer::sendMessageToBackend) },
     });
 
     return dispatchMap;
@@ -108,7 +136,7 @@ bool RemoteInspectorServer::start(uint16_t port)
 {
     m_server = RemoteInspectorSocketEndpoint::create(this, "RemoteInspectorServer");
 
-    if (!m_server->listenInet(port)) {
+    if (!m_server->listenInet(nullptr, port)) {
         m_server = nullptr;
         return false;
     }
index b5080ae..4138ab5 100644 (file)
@@ -43,9 +43,13 @@ public:
     JS_EXPORT_PRIVATE bool start(uint16_t);
     bool isRunning() const { return !!m_server; }
 
-    JS_EXPORT_PRIVATE void addServerConnection(PlatformSocketType);
+    JS_EXPORT_PRIVATE Optional<uint16_t> listenForTargets();
+    JS_EXPORT_PRIVATE Optional<PlatformSocketType> connect();
 
 private:
+    friend class NeverDestroyed<RemoteInspectorServer>;
+    RemoteInspectorServer() { Socket::init(); }
+
     void connectionClosed(ConnectionID);
 
     void setTargetList(const Event&);
@@ -58,7 +62,7 @@ private:
     void sendCloseEvent(ConnectionID, TargetID);
     void clientConnectionClosed();
 
-    void didAccept(ConnectionID, Socket::Domain) override;
+    void didAccept(ConnectionID acceptedID, ConnectionID listenerID, Socket::Domain) override;
     void didClose(ConnectionID) override;
 
     void sendWebInspectorEvent(ConnectionID, const String&);
@@ -72,6 +76,9 @@ private:
     Vector<ConnectionID> m_inspectorConnections;
     Lock m_connectionsLock;
 
+    // Listener for targets.
+    Optional<ConnectionID> m_inspectorListener;
+
     // Connections from RemoteInspectorClient.
     Optional<ConnectionID> m_clientConnection;
 };
index 536d3c7..52f09b8 100644 (file)
@@ -39,6 +39,7 @@
 namespace Inspector {
 
 PlatformSocketType RemoteInspector::s_connectionIdentifier = INVALID_SOCKET_VALUE;
+uint16_t RemoteInspector::s_serverPort = 0;
 
 RemoteInspector& RemoteInspector::singleton()
 {
@@ -48,7 +49,7 @@ RemoteInspector& RemoteInspector::singleton()
 
 RemoteInspector::RemoteInspector()
 {
-    start();
+    Socket::init();
 }
 
 void RemoteInspector::didClose(ConnectionID id)
@@ -65,10 +66,10 @@ void RemoteInspector::didClose(ConnectionID id)
 HashMap<String, RemoteInspector::CallHandler>& RemoteInspector::dispatchMap()
 {
     static NeverDestroyed<HashMap<String, CallHandler>> methods = HashMap<String, CallHandler>({
-        {"GetTargetList"_s, static_cast<CallHandler>(&RemoteInspector::receivedGetTargetListMessage)},
-        {"Setup"_s, static_cast<CallHandler>(&RemoteInspector::receivedSetupMessage)},
-        {"SendMessageToTarget"_s, static_cast<CallHandler>(&RemoteInspector::receivedDataMessage)},
-        {"FrontendDidClose"_s, static_cast<CallHandler>(&RemoteInspector::receivedCloseMessage)},
+        { "GetTargetList"_s, static_cast<CallHandler>(&RemoteInspector::receivedGetTargetListMessage) },
+        { "Setup"_s, static_cast<CallHandler>(&RemoteInspector::receivedSetupMessage) },
+        { "SendMessageToTarget"_s, static_cast<CallHandler>(&RemoteInspector::receivedDataMessage) },
+        { "FrontendDidClose"_s, static_cast<CallHandler>(&RemoteInspector::receivedCloseMessage) },
     });
 
     return methods;
@@ -87,14 +88,18 @@ void RemoteInspector::start()
 {
     LockHolder lock(m_mutex);
 
-    if (m_enabled || s_connectionIdentifier == INVALID_SOCKET_VALUE)
+    if (m_enabled || (s_connectionIdentifier == INVALID_SOCKET_VALUE && !s_serverPort))
         return;
 
     m_enabled = true;
 
     m_socketConnection = RemoteInspectorSocketEndpoint::create(this, "RemoteInspector");
 
-    m_clientID = m_socketConnection->createClient(s_connectionIdentifier);
+    if (s_connectionIdentifier) {
+        m_clientID = m_socketConnection->createClient(s_connectionIdentifier);
+        s_connectionIdentifier = INVALID_SOCKET_VALUE;
+    } else
+        m_clientID = m_socketConnection->connectInet("127.0.0.1", s_serverPort);
 
     if (!m_targetMap.isEmpty())
         pushListingsSoon();
@@ -117,7 +122,6 @@ void RemoteInspector::stopInternal(StopSource)
     m_automaticInspectionPaused = false;
     m_socketConnection = nullptr;
     m_clientID = WTF::nullopt;
-    s_connectionIdentifier = INVALID_SOCKET_VALUE;
 }
 
 TargetListing RemoteInspector::listingForInspectionTarget(const RemoteInspectionTarget& target) const
@@ -291,6 +295,11 @@ void RemoteInspector::setConnectionIdentifier(PlatformSocketType connectionIdent
     RemoteInspector::s_connectionIdentifier = connectionIdentifier;
 }
 
+void RemoteInspector::setServerPort(uint16_t port)
+{
+    RemoteInspector::s_serverPort = port;
+}
+
 } // namespace Inspector
 
 #endif // ENABLE(REMOTE_INSPECTOR)
index 2f2dadb..bcc609f 100644 (file)
@@ -66,14 +66,17 @@ enum class Domain {
     Network,
 };
 
+void init();
+
 Optional<PlatformSocketType> connect(const char* serverAddress, uint16_t serverPort);
-Optional<PlatformSocketType> listen(uint16_t port);
+Optional<PlatformSocketType> listen(const char* address, uint16_t port);
 Optional<PlatformSocketType> accept(PlatformSocketType);
 Optional<std::array<PlatformSocketType, 2>> createPair();
 
 void setup(PlatformSocketType);
 bool isValid(PlatformSocketType);
 bool isListening(PlatformSocketType);
+uint16_t getPort(PlatformSocketType);
 
 Optional<size_t> read(PlatformSocketType, void* buffer, int bufferSize);
 Optional<size_t> write(PlatformSocketType, const void* data, int size);
index 647ff69..7101668 100644 (file)
@@ -76,14 +76,12 @@ Optional<ConnectionID> RemoteInspectorSocketEndpoint::connectInet(const char* se
     return WTF::nullopt;
 }
 
-bool RemoteInspectorSocketEndpoint::listenInet(uint16_t port)
+Optional<ConnectionID> RemoteInspectorSocketEndpoint::listenInet(const char* address, uint16_t port)
 {
-    if (auto socket = Socket::listen(port)) {
-        if (createClient(*socket))
-            return true;
-    }
+    if (auto socket = Socket::listen(address, port))
+        return createClient(*socket);
 
-    return false;
+    return WTF::nullopt;
 }
 
 bool RemoteInspectorSocketEndpoint::isListening(ConnectionID id)
@@ -161,6 +159,15 @@ Optional<ConnectionID> RemoteInspectorSocketEndpoint::createClient(PlatformSocke
     return id;
 }
 
+Optional<uint16_t> RemoteInspectorSocketEndpoint::getPort(ConnectionID id) const
+{
+    LockHolder lock(m_connectionsLock);
+    if (const auto& connection = m_connections.get(id))
+        return Socket::getPort(connection->socket);
+
+    return WTF::nullopt;
+}
+
 void RemoteInspectorSocketEndpoint::recvIfEnabled(ConnectionID id)
 {
     LockHolder lock(m_connectionsLock);
@@ -246,7 +253,7 @@ void RemoteInspectorSocketEndpoint::acceptInetSocketIfEnabled(ConnectionID id)
             lock.unlockEarly();
             if (auto newID = createClient(*socket)) {
                 if (m_inspectorClient) {
-                    m_inspectorClient->didAccept(newID.value(), Socket::Domain::Network);
+                    m_inspectorClient->didAccept(newID.value(), id, Socket::Domain::Network);
                     return;
                 }
             }
index 669a848..79657c2 100644 (file)
@@ -53,12 +53,14 @@ public:
     ~RemoteInspectorSocketEndpoint();
 
     Optional<ConnectionID> connectInet(const char* serverAddr, uint16_t serverPort);
-    bool listenInet(uint16_t port);
+    Optional<ConnectionID> listenInet(const char* address, uint16_t port);
 
     void send(ConnectionID, const uint8_t* data, size_t);
 
     Optional<ConnectionID> createClient(PlatformSocketType fd);
 
+    Optional<uint16_t> getPort(ConnectionID) const;
+
 protected:
     void recvIfEnabled(ConnectionID);
     void sendIfEnabled(ConnectionID);
@@ -67,7 +69,7 @@ protected:
     void acceptInetSocketIfEnabled(ConnectionID);
     bool isListening(ConnectionID);
 
-    Lock m_connectionsLock;
+    mutable Lock m_connectionsLock;
     HashMap<ConnectionID, std::unique_ptr<Socket::Connection>> m_connections;
 
     PlatformSocketType m_wakeupSendSocket { INVALID_SOCKET_VALUE };
index def4db5..a85aaa4 100644 (file)
@@ -39,6 +39,10 @@ namespace Inspector {
 
 namespace Socket {
 
+void init()
+{
+}
+
 Optional<PlatformSocketType> connect(const char* serverAddress, uint16_t serverPort)
 {
     struct sockaddr_in address = { };
@@ -63,7 +67,7 @@ Optional<PlatformSocketType> connect(const char* serverAddress, uint16_t serverP
     return fd;
 }
 
-Optional<PlatformSocketType> listen(uint16_t port)
+Optional<PlatformSocketType> listen(const char* addressStr, uint16_t port)
 {
     struct sockaddr_in address = { };
 
@@ -87,7 +91,10 @@ Optional<PlatformSocketType> listen(uint16_t port)
 
     // FIXME: Support AF_INET6 connections.
     address.sin_family = AF_INET;
-    address.sin_addr.s_addr = htonl(INADDR_ANY);
+    if (addressStr)
+        inet_aton(addressStr, &address.sin_addr);
+    else
+        address.sin_addr.s_addr = htonl(INADDR_ANY);
     address.sin_port = htons(port);
     error = ::bind(fdListen, (struct sockaddr*)&address, sizeof(address));
     if (error < 0) {
@@ -155,6 +162,16 @@ bool isListening(PlatformSocketType socket)
     return false;
 }
 
+uint16_t getPort(PlatformSocketType socket)
+{
+    ASSERT(isValid(socket));
+
+    struct sockaddr_in address = { };
+    int len = sizeof(address);
+    getsockname(socket, reinterpret_cast<struct sockaddr*>(&address), &len);
+    return address.sin_port;
+}
+
 Optional<size_t> read(PlatformSocketType socket, void* buffer, int bufferSize)
 {
     ASSERT(isValid(socket));
diff --git a/Source/JavaScriptCore/inspector/remote/socket/win/RemoteInspectorSocketWin.cpp b/Source/JavaScriptCore/inspector/remote/socket/win/RemoteInspectorSocketWin.cpp
new file mode 100644 (file)
index 0000000..dc32cd6
--- /dev/null
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2019 Sony Interactive Entertainment Inc.
+ *
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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"
+#include "RemoteInspectorSocket.h"
+
+#if ENABLE(REMOTE_INSPECTOR)
+
+#include <mutex>
+#include <ws2tcpip.h>
+
+namespace Inspector {
+
+namespace Socket {
+
+void init()
+{
+    static std::once_flag flag;
+    std::call_once(flag, [] {
+        WSADATA data;
+        WORD versionRequested = MAKEWORD(2, 0);
+
+        WSAStartup(versionRequested, &data);
+    });
+}
+
+class Socket {
+public:
+    Socket()
+        : m_socket(create())
+    {
+    }
+
+    explicit Socket(PlatformSocketType socket)
+        : m_socket(socket)
+    {
+    }
+
+    explicit Socket(const Socket&) = delete;
+    ~Socket()
+    {
+        close();
+    }
+
+    void close()
+    {
+        if (isValid(m_socket)) {
+            ::closesocket(m_socket);
+            m_socket = INVALID_SOCKET_VALUE;
+        }
+    }
+
+    operator PlatformSocketType() const { return m_socket; }
+    operator bool() const { return isValid(m_socket); }
+
+    PlatformSocketType leak()
+    {
+        auto socket = m_socket;
+        m_socket = INVALID_SOCKET_VALUE;
+        return socket;
+    }
+
+private:
+    static PlatformSocketType create()
+    {
+        PlatformSocketType socket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+        if (socket == INVALID_SOCKET) {
+            LOG_ERROR("socket() failed, errno = %d", WSAGetLastError());
+            return INVALID_SOCKET_VALUE;
+        }
+        return socket;
+    }
+
+    PlatformSocketType m_socket { INVALID_SOCKET_VALUE };
+};
+
+static bool setOpt(PlatformSocketType socket, int optname, const void* optval, int optlen, const char* debug)
+{
+    int error = ::setsockopt(socket, SOL_SOCKET, optname, static_cast<const char*>(optval), optlen);
+    if (error < 0) {
+        LOG_ERROR("setsockopt() %s, errno = %d", debug, WSAGetLastError());
+        return false;
+    }
+    return true;
+}
+
+static bool setOptEnabled(PlatformSocketType socket, int optname, bool flag, const char* debug)
+{
+    const int val = flag;
+    return setOpt(socket, optname, &val, sizeof(val), debug);
+}
+
+static bool enableOpt(PlatformSocketType socket, int optname, const char* debug)
+{
+    return setOptEnabled(socket, optname, true, debug);
+}
+
+static PlatformSocketType connectTo(struct sockaddr_in& address)
+{
+    Socket socket;
+    if (!socket)
+        return INVALID_SOCKET_VALUE;
+
+    int error = ::connect(socket, (struct sockaddr*)&address, sizeof(address));
+    if (error < 0)
+        return INVALID_SOCKET_VALUE;
+
+    return socket.leak();
+}
+
+static PlatformSocketType bindAndListen(struct sockaddr_in& address)
+{
+    Socket socket;
+    if (!socket)
+        return INVALID_SOCKET_VALUE;
+
+    if (!enableOpt(socket, SO_REUSEADDR, "SO_REUSEADDR"))
+        return INVALID_SOCKET_VALUE;
+
+    // WinSock doesn't have `SO_REUSEPORT`.
+
+    int error = ::bind(socket, (struct sockaddr*)&address, sizeof(address));
+    if (error < 0) {
+        LOG_ERROR("bind() failed, errno = %d", WSAGetLastError());
+        return INVALID_SOCKET_VALUE;
+    }
+
+    error = ::listen(socket, 1);
+    if (error < 0) {
+        LOG_ERROR("listen() failed, errno = %d", WSAGetLastError());
+        return INVALID_SOCKET_VALUE;
+    }
+
+    return socket.leak();
+}
+
+Optional<PlatformSocketType> connect(const char* serverAddress, uint16_t serverPort)
+{
+    struct sockaddr_in address = { };
+
+    address.sin_family = AF_INET;
+    ::inet_pton(AF_INET, serverAddress, &address.sin_addr);
+    address.sin_port = htons(serverPort);
+
+    auto socket = connectTo(address);
+    if (!isValid(socket)) {
+        LOG_ERROR("Failed to connect to %s:%u, errno = %d", serverAddress, serverPort, WSAGetLastError());
+        return WTF::nullopt;
+    }
+
+    return socket;
+}
+
+Optional<PlatformSocketType> listen(const char* addressStr, uint16_t port)
+{
+    // FIXME: Support AF_INET6 connections.
+    struct sockaddr_in address = { };
+    address.sin_family = AF_INET;
+    if (addressStr)
+        ::inet_pton(AF_INET, addressStr, &address.sin_addr);
+    else
+        address.sin_addr.s_addr = htonl(INADDR_ANY);
+    address.sin_port = htons(port);
+
+    auto socket = bindAndListen(address);
+    if (!isValid(socket))
+        return WTF::nullopt;
+
+    return socket;
+}
+
+Optional<PlatformSocketType> accept(PlatformSocketType socket)
+{
+    struct sockaddr_in address = { };
+
+    socklen_t len = sizeof(struct sockaddr_in);
+    int fd = ::accept(socket, (struct sockaddr*) &address, &len);
+    if (fd >= 0)
+        return fd;
+
+    LOG_ERROR("accept(inet) error (errno = %d)", WSAGetLastError());
+    return WTF::nullopt;
+}
+
+Optional<std::array<PlatformSocketType, 2>> createPair()
+{
+    struct sockaddr_in address;
+    address.sin_family = AF_INET;
+    address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+    address.sin_port = 0;
+
+    Socket server(bindAndListen(address));
+    if (!server)
+        return WTF::nullopt;
+
+    address.sin_port = getPort(server);
+
+    std::array<PlatformSocketType, 2> sockets;
+    sockets[0] = connectTo(address);
+    if (!isValid(sockets[0]))
+        return WTF::nullopt;
+
+    if (auto socket = accept(server)) {
+        sockets[1] = *socket;
+        return sockets;
+    }
+
+    return WTF::nullopt;
+}
+
+void setup(PlatformSocketType socket)
+{
+    setOpt(socket, SO_RCVBUF, &BufferSize, sizeof(BufferSize), "SO_RCVBUF");
+    setOpt(socket, SO_SNDBUF, &BufferSize, sizeof(BufferSize), "SO_SNDBUF");
+}
+
+bool isValid(PlatformSocketType socket)
+{
+    return socket != INVALID_SOCKET_VALUE;
+}
+
+bool isListening(PlatformSocketType socket)
+{
+    int out;
+    socklen_t outSize = sizeof(out);
+    if (getsockopt(socket, SOL_SOCKET, SO_ACCEPTCONN, reinterpret_cast<char*>(&out), &outSize) != -1)
+        return out;
+
+    LOG_ERROR("getsockopt errno = %d", WSAGetLastError());
+    return false;
+}
+
+uint16_t getPort(PlatformSocketType socket)
+{
+    ASSERT(isValid(socket));
+
+    struct sockaddr_in address = { };
+    int len = sizeof(address);
+    getsockname(socket, reinterpret_cast<struct sockaddr*>(&address), &len);
+    return address.sin_port;
+}
+
+Optional<size_t> read(PlatformSocketType socket, void* buffer, int bufferSize)
+{
+    ASSERT(isValid(socket));
+
+    auto readSize = ::recv(socket, reinterpret_cast<char*>(buffer), bufferSize, 0);
+    if (readSize != SOCKET_ERROR)
+        return static_cast<size_t>(readSize);
+
+    LOG_ERROR("read error (errno = %d)", WSAGetLastError());
+    return WTF::nullopt;
+}
+
+Optional<size_t> write(PlatformSocketType socket, const void* data, int size)
+{
+    ASSERT(isValid(socket));
+
+    auto writeSize = ::send(socket, reinterpret_cast<const char*>(data), size, 0);
+    if (writeSize != SOCKET_ERROR)
+        return static_cast<size_t>(writeSize);
+
+    LOG_ERROR("write error (errno = %d)", WSAGetLastError());
+    return WTF::nullopt;
+}
+
+void close(PlatformSocketType& socket)
+{
+    Socket(socket).close();
+    socket = INVALID_SOCKET_VALUE;
+}
+
+PollingDescriptor preparePolling(PlatformSocketType socket)
+{
+    PollingDescriptor poll;
+    poll.fd = socket;
+    poll.events = POLLIN;
+    return poll;
+}
+
+bool poll(Vector<PollingDescriptor>& pollDescriptors, int timeout)
+{
+    int ret = ::WSAPoll(pollDescriptors.data(), pollDescriptors.size(), timeout);
+    return ret > 0;
+}
+
+bool isReadable(const PollingDescriptor& poll)
+{
+    return poll.revents & POLLIN;
+}
+
+bool isWritable(const PollingDescriptor& poll)
+{
+    return poll.revents & POLLOUT;
+}
+
+void markWaitingWritable(PollingDescriptor& poll)
+{
+    poll.events |= POLLOUT;
+}
+
+void clearWaitingWritable(PollingDescriptor& poll)
+{
+    poll.events &= ~POLLOUT;
+}
+
+} // namespace Socket
+
+} // namespace Inspector
+
+#endif // ENABLE(REMOTE_INSPECTOR)
index 6be35a7..8d6556f 100644 (file)
@@ -108,6 +108,7 @@ SET_AND_EXPOSE_TO_BUILD(USE_CURL ON)
 SET_AND_EXPOSE_TO_BUILD(USE_FREETYPE ON)
 SET_AND_EXPOSE_TO_BUILD(USE_HARFBUZZ ON)
 SET_AND_EXPOSE_TO_BUILD(USE_LIBWPE ON)
+SET_AND_EXPOSE_TO_BUILD(USE_INSPECTOR_SOCKET_SERVER ENABLE_REMOTE_INSPECTOR)
 
 # Rendering options
 SET_AND_EXPOSE_TO_BUILD(ENABLE_GRAPHICS_CONTEXT_3D ON)
index d89cbff..b6c1386 100644 (file)
@@ -67,7 +67,6 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEBASSEMBLY PRIVATE OFF)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_AUDIO PUBLIC OFF)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_XSLT PUBLIC ON)
 
-WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_REMOTE_INSPECTOR PRIVATE OFF)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SMOOTH_SCROLLING PRIVATE OFF)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_USER_MESSAGE_HANDLERS PRIVATE OFF)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_USERSELECT_ALL PRIVATE OFF)
@@ -92,6 +91,7 @@ if (${WTF_PLATFORM_WIN_CAIRO})
     WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_RESOURCE_LOAD_STATISTICS PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
     WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SERVICE_WORKER PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
     WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_VARIATION_FONTS PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
+    WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_REMOTE_INSPECTOR PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
 
     # FIXME: Implement plugin process on Modern WebKit. https://bugs.webkit.org/show_bug.cgi?id=185313
     WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NETSCAPE_PLUGIN_API PRIVATE OFF)
@@ -100,6 +100,7 @@ else ()
     WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INTL PUBLIC OFF)
     WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_PUBLIC_SUFFIX_LIST PRIVATE OFF)
     WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEBGL PUBLIC OFF)
+    WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_REMOTE_INSPECTOR PRIVATE OFF)
     WEBKIT_OPTION_DEFAULT_PORT_VALUE(USE_VERSION_STAMPER PRIVATE ON)
 endif ()
 
index ae4c779..2458e7e 100644 (file)
@@ -28,6 +28,7 @@ SET_AND_EXPOSE_TO_BUILD(USE_CURL ON)
 SET_AND_EXPOSE_TO_BUILD(USE_TEXTURE_MAPPER ON)
 SET_AND_EXPOSE_TO_BUILD(USE_TEXTURE_MAPPER_GL ON)
 SET_AND_EXPOSE_TO_BUILD(USE_MEDIA_FOUNDATION ON)
+SET_AND_EXPOSE_TO_BUILD(USE_INSPECTOR_SOCKET_SERVER ENABLE_REMOTE_INSPECTOR)
 
 set(ENABLE_GRAPHICS_CONTEXT_3D ON)
 set(ENABLE_WEBKIT ON)