[libsoup/pgriffis/updated-examples] WIP: Start updating examples/get




commit 406aa2dc5f0293e141acee9f803f4374b8e79877
Author: Patrick Griffis <pgriffis igalia com>
Date:   Sat Nov 14 14:55:20 2020 -0600

    WIP: Start updating examples/get

 examples/get.c | 201 ++++++++++++++++++++++++++++++---------------------------
 meson.build    |   3 +-
 2 files changed, 107 insertions(+), 97 deletions(-)
---
diff --git a/examples/get.c b/examples/get.c
index 377cf854..5e62deb2 100644
--- a/examples/get.c
+++ b/examples/get.c
@@ -13,82 +13,90 @@
 
 #include <libsoup/soup.h>
 
-static SoupSession *session;
 static GMainLoop *loop;
 static gboolean debug, head, quiet;
 static const gchar *output_file_path = NULL;
 
 static void
-finished (SoupSession *session, SoupMessage *msg, gpointer loop)
+on_stream_splice (GObject *source, GAsyncResult *result, gpointer user_data)
 {
-       g_main_loop_quit (loop);
+        GError *error = NULL;
+        gssize written = g_output_stream_splice_finish (G_OUTPUT_STREAM (source),
+                                                        result,
+                                                        &error);
+        if (error) {
+                g_printerr ("Failed to download: %s\n", error->message);
+                g_error_free (error);
+                g_main_loop_quit (loop);
+                return;
+        }
+
+        char *size_string = g_format_size (written);
+        g_print ("Downloaded %s\n", size_string);
+        g_free (size_string);
+
+        g_main_loop_quit (loop);
 }
 
 static void
-get_url (const char *url)
+on_read_uri (GObject *source, GAsyncResult *result, gpointer user_data)
 {
-       const char *name;
-       SoupMessage *msg;
-       const char *header;
-       FILE *output_file = NULL;
-
-       msg = soup_message_new (head ? "HEAD" : "GET", url);
-       soup_message_set_flags (msg, SOUP_MESSAGE_NO_REDIRECT);
-
-        g_object_ref (msg);
-        soup_session_queue_message (session, msg, finished, loop);
-        g_main_loop_run (loop);
-
-       name = g_uri_get_path (soup_message_get_uri (msg));
-
-       if (!debug) {
-               if (soup_message_get_status (msg) == SOUP_STATUS_SSL_FAILED) {
-                       GTlsCertificateFlags flags;
-
-                       if (soup_message_get_https_status (msg, NULL, &flags))
-                               g_print ("%s: %d %s (0x%x)\n", name, soup_message_get_status (msg), 
soup_message_get_reason_phrase (msg), flags);
-                       else
-                               g_print ("%s: %d %s (no handshake status)\n", name, soup_message_get_status 
(msg), soup_message_get_reason_phrase (msg));
-               } else if (!quiet || SOUP_STATUS_IS_TRANSPORT_ERROR (soup_message_get_status (msg)))
-                       g_print ("%s: %d %s\n", name, soup_message_get_status (msg), 
soup_message_get_reason_phrase (msg));
-       }
-
-       if (SOUP_STATUS_IS_REDIRECTION (soup_message_get_status (msg))) {
-               header = soup_message_headers_get_one (soup_message_get_response_headers (msg),
-                                                      "Location");
-               if (header) {
-                       GUri *uri;
-                       char *uri_string;
-
-                       if (!debug && !quiet)
-                               g_print ("  -> %s\n", header);
-
-                       uri = g_uri_parse_relative (soup_message_get_uri (msg), header, SOUP_HTTP_URI_FLAGS, 
NULL);
-                        g_assert (uri != NULL);
-                       uri_string = g_uri_to_string (uri);
-                       get_url (uri_string);
-                       g_free (uri_string);
-                       g_uri_unref (uri);
-               }
-       } else if (!head && SOUP_STATUS_IS_SUCCESSFUL (soup_message_get_status (msg))) {
-               if (output_file_path) {
-                       output_file = fopen (output_file_path, "w");
-                       if (!output_file)
-                               g_printerr ("Error trying to create file %s.\n", output_file_path);
-               } else if (!quiet)
-                       output_file = stdout;
-
-               if (output_file) {
-                       fwrite (msg->response_body->data,
-                               1,
-                               msg->response_body->length,
-                               output_file);
-
-                       if (output_file_path)
-                               fclose (output_file);
-               }
-       }
-       g_object_unref (msg);
+        const char *url = user_data;
+        char *content_type, *size_string;
+        goffset content_length;
+        GError *error = NULL;
+        GOutputStream *out;
+
+        /* We now have a stream to read data from */
+        GInputStream *in = soup_session_read_uri_finish (SOUP_SESSION (source),
+                                                         result,
+                                                         &content_length,
+                                                         &content_type,
+                                                         &error);
+
+        if (error) {
+                g_printerr ("Failed to get \"%s\": %s\n", url, error->message);
+                g_error_free (error);
+                g_main_loop_quit (loop);
+                return;
+        }
+
+        /* Now we make an output stream to write data to */
+        if (output_file_path) {
+                GFile *output_file = g_file_new_for_path (output_file_path);
+                out = G_OUTPUT_STREAM (g_file_create (output_file, G_FILE_CREATE_NONE,
+                                                      NULL, &error));
+                if (error) {
+                        g_print ("Failed to create \"%s\": %s\n", output_file_path, error->message);
+                        g_error_free (error);
+                        g_free (content_type);
+                        g_object_unref (in);
+                        g_object_unref (output_file);
+                        g_main_loop_quit (loop);
+                        return;
+                }
+        } else {
+                g_assert_not_reached (); // TODO
+        }
+
+        size_string = g_format_size (content_length);
+        g_print ("Downloading %s (%s) to %s\n",
+                 content_length > 0 ? size_string : "data",
+                 content_type,
+                 output_file_path ? output_file_path : "stdout");
+        g_free (size_string);
+        g_free (content_type);
+
+        /* Start downloading to the file */
+        g_output_stream_splice_async (G_OUTPUT_STREAM (out), in,
+                                      G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | 
G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
+                                      G_PRIORITY_DEFAULT,
+                                      NULL,
+                                      on_stream_splice,
+                                      NULL);
+
+        g_object_unref (in);
+        g_object_unref (out);
 }
 
 /* Inline class for providing a pre-configured client certificate */
