Changeset 228088 in webkit


Ignore:
Timestamp:
Feb 5, 2018 1:02:24 AM (6 years ago)
Author:
Carlos Garcia Campos
Message:

[SOUP] WebSockets must use system proxy settings
https://bugs.webkit.org/show_bug.cgi?id=126384

Reviewed by Michael Catanzaro.

Source/WebCore:

Use soup_session_connect_async() when available to create the WebSockets connection instead of GSocketClient
directly.

  • platform/network/soup/SocketStreamHandleImpl.h:
  • platform/network/soup/SocketStreamHandleImplSoup.cpp:

(WebCore::wssSocketClientEventCallback):
(WebCore::SocketStreamHandleImpl::create):
(WebCore::SocketStreamHandleImpl::connected):
(WebCore::SocketStreamHandleImpl::connectedCallback):
(WebCore::SocketStreamHandleImpl::platformClose):

Tools:

Check also WebSockets in /webkit2/WebKitWebContext/proxy.

  • TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebContext.cpp:

(ProxyTest::webSocketProxyServerCallback):
(ProxyTest::ProxyTest):
(ProxyTest::webSocketConnected):
(ProxyTest::createWebSocketAndWaitUntilConnected):
(webSocketServerCallback):
(testWebContextProxySettings):

  • TestWebKitAPI/glib/WebKitGLib/WebKitTestServer.cpp:

(WebKitTestServer::~WebKitTestServer):
(WebKitTestServer::addWebSocketHandler):
(WebKitTestServer::removeWebSocketHandler):
(WebKitTestServer::getWebSocketURIForPath const):
(WebKitTestServer::getURIForPath const):

  • TestWebKitAPI/glib/WebKitGLib/WebKitTestServer.h:

