[libsoup/carlosgc/message-io: 2/2] connection: move the code to check if idle connection is open to http1 implementation




commit ea5d03791b2ae66051045841af4538beabc95309
Author: Carlos Garcia Campos <cgarcia igalia com>
Date:   Sat May 15 16:44:16 2021 +0200

    connection: move the code to check if idle connection is open to http1 implementation
    
    Add SoupClientMessageIO::is_open, implemented by http1 and used by
    SoupConnection.

 libsoup/soup-client-message-io-http1.c | 32 +++++++++++++++++++++++++++++++-
 libsoup/soup-client-message-io.c       |  6 ++++++
 libsoup/soup-client-message-io.h       |  4 +++-
 libsoup/soup-connection.c              | 26 +-------------------------
 4 files changed, 41 insertions(+), 27 deletions(-)
---
diff --git a/libsoup/soup-client-message-io-http1.c b/libsoup/soup-client-message-io-http1.c
index b8f8724e..5c19d5cd 100644
--- a/libsoup/soup-client-message-io-http1.c
+++ b/libsoup/soup-client-message-io-http1.c
@@ -1069,6 +1069,35 @@ soup_client_message_io_http1_is_paused (SoupClientMessageIO *iface,
         return io->msg_io->base.paused;
 }
 
+static gboolean
+soup_client_message_io_http1_is_open (SoupClientMessageIO *iface)
+{
+        SoupClientMessageIOHTTP1 *io = (SoupClientMessageIOHTTP1 *)iface;
+        char buffer[1];
+        GError *error = NULL;
+
+        /* This is tricky. The goal is to check if the socket is readable. If
+         * so, that means either the server has disconnected or it's broken (it
+         * should not send any data while the connection is in idle state). But
+         * we can't just check the readability of the SoupSocket because there
+         * could be non-application layer TLS data that is readable, but which
+         * we don't want to consider. So instead, just read and see if the read
+         * succeeds. This is OK to do here because if the read does succeed, we
+         * just disconnect and ignore the data anyway.
+         */
+        g_pollable_input_stream_read_nonblocking (G_POLLABLE_INPUT_STREAM (io->istream),
+                                                  &buffer, sizeof (buffer),
+                                                 NULL, &error);
+        if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
+                g_clear_error (&error);
+               return FALSE;
+        }
+
+        g_error_free (error);
+
+        return TRUE;
+}
+
 static const SoupClientMessageIOFuncs io_funcs = {
         soup_client_message_io_http1_destroy,
         soup_client_message_io_http1_finished,
@@ -1081,7 +1110,8 @@ static const SoupClientMessageIOFuncs io_funcs = {
         soup_client_message_io_http1_run,
         soup_client_message_io_http1_run_until_read,
         soup_client_message_io_http1_run_until_read_async,
-        soup_client_message_io_http1_run_until_finish
+        soup_client_message_io_http1_run_until_finish,
+        soup_client_message_io_http1_is_open
 };
 
 SoupClientMessageIO *
diff --git a/libsoup/soup-client-message-io.c b/libsoup/soup-client-message-io.c
index 7a48006a..c0c2c533 100644
--- a/libsoup/soup-client-message-io.c
+++ b/libsoup/soup-client-message-io.c
@@ -106,3 +106,9 @@ soup_client_message_io_get_response_stream (SoupClientMessageIO *io,
 {
         return io->funcs->get_response_stream (io, msg, error);
 }
+
+gboolean
+soup_client_message_io_is_open (SoupClientMessageIO *io)
+{
+        return io->funcs->is_open (io);
+}
diff --git a/libsoup/soup-client-message-io.h b/libsoup/soup-client-message-io.h
index dfdb8690..69317eb6 100644
--- a/libsoup/soup-client-message-io.h
+++ b/libsoup/soup-client-message-io.h
@@ -46,6 +46,7 @@ typedef struct {
                                                gboolean                   blocking,
                                                GCancellable              *cancellable,
                                                GError                   **error);
+        gboolean      (*is_open)              (SoupClientMessageIO       *io);
 } SoupClientMessageIOFuncs;
 
 struct _SoupClientMessageIO {
@@ -86,4 +87,5 @@ gboolean      soup_client_message_io_run_until_finish     (SoupClientMessageIO
                                                            GError                   **error);
 GInputStream *soup_client_message_io_get_response_stream  (SoupClientMessageIO       *io,
                                                            SoupMessage               *msg,
-                                                           GError                   **error);
\ No newline at end of file
+                                                           GError                   **error);
+gboolean      soup_client_message_io_is_open              (SoupClientMessageIO       *io);
diff --git a/libsoup/soup-connection.c b/libsoup/soup-connection.c
index 3b65cc37..c0a530f2 100644
--- a/libsoup/soup-connection.c
+++ b/libsoup/soup-connection.c
@@ -963,9 +963,6 @@ gboolean
 soup_connection_is_idle_open (SoupConnection *conn)
 {
         SoupConnectionPrivate *priv = soup_connection_get_instance_private (conn);
-       GInputStream *istream;
-       char buffer[1];
-       GError *error = NULL;
 
         g_assert (priv->state == SOUP_CONNECTION_IDLE);
 
@@ -975,28 +972,7 @@ soup_connection_is_idle_open (SoupConnection *conn)
        if (priv->unused_timeout && priv->unused_timeout < time (NULL))
                return FALSE;
 
-       istream = g_io_stream_get_input_stream (priv->iostream);
-
-       /* This is tricky. The goal is to check if the socket is readable. If
-        * so, that means either the server has disconnected or it's broken (it
-        * should not send any data while the connection is in idle state). But
-        * we can't just check the readability of the SoupSocket because there
-        * could be non-application layer TLS data that is readable, but which
-        * we don't want to consider. So instead, just read and see if the read
-        * succeeds. This is OK to do here because if the read does succeed, we
-        * just disconnect and ignore the data anyway.
-        */
-       g_pollable_input_stream_read_nonblocking (G_POLLABLE_INPUT_STREAM (istream),
-                                                 &buffer, sizeof (buffer),
-                                                 NULL, &error);
-       if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
-               g_clear_error (&error);
-               return FALSE;
-       }
-
-       g_error_free (error);
-
-       return TRUE;
+        return soup_client_message_io_is_open (priv->io_data);
 }
 
 SoupConnectionState


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