WebSocket client and permessage-deflate compression



Hey @all o/

I'm currently fooling around with a libsoup-based WebSocket server and client and I have problems with the deflate compression. It works per default on the server side w/o any additional lines of code but not on the client.
The client says the deflate extension feature is on/active but it doesn't seem to work. Adding the "Sec-Websocket-Extensions" to the HTTP Header also didn't help, although this was more out of desperation.
I verified both, the server compression working and the client compression not working, with Wireshark and a 3rd party WebSocket client. My libsoup library version is 2.74.2 . Can anyone point me in the right direction or confirm that I've stumbled upon a bug?

with best regards

Benjamin Reikowski

This is the server+client test code I used:

static void closed_cb(SoupWebsocketConnection *ws, gpointer user_data)
{
    (void)user_data;

    g_message("%s", __func__);
    g_object_unref(ws);
}

static void message_cb(SoupWebsocketConnection *ws, SoupWebsocketDataType type, GBytes *message, gpointer user_data)
{
    (void) user_data;

    if (message && (type == SOUP_WEBSOCKET_DATA_TEXT)) {
        g_message("%s data:%s", __func__, (gchar *)g_bytes_get_data(message, NULL));
        soup_websocket_connection_send_text(ws, "bla");
    } else {
        g_warning("%s no text data", __func__);
    }
}

static void error_cb(SoupWebsocketConnection *ws, GError *error, gpointer user_data)
{
    (void) ws; (void) error; (void) user_data;
    g_message("%s", __func__);
}


static void connected_cb(GObject *object, GAsyncResult *result, gpointer user_data)
{
    (void)user_data;

    SoupWebsocketConnection *ws = soup_session_websocket_connect_finish(SOUP_SESSION(object), result, NULL);
    if (ws) {
        g_message("%s", __func__);
        g_signal_connect(ws, "message", G_CALLBACK(message_cb), NULL);
        g_signal_connect(ws, "closed", G_CALLBACK(closed_cb), NULL);
        g_signal_connect(ws, "error",  G_CALLBACK(error_cb), NULL);
        soup_websocket_connection_send_text(ws, "bla");
    } else {
        g_warning("%s", __func__);
    }
}

static void client_connect_cb(SoupServer *server, SoupWebsocketConnection *ws,
        const char *path, SoupClientContext *client, gpointer user_data)
{
    (void) server; (void) client; (void) user_data; (void) path;

    g_object_ref(ws);
    g_signal_connect(ws, "message", G_CALLBACK(message_cb), NULL);
    g_signal_connect(ws, "closed",  G_CALLBACK(closed_cb), NULL);
    g_signal_connect(ws, "error",  G_CALLBACK(error_cb), NULL);
    g_message("%s", __func__);
}

int main(int argc, char* argv[])
{
    GMainLoop *mainloop = g_main_loop_new(0, FALSE);
    gboolean role_server = TRUE;

    if (1 < argc) {
        if (0 == g_strcmp0(argv[1], "c")) {
            role_server = FALSE;
        }
    }

    g_message("role: %s", (role_server ? "server" : "client"));

    if (role_server) {
        GError *error = NULL;
        SoupServer *server = soup_server_new(NULL, NULL);
        //soup_server_add_websocket_extension(server, SOUP_TYPE_WEBSOCKET_EXTENSION_DEFLATE);
        soup_server_listen_all(server, 666, 0, &error);
        g_assert_no_error(error);
        soup_server_add_websocket_handler(server, "/", NULL, NULL, client_connect_cb, NULL, NULL);
    } else {
        SoupSession *session = soup_session_new();
        SoupMessage *message = soup_message_new("GET", "ws://localhost:666");
        gboolean is_off = soup_message_is_feature_disabled(message, SOUP_TYPE_WEBSOCKET_EXTENSION_DEFLATE);
        g_message("deflate is %s", (is_off ? "OFF" : "ON"));
        //soup_message_headers_append(message->request_headers, "Sec-WebSocket-Extensions", "permessage-deflate");
        soup_session_websocket_connect_async(session, message, NULL, NULL, NULL, connected_cb, NULL);
    }

    g_message("running mainloop");
    g_main_loop_run(mainloop);
}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]