(WebKitTestServer::baseURI const):
(WebKitTestServer::baseWebSocketURI const):

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r228086 r228088  
     12018-02-05  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [SOUP] WebSockets must use system proxy settings
     4        https://bugs.webkit.org/show_bug.cgi?id=126384
     5
     6        Reviewed by Michael Catanzaro.
     7
     8        Use soup_session_connect_async() when available to create the WebSockets connection instead of GSocketClient
     9        directly.
     10
     11        * platform/network/soup/SocketStreamHandleImpl.h:
     12        * platform/network/soup/SocketStreamHandleImplSoup.cpp:
     13        (WebCore::wssSocketClientEventCallback):
     14        (WebCore::SocketStreamHandleImpl::create):
     15        (WebCore::SocketStreamHandleImpl::connected):
     16        (WebCore::SocketStreamHandleImpl::connectedCallback):
     17        (WebCore::SocketStreamHandleImpl::platformClose):
     18
    1192018-02-05  Carlos Garcia Campos  <cgarcia@igalia.com>
    220
  • trunk/Source/WebCore/platform/network/soup/SocketStreamHandleImpl.h

    r220887 r228088  
    4949public:
    5050    static Ref<SocketStreamHandleImpl> create(const URL&, SocketStreamHandleClient&, PAL::SessionID, const String&, SourceApplicationAuditToken&&);
    51     static Ref<SocketStreamHandle> create(GSocketConnection*, SocketStreamHandleClient&);
    52 
    5351    virtual ~SocketStreamHandleImpl();
    5452
     
    6563    void stopWaitingForSocketWritability();
    6664
    67     static void connectedCallback(GSocketClient*, GAsyncResult*, SocketStreamHandleImpl*);
     65    static void connectedCallback(GObject*, GAsyncResult*, SocketStreamHandleImpl*);
    6866    static void readReadyCallback(GInputStream*, GAsyncResult*, SocketStreamHandleImpl*);
    6967    static gboolean writeReadyCallback(GPollableOutputStream*, SocketStreamHandleImpl*);
    7068
    71     void connected(GRefPtr<GSocketConnection>&&);
     69    void connected(GRefPtr<GIOStream>&&);
    7270    void readBytes(gssize);
    7371    void didFail(SocketStreamError&&);
    7472    void writeReady();
    7573
    76     GRefPtr<GSocketConnection> m_socketConnection;
     74    GRefPtr<GIOStream> m_stream;
    7775    GRefPtr<GInputStream> m_inputStream;
    7876    GRefPtr<GPollableOutputStream> m_outputStream;
  • trunk/Source/WebCore/platform/network/soup/SocketStreamHandleImplSoup.cpp

    r223720 r228088  
    5656}
    5757
     58#if SOUP_CHECK_VERSION(2, 61, 90)
     59static void wssSocketClientEventCallback(SoupSession*, GSocketClientEvent event, GIOStream* connection)
     60{
     61    if (event != G_SOCKET_CLIENT_TLS_HANDSHAKING)
     62        return;
     63
     64    g_signal_connect(connection, "accept-certificate", G_CALLBACK(wssConnectionAcceptCertificateCallback), nullptr);
     65}
     66#else
    5867static void wssSocketClientEventCallback(GSocketClient*, GSocketClientEvent event, GSocketConnectable*, GIOStream* connection)
    5968{
     
    6372    g_signal_connect(connection, "accept-certificate", G_CALLBACK(wssConnectionAcceptCertificateCallback), nullptr);
    6473}
    65 
    66 Ref<SocketStreamHandleImpl> SocketStreamHandleImpl::create(const URL& url, SocketStreamHandleClient& client, PAL::SessionID, const String&, SourceApplicationAuditToken&&)
     74#endif
     75
     76Ref<SocketStreamHandleImpl> SocketStreamHandleImpl::create(const URL& url, SocketStreamHandleClient& client, PAL::SessionID sessionID, const String&, SourceApplicationAuditToken&&)
    6777{
    6878    Ref<SocketStreamHandleImpl> socket = adoptRef(*new SocketStreamHandleImpl(url, client));
    6979
     80    // FIXME: Using DeprecatedGlobalSettings from here is a layering violation.
     81    bool allowsAnySSLCertificate = url.protocolIs("wss") && DeprecatedGlobalSettings::allowsAnySSLCertificate();
     82
     83#if SOUP_CHECK_VERSION(2, 61, 90)
     84    auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID);
     85    if (!networkStorageSession)
     86        return socket;
     87
     88    auto uri = url.createSoupURI();
     89    Ref<SocketStreamHandle> protectedSocketStreamHandle = socket.copyRef();
     90    soup_session_connect_async(networkStorageSession->getOrCreateSoupNetworkSession().soupSession(), uri.get(), socket->m_cancellable.get(),
     91        allowsAnySSLCertificate ? reinterpret_cast<SoupSessionConnectProgressCallback>(wssSocketClientEventCallback) : nullptr,
     92        reinterpret_cast<GAsyncReadyCallback>(connectedCallback), &protectedSocketStreamHandle.leakRef());
     93#else
     94    UNUSED_PARAM(sessionID);
    7095    unsigned port = url.port() ? url.port().value() : (url.protocolIs("wss") ? 443 : 80);
    7196    GRefPtr<GSocketClient> socketClient = adoptGRef(g_socket_client_new());
    7297    if (url.protocolIs("wss")) {
    7398        g_socket_client_set_tls(socketClient.get(), TRUE);
    74         // FIXME: Using DeprecatedGlobalSettings from here is a layering violation.
    75         if (DeprecatedGlobalSettings::allowsAnySSLCertificate())
     99        if (allowsAnySSLCertificate)
    76100            g_signal_connect(socketClient.get(), "event", G_CALLBACK(wssSocketClientEventCallback), nullptr);
    77101    }
     
    79103    g_socket_client_connect_to_host_async(socketClient.get(), url.host().utf8().data(), port, socket->m_cancellable.get(),
    80104        reinterpret_cast<GAsyncReadyCallback>(connectedCallback), &protectedSocketStreamHandle.leakRef());
     105#endif
     106
    81107    return socket;
    82 }
    83 
    84 Ref<SocketStreamHandle> SocketStreamHandleImpl::create(GSocketConnection* socketConnection, SocketStreamHandleClient& client)
    85 {
    86     Ref<SocketStreamHandleImpl> socket = adoptRef(*new SocketStreamHandleImpl(URL(), client));
    87 
    88     GRefPtr<GSocketConnection> connection = socketConnection;
    89     socket->connected(WTFMove(connection));
    90     return WTFMove(socket);
    91108}
    92109
     
    103120}
    104121
    105 void SocketStreamHandleImpl::connected(GRefPtr<GSocketConnection>&& socketConnection)
    106 {
    107     m_socketConnection = WTFMove(socketConnection);
    108     m_outputStream = G_POLLABLE_OUTPUT_STREAM(g_io_stream_get_output_stream(G_IO_STREAM(m_socketConnection.get())));
    109     m_inputStream = g_io_stream_get_input_stream(G_IO_STREAM(m_socketConnection.get()));
     122void SocketStreamHandleImpl::connected(GRefPtr<GIOStream>&& stream)
     123{
     124    m_stream = WTFMove(stream);
     125    m_outputStream = G_POLLABLE_OUTPUT_STREAM(g_io_stream_get_output_stream(m_stream.get()));
     126    m_inputStream = g_io_stream_get_input_stream(m_stream.get());
    110127    m_readBuffer = std::make_unique<char[]>(READ_BUFFER_SIZE);
    111128
     
    118135}
    119136
    120 void SocketStreamHandleImpl::connectedCallback(GSocketClient* client, GAsyncResult* result, SocketStreamHandleImpl* handle)
     137void SocketStreamHandleImpl::connectedCallback(GObject* object, GAsyncResult* result, SocketStreamHandleImpl* handle)
    121138{
    122139    RefPtr<SocketStreamHandle> protectedThis = adoptRef(handle);
     
    124141    // Always finish the connection, even if this SocketStreamHandle was cancelled earlier.
    125142    GUniqueOutPtr<GError> error;
    126     GRefPtr<GSocketConnection> socketConnection = adoptGRef(g_socket_client_connect_to_host_finish(client, result, &error.outPtr()));
     143#if SOUP_CHECK_VERSION(2, 61, 90)
     144    GRefPtr<GIOStream> stream = adoptGRef(soup_session_connect_finish(SOUP_SESSION(object), result, &error.outPtr()));
     145#else
     146    GRefPtr<GIOStream> stream = adoptGRef(G_IO_STREAM(g_socket_client_connect_to_host_finish(G_SOCKET_CLIENT(object), result, &error.outPtr())));
     147#endif
    127148
    128149    // The SocketStreamHandle has been cancelled, so just close the connection, ignoring errors.
    129150    if (g_cancellable_is_cancelled(handle->m_cancellable.get())) {
    130         if (socketConnection)
    131             g_io_stream_close(G_IO_STREAM(socketConnection.get()), nullptr, nullptr);
     151        if (stream)
     152            g_io_stream_close(stream.get(), nullptr, nullptr);
    132153        return;
    133154    }
    134155
    135156    if (error)
    136         handle->didFail(SocketStreamError(error->code, String(), error->message));
     157        handle->didFail(SocketStreamError(error->code, { }, error->message));
    137158    else
    138         handle->connected(WTFMove(socketConnection));
     159        handle->connected(WTFMove(stream));
    139160}
    140161
     
    226247    stopWaitingForSocketWritability();
    227248
    228     if (m_socketConnection) {
     249    if (m_stream) {
    229250        GUniqueOutPtr<GError> error;
    230         g_io_stream_close(G_IO_STREAM(m_socketConnection.get()), nullptr, &error.outPtr());
     251        g_io_stream_close(m_stream.get(), nullptr, &error.outPtr());
    231252        if (error)
    232             didFail(SocketStreamError(error->code, String(), error->message));
    233         m_socketConnection = nullptr;
     253            didFail(SocketStreamError(error->code, { }, error->message));
     254        m_stream = nullptr;
    234255    }
    235256
  • trunk/Tools/ChangeLog

    r228086 r228088  
     12018-02-05  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [SOUP] WebSockets must use system proxy settings
     4        https://bugs.webkit.org/show_bug.cgi?id=126384
     5
     6        Reviewed by Michael Catanzaro.
     7
     8        Check also WebSockets in /webkit2/WebKitWebContext/proxy.
     9
     10        * TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebContext.cpp:
     11        (ProxyTest::webSocketProxyServerCallback):
     12        (ProxyTest::ProxyTest):
     13        (ProxyTest::webSocketConnected):
     14        (ProxyTest::createWebSocketAndWaitUntilConnected):
     15        (webSocketServerCallback):
     16        (testWebContextProxySettings):
     17        * TestWebKitAPI/glib/WebKitGLib/WebKitTestServer.cpp:
     18        (WebKitTestServer::~WebKitTestServer):
     19        (WebKitTestServer::addWebSocketHandler):
     20        (WebKitTestServer::removeWebSocketHandler):
     21        (WebKitTestServer::getWebSocketURIForPath const):
     22        (WebKitTestServer::getURIForPath const):
     23        * TestWebKitAPI/glib/WebKitGLib/WebKitTestServer.h:
     24        (WebKitTestServer::baseURI const):
     25        (WebKitTestServer::baseWebSocketURI const):
     26
    1272018-02-05  Carlos Garcia Campos  <cgarcia@igalia.com>
    228
  • trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebContext.cpp

    r225045 r228088  
    654654    MAKE_GLIB_TEST_FIXTURE(ProxyTest);
    655655
     656#if SOUP_CHECK_VERSION(2, 61, 90)
     657    enum class WebSocketServerType {
     658        Unknown,
     659        NoProxy,
     660        Proxy
     661    };
     662
     663    static void webSocketProxyServerCallback(SoupServer*, SoupWebsocketConnection*, const char* path, SoupClientContext*, gpointer userData)
     664    {
     665        static_cast<ProxyTest*>(userData)->webSocketConnected(ProxyTest::WebSocketServerType::Proxy);
     666    }
     667#endif
     668
    656669    ProxyTest()
    657670    {
     
    663676        m_proxyServer.run(serverCallback);
    664677        g_assert(m_proxyServer.baseURI());
     678#if SOUP_CHECK_VERSION(2, 61, 90)
     679        m_proxyServer.addWebSocketHandler(webSocketProxyServerCallback, this);
     680        g_assert(m_proxyServer.baseWebSocketURI());
     681#endif
    665682    }
    666683
     
    680697    }
    681698
     699#if SOUP_CHECK_VERSION(2, 61, 90)
     700    void webSocketConnected(WebSocketServerType serverType)
     701    {
     702        m_webSocketRequestReceived = serverType;
     703        quitMainLoop();
     704    }
     705
     706    WebSocketServerType createWebSocketAndWaitUntilConnected()
     707    {
     708        m_webSocketRequestReceived = WebSocketServerType::Unknown;
     709        GUniquePtr<char> createWebSocket(g_strdup_printf("var ws = new WebSocket('%s');", kServer->getWebSocketURIForPath("/foo").data()));
     710        webkit_web_view_run_javascript(m_webView, createWebSocket.get(), nullptr, nullptr, nullptr);
     711        g_main_loop_run(m_mainLoop);
     712        return m_webSocketRequestReceived;
     713    }
     714#endif
     715
    682716    WebKitTestServer m_proxyServer;
     717
     718#if SOUP_CHECK_VERSION(2, 61, 90)
     719    WebSocketServerType m_webSocketRequestReceived { WebSocketServerType::Unknown };
     720#endif
    683721};
     722
     723#if SOUP_CHECK_VERSION(2, 61, 90)
     724static void webSocketServerCallback(SoupServer*, SoupWebsocketConnection*, const char*, SoupClientContext*, gpointer userData)
     725{
     726    static_cast<ProxyTest*>(userData)->webSocketConnected(ProxyTest::WebSocketServerType::NoProxy);
     727}
     728#endif
    684729
    685730static void ephemeralViewloadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent, WebViewTest* test)
     
    697742    auto mainResourceData = test->loadURIAndGetMainResourceData(kServer->getURIForPath("/echoPort").data());
    698743    ASSERT_CMP_CSTRING(mainResourceData, ==, serverPortAsString.get());
     744
     745#if SOUP_CHECK_VERSION(2, 61, 90)
     746    // WebSocket requests should also be received by kServer.
     747    kServer->addWebSocketHandler(webSocketServerCallback, test);
     748    auto serverType = test->createWebSocketAndWaitUntilConnected();
     749    g_assert(serverType == ProxyTest::WebSocketServerType::NoProxy);
     750#endif
    699751
    700752    // Set default proxy URI to point to proxyServer. Requests to kServer should be received by proxyServer instead.
     
    706758    ASSERT_CMP_CSTRING(mainResourceData, ==, proxyServerPortAsString.get());
    707759    webkit_network_proxy_settings_free(settings);
     760
     761#if SOUP_CHECK_VERSION(2, 61, 90)
     762    // WebSocket requests should also be received by proxyServer.
     763    serverType = test->createWebSocketAndWaitUntilConnected();
     764    g_assert(serverType == ProxyTest::WebSocketServerType::Proxy);
     765#endif
    708766
    709767    // Proxy settings also affect ephemeral web views.
     
    767825    mainResourceData = test->loadURIAndGetMainResourceData(kServer->getURIForPath("/echoPort").data());
    768826    ASSERT_CMP_CSTRING(mainResourceData, ==, serverPortAsString.get());
     827
     828#if SOUP_CHECK_VERSION(2, 61, 90)
     829    kServer->removeWebSocketHandler();
     830#endif
    769831}
    770832
  • trunk/Tools/TestWebKitAPI/glib/WebKitGLib/WebKitTestServer.cpp

    r218685 r228088  
    5454{
    5555    soup_uri_free(m_baseURI);
     56#if SOUP_CHECK_VERSION(2, 50, 0)
     57    if (m_baseWebSocketURI)
     58        soup_uri_free(m_baseWebSocketURI);
     59#endif
    5660}
    5761
     
    6973}
    7074
    71 CString WebKitTestServer::getURIForPath(const char* path)
     75#if SOUP_CHECK_VERSION(2, 50, 0)
     76void WebKitTestServer::addWebSocketHandler(SoupServerWebsocketCallback callback, gpointer userData)
     77{
     78    m_baseWebSocketURI = soup_uri_new_with_base(m_baseURI, "/websocket/");
     79    m_baseWebSocketURI->scheme = m_baseWebSocketURI->scheme == SOUP_URI_SCHEME_HTTP ? SOUP_URI_SCHEME_WS : SOUP_URI_SCHEME_WSS;
     80
     81    if (m_queue) {
     82        m_queue->dispatch([this, callback, userData] {
     83            soup_server_add_websocket_handler(m_soupServer.get(), "/websocket", nullptr, nullptr, callback, userData, nullptr);
     84        });
     85    } else
     86        soup_server_add_websocket_handler(m_soupServer.get(), "/websocket", nullptr, nullptr, callback, userData, nullptr);
     87}
     88
     89void WebKitTestServer::removeWebSocketHandler()
     90{
     91    soup_uri_free(m_baseWebSocketURI);
     92    m_baseWebSocketURI = nullptr;
     93
     94    if (m_queue) {
     95        m_queue->dispatch([this] {
     96            soup_server_remove_handler(m_soupServer.get(), "/websocket");
     97        });
     98    } else
     99        soup_server_remove_handler(m_soupServer.get(), "/websocket");
     100}
     101
     102CString WebKitTestServer::getWebSocketURIForPath(const char* path) const
     103{
     104    g_assert(m_baseWebSocketURI);
     105    g_assert(path && *path == '/');
     106    SoupURI* uri = soup_uri_new_with_base(m_baseWebSocketURI, path + 1); // Ignore the leading slash.
     107    GUniquePtr<gchar> uriString(soup_uri_to_string(uri, FALSE));
     108    soup_uri_free(uri);
     109    return uriString.get();
     110}
     111#endif // SOUP_CHECK_VERSION(2, 50, 0)
     112
     113CString WebKitTestServer::getURIForPath(const char* path) const
    72114{
    73115    SoupURI* uri = soup_uri_new_with_base(m_baseURI, path);
     
    76118    return uriString.get();
    77119}
    78 
  • trunk/Tools/TestWebKitAPI/glib/WebKitGLib/WebKitTestServer.h

    r218685 r228088  
    3737    virtual ~WebKitTestServer();
    3838
    39     SoupURI* baseURI() { return m_baseURI; }
     39    SoupURI* baseURI() const { return m_baseURI; }
     40    CString getURIForPath(const char* path) const;
     41    void run(SoupServerCallback);
    4042
    41     CString getURIForPath(const char* path);
    42     void run(SoupServerCallback);
     43#if SOUP_CHECK_VERSION(2, 50, 0)
     44    void addWebSocketHandler(SoupServerWebsocketCallback, gpointer userData);
     45    void removeWebSocketHandler();
     46    SoupURI* baseWebSocketURI() const { return m_baseWebSocketURI; }
     47    CString getWebSocketURIForPath(const char* path) const;
     48#endif
    4349
    4450private:
    4551    GRefPtr<SoupServer> m_soupServer;
    46     SoupURI* m_baseURI;
     52    SoupURI* m_baseURI { nullptr };
     53#if SOUP_CHECK_VERSION(2, 50, 0)
     54    SoupURI* m_baseWebSocketURI { nullptr };
     55#endif
    4756    RefPtr<WorkQueue> m_queue;
    4857};
Note: See TracChangeset for help on using the changeset viewer.