@@ -190,11 +198,9 @@ int
 main (int argc, char **argv)
 {
        GOptionContext *opts;
+        SoupSession *session;
        const char *url;
-       GUri *proxy_uri, *parsed;
        GError *error = NULL;
-       SoupLogger *logger = NULL;
-       char *help;
 
        opts = g_option_context_new (NULL);
        g_option_context_add_main_entries (opts, entries, NULL);
@@ -209,7 +215,7 @@ main (int argc, char **argv)
        }
 
        if (argc != 2) {
-               help = g_option_context_get_help (opts, TRUE, NULL);
+               char *help = g_option_context_get_help (opts, TRUE, NULL);
                g_printerr ("%s", help);
                g_free (help);
                exit (1);
@@ -217,23 +223,32 @@ main (int argc, char **argv)
        g_option_context_free (opts);
 
        url = argv[1];
-       parsed = g_uri_parse (url, SOUP_HTTP_URI_FLAGS, &error);
-       if (!parsed) {
-               g_printerr ("Could not parse '%s' as a URL: %s\n", url, error->message);
-               exit (1);
-       }
-       g_uri_unref (parsed);
 
-       session = g_object_new (SOUP_TYPE_SESSION,
-                               "user-agent", "get ",
-                               "accept-language-auto", TRUE,
-                               NULL);
+       session = soup_session_new_with_options ("user-agent", "get ",
+                                                "accept-language-auto", TRUE,
+                                                 "timeout", 1,
+                                                NULL);
         soup_session_add_feature_by_type (session, SOUP_TYPE_CONTENT_DECODER);
         soup_session_add_feature_by_type (session, SOUP_TYPE_COOKIE_JAR);
        if (ntlm)
                soup_session_add_feature_by_type (session, SOUP_TYPE_AUTH_NTLM);
-       if (ca_file)
-               g_object_set (session, "ssl-ca-file", ca_file, NULL);
+#ifdef LIBSOUP_HAVE_GSSAPI
+       if (negotiate)
+               soup_session_add_feature_by_type (session,
+                                                 SOUP_TYPE_AUTH_NEGOTIATE);
+#endif
+
+        if (ca_file) {
+                GTlsDatabase *tls_db = g_tls_file_database_new (ca_file, &error);
+                if (error) {
+                        g_printerr ("Failed to load TLS database \"%s\": %s", ca_file, error->message);
+                        g_error_free (error);
+                        exit (1);
+                }
+
+                g_object_set (session, "tls-database", tls_db, NULL);
+                g_object_unref (tls_db);
+        }
 
        if (client_cert_file) {
                GTlsCertificate *client_cert;
@@ -249,19 +264,19 @@ main (int argc, char **argv)
                }
                interaction = _get_tls_cert_interaction_new (client_cert);
                g_object_set (session, "tls-interaction", interaction, NULL);
+                g_object_unref (interaction);
        }
 
        if (debug) {
-               logger = soup_logger_new (SOUP_LOGGER_LOG_BODY, -1);
+               SoupLogger *logger = soup_logger_new (SOUP_LOGGER_LOG_BODY, -1);
                soup_session_add_feature (session, SOUP_SESSION_FEATURE (logger));
                g_object_unref (logger);
        }
 
        if (proxy) {
                GProxyResolver *resolver;
-                GError *error;
-               proxy_uri = g_uri_parse (proxy, SOUP_HTTP_URI_FLAGS, &error);
-               if (!proxy_uri) {
+               GUri *proxy_uri = g_uri_parse (proxy, SOUP_HTTP_URI_FLAGS, &error);
+               if (error) {
                        g_printerr ("Could not parse '%s' as URI: %s\n",
                                    proxy, error->message);
                         g_error_free (error);
@@ -276,19 +291,15 @@ main (int argc, char **argv)
                g_object_unref (resolver);
        }
 
-#ifdef LIBSOUP_HAVE_GSSAPI
-       if (negotiate) {
-               soup_session_add_feature_by_type (session,
-                                                 SOUP_TYPE_AUTH_NEGOTIATE);
-       }
-#endif /* LIBSOUP_HAVE_GSSAPI */
-
        loop = g_main_loop_new (NULL, TRUE);
 
-       get_url (url);
+        g_print ("Requesting %s\n", url);
 
-       g_main_loop_unref (loop);
+        soup_session_read_uri_async (session, url, G_PRIORITY_DEFAULT, NULL,
+                                     on_read_uri, (char*)url);
 
+        g_main_loop_run (loop);
+       g_main_loop_unref (loop);
        g_object_unref (session);
 
        return 0;
diff --git a/meson.build b/meson.build
index fe1f95af..74bab2fc 100644
--- a/meson.build
+++ b/meson.build
@@ -357,8 +357,7 @@ if find_program('xgettext', required : false).found()
   subdir('po')
 endif
 
-# FIXME: port examples to use the new API.
-#subdir('examples')
+subdir('examples')
 
 if get_option('tests')
   subdir('tests')


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