summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Griffis <pgriffis@igalia.com>2021-03-29 12:38:42 -0500
committerPatrick Griffis <pgriffis@igalia.com>2021-04-08 14:41:28 -0500
commit88b352fdceccfa070bbea22a2ac12e9137d5cc5d (patch)
tree37da948f648afea4c63354e922132b2891696603
parent768f98811bede0dbb9e314782d6f4c039f3ac9cc (diff)
downloadlibsoup-pgriffis/connection-id.tar.gz
Add soup_message_get_connection_id() APIpgriffis/connection-id
This is useful for WebKit to show in its inspector for easy debugging.
-rw-r--r--docs/reference/libsoup-3.0-sections.txt1
-rw-r--r--libsoup/soup-connection.c24
-rw-r--r--libsoup/soup-connection.h3
-rw-r--r--libsoup/soup-message.c27
-rw-r--r--libsoup/soup-message.h2
-rw-r--r--libsoup/soup-session.c2
-rw-r--r--tests/misc-test.c35
7 files changed, 93 insertions, 1 deletions
diff --git a/docs/reference/libsoup-3.0-sections.txt b/docs/reference/libsoup-3.0-sections.txt
index 77e03b56..26775111 100644
--- a/docs/reference/libsoup-3.0-sections.txt
+++ b/docs/reference/libsoup-3.0-sections.txt
@@ -27,6 +27,7 @@ soup_message_get_request_headers
soup_message_get_response_headers
<SUBSECTION>
soup_message_is_keepalive
+soup_message_get_connection_id
soup_message_get_tls_certificate
soup_message_get_tls_certificate_errors
<SUBSECTION>
diff --git a/libsoup/soup-connection.c b/libsoup/soup-connection.c
index 60384fdf..4beb599b 100644
--- a/libsoup/soup-connection.c
+++ b/libsoup/soup-connection.c
@@ -26,6 +26,7 @@ typedef struct {
GSocketConnectable *remote_connectable;
GIOStream *iostream;
SoupSocketProperties *socket_props;
+ guint64 id;
GUri *proxy_uri;
gboolean ssl;
@@ -53,6 +54,7 @@ static guint signals[LAST_SIGNAL] = { 0 };
enum {
PROP_0,
+ PROP_ID,
PROP_REMOTE_CONNECTABLE,
PROP_SOCKET_PROPERTIES,
PROP_STATE,
@@ -131,6 +133,9 @@ soup_connection_set_property (GObject *object, guint prop_id,
case PROP_SSL:
priv->ssl = g_value_get_boolean (value);
break;
+ case PROP_ID:
+ priv->id = g_value_get_uint64 (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -156,6 +161,9 @@ soup_connection_get_property (GObject *object, guint prop_id,
case PROP_SSL:
g_value_set_boolean (value, priv->ssl);
break;
+ case PROP_ID:
+ g_value_set_uint64 (value, priv->id);
+ break;
case PROP_TLS_CERTIFICATE:
g_value_set_object (value, soup_connection_get_tls_certificate (SOUP_CONNECTION (object)));
break;
@@ -242,6 +250,14 @@ soup_connection_class_init (SoupConnectionClass *connection_class)
FALSE,G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (
+ object_class, PROP_ID,
+ g_param_spec_uint64 ("id",
+ "Connection Identifier",
+ "Unique identifier for the connection",
+ 0, G_MAXUINT64,
+ 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (
object_class, PROP_TLS_CERTIFICATE,
g_param_spec_object ("tls-certificate",
"TLS Certificate",
@@ -1083,3 +1099,11 @@ soup_connection_get_tls_certificate_errors (SoupConnection *conn)
return g_tls_connection_get_peer_certificate_errors (G_TLS_CONNECTION (priv->connection));
}
+
+guint64
+soup_connection_get_id (SoupConnection *conn)
+{
+ SoupConnectionPrivate *priv = soup_connection_get_instance_private (conn);
+
+ return priv->id;
+}
diff --git a/libsoup/soup-connection.h b/libsoup/soup-connection.h
index 04c9353b..410bde0e 100644
--- a/libsoup/soup-connection.h
+++ b/libsoup/soup-connection.h
@@ -75,6 +75,9 @@ void soup_connection_send_request (SoupConnection *conn,
GTlsCertificate *soup_connection_get_tls_certificate (SoupConnection *conn);
GTlsCertificateFlags soup_connection_get_tls_certificate_errors (SoupConnection *conn);
+
+guint64 soup_connection_get_id (SoupConnection *conn);
+
G_END_DECLS
#endif /* __SOUP_CONNECTION_H__ */
diff --git a/libsoup/soup-message.c b/libsoup/soup-message.c
index 4e2782ff..410189b1 100644
--- a/libsoup/soup-message.c
+++ b/libsoup/soup-message.c
@@ -92,6 +92,7 @@ typedef struct {
gboolean is_top_level_navigation;
gboolean is_options_ping;
+ guint last_connection_id;
} SoupMessagePrivate;
G_DEFINE_TYPE_WITH_PRIVATE (SoupMessage, soup_message, G_TYPE_OBJECT)
@@ -1361,6 +1362,8 @@ soup_message_set_connection (SoupMessage *msg,
if (!priv->connection)
return;
+ priv->last_connection_id = soup_connection_get_id (priv->connection);
+
g_object_add_weak_pointer (G_OBJECT (priv->connection), (gpointer*)&priv->connection);
soup_message_set_tls_certificate (msg,
soup_connection_get_tls_certificate (priv->connection),
@@ -1397,8 +1400,10 @@ soup_message_cleanup_response (SoupMessage *msg)
soup_message_set_status (msg, SOUP_STATUS_NONE, NULL);
soup_message_set_http_version (msg, priv->orig_http_version);
- if (!priv->connection)
+ if (!priv->connection) {
soup_message_set_tls_certificate (msg, NULL, 0);
+ priv->last_connection_id = 0;
+ }
g_object_thaw_notify (G_OBJECT (msg));
}
@@ -2309,3 +2314,23 @@ soup_message_set_is_options_ping (SoupMessage *msg,
if (priv->is_options_ping)
soup_message_set_method (msg, SOUP_METHOD_OPTIONS);
}
+
+/**
+ * soup_message_get_connection_id:
+ * @msg: The #SoupMessage
+ *
+ * Returns the unique idenfier for the last connection used.
+ * This may be 0 if it was a cached resource or it has not gotten
+ * a connection yet.
+ *
+ * Returns: An id or 0 if no connection.
+ */
+guint64
+soup_message_get_connection_id (SoupMessage *msg)
+{
+ SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
+
+ g_return_val_if_fail (SOUP_IS_MESSAGE (msg), 0);
+
+ return priv->last_connection_id;
+}
diff --git a/libsoup/soup-message.h b/libsoup/soup-message.h
index 008ea5a2..99ebb766 100644
--- a/libsoup/soup-message.h
+++ b/libsoup/soup-message.h
@@ -168,5 +168,7 @@ gboolean soup_message_get_is_options_ping (SoupMessage *msg);
SOUP_AVAILABLE_IN_ALL
void soup_message_set_is_options_ping (SoupMessage *msg,
gboolean is_options_ping);
+SOUP_AVAILABLE_IN_ALL
+guint64 soup_message_get_connection_id (SoupMessage *msg);
G_END_DECLS
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c
index df9b1ad8..06374dd5 100644
--- a/libsoup/soup-session.c
+++ b/libsoup/soup-session.c
@@ -121,6 +121,7 @@ typedef struct {
GHashTable *conns; /* SoupConnection -> SoupSessionHost */
guint num_conns;
guint max_conns, max_conns_per_host;
+ guint64 last_connection_id;
} SoupSessionPrivate;
static void free_host (SoupSessionHost *host);
@@ -1862,6 +1863,7 @@ get_connection_for_host (SoupSession *session,
ensure_socket_props (session);
conn = g_object_new (SOUP_TYPE_CONNECTION,
+ "id", ++priv->last_connection_id,
"remote-connectable", remote_connectable,
"ssl", soup_uri_is_https (host->uri),
"socket-properties", priv->socket_props,
diff --git a/tests/misc-test.c b/tests/misc-test.c
index d2ad457f..7efa94bf 100644
--- a/tests/misc-test.c
+++ b/tests/misc-test.c
@@ -621,6 +621,40 @@ do_msg_flags_test (void)
g_object_unref (msg);
}
+static void
+do_connection_id_test (void)
+{
+ SoupSession *session = soup_test_session_new (NULL);
+ SoupMessage *msg = soup_message_new_from_uri (SOUP_METHOD_GET, base_uri);
+
+ /* Test that the ID is set for each new connection and that it is
+ * cached after the message is completed */
+
+ g_assert_cmpuint (soup_message_get_connection_id (msg), ==, 0);
+
+ guint status = soup_test_session_send_message (session, msg);
+
+ g_assert_cmpuint (status, ==, SOUP_STATUS_OK);
+ g_assert_cmpuint (soup_message_get_connection_id (msg), ==, 1);
+
+ status = soup_test_session_send_message (session, msg);
+
+ g_assert_cmpuint (status, ==, SOUP_STATUS_OK);
+ g_assert_cmpuint (soup_message_get_connection_id (msg), ==, 2);
+
+ GUri *uri = g_uri_parse_relative (base_uri, "/redirect", SOUP_HTTP_URI_FLAGS, NULL);
+ soup_message_set_uri (msg, uri);
+ g_uri_unref (uri);
+
+ status = soup_test_session_send_message (session, msg);
+
+ g_assert_cmpuint (status, ==, SOUP_STATUS_OK);
+ g_assert_cmpuint (soup_message_get_connection_id (msg), ==, 3);
+
+ g_object_unref (msg);
+ soup_test_session_abort_unref (session);
+}
+
int
main (int argc, char **argv)
{
@@ -652,6 +686,7 @@ main (int argc, char **argv)
g_test_add_func ("/misc/cancel-while-reading/req/delayed", do_cancel_while_reading_delayed_req_test);
g_test_add_func ("/misc/cancel-while-reading/req/preemptive", do_cancel_while_reading_preemptive_req_test);
g_test_add_func ("/misc/msg-flags", do_msg_flags_test);
+ g_test_add_func ("/misc/connection-id", do_connection_id_test);
ret = g_test_run ();