[easytag/wip/libsoup-cddb: 1/5] Port to using libsoup for CDDB requests
- From: David King <davidk src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [easytag/wip/libsoup-cddb: 1/5] Port to using libsoup for CDDB requests
- Date: Tue, 15 Mar 2016 22:42:33 +0000 (UTC)
commit 8b1e856b495b105732ae45e224199327c12966d7
Author: David King <amigadave amigadave com>
Date: Wed Mar 9 16:37:52 2016 +0000
Port to using libsoup for CDDB requests
Makefile.am | 3 +-
README | 1 +
configure.ac | 35 +-
src/browser.c | 1 +
src/cddb_dialog.c | 1335 +++++++++++++++--------------------------------------
5 files changed, 405 insertions(+), 970 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index d791604..9e850b2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -26,7 +26,8 @@ easytag_CPPFLAGS = \
-I$(top_builddir)/src \
-DLOCALEDIR=\"$(localedir)\" \
$(GLIB_DEPRECATION_FLAGS) \
- $(GTK_DEPRECATION_FLAGS)
+ $(GTK_DEPRECATION_FLAGS) \
+ $(SOUP_DEPRECATION_FLAGS)
easytag_CFLAGS = \
$(WARN_CFLAGS) \
diff --git a/README b/README
index 7b4388d..415a8ee 100644
--- a/README
+++ b/README
@@ -64,6 +64,7 @@ Installation
* flac (http://flac.sourceforge.net) (if not deactivated by './configure --disable-flac')
* libogg and libvorbis (http://www.vorbis.com) (if not deactivated by './configure --disable-ogg')
* libnautilus-extension (https://wiki.gnome.org/Apps/Nautilus) (if not deactivated by ./configure
--disable-nautilus-actions')
+* libsoup (https://wiki.gnome.org/Projects/libsoup) (if not deactivated for './configure --disable-cddb')
* opus and opusfile (http://www.opus-codec.org/) (if not deactivated by './configure --disable-opus')
* taglib (http://taglib.github.com/) (if not deactivated by './configure --disable-mp4')
* wavpack (http://www.wavpack.com/) (if not deactivated by './configure --disable-wavpack')
diff --git a/configure.ac b/configure.ac
index d94ce2a..bd911f1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -162,6 +162,8 @@ AC_ARG_ENABLE([mp4],
AC_ARG_ENABLE([wavpack],
[AS_HELP_STRING([--disable-wavpack], [Disable support for Wavpack files (default=auto)])])
+AC_ARG_ENABLE([cddb],
+ [AS_HELP_STRING([--disable-cddb], [Disable CDDB support (default=auto)])])
AC_ARG_ENABLE([nautilus_actions],
[AS_HELP_STRING([--disable-nautilus-actions], [do not build the nautilus context menu actions
(default=auto)])])
@@ -171,10 +173,6 @@ dnl -------------------------------
dnl Checks for libraries.
dnl -------------------------------
-dnl Patch from Ben Taylor to fix a Solaris bug (for CDDB)
-AC_CHECK_LIB([socket], [recv])
-
-
dnl ################################################
dnl # Ogg Vorbis libraries
dnl ################################################
@@ -320,6 +318,20 @@ AS_IF([test "x$have_wavpack" != "xno"],
[AC_MSG_ERROR([Wavpack support requested but required dependencies ($WAVPACK_DEPS) not
found])])])
dnl ################################################
+dnl # CDDB (libsoup)
+dnl ################################################
+CDDB_DEPS="libsoup-2.4 >= 2.42"
+AS_IF([test "x$enable_cddb" != "xno"],
+ [PKG_CHECK_EXISTS([$CDDB_DEPS], [have_cddb=yes], [have_cddb=no])],
+ [have_cddb=no])
+
+AS_IF([test "x$enable_cddb" != "xno"],
+ [AC_DEFINE([ENABLE_CDDB], [], [Define for CDDB support])],
+ [CDDB_DEPS=""
+ AS_IF([test "x$enable_cddb" = "xyes"],
+ [AC_MSG_ERROR([CDDB support requested but required dependences ($CDDB_DEPS) not found])])])
+
+dnl ################################################
dnl # Nautilus
dnl ################################################
NAUTILUS_DEPS="libnautilus-extension >= 3.0 gio-unix-2.0"
@@ -344,17 +356,9 @@ AC_SUBST([GLIB_DEPRECATION_FLAGS],
GTK_DEPS="gtk+-3.0 >= 3.10.0"
AC_SUBST([GTK_DEPRECATION_FLAGS],
["-DGDK_VERSION_MIN_REQUIRED=GDK_VERSION_3_10 -DGDK_VERSION_MAX_ALLOWED=GDK_VERSION_3_10"])
-PKG_CHECK_MODULES([EASYTAG], [$GIO_DEPS $GTK_DEPS $OPUS_DEPS $OGG_DEPS $SPEEX_DEPS $FLAC_DEPS $ID3TAG_DEPS
$TAGLIB_DEPS $WAVPACK_DEPS])
-
-dnl Check for winsock
-AC_SEARCH_LIBS([gethostbyname], [nsl socket], [],
- [saved_LIBS=$LIBS
- LIBS="-lws2_32 $LIBS"
- AC_MSG_CHECKING([for gethostbyname in ws2_32])
- AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <winsock2.h>]],
- [[gethostbyname ("");]])],
- [have_ws2=yes], [have_ws2=no LIBS=$saved_LIBS])
- AC_MSG_RESULT([$have_ws2])])
+AC_SUBST([SOUP_DEPRECATION_FLAGS],
+ ["-DSOUP_VERSION_MIN_REQUIRED=SOUP_VERSION_2_42 -DSOUP_VERSION_MAX_ALLOWED=SOUP_VERSION_2_42"])
+PKG_CHECK_MODULES([EASYTAG], [$CDDB_DEPS $GIO_DEPS $GTK_DEPS $OPUS_DEPS $OGG_DEPS $SPEEX_DEPS $FLAC_DEPS
$ID3TAG_DEPS $TAGLIB_DEPS $WAVPACK_DEPS])
dnl Set warning flags
AX_IS_RELEASE([git-directory])
@@ -382,6 +386,7 @@ echo Compiler ................: $CC $CFLAGS
echo Compiler warnings .......: $WARN_CFLAGS
echo C++ Compiler warnings ...: $WARN_CXXFLAGS
echo Linker ..................: $CC $LDFLAGS $LIBS
+echo CDDB support ............: $have_cddb
echo MP3 file support ........: $have_mp3
echo ID3v2.3 tags support ....: $have_id3lib $ID3LIB_VERSION
echo Ogg Vorbis file support .: $have_ogg
diff --git a/src/browser.c b/src/browser.c
index 4d51eae..18eb587 100644
--- a/src/browser.c
+++ b/src/browser.c
@@ -994,6 +994,7 @@ et_browser_win32_get_drive_root (EtBrowser *self,
{
gtk_tree_model_get(GTK_TREE_MODEL(priv->directory_model), &parentNode,
TREE_COLUMN_FULL_PATH, &nodeName, -1);
+ /* FIXME: Use something other than strncasecmp()! */
if (strncasecmp(drive,nodeName, strlen(drive)) == 0)
{
g_free(nodeName);
diff --git a/src/cddb_dialog.c b/src/cddb_dialog.c
index be688d9..31bca7b 100644
--- a/src/cddb_dialog.c
+++ b/src/cddb_dialog.c
@@ -23,20 +23,13 @@
#include <glib/gi18n.h>
#include <glib/gstdio.h>
+#include <libsoup/soup.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include "win32/win32dep.h"
-#ifndef G_OS_WIN32
-#include <sys/socket.h>
-/* Patch OpenBSD from Jim Geovedi. */
-#include <netinet/in.h>
-#include <arpa/inet.h>
-/* End patch */
-#include <netdb.h>
-#endif /* !G_OS_WIN32 */
#include <errno.h>
#include "application_window.h"
@@ -101,6 +94,8 @@ typedef struct
GtkWidget *scanner_check;
GtkWidget *dlm_check;
+
+ SoupSession *session;
} EtCDDBDialogPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (EtCDDBDialog, et_cddb_dialog, GTK_TYPE_DIALOG)
@@ -198,10 +193,6 @@ static const gchar *cddb_genre_vs_id3_genre [][2] =
{"Misc", "Other"}
};
-
-// File for result of the Cddb/Freedb request (on remote access)
-static const gchar CDDB_RESULT_FILE[] = "cddb_result_file.tmp";
-
static const guint MAX_STRING_LEN = 1024;
@@ -210,10 +201,6 @@ static const guint MAX_STRING_LEN = 1024;
**************/
static gboolean Cddb_Free_Track_Album_List (GList *track_list);
-static gint Cddb_Read_Line (FILE **file, gchar **cddb_out);
-static gint Cddb_Read_Http_Header (FILE **file, gchar **cddb_out);
-static gint Cddb_Read_Cddb_Header (FILE **file, gchar **cddb_out);
-
static GdkPixbuf *Cddb_Get_Pixbuf_From_Server_Name (const gchar *server_name);
static const gchar *Cddb_Get_Id3_Genre_From_Cddb_Genre (const gchar *cddb_genre);
@@ -221,13 +208,12 @@ static const gchar *Cddb_Get_Id3_Genre_From_Cddb_Genre (const gchar *cddb_genre)
static gint Cddb_Track_List_Sort_Func (GtkTreeModel *model, GtkTreeIter *a,
GtkTreeIter *b, gpointer data);
-static gchar *Cddb_Format_Proxy_Authentification (void);
-
static gboolean Cddb_Get_Album_Tracks_List_CB (EtCDDBDialog *self, GtkTreeSelection *selection);
/*
* The window to connect to the cd data base.
+ * Protocol information: http://ftp.freedb.org/pub/freedb/latest/CDDBPROTO
*/
static void
@@ -579,274 +565,165 @@ Cddb_Load_Track_Album_List (EtCDDBDialog *self, GList *track_list)
}
}
+static void
+cddb_track_frame_offset_free (CddbTrackFrameOffset *offset)
+{
+ g_slice_free (CddbTrackFrameOffset, offset);
+}
+
/*
- * Cddb_Open_Connection:
- * @host: a hostname
- * @port: a port number
+ * check_message_successful:
+ * @message: the message on which to check for success
*
- * Open a connection to @hostname, performing a DNS lookup as necessary.
+ * Check the result of @message to see whether it was a success. Soup handles
+ * redirects, so that the result code is that of the final request.
*
- * Returns: the socket fd, or 0 upon failure
+ * Returns: %TRUE if the request was successful, %FALSE otherwise
*/
-/* TODO: Propagate the GError to the caller. */
-static gint
-Cddb_Open_Connection (EtCDDBDialog *self, const gchar *host, gint port)
+static gboolean
+check_message_successful (SoupMessage *message)
{
- EtCDDBDialogPrivate *priv;
- GSocketConnectable *address;
- GSocketAddressEnumerator *enumerator;
- GCancellable *cancellable;
- GSocketAddress *sockaddress;
- GError *error = NULL;
- GError *sock_error = NULL;
- gint socket_id = 0;
- gchar *msg;
-
- g_return_val_if_fail (self != NULL, 0);
- g_return_val_if_fail (host != NULL && port > 0, 0);
-
- priv = et_cddb_dialog_get_instance_private (self);
-
- msg = g_strdup_printf(_("Resolving host '%s'…"),host);
- gtk_statusbar_push (GTK_STATUSBAR (priv->status_bar),
- priv->status_bar_context, msg);
- g_free(msg);
-
- while (gtk_events_pending ())
- {
- gtk_main_iteration ();
- }
-
- address = g_network_address_new (host, port);
- enumerator = g_socket_connectable_enumerate (address);
- g_object_unref (address);
+ return message->status_code == SOUP_STATUS_OK;
+}
- cancellable = g_cancellable_new ();
+/*
+ * read_cddb_result_line:
+ * @dstream: a #GDataInputStream corresponding to a CDDB result, with the line
+ * ending mode set appropriately
+ * @cancellable: a #GCancellable for the operation
+ * @result: a location to store the resulting line
+ *
+ * Read a single line from a CDDB result.
+ *
+ * Returns: %TRUE on success, %FALSE otherwise. @result is always set, and
+ * should be freed when finished with
+ */
+static gboolean
+read_cddb_result_line (GDataInputStream *dstream,
+ GCancellable *cancellable,
+ gchar **result)
+{
+ gchar *buffer;
+ gsize bytes_read;
+ GError *error = NULL;
- while (socket_id == 0
- && (sockaddress = g_socket_address_enumerator_next (enumerator,
- cancellable,
- &error)))
+ if ((buffer = g_data_input_stream_read_line_utf8 (dstream, &bytes_read,
+ cancellable, &error))
+ == NULL)
{
- struct sockaddr sockaddr_in;
- gint optval = 1;
-
- if (!g_socket_address_to_native (sockaddress, &sockaddr_in,
- sizeof (sockaddr_in),
- sock_error ? NULL : &sock_error))
+ /* The error is not set if there are no more lines to read. */
+ if (error)
{
- g_object_unref (sockaddress);
- continue;
+ g_debug ("Error reading line from CDDB result: %s",
+ error->message);
+ g_error_free (error);
}
- g_object_unref (sockaddress);
-
- while (gtk_events_pending ())
- {
- gtk_main_iteration ();
- }
-
- /* Create socket. */
- if ((socket_id = socket (AF_INET, SOCK_STREAM, 0)) < 0)
- {
- msg = g_strdup_printf (_("Cannot create a new socket ‘%s’"),
- g_strerror (errno));
- gtk_statusbar_push (GTK_STATUSBAR (priv->status_bar),
- priv->status_bar_context, msg);
- Log_Print (LOG_ERROR, "%s", msg);
- g_free (msg);
- goto err;
- }
-
- /* FIXME : must catch SIGPIPE? */
- if (setsockopt (socket_id, SOL_SOCKET, SO_KEEPALIVE, (void *)&optval,
- sizeof (optval)) < 0)
- {
- Log_Print (LOG_WARNING,
- _("Cannot set options on the newly-created socket"));
- }
+ *result = NULL;
+ return FALSE;
+ }
- /* Open connection to the server. */
- msg = g_strdup_printf (_("Connecting to host ‘%s’, port ‘%d’…"), host,
- port);
- gtk_statusbar_push (GTK_STATUSBAR (priv->status_bar),
- priv->status_bar_context, msg);
- g_free (msg);
+ if (bytes_read > MAX_STRING_LEN)
+ {
+ /* TODO: Although the maximum line length is not specified, this is
+ * probably bogus. */
+ g_warning ("Overly long line in CDDB result");
+ }
- while (gtk_events_pending ())
- {
- gtk_main_iteration ();
- }
+ *result = buffer;
- if (connect (socket_id, &sockaddr_in, sizeof (struct sockaddr)) < 0)
- {
- msg = g_strdup_printf (_("Cannot connect to host ‘%s’: %s"), host,
- g_strerror (errno));
- gtk_statusbar_push (GTK_STATUSBAR (priv->status_bar),
- priv->status_bar_context, msg);
- Log_Print (LOG_ERROR, "%s", msg);
- g_free (msg);
+ return TRUE;
+}
- goto err;
- }
- }
+/*
+ * read_cddb_header_line:
+ * @dstream: a #GDataInputStream corresponding to a CDDB header, with the line
+ * ending mode set appropriately
+ * @cancellable: a #GCancellable for the operation
+ * @result: a location to store the resulting line
+ *
+ * Read a single line from a CDDB header.
+ *
+ * Returns: %TRUE on success, %FALSE otherwise. @result is always set, and
+ * should be freed when finished with
+ */
+static gboolean
+read_cddb_header_line (GDataInputStream *dstream,
+ GCancellable *cancellable,
+ gchar **result)
+{
+ gchar *buffer;
+ gsize bytes_read;
+ GError *error = NULL;
- if (socket_id != 0)
+ if ((buffer = g_data_input_stream_read_line_utf8 (dstream, &bytes_read,
+ cancellable, &error))
+ == NULL)
{
- /* First address failed, but a later address succeeded. */
- if (sock_error)
+ /* The error is not set if there are no more lines to read. */
+ if (error)
{
- g_debug ("Failure while looking up address: %s",
- sock_error->message);
- g_error_free (sock_error);
+ g_debug ("Error reading line from CDDB header: %s",
+ error->message);
+ g_error_free (error);
}
+
+ return FALSE;
}
- if (error)
+ if (bytes_read > MAX_STRING_LEN)
{
- msg = g_strdup_printf (_("Cannot resolve host ‘%s’: %s"), host,
- error->message);
- gtk_statusbar_push (GTK_STATUSBAR (priv->status_bar),
- priv->status_bar_context, msg);
- Log_Print (LOG_ERROR, "%s", msg);
- g_free (msg);
- g_error_free (error);
- goto err;
+ /* TODO: Although the maximum line length is not specified, this is
+ * probably bogus. */
+ g_warning ("Overly long line in CDDB header");
}
- g_object_unref (enumerator);
- g_object_unref (cancellable);
+ *result = buffer;
- msg = g_strdup_printf (_("Connected to host ‘%s’"), host);
- gtk_statusbar_push (GTK_STATUSBAR (priv->status_bar), priv->status_bar_context,
- msg);
- g_free (msg);
-
- while (gtk_events_pending ())
+ if (result == NULL || (strncmp (*result, "200", 3) != 0
+ && strncmp (*result, "210", 3) != 0
+ && strncmp (*result, "211", 3) != 0))
{
- gtk_main_iteration ();
+ return FALSE;
}
- return socket_id;
-
-err:
- g_object_unref (enumerator);
- g_object_unref (cancellable);
-
- return 0;
-}
-
-/*
- * Close the connection correcponding to the socket_id
- */
-static void
-Cddb_Close_Connection (EtCDDBDialog *self, gint socket_id)
-{
- EtCDDBDialogPrivate *priv;
-
-#ifndef G_OS_WIN32
- shutdown(socket_id,SHUT_RDWR);
-#endif /* !G_OS_WIN32 */
- close(socket_id);
-
- g_return_if_fail (ET_CDDB_DIALOG (self));
-
- priv = et_cddb_dialog_get_instance_private (self);
-
- priv->stop_searching = FALSE;
+ return TRUE;
}
/*
- * Read the result of the request and write it into a file.
- * And return the number of bytes read.
- * - bytes_read=0 => no more data.
- * - bytes_read_total : use to add bytes of severals pages... must be initialized before
+ * log_message_from_request_error:
+ * @message: the message which failed to be sent
+ * @error: the error associated with the failed message
*
- * Server answser is formated like this :
+ * Create an appropriate message for @message based on the status code and
+ * contents of @error.
*
- * HTTP/1.1 200 OK\r\n }
- * Server: Apache/1.3.19 (Unix) PHP/4.0.4pl1\r\n } "Header"
- * Connection: close\r\n }
- * \r\n
- * <html>\n }
- * [...] } "Body"
+ * Returns: a newly-allocated string
*/
-static gint
-Cddb_Write_Result_To_File (EtCDDBDialog *self,
- gint socket_id,
- gulong *bytes_read_total)
+static gchar *
+log_message_from_request_error (SoupMessage *message,
+ GError *error)
{
- EtCDDBDialogPrivate *priv;
- gchar *file_path = NULL;
- FILE *file;
-
- priv = et_cddb_dialog_get_instance_private (self);
-
- /* Cache directory was already created by Log_Print(). */
- file_path = g_build_filename (g_get_user_cache_dir (), PACKAGE_TARNAME,
- CDDB_RESULT_FILE, NULL);
-
- if ((file = g_fopen (file_path, "w+")) != NULL)
- {
- gchar cddb_out[MAX_STRING_LEN+1];
- gint bytes_read = 0;
-
- while (!priv->stop_searching
- // Read data
- && (bytes_read = recv(socket_id,(void *)&cddb_out,MAX_STRING_LEN,0)) > 0 )
- {
- gchar *size_str;
- gchar *msg;
-
-
- // Write to file
- cddb_out[bytes_read] = 0;
- if (fwrite (&cddb_out, bytes_read, 1, file) != 1)
- {
- Log_Print (LOG_ERROR,
- _("Error while writing CDDB results to file ‘%s’"),
- file_path);
- break;
- }
-
- *bytes_read_total += bytes_read;
-
- //g_print("\nLine : %lu : %s\n",bytes_read,cddb_out);
-
- // Display message
- size_str = g_format_size (*bytes_read_total);
- msg = g_strdup_printf(_("Receiving data (%s)…"),size_str);
- gtk_statusbar_push (GTK_STATUSBAR (priv->status_bar),
- priv->status_bar_context, msg);
- g_free(msg);
- g_free(size_str);
- while (gtk_events_pending())
- gtk_main_iteration();
- }
+ SoupURI *uri;
+ gchar *msg;
- fclose(file);
+ uri = soup_message_get_uri (message);
- if (bytes_read < 0)
- {
- Log_Print (LOG_ERROR, _("Error when reading CDDB response ‘%s’"),
- g_strerror(errno));
- return -1; // Error!
- }
-
- } else
+ switch (message->status_code)
{
- Log_Print (LOG_ERROR, _("Cannot create file ‘%s’: %s"), file_path,
- g_strerror(errno));
+ case SOUP_STATUS_CANT_RESOLVE:
+ case SOUP_STATUS_CANT_RESOLVE_PROXY:
+ msg = g_strdup_printf (_("Cannot resolve host: ‘%s’: %s"),
+ soup_uri_get_host (uri), error->message);
+ case SOUP_STATUS_CANT_CONNECT:
+ case SOUP_STATUS_CANT_CONNECT_PROXY:
+ case SOUP_STATUS_TOO_MANY_REDIRECTS:
+ default:
+ msg = g_strdup_printf (_("Cannot connect to host: ‘%s’: %s"),
+ soup_uri_get_host (uri), error->message);
}
- g_free(file_path);
-
- return 0;
-}
-static void
-cddb_track_frame_offset_free (CddbTrackFrameOffset *offset)
-{
- g_slice_free (CddbTrackFrameOffset, offset);
+ return msg;
}
/*
@@ -856,24 +733,21 @@ static gboolean
Cddb_Get_Album_Tracks_List (EtCDDBDialog *self, GtkTreeSelection* selection)
{
EtCDDBDialogPrivate *priv;
- gint socket_id = 0;
CddbAlbum *cddbalbum = NULL;
GList *TrackOffsetList = NULL;
- gchar *cddb_in, *cddb_out = NULL;
+ gchar *uri;
+ gchar *cddb_out = NULL;
gchar *msg, *copy, *valid;
- const gchar CDDB_END_STR[] = ".";
- gchar *proxy_auth;
gchar *cddb_server_name;
guint cddb_server_port;
gchar *cddb_server_cgi_path;
- gboolean proxy_enabled;
- gchar *proxy_hostname;
- guint proxy_port;
- gint bytes_written;
- gulong bytes_read_total = 0;
- FILE *file = NULL;
gboolean read_track_offset = FALSE;
GtkTreeIter row;
+ SoupMessage *message;
+ GCancellable *cancellable;
+ GError *error = NULL;
+ GInputStream *istream;
+ GDataInputStream *dstream;
priv = et_cddb_dialog_get_instance_private (self);
@@ -899,197 +773,100 @@ Cddb_Get_Album_Tracks_List (EtCDDBDialog *self, GtkTreeSelection* selection)
cddb_server_port = cddbalbum->server_port;
cddb_server_cgi_path = cddbalbum->server_cgi_path;
- {
- /* Connection to the server. */
- proxy_enabled = g_settings_get_boolean (MainSettings,
- "cddb-proxy-enabled");
- proxy_hostname = g_settings_get_string (MainSettings,
- "cddb-proxy-hostname");
- proxy_port = g_settings_get_uint (MainSettings, "cddb-proxy-port");
- if ((socket_id = Cddb_Open_Connection (self,
- proxy_enabled
- ? proxy_hostname
- : cddb_server_name,
- proxy_enabled
- ? proxy_port
- : cddb_server_port)) <= 0)
- {
- g_free (proxy_hostname);
- return FALSE;
- }
- if ( strstr(cddb_server_name,"gnudb") != NULL )
- {
- // For gnudb
- // New version of gnudb doesn't use a cddb request, but a http request
- /* HTTP/1.0 to avoid the server returning chunked results.
- * https://bugzilla.gnome.org/show_bug.cgi?id=743812 */
- cddb_in = g_strdup_printf("GET %s%s/gnudb/"
- "%s/%s"
- " HTTP/1.0\r\n"
- "Host: %s:%u\r\n"
- "User-Agent: %s %s\r\n"
- "%s"
- "Connection: close\r\n"
- "\r\n",
- proxy_enabled ? "http://" : "",
- proxy_enabled ? cddb_server_name : "",
- cddbalbum->category,cddbalbum->id,
- cddb_server_name,cddb_server_port,
- PACKAGE_NAME, PACKAGE_VERSION,
- (proxy_auth=Cddb_Format_Proxy_Authentification())
- );
- }else
- {
- // CDDB Request (ex: GET
/~cddb/cddb.cgi?cmd=cddb+read+jazz+0200a401&hello=noname+localhost+EasyTAG+0.31&proto=1 HTTP/1.1\r\nHost:
freedb.freedb.org:80\r\nConnection: close)
- // Without proxy : "GET /~cddb/cddb.cgi?…" but doesn't work with a proxy.
- // With proxy : "GET http://freedb.freedb.org/~cddb/cddb.cgi?…"
- /* HTTP/1.0 to avoid the server returning chunked results.
- * https://bugzilla.gnome.org/show_bug.cgi?id=743812 */
- cddb_in = g_strdup_printf("GET %s%s%s?cmd=cddb+read+"
- "%s+%s"
- "&hello=noname+localhost+%s+%s"
- "&proto=6 HTTP/1.0\r\n"
- "Host: %s:%u\r\n"
- "%s"
- "Connection: close\r\n\r\n",
- proxy_enabled ? "http://" : "",
- proxy_enabled ? cddb_server_name : "",
- cddb_server_cgi_path,
- cddbalbum->category,cddbalbum->id,
- PACKAGE_NAME, PACKAGE_VERSION,
- cddb_server_name,cddb_server_port,
- (proxy_auth=Cddb_Format_Proxy_Authentification())
- );
- }
-
-
- g_free(proxy_auth);
- //g_print("Request Cddb_Get_Album_Tracks_List : '%s'\n", cddb_in);
-
- // Send the request
- gtk_statusbar_push(GTK_STATUSBAR(priv->status_bar),priv->status_bar_context,_("Sending request…"));
- while (gtk_events_pending()) gtk_main_iteration();
- if ( (bytes_written=send(socket_id,cddb_in,strlen(cddb_in)+1,0)) < 0)
- {
- Log_Print (LOG_ERROR, _("Cannot send the request ‘%s’"),
- g_strerror (errno));
- Cddb_Close_Connection (self, socket_id);
- g_free(cddb_in);
- g_free (proxy_hostname);
- return FALSE;
- }
- g_free(cddb_in);
- g_free (proxy_hostname);
+ /* Connection to the server. */
+ if (strstr (cddb_server_name, "gnudb") != NULL)
+ {
+ /* For gnudb. */
+ uri = g_strdup_printf ("http://%s:%u/gnudb/%s/%s", cddb_server_name,
+ cddb_server_port, cddbalbum->category,
+ cddbalbum->id);
+ }
+ else
+ {
+ /* CDDB Request (ex: GET
/~cddb/cddb.cgi?cmd=cddb+read+jazz+0200a401&hello=noname+localhost+EasyTAG+0.31&proto=1 HTTP/1.1\r\nHost:
freedb.freedb.org:80\r\nConnection: close). */
+ uri = g_strdup_printf ("http://%s:%u%s?cmd=cddb+read+%s+%s&hello=noname+localhost+%s+%s&proto=6",
+ cddb_server_name, cddb_server_port,
+ cddb_server_cgi_path, cddbalbum->category,
+ cddbalbum->id, PACKAGE_NAME, PACKAGE_VERSION);
+ }
+ /* Send the request. */
+ gtk_statusbar_push(GTK_STATUSBAR(priv->status_bar),priv->status_bar_context,_("Sending request…"));
+ while (gtk_events_pending()) gtk_main_iteration();
- // Read the answer
- gtk_statusbar_push(GTK_STATUSBAR(priv->status_bar),priv->status_bar_context,_("Receiving data…"));
- while (gtk_events_pending())
- gtk_main_iteration();
+ /* Write result in a file. */
+ message = soup_message_new (SOUP_METHOD_GET, uri);
- /* Write result in a file. */
- if (Cddb_Write_Result_To_File (self, socket_id, &bytes_read_total) < 0)
- {
- msg = g_strdup(_("The server returned a bad response"));
- gtk_statusbar_push(GTK_STATUSBAR(priv->status_bar),priv->status_bar_context,msg);
- Log_Print(LOG_ERROR,"%s",msg);
- g_free(msg);
- gtk_widget_set_sensitive(GTK_WIDGET(priv->stop_search_button),FALSE);
- return FALSE;
- }
+ if (!message)
+ {
+ g_critical ("Invalid CDDB request URI: %s", uri);
+ g_free (uri);
+ return FALSE;
+ }
+ g_free (uri);
- // Parse server answer : Check HTTP Header (freedb or gnudb) and CDDB Header (freedb only)
- file = NULL;
- if ( strstr(cddb_server_name,"gnudb") != NULL )
- {
- // For gnudb (don't check CDDB header)
- if ( Cddb_Read_Http_Header(&file,&cddb_out) <= 0 )
- {
- msg = g_strdup_printf (_("The server returned a bad response ‘%s’"),
- cddb_out);
- gtk_statusbar_push(GTK_STATUSBAR(priv->status_bar),priv->status_bar_context,msg);
- Log_Print(LOG_ERROR,"%s",msg);
- g_free(msg);
- g_free(cddb_out);
- if (file)
- fclose(file);
- return FALSE;
- }
- }else
- {
- /* For freedb. */
- if (Cddb_Read_Http_Header (&file, &cddb_out) <= 0)
- {
- msg = g_strdup_printf (_("The server returned a bad response ‘%s’"),
- cddb_out);
- gtk_statusbar_push (GTK_STATUSBAR (priv->status_bar),
- priv->status_bar_context, msg);
- Log_Print (LOG_ERROR, "%s", msg);
+ cancellable = g_cancellable_new ();
+ istream = soup_session_send (priv->session, message, cancellable,
+ &error);
- g_free (msg);
- g_free (cddb_out);
+ if (!check_message_successful (message))
+ {
+ msg = log_message_from_request_error (message, error);
+ gtk_statusbar_push (GTK_STATUSBAR (priv->status_bar),
+ priv->status_bar_context, msg);
+ Log_Print (LOG_ERROR, "%s", msg);
+ g_free (msg);
+ g_error_free (error);
+ g_object_unref (cancellable);
+ g_object_unref (message);
+ gtk_widget_set_sensitive (GTK_WIDGET (priv->stop_search_button),FALSE);
+ return FALSE;
+ }
- if (file)
- {
- fclose (file);
- }
+ dstream = g_data_input_stream_new (istream);
+ g_object_unref (istream);
+ g_data_input_stream_set_newline_type (dstream,
+ G_DATA_STREAM_NEWLINE_TYPE_ANY);
- return FALSE;
- }
+ /* Parse server answer: Check CDDB Header (freedb only). */
+ if (strstr (cddb_server_name, "gnudb") == NULL)
+ {
+ /* For freedb. */
+ if (!read_cddb_header_line (dstream, cancellable, &cddb_out))
+ {
+ msg = g_strdup_printf (_("The server returned a bad response ‘%s’"),
+ cddb_out);
+ gtk_statusbar_push (GTK_STATUSBAR (priv->status_bar),
+ priv->status_bar_context, msg);
+ Log_Print (LOG_ERROR, "%s", msg);
+ g_object_unref (dstream);
+ g_object_unref (cancellable);
+ g_object_unref (message);
+ g_free (msg);
g_free (cddb_out);
- if (Cddb_Read_Cddb_Header (&file, &cddb_out) <= 0)
- {
- msg = g_strdup_printf (_("The server returned a bad response ‘%s’"),
- cddb_out);
- gtk_statusbar_push (GTK_STATUSBAR (priv->status_bar),
- priv->status_bar_context, msg);
- Log_Print (LOG_ERROR, "%s", msg);
-
- g_free (msg);
- g_free (cddb_out);
-
- if (file)
- {
- fclose (file);
- }
-
- return FALSE;
- }
- }
- g_free(cddb_out);
-
+ return FALSE;
+ }
}
- while (!priv->stop_searching && Cddb_Read_Line (&file, &cddb_out) > 0)
+ g_free (cddb_out);
+
+ while (!priv->stop_searching
+ && read_cddb_result_line (dstream, cancellable, &cddb_out))
{
if (!cddb_out) // Empty line?
continue;
- //g_print("%s\n",cddb_out);
-
- // To avoid the cddb lookups to hang (Patch from Paul Giordano)
- /* It appears that on some systems that cddb lookups continue to attempt
- * to get data from the socket even though the other system has completed
- * sending. The fix adds one check to the loops to see if the actual
- * end of data is in the last block read. In this case, the last line
- * will be a single '.'
- */
- if (strlen (cddb_out) <= 3 && strstr (cddb_out, CDDB_END_STR) != NULL)
- {
- g_free (cddb_out);
- break;
- }
- if ( strstr(cddb_out,"Track frame offsets")!=NULL ) // We read the Track frame offset
+ if (strstr (cddb_out, "Track frame offsets") != NULL) /* We read the Track frame offset. */
{
read_track_offset = TRUE; // The next reads are for the tracks offset
g_free (cddb_out);
continue;
-
- }else if (read_track_offset) // We are reading a track offset? (generates TrackOffsetList)
+ }
+ else if (read_track_offset) /* We are reading a track offset? (generates TrackOffsetList). */
{
if ( strtoul(cddb_out+1,NULL,10)>0 )
{
@@ -1104,9 +881,11 @@ Cddb_Get_Album_Tracks_List (EtCDDBDialog *self, GtkTreeSelection* selection)
g_free (cddb_out);
continue;
- }else if ( strstr(cddb_out,"Disc length: ")!=NULL ) // Length of album (in second)
+ }
+ else if (strstr (cddb_out, "Disc length: ") != NULL) /* Length of album (in second). */
{
cddbalbum->duration = atoi(strchr(cddb_out,':')+1);
+
if (TrackOffsetList) // As it must be the last item, do nothing if no previous data
{
CddbTrackFrameOffset *cddbtrackframeoffset = g_slice_new (CddbTrackFrameOffset);
@@ -1117,7 +896,8 @@ Cddb_Get_Album_Tracks_List (EtCDDBDialog *self, GtkTreeSelection* selection)
g_free (cddb_out);
continue;
- }else if ( strncmp(cddb_out,"DTITLE=",7)==0 ) // "Artist / Album" names
+ }
+ else if (strncmp (cddb_out, "DTITLE=", 7) == 0) /* "Artist / Album" names. */
{
// Note : disc title too long take severals lines. For example :
// DTITLE=Marilyn Manson / The Nobodies (2005 Against All Gods Mix - Korea Tour L
@@ -1240,16 +1020,11 @@ Cddb_Get_Album_Tracks_List (EtCDDBDialog *self, GtkTreeSelection* selection)
g_free(cddb_out);
}
- // Close file opened for reading lines
- if (file)
- {
- fclose(file);
- file = NULL;
- }
-
/* Remote access. */
/* Close connection */
- Cddb_Close_Connection (self, socket_id);
+ g_object_unref (dstream);
+ g_object_unref (cancellable);
+ g_object_unref (message);
/* Set color of the selected row (without reloading the whole list) */
Cddb_Album_List_Set_Row_Appearance (self, &row);
@@ -1496,7 +1271,6 @@ Cddb_Generate_Request_String_With_Fields_And_Categories_Options (EtCDDBDialog *s
return g_string_free (string, FALSE);
}
-
/*
* Site FREEDB.ORG - Manual Search
* Send request (using the HTML search page in freedb.org site) to the CD database
@@ -1506,20 +1280,15 @@ static gboolean
Cddb_Search_Album_List_From_String_Freedb (EtCDDBDialog *self)
{
EtCDDBDialogPrivate *priv;
- gint socket_id;
gchar *string = NULL;
gchar *tmp, *tmp1;
gchar *cddb_in; // For the request to send
gchar *cddb_out = NULL; // Answer received
gchar *cddb_out_tmp;
gchar *msg;
- gchar *proxy_auth = NULL;
gchar *cddb_server_name;
guint cddb_server_port;
gchar *cddb_server_cgi_path;
- gboolean proxy_enabled;
- gchar *proxy_hostname;
- guint proxy_port;
gchar *ptr_cat, *cat_str, *id_str, *art_alb_str;
gchar *art_alb_tmp = NULL;
@@ -1527,11 +1296,14 @@ Cddb_Search_Album_List_From_String_Freedb (EtCDDBDialog *self)
gchar *end_str;
gchar *html_end_str;
gchar buffer[MAX_STRING_LEN+1];
- gint bytes_written;
- gulong bytes_read_total = 0;
- FILE *file = NULL;
gboolean web_search_disabled = FALSE;
+ SoupMessage *message;
+ GCancellable *cancellable;
+ GError *error = NULL;
+ GInputStream *istream;
+ GDataInputStream *dstream;
+
priv = et_cddb_dialog_get_instance_private (self);
gtk_statusbar_push(GTK_STATUSBAR(priv->status_bar),priv->status_bar_context,"");
@@ -1565,70 +1337,38 @@ Cddb_Search_Album_List_From_String_Freedb (EtCDDBDialog *self)
cddb_server_cgi_path = g_settings_get_string (MainSettings,
"cddb-manual-search-path");
- /* Connection to the server */
- proxy_enabled = g_settings_get_boolean (MainSettings,
- "cddb-proxy-enabled");
- proxy_hostname = g_settings_get_string (MainSettings,
- "cddb-proxy-hostname");
- proxy_port = g_settings_get_uint (MainSettings, "cddb-proxy-port");
- if ((socket_id = Cddb_Open_Connection (self,
- proxy_enabled
- ? proxy_hostname
- : cddb_server_name,
- proxy_enabled
- ? proxy_port
- : cddb_server_port)) <= 0)
- {
- g_free (string);
- g_free (cddb_server_name);
- g_free (cddb_server_cgi_path);
- g_free (proxy_hostname);
- return FALSE;
- }
-
/* Build request */
- //cddb_in = g_strdup_printf("GET http://www.freedb.org/freedb_search.php?" // In this case, problem with
squid cache...
- cddb_in = g_strdup_printf("GET %s%s/freedb_search.php?"
- "words=%s"
- "%s"
- "&grouping=none"
- " HTTP/1.1\r\n"
- "Host: %s:%u\r\n"
- "User-Agent: %s %s\r\n"
- "%s"
- "Connection: close\r\n"
- "\r\n",
- proxy_enabled ? "http://" : "",
- proxy_enabled ? cddb_server_name : "",
- string,
- (tmp = Cddb_Generate_Request_String_With_Fields_And_Categories_Options (self)),
- cddb_server_name,cddb_server_port,
- PACKAGE_NAME, PACKAGE_VERSION,
- (proxy_auth=Cddb_Format_Proxy_Authentification())
- );
+ cddb_in = g_strdup_printf ("http://%s:%u/freedb_search.php?words=%s%s&grouping=none",
+ cddb_server_name,
+ cddb_server_port,
+ string,
+ (tmp = Cddb_Generate_Request_String_With_Fields_And_Categories_Options
(self)));
+
+ message = soup_message_new (SOUP_METHOD_GET, cddb_in);
g_free(string);
g_free(tmp);
- g_free(proxy_auth);
+ g_free (cddb_in);
//g_print("Request Cddb_Search_Album_List_From_String_Freedb : '%s'\n", cddb_in);
- // Send the request
+ /* Send the request. */
+ cancellable = g_cancellable_new ();
+ istream = soup_session_send (priv->session, message, cancellable, &error);
gtk_statusbar_push(GTK_STATUSBAR(priv->status_bar),priv->status_bar_context,_("Sending request…"));
while (gtk_events_pending()) gtk_main_iteration();
- if ( (bytes_written=send(socket_id,cddb_in,strlen(cddb_in)+1,0)) < 0)
+
+ if (!check_message_successful (message))
{
- Log_Print (LOG_ERROR, _("Cannot send the request ‘%s’"),
- g_strerror (errno));
- Cddb_Close_Connection (self, socket_id);
- g_free(cddb_in);
- g_free(string);
+ msg = log_message_from_request_error (message, error);
+ gtk_statusbar_push (GTK_STATUSBAR (priv->status_bar),
+ priv->status_bar_context, msg);
+ Log_Print (LOG_ERROR, "%s", msg);
+ g_error_free (error);
+ g_object_unref (message);
g_free(cddb_server_name);
g_free(cddb_server_cgi_path);
- g_free (proxy_hostname);
return FALSE;
}
- g_free(cddb_in);
-
/* Delete previous album list. */
cddb_album_model_clear (self);
@@ -1648,37 +1388,11 @@ Cddb_Search_Album_List_From_String_Freedb (EtCDDBDialog *self)
while (gtk_events_pending())
gtk_main_iteration();
- /* Write result in a file. */
- if (Cddb_Write_Result_To_File (self, socket_id, &bytes_read_total) < 0)
- {
- msg = g_strdup(_("The server returned a bad response"));
- gtk_statusbar_push(GTK_STATUSBAR(priv->status_bar),priv->status_bar_context,msg);
- Log_Print(LOG_ERROR,"%s",msg);
- g_free(msg);
- g_free(cddb_server_name);
- g_free(cddb_server_cgi_path);
- gtk_widget_set_sensitive(GTK_WIDGET(priv->stop_search_button),FALSE);
- return FALSE;
- }
-
- // Parse server answer : Check returned code in the first line
- if (Cddb_Read_Http_Header(&file,&cddb_out) <= 0 || !cddb_out) // Order is important!
- {
- msg = g_strdup_printf (_("The server returned a bad response ‘%s’"),
- cddb_out);
- gtk_statusbar_push(GTK_STATUSBAR(priv->status_bar),priv->status_bar_context,msg);
- Log_Print(LOG_ERROR,"%s",msg);
- g_free(msg);
- g_free(cddb_out);
- g_free(cddb_server_name);
- g_free(cddb_server_cgi_path);
- g_free (proxy_hostname);
- gtk_widget_set_sensitive(GTK_WIDGET(priv->stop_search_button),FALSE);
- if (file)
- fclose(file);
- return FALSE;
- }
- g_free(cddb_out);
+ /* Parse server answer : Check returned code in the first line. */
+ dstream = g_data_input_stream_new (istream);
+ g_object_unref (istream);
+ g_data_input_stream_set_newline_type (dstream,
+ G_DATA_STREAM_NEWLINE_TYPE_ANY);
// Read other lines, and get list of matching albums
// Composition of a line :
@@ -1689,7 +1403,9 @@ Cddb_Search_Album_List_From_String_Freedb (EtCDDBDialog *self)
art_alb_str = g_strdup("\">");
end_str = g_strdup("</a>"); //"</a><br>");
html_end_str = g_strdup("</body>"); // To avoid the cddb lookups to hang
- while (!priv->stop_searching && Cddb_Read_Line (&file, &cddb_out) > 0)
+ while (!priv->stop_searching && read_cddb_result_line (dstream,
+ cancellable,
+ &cddb_out))
{
cddb_out_tmp = cddb_out;
//g_print("%s\n",cddb_out); // To print received data
@@ -1796,19 +1512,13 @@ Cddb_Search_Album_List_From_String_Freedb (EtCDDBDialog *self)
g_free(cat_str); g_free(id_str); g_free(art_alb_str); g_free(end_str); g_free(html_end_str);
g_free(cddb_server_name);
g_free(cddb_server_cgi_path);
- g_free (proxy_hostname);
-
- // Close file opened for reading lines
- if (file)
- {
- fclose(file);
- file = NULL;
- }
gtk_widget_set_sensitive(GTK_WIDGET(priv->stop_search_button),FALSE);
/* Close connection. */
- Cddb_Close_Connection (self, socket_id);
+ g_object_unref (dstream);
+ g_object_unref (cancellable);
+ g_object_unref (message);
if (web_search_disabled)
msg = g_strdup_printf(_("Sorry, the web-based search is currently not available"));
@@ -1838,33 +1548,23 @@ static gboolean
Cddb_Search_Album_List_From_String_Gnudb (EtCDDBDialog *self)
{
EtCDDBDialogPrivate *priv;
- gint socket_id;
gchar *string = NULL;
gchar *tmp, *tmp1;
- gchar *cddb_in; // For the request to send
gchar *cddb_out = NULL; // Answer received
gchar *cddb_out_tmp;
gchar *msg;
- gchar *proxy_auth = NULL;
gchar *cddb_server_name;
guint cddb_server_port;
gchar *cddb_server_cgi_path;
- gboolean proxy_enabled;
- gchar *proxy_hostname;
- guint proxy_port;
gchar *ptr_cat, *cat_str, *art_alb_str;
gchar *end_str;
gchar *ptr_sraf, *sraf_str, *sraf_end_str;
gchar *html_end_str;
gchar buffer[MAX_STRING_LEN+1];
- gint bytes_written;
- gulong bytes_read_total = 0;
- FILE *file;
gint num_albums = 0;
gint total_num_albums = 0;
- gchar *next_page = NULL;
gint next_page_cpt = 0;
gboolean next_page_found;
@@ -1908,6 +1608,14 @@ Cddb_Search_Album_List_From_String_Gnudb (EtCDDBDialog *self)
// Do a loop to load all the pages of results
do
{
+ gchar *uri;
+ SoupMessage *message;
+ GCancellable *cancellable;
+ GError *error = NULL;
+ GInputStream *istream;
+ GDataInputStream *dstream;
+ gchar *next_page;
+
cddb_server_name = g_settings_get_string (MainSettings,
"cddb-manual-search-hostname");
cddb_server_port = g_settings_get_uint (MainSettings,
@@ -1915,67 +1623,49 @@ Cddb_Search_Album_List_From_String_Gnudb (EtCDDBDialog *self)
cddb_server_cgi_path = g_settings_get_string (MainSettings,
"cddb-manual-search-path");
- /* Connection to the server */
- proxy_enabled = g_settings_get_boolean (MainSettings,
- "cddb-proxy-enabled");
- proxy_hostname = g_settings_get_string (MainSettings,
- "cddb-proxy-hostname");
- proxy_port = g_settings_get_uint (MainSettings, "cddb-proxy-port");
- if ((socket_id = Cddb_Open_Connection (self,
- proxy_enabled ? proxy_hostname
- : cddb_server_name,
- proxy_enabled ? proxy_port
- : cddb_server_port)) <= 0)
+ /* Build request */
+ uri = g_strdup_printf ("http://%s:%u/search/%s?page=%d",
+ cddb_server_name, cddb_server_port, string,
+ next_page_cpt);
+ next_page_found = FALSE;
+
+ message = soup_message_new (SOUP_METHOD_GET, uri);
+
+ if (!message)
{
- g_free(string);
- g_free(cddb_server_name);
- g_free(cddb_server_cgi_path);
- g_free (proxy_hostname);
- gtk_widget_set_sensitive(GTK_WIDGET(priv->stop_search_button),FALSE);
+ g_critical ("Invalid CDDB_request URI: %s", uri);
+ g_free (uri);
return FALSE;
}
+ g_free (uri);
- /* Build request */
- cddb_in = g_strdup_printf("GET %s%s/search/"
- "%s"
- "?page=%d"
- " HTTP/1.1\r\n"
- "Host: %s:%u\r\n"
- "User-Agent: %s %s\r\n"
- "%s"
- "Connection: close\r\n"
- "\r\n",
- proxy_enabled ? "http://" : "",
- proxy_enabled ? cddb_server_name : "",
- string,
- next_page_cpt,
- cddb_server_name,cddb_server_port,
- PACKAGE_NAME, PACKAGE_VERSION,
- (proxy_auth=Cddb_Format_Proxy_Authentification())
- );
- next_page_found = FALSE;
- g_free(proxy_auth);
- //g_print("Request Cddb_Search_Album_List_From_String_Gnudb : '%s'\n", cddb_in);
-
- // Send the request
- gtk_statusbar_push(GTK_STATUSBAR(priv->status_bar),priv->status_bar_context,_("Sending request…"));
+ /* Send the request. */
+ gtk_statusbar_push (GTK_STATUSBAR (priv->status_bar),
+ priv->status_bar_context, _("Sending request…"));
while (gtk_events_pending()) gtk_main_iteration();
- if ( (bytes_written=send(socket_id,cddb_in,strlen(cddb_in)+1,0)) < 0)
+
+ cancellable = g_cancellable_new ();
+ istream = soup_session_send (priv->session, message, cancellable,
+ &error);
+
+ if (!check_message_successful (message))
{
- Log_Print (LOG_ERROR, _("Cannot send the request ‘%s’"),
- g_strerror (errno));
- Cddb_Close_Connection (self, socket_id);
- g_free (cddb_in);
+ msg = log_message_from_request_error (message, error);
+ gtk_statusbar_push (GTK_STATUSBAR (priv->status_bar),
+ priv->status_bar_context, msg);
+ Log_Print (LOG_ERROR, "%s", msg);
+ g_free (msg);
+ g_object_unref (cancellable);
+ g_object_unref (message);
+ g_error_free (error);
g_free (string);
g_free (cddb_server_name);
g_free (cddb_server_cgi_path);
- g_free (proxy_hostname);
gtk_widget_set_sensitive (GTK_WIDGET (priv->stop_search_button),
FALSE);
return FALSE;
}
- g_free(cddb_in);
/*
@@ -1991,44 +1681,33 @@ Cddb_Search_Album_List_From_String_Gnudb (EtCDDBDialog *self)
while (gtk_events_pending())
gtk_main_iteration();
- /* Write result in a file. */
- if (Cddb_Write_Result_To_File (self, socket_id, &bytes_read_total) < 0)
- {
- msg = g_strdup(_("The server returned a bad response"));
- gtk_statusbar_push(GTK_STATUSBAR(priv->status_bar),priv->status_bar_context,msg);
- Log_Print(LOG_ERROR,"%s",msg);
- g_free(msg);
- g_free(string);
- g_free(cddb_server_name);
- g_free(cddb_server_cgi_path);
- g_free (proxy_hostname);
- gtk_widget_set_sensitive(GTK_WIDGET(priv->stop_search_button),FALSE);
- return FALSE;
- }
+ /* Parse server answer : Check returned code in the first line. */
+ dstream = g_data_input_stream_new (istream);
+ g_object_unref (istream);
+ g_data_input_stream_set_newline_type (dstream,
+ G_DATA_STREAM_NEWLINE_TYPE_ANY);
- // Parse server answer : Check returned code in the first line
- file = NULL;
- if (Cddb_Read_Http_Header(&file,&cddb_out) <= 0 || !cddb_out) // Order is important!
+ if (!read_cddb_result_line (dstream, cancellable, &cddb_out)
+ || !cddb_out)
{
- msg = g_strdup_printf (_("The server returned a bad response ‘%s’"),
- cddb_out);
- gtk_statusbar_push(GTK_STATUSBAR(priv->status_bar),priv->status_bar_context,msg);
- Log_Print(LOG_ERROR,"%s",msg);
+ msg = g_strdup (_("The server returned a bad response"));
+ gtk_statusbar_push (GTK_STATUSBAR (priv->status_bar),
+ priv->status_bar_context, msg);
+ Log_Print (LOG_ERROR, "%s", msg);
+ g_object_unref (dstream);
+ g_object_unref (cancellable);
+ g_object_unref (message);
g_free(msg);
g_free(cddb_out);
g_free(string);
g_free(cddb_server_name);
g_free(cddb_server_cgi_path);
- g_free (proxy_hostname);
gtk_widget_set_sensitive(GTK_WIDGET(priv->stop_search_button),FALSE);
- if (file)
- fclose(file);
return FALSE;
}
g_free(cddb_out);
// The next page if exists will contains this url :
- g_free(next_page);
next_page = g_strdup_printf("?page=%d",++next_page_cpt);
// Read other lines, and get list of matching albums
@@ -2044,7 +1723,9 @@ Cddb_Search_Album_List_From_String_Gnudb (EtCDDBDialog *self)
sraf_str = g_strdup("<h2>Search Results, ");
sraf_end_str = g_strdup(" albums found:</h2>");
- while (!priv->stop_searching && Cddb_Read_Line (&file, &cddb_out) > 0)
+ while (!priv->stop_searching && read_cddb_result_line (dstream,
+ cancellable,
+ &cddb_out))
{
cddb_out_tmp = cddb_out;
//g_print("%s\n",cddb_out); // To print received data
@@ -2159,22 +1840,17 @@ Cddb_Search_Album_List_From_String_Gnudb (EtCDDBDialog *self)
g_free(cddb_out);
}
+
g_free(cat_str); g_free(art_alb_str); g_free(end_str); g_free(html_end_str);
g_free(sraf_str);g_free(sraf_end_str);
g_free(cddb_server_name);
g_free(cddb_server_cgi_path);
- g_free (proxy_hostname);
-
- // Close file opened for reading lines
- if (file)
- {
- fclose(file);
- file = NULL;
- }
+ g_free (next_page);
/* Close connection. */
- Cddb_Close_Connection (self, socket_id);
-
+ g_object_unref (dstream);
+ g_object_unref (cancellable);
+ g_object_unref (message);
} while (next_page_found);
g_free(string);
@@ -2871,6 +2547,13 @@ create_cddb_dialog (EtCDDBDialog *self)
g_signal_emit_by_name (priv->search_entry, "changed");
priv->stop_searching = FALSE;
+
+ /* The User-Agent header is not used by the CDDB protocol over HTTP, but it
+ * is still good practice to set it appropriately. */
+ /* FIXME: Enable a SoupLogger with g_parse_debug_string(). */
+ priv->session = soup_session_new_with_options (SOUP_SESSION_USER_AGENT,
+ PACKAGE_NAME " " PACKAGE_VERSION,
+ NULL);
}
/*
@@ -2924,153 +2607,6 @@ Cddb_Track_List_Sort_Func (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b,
return ret;
}
-/*
- * Read one line (of the connection) into cddb_out.
- * return : -1 on error
- * 0 if no more line to read (EOF)
- * 1 if more lines to read
- *
- * Server answser is formated like this :
- *
- * HTTP/1.1 200 OK\r\n }
- * Server: Apache/1.3.19 (Unix) PHP/4.0.4pl1\r\n } "Header"
- * Connection: close\r\n }
- * \r\n
- * <html>\n }
- * [...] } "Body"
- */
-static gint
-Cddb_Read_Line (FILE **file, gchar **cddb_out)
-{
- gchar buffer[MAX_STRING_LEN];
- gchar *result;
- size_t l;
-
- if (*file == NULL)
- {
- // Open the file for reading the first time
- gchar *file_path;
-
- file_path = g_build_filename (g_get_user_cache_dir (), PACKAGE_TARNAME,
- CDDB_RESULT_FILE, NULL);
-
- if ((*file = g_fopen (file_path, "r")) == 0)
- {
- Log_Print (LOG_ERROR, _("Cannot open file ‘%s’: %s"), file_path,
- g_strerror (errno));
- g_free (file_path);
- return -1; // Error!
- }
- g_free (file_path);
- }
-
- result = fgets(buffer,sizeof(buffer),*file);
- if (result != NULL)
- {
- l = strlen(buffer);
- if (l > 0 && buffer[l-1] == '\n')
- buffer[l-1] = '\0';
-
- // Many '\r' chars may be present
- while ((l = strlen(buffer)) > 0 && buffer[l-1] == '\r')
- buffer[l-1] = '\0';
-
- *cddb_out = g_strdup(buffer);
- }else
- {
- // On error, or EOF
- fclose(*file);
- *file = NULL;
-
- //*cddb_out = NULL;
- *cddb_out = g_strdup(""); // To avoid a crash
-
- return 0;
- }
-
- //g_print("Line read: %s\n",*cddb_out);
- return 1;
-}
-
-
-/*
- * Read HTTP header data : from "HTTP/1.1 200 OK" to the blank line
- */
-static gint
-Cddb_Read_Http_Header (FILE **file, gchar **cddb_out)
-{
-
- // The 'file' is opened (if no error) in this function
- if ( Cddb_Read_Line(file,cddb_out) < 0 )
- return -1; // Error!
-
- // First line must be : "HTTP/1.1 200 OK"
- if ( !*cddb_out || strncmp("HTTP",*cddb_out,4)!=0 || strstr(*cddb_out,"200 OK")==NULL )
- return -1;
-
- /* Read until end of the HTTP header up to the next blank line. */
- do
- {
- g_free (*cddb_out);
- }
- while (Cddb_Read_Line (file, cddb_out) > 0 && !et_str_empty (*cddb_out));
-
- //g_print("Http Header : %s\n",*cddb_out);
- return 1;
-}
-
-/*
- * Read CDDB header data when requesting a file (cmd=cddb+read+<album genre>+<discid>)
- * Must be read after the HTTP header :
- *
- * HTTP/1.1 200 OK
- * Date: Sun, 26 Nov 2006 22:37:13 GMT
- * Server: Apache/2.0.54 (Debian GNU/Linux) mod_python/3.1.3 Python/2.3.5 PHP/4.3.10-16 proxy_html/2.4
mod_perl/1.999.21 Perl/v5.8.4
- * Expires: Sun Nov 26 23:37:14 2006
- * Content-Length: 1013
- * Connection: close
- * Content-Type: text/plain; charset=UTF-8
- *
- * 210 newage 710ed208 CD database entry follows (until terminating `.')
- *
- * Cddb Header is the line like this :
- * 210 newage 710ed208 CD database entry follows (until terminating `.')
- */
-static gint
-Cddb_Read_Cddb_Header (FILE **file, gchar **cddb_out)
-{
- if ( Cddb_Read_Line(file,cddb_out) < 0 )
- return -1; // Error!
-
- /* Some requests receive some strange data (arbitrary: less than 10 chars.)
- * at the beginning (2 or 3 characters)... So we read one line more... */
- if (!*cddb_out || strlen (*cddb_out) < 10)
- {
- g_free (*cddb_out);
-
- if (Cddb_Read_Line (file, cddb_out) < 0)
- {
- return -1; /* Error! */
- }
- }
-
- //g_print("Cddb Header : %s\n",*cddb_out);
-
- // Read the line
- // 200 - exact match
- // 210 - multiple exact matches
- // 211 - inexact match
- if ( *cddb_out == NULL
- || (strncmp(*cddb_out,"200",3)!=0
- && strncmp(*cddb_out,"210",3)!=0
- && strncmp(*cddb_out,"211",3)!=0) )
- return -1;
-
- return 1;
-}
-
-
-
static gboolean
Cddb_Free_Track_Album_List (GList *track_list)
{
@@ -3104,26 +2640,15 @@ gboolean
et_cddb_dialog_search_from_selection (EtCDDBDialog *self)
{
EtCDDBDialogPrivate *priv;
- gint socket_id;
- gint bytes_written;
- gulong bytes_read_total = 0;
- FILE *file = NULL;
- gchar *cddb_in = NULL; /* For the request to send. */
gchar *cddb_out = NULL; /* Answer received */
- gchar *cddb_out_tmp;
gchar *msg;
- gchar *proxy_auth;
gchar *cddb_server_name;
guint cddb_server_port;
gchar *cddb_server_cgi_path;
- gboolean proxy_enabled;
- gchar *proxy_hostname;
- guint proxy_port;
gint server_try = 0;
GString *query_string;
gchar *cddb_discid;
- const gchar CDDB_END_STR[] = ".";
guint total_frames = 150; /* First offset is (almost) always 150 */
guint disc_length = 2; /* and 2s elapsed before first track */
@@ -3211,6 +2736,7 @@ et_cddb_dialog_search_from_selection (EtCDDBDialog *self)
file_iterlist = g_list_reverse (file_iterlist);
+ /* FIXME: Split this out to a separate function. */
for (l = file_iterlist; l != NULL; l = g_list_next (l))
{
ET_File *etfile;
@@ -3267,7 +2793,15 @@ et_cddb_dialog_search_from_selection (EtCDDBDialog *self)
*/
while (server_try < 2)
{
+ gchar *uri;
+ SoupMessage *message;
+ GError *error = NULL;
+ GCancellable *cancellable;
+ GInputStream *istream;
+ GDataInputStream *dstream;
+
server_try++;
+
if (server_try == 1)
{
/* 1st try. */
@@ -3290,59 +2824,31 @@ et_cddb_dialog_search_from_selection (EtCDDBDialog *self)
"cddb-automatic-search-path2");
}
- // Check values
- if (!cddb_server_name || strcmp(cddb_server_name,"")==0)
+ /* Check values. */
+ if (et_str_empty (cddb_server_name))
+ {
+ g_free (cddb_server_name);
+ g_free (cddb_server_cgi_path);
continue;
+ }
- /* Connection to the server. */
- proxy_enabled = g_settings_get_boolean (MainSettings,
- "cddb-proxy-enabled");
- proxy_hostname = g_settings_get_string (MainSettings,
- "cddb-proxy-hostname");
- proxy_port = g_settings_get_uint (MainSettings, "cddb-proxy-port");
-
- if ((socket_id = Cddb_Open_Connection (self,
- proxy_enabled
- ? proxy_hostname
- : cddb_server_name,
- proxy_enabled
- ? proxy_port
- : cddb_server_port)) <= 0)
+ // CDDB Request (ex: GET
/~cddb/cddb.cgi?cmd=cddb+query+0800ac01+1++150+172&hello=noname+localhost+EasyTAG+0.31&proto=1
HTTP/1.1\r\nHost: freedb.freedb.org:80\r\nConnection: close)
+ // proto=1 => ISO-8859-1 - proto=6 => UTF-8
+ uri = g_strdup_printf
("http://%s:%u%s?cmd=cddb+query+%s+%u+%s+%u&hello=noname+localhost+%s+%s&proto=6",
+ cddb_server_name, cddb_server_port,
+ cddb_server_cgi_path, cddb_discid,
+ num_tracks, query_string->str, disc_length,
+ PACKAGE_NAME, PACKAGE_VERSION);
+ message = soup_message_new (SOUP_METHOD_GET, uri);
+
+ if (!message)
{
- g_free(cddb_in);
- g_free(cddb_server_name);
- g_free(cddb_server_cgi_path);
- g_free (proxy_hostname);
- g_string_free (query_string, TRUE);
- g_free (cddb_discid);
+ g_critical ("Invalid CDDB request URI: %s", uri);
+ g_free (uri);
return FALSE;
}
- // CDDB Request (ex: GET
/~cddb/cddb.cgi?cmd=cddb+query+0800ac01+1++150+172&hello=noname+localhost+EasyTAG+0.31&proto=1
HTTP/1.1\r\nHost: freedb.freedb.org:80\r\nConnection: close)
- // Without proxy : "GET /~cddb/cddb.cgi?…" but doesn't work with a proxy.
- // With proxy : "GET http://freedb.freedb.org/~cddb/cddb.cgi?…"
- // proto=1 => ISO-8859-1 - proto=6 => UTF-8
- cddb_in = g_strdup_printf("GET %s%s%s?cmd=cddb+query+"
- "%s+"
- "%u+%s+"
- "%u"
- "&hello=noname+localhost+%s+%s"
- "&proto=6 HTTP/1.1\r\n"
- "Host: %s:%u\r\n"
- "%s"
- "Connection: close\r\n\r\n",
- proxy_enabled ? "http://" : "",
- proxy_enabled ? cddb_server_name : "",
- cddb_server_cgi_path,
- cddb_discid,
- num_tracks, query_string->str,
- disc_length,
- PACKAGE_NAME, PACKAGE_VERSION,
- cddb_server_name,cddb_server_port,
- (proxy_auth=Cddb_Format_Proxy_Authentification())
- );
- g_free (proxy_auth);
- //g_print("Request Cddb_Search_Album_From_Selected_Files : '%s'\n", cddb_in);
+ g_free (uri);
msg = g_strdup_printf (_("Sending request (disc ID: %s, #tracks: %u, Disc length: %u)…"),
cddb_discid, num_tracks, disc_length);
@@ -3352,67 +2858,34 @@ et_cddb_dialog_search_from_selection (EtCDDBDialog *self)
while (gtk_events_pending())
gtk_main_iteration();
- if ( (bytes_written=send(socket_id,cddb_in,strlen(cddb_in)+1,0)) < 0)
+ cancellable = g_cancellable_new ();
+ istream = soup_session_send (priv->session, message, cancellable,
+ &error);
+
+ if (!check_message_successful (message))
{
- Log_Print (LOG_ERROR, _("Cannot send the request ‘%s’"),
- g_strerror (errno));
- Cddb_Close_Connection (self, socket_id);
- g_free (cddb_in);
+ msg = log_message_from_request_error (message, error);
+ gtk_statusbar_push (GTK_STATUSBAR (priv->status_bar),
+ priv->status_bar_context, msg);
+ Log_Print (LOG_ERROR, "%s", msg);
+ g_free (msg);
+ g_error_free (error);
g_free (cddb_server_name);
g_free (cddb_server_cgi_path);
- g_free (proxy_hostname);
g_string_free (query_string, TRUE);
g_free (cddb_discid);
+ g_object_unref (cancellable);
+ g_object_unref (message);
+ gtk_widget_set_sensitive (GTK_WIDGET (priv->stop_search_button),
+ FALSE);
return FALSE;
}
- g_free(cddb_in);
- cddb_in = NULL;
-
-
- /*
- * Read the answer
- */
- gtk_statusbar_push(GTK_STATUSBAR(priv->status_bar),priv->status_bar_context,_("Receiving
data…"));
- while (gtk_events_pending())
- gtk_main_iteration();
- /* Write result in a file. */
- if (Cddb_Write_Result_To_File (self, socket_id, &bytes_read_total) < 0)
- {
- msg = g_strdup(_("The server returned a bad response"));
- gtk_statusbar_push(GTK_STATUSBAR(priv->status_bar),priv->status_bar_context,msg);
- Log_Print(LOG_ERROR,"%s",msg);
- g_free(msg);
- g_free(cddb_server_name);
- g_free(cddb_server_cgi_path);
- g_free (proxy_hostname);
- g_string_free (query_string, TRUE);
- g_free (cddb_discid);
- gtk_widget_set_sensitive(GTK_WIDGET(priv->stop_search_button),FALSE);
- return FALSE;
- }
-
- // Parse server answer : Check returned code in the first line
- file = NULL;
- if (Cddb_Read_Http_Header(&file,&cddb_out) <= 0 || !cddb_out) // Order is important!
- {
- msg = g_strdup_printf (_("The server returned a bad response ‘%s’"),
- cddb_out);
- gtk_statusbar_push(GTK_STATUSBAR(priv->status_bar),priv->status_bar_context,msg);
- Log_Print(LOG_ERROR,"%s",msg);
- g_free(msg);
- g_free(cddb_out);
- g_free(cddb_server_name);
- g_free(cddb_server_cgi_path);
- g_free (proxy_hostname);
- g_string_free (query_string, TRUE);
- g_free (cddb_discid);
- gtk_widget_set_sensitive(GTK_WIDGET(priv->stop_search_button),FALSE);
- if (file)
- fclose(file);
- return FALSE;
- }
- g_free(cddb_out);
+ /* Read the answer. */
+ dstream = g_data_input_stream_new (istream);
+ g_object_unref (istream);
+ g_data_input_stream_set_newline_type (dstream,
+ G_DATA_STREAM_NEWLINE_TYPE_ANY);
/*
* Format :
@@ -3425,36 +2898,27 @@ et_cddb_dialog_search_from_selection (EtCDDBDialog *self)
* 200 jazz 7e0a100a Pink Floyd / Dark Side of the Moon
*/
while (!priv->stop_searching
- && Cddb_Read_Line (&file, &cddb_out) > 0)
+ && read_cddb_result_line (dstream, cancellable, &cddb_out))
{
- cddb_out_tmp = cddb_out;
- //g_print("%s\n",cddb_out);
-
- // To avoid the cddb lookups to hang (Patch from Paul Giordano)
- /* It appears that on some systems that cddb lookups continue to attempt
- * to get data from the socket even though the other system has completed
- * sending. The fix adds one check to the loops to see if the actual
- * end of data is in the last block read. In this case, the last line
- * will be a single '.'
- */
- if (cddb_out_tmp && strlen (cddb_out_tmp) <= 3
- && strstr (cddb_out_tmp, CDDB_END_STR) != NULL)
+ const gchar *cddb_out_tmp = cddb_out;
+
+ if (!cddb_out_tmp)
{
- g_free (cddb_out);
- cddb_out = NULL;
break;
}
- // Compatibility for the MusicBrainz CddbGateway
- if ( cddb_out_tmp && strlen(cddb_out_tmp)>3
- && (strncmp(cddb_out_tmp,"200",3)==0
- || strncmp(cddb_out_tmp,"210",3)==0
- || strncmp(cddb_out_tmp,"211",3)==0) )
- cddb_out_tmp = cddb_out_tmp + 4;
+ /* Compatibility for the MusicBrainz CddbGateway. */
+ if (strlen (cddb_out_tmp) > 3
+ && (strncmp (cddb_out_tmp, "200", 3) == 0
+ || strncmp (cddb_out_tmp, "210", 3) == 0
+ || strncmp (cddb_out_tmp, "211", 3) == 0))
+ {
+ cddb_out_tmp += 4;
+ }
// Reading of lines with albums (skiping return code lines :
// "211 Found inexact matches, list follows (until terminating `.')" )
- if (cddb_out != NULL && strstr(cddb_out_tmp,"/") != NULL)
+ if (strstr (cddb_out_tmp, "/") != NULL)
{
gchar* ptr;
CddbAlbum *cddbalbum;
@@ -3491,22 +2955,17 @@ et_cddb_dialog_search_from_selection (EtCDDBDialog *self)
priv->album_list = g_list_append(priv->album_list,cddbalbum);
}
+ /* There is no need to explicitly check for the terminating
+ * '.' */
g_free(cddb_out);
}
+
g_free (cddb_out);
g_free(cddb_server_name);
g_free(cddb_server_cgi_path);
- g_free (proxy_hostname);
-
- /* Close file opened for reading lines. */
- if (file)
- {
- fclose(file);
- file = NULL;
- }
-
- /* Close connection. */
- Cddb_Close_Connection (self, socket_id);
+ g_object_unref (dstream);
+ g_object_unref (cancellable);
+ g_object_unref (message);
}
}
@@ -3566,40 +3025,6 @@ Cddb_Get_Pixbuf_From_Server_Name (const gchar *server_name)
return NULL;
}
-
-static gchar *
-Cddb_Format_Proxy_Authentification (void)
-{
- gchar *username;
- gchar *password;
- gchar *ret;
-
- username = g_settings_get_string (MainSettings, "cddb-proxy-username");
- password = g_settings_get_string (MainSettings, "cddb-proxy-password");
-
- if (g_settings_get_boolean (MainSettings, "cddb-proxy-enabled")
- && username && *username )
- {
- const gchar *tempstr;
- gchar *str_encoded;
-
- tempstr = g_strconcat (username, ":", password, NULL);
- str_encoded = g_base64_encode((const guchar *)tempstr, strlen(tempstr));
-
- ret = g_strdup_printf("Proxy-authorization: Basic %s\r\n", str_encoded);
- g_free (str_encoded);
- }
- else
- {
- ret = g_strdup ("");
- }
-
- g_free (username);
- g_free (password);
-
- return ret;
-}
-
static void
et_cddb_dialog_finalize (GObject *object)
{
@@ -3614,6 +3039,8 @@ et_cddb_dialog_finalize (GObject *object)
Cddb_Free_Album_List (self);
}
+ g_object_unref (priv->session);
+
G_OBJECT_CLASS (et_cddb_dialog_parent_class)->finalize (object);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]