[libsoup/gnome-3-18] soup-server: fix SoupClientContext usage from SoupServerWebsocketCallback
- From: Dan Winship <danw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libsoup/gnome-3-18] soup-server: fix SoupClientContext usage from SoupServerWebsocketCallback
- Date: Wed, 14 Oct 2015 15:46:18 +0000 (UTC)
commit c4d290d99529a0eb35149ac2e3b673858e0efdfb
Author: Dan Winship <danw gnome org>
Date: Wed Oct 14 11:43:47 2015 -0400
soup-server: fix SoupClientContext usage from SoupServerWebsocketCallback
SoupServerWebsocketCallback gets passed the SoupClientContext, but
calling most functions on it would spew errors and/or crash. Oops.
Pointed out in email by Ruben Blanco.
libsoup/soup-server.c | 52 +++++++++++++++++++++++++++++++++--------------
tests/websocket-test.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 88 insertions(+), 16 deletions(-)
---
diff --git a/libsoup/soup-server.c b/libsoup/soup-server.c
index a1fefeb..0c4201c 100644
--- a/libsoup/soup-server.c
+++ b/libsoup/soup-server.c
@@ -133,11 +133,13 @@ static guint signals[LAST_SIGNAL] = { 0 };
struct SoupClientContext {
SoupServer *server;
SoupSocket *sock;
+ GSocket *gsock;
SoupMessage *msg;
SoupAuthDomain *auth_domain;
char *auth_user;
GSocketAddress *remote_addr;
+ const char *remote_ip;
GSocketAddress *local_addr;
int ref_count;
@@ -1125,6 +1127,9 @@ soup_client_context_new (SoupServer *server, SoupSocket *sock)
client->server = server;
client->sock = g_object_ref (sock);
+ client->gsock = soup_socket_get_gsocket (sock);
+ if (client->gsock)
+ g_object_ref (client->gsock);
g_signal_connect (sock, "disconnected",
G_CALLBACK (socket_disconnected), client);
client->ref_count = 1;
@@ -1160,6 +1165,8 @@ soup_client_context_unref (SoupClientContext *client)
g_signal_handlers_disconnect_by_func (client->sock, socket_disconnected, client);
g_object_unref (client->sock);
+ g_clear_object (&client->gsock);
+ g_clear_pointer (&client->remote_ip, g_free);
g_slice_free (SoupClientContext, client);
}
@@ -1353,6 +1360,7 @@ complete_websocket_upgrade (SoupMessage *msg, gpointer user_data)
if (!handler || !handler->websocket_callback)
return;
+ soup_client_context_ref (client);
stream = soup_client_context_steal_connection (client);
conn = soup_websocket_connection_new (stream, uri,
SOUP_WEBSOCKET_CONNECTION_SERVER,
@@ -1364,6 +1372,7 @@ complete_websocket_upgrade (SoupMessage *msg, gpointer user_data)
(*handler->websocket_callback) (server, conn, uri->path, client,
handler->websocket_user_data);
g_object_unref (conn);
+ soup_client_context_unref (client);
}
static void
@@ -2231,7 +2240,7 @@ soup_client_context_get_gsocket (SoupClientContext *client)
{
g_return_val_if_fail (client != NULL, NULL);
- return soup_socket_get_gsocket (client->sock);
+ return client->gsock;
}
/**
@@ -2272,16 +2281,13 @@ soup_client_context_get_address (SoupClientContext *client)
GSocketAddress *
soup_client_context_get_remote_address (SoupClientContext *client)
{
- GSocket *sock;
-
g_return_val_if_fail (client != NULL, NULL);
if (client->remote_addr)
return client->remote_addr;
- sock = soup_client_context_get_gsocket (client);
- client->remote_addr = sock ?
- g_socket_get_remote_address (sock, NULL) :
+ client->remote_addr = client->gsock ?
+ g_socket_get_remote_address (client->gsock, NULL) :
soup_address_get_gsockaddr (soup_socket_get_remote_address (client->sock));
return client->remote_addr;
@@ -2303,16 +2309,13 @@ soup_client_context_get_remote_address (SoupClientContext *client)
GSocketAddress *
soup_client_context_get_local_address (SoupClientContext *client)
{
- GSocket *sock;
-
g_return_val_if_fail (client != NULL, NULL);
if (client->local_addr)
return client->local_addr;
- sock = soup_client_context_get_gsocket (client);
- client->local_addr = sock ?
- g_socket_get_local_address (sock, NULL) :
+ client->local_addr = client->gsock ?
+ g_socket_get_local_address (client->gsock, NULL) :
soup_address_get_gsockaddr (soup_socket_get_local_address (client->sock));
return client->local_addr;
@@ -2332,12 +2335,29 @@ soup_client_context_get_local_address (SoupClientContext *client)
const char *
soup_client_context_get_host (SoupClientContext *client)
{
- SoupAddress *address;
+ g_return_val_if_fail (client != NULL, NULL);
+
+ if (client->remote_ip)
+ return client->remote_ip;
+
+ if (client->gsock) {
+ GSocketAddress *addr = soup_client_context_get_remote_address (client);
+ GInetAddress *iaddr;
+
+ if (!addr || !G_IS_INET_SOCKET_ADDRESS (addr))
+ return NULL;
+ iaddr = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (addr));
+ client->remote_ip = g_inet_address_to_string (iaddr);
+ } else {
+ SoupAddress *addr;
+
+ G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
+ addr = soup_client_context_get_address (client);
+ G_GNUC_END_IGNORE_DEPRECATIONS;
+ client->remote_ip = g_strdup (soup_address_get_physical (addr));
+ }
- G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
- address = soup_client_context_get_address (client);
- G_GNUC_END_IGNORE_DEPRECATIONS;
- return soup_address_get_physical (address);
+ return client->remote_ip;
}
/**
diff --git a/tests/websocket-test.c b/tests/websocket-test.c
index 78dced5..c4f5b39 100644
--- a/tests/websocket-test.c
+++ b/tests/websocket-test.c
@@ -783,6 +783,54 @@ test_receive_fragmented (Test *test,
WAIT_UNTIL (soup_websocket_connection_get_state (test->client) == SOUP_WEBSOCKET_STATE_CLOSED);
}
+static void
+test_client_context_got_server_connection (SoupServer *server,
+ SoupWebsocketConnection *connection,
+ const char *path,
+ SoupClientContext *client,
+ gpointer user_data)
+{
+ Test *test = user_data;
+ GSocketAddress *addr;
+ GInetAddress *iaddr;
+ char *str;
+ const char *remote_ip;
+
+ addr = soup_client_context_get_local_address (client);
+ iaddr = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (addr));
+ str = g_inet_address_to_string (iaddr);
+ if (g_inet_address_get_family (iaddr) == G_SOCKET_FAMILY_IPV4)
+ g_assert_cmpstr (str, ==, "127.0.0.1");
+ else
+ g_assert_cmpstr (str, ==, "::1");
+ g_free (str);
+
+ addr = soup_client_context_get_remote_address (client);
+ iaddr = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (addr));
+ str = g_inet_address_to_string (iaddr);
+ if (g_inet_address_get_family (iaddr) == G_SOCKET_FAMILY_IPV4)
+ g_assert_cmpstr (str, ==, "127.0.0.1");
+ else
+ g_assert_cmpstr (str, ==, "::1");
+
+ remote_ip = soup_client_context_get_host (client);
+ g_assert_cmpstr (remote_ip, ==, str);
+ g_free (str);
+
+ test->server = g_object_ref (connection);
+}
+
+static void
+test_client_context (Test *test,
+ gconstpointer unused)
+{
+ setup_soup_server (test, NULL, NULL, test_client_context_got_server_connection, test);
+ client_connect (test, NULL, NULL, got_client_connection, test);
+ WAIT_UNTIL (test->server != NULL);
+ WAIT_UNTIL (test->client != NULL || test->client_error != NULL);
+ g_assert_no_error (test->client_error);
+}
+
int
main (int argc,
char *argv[])
@@ -901,6 +949,10 @@ main (int argc,
teardown_direct_connection);
}
+ g_test_add ("/websocket/soup/client-context", Test, NULL, NULL,
+ test_client_context,
+ teardown_soup_connection);
+
ret = g_test_run ();
test_cleanup ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]