[totem-pl-parser/gnome-2-26] Backport path resolution function from master



commit af3624664a4542a3a9661c9338eda6cc6e286e13
Author: Bastien Nocera <hadess hadess net>
Date:   Wed Apr 22 11:17:36 2009 +0100

    Backport path resolution function from master
    
    2009-04-22  Bastien Nocera  <hadess hadess net>
    
    	* plparse/totem-pl-parser-private.h:
    	* plparse/totem-pl-parser-smil.c (parse_smil_entry):
    	* plparse/totem-pl-parser-wm.c (parse_asx_entry),
    	(parse_asx_entryref):
    	* plparse/totem-pl-parser-xspf.c (parse_xspf_track):
    	* plparse/totem-pl-parser.c (relative_uri_remove_query),
    	(is_probably_dir), (totem_pl_parser_resolve_uri):
    	Backport path resolution function from master
    	fixes parsing of relative URIs in playlists (Closes: #577547)
---
 ChangeLog                         |   12 +++
 plparse/totem-pl-parser-private.h |    2 +
 plparse/totem-pl-parser-smil.c    |    8 +-
 plparse/totem-pl-parser-wm.c      |   17 ++---
 plparse/totem-pl-parser-xspf.c    |    9 ++-
 plparse/totem-pl-parser.c         |  137 +++++++++++++++++++++++++++++++++++++
 6 files changed, 168 insertions(+), 17 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 3cb7ab9..152ddc2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2009-04-22  Bastien Nocera  <hadess hadess net>
+
+	* plparse/totem-pl-parser-private.h:
+	* plparse/totem-pl-parser-smil.c (parse_smil_entry):
+	* plparse/totem-pl-parser-wm.c (parse_asx_entry),
+	(parse_asx_entryref):
+	* plparse/totem-pl-parser-xspf.c (parse_xspf_track):
+	* plparse/totem-pl-parser.c (relative_uri_remove_query),
+	(is_probably_dir), (totem_pl_parser_resolve_uri):
+	Backport path resolution function from master
+	fixes parsing of relative URIs in playlists (Closes: #577547)
+
 ============ Version 2.26.1
 
 2009-03-31  Bastien Nocera  <hadess hadess net>
diff --git a/plparse/totem-pl-parser-private.h b/plparse/totem-pl-parser-private.h
index ddd16c1..d09b4cd 100644
--- a/plparse/totem-pl-parser-private.h
+++ b/plparse/totem-pl-parser-private.h
@@ -110,6 +110,8 @@ gboolean totem_pl_parser_write_buffer		(GOutputStream *stream,
 						 GError **error);
 char * totem_pl_parser_relative			(GFile *output,
 						 const char *filepath);
+char * totem_pl_parser_resolve_uri		(GFile *base_gfile,
+						 const char *relative_uri);
 TotemPlParserResult totem_pl_parser_parse_internal (TotemPlParser *parser,
 						    GFile *file,
 						    GFile *base_file);
diff --git a/plparse/totem-pl-parser-smil.c b/plparse/totem-pl-parser-smil.c
index dc0b575..3850739 100644
--- a/plparse/totem-pl-parser-smil.c
+++ b/plparse/totem-pl-parser-smil.c
@@ -73,12 +73,12 @@ parse_smil_entry (TotemPlParser *parser,
 			copyright = xml_parser_get_property (node, "copyright");
 
 			if (uri != NULL) {
+				char *resolved_uri;
 				GFile *resolved;
 
-				if (base_file != NULL && strstr (uri, "://") == NULL)
-					resolved = g_file_resolve_relative_path (base_file, uri);
-				else
-					resolved = g_file_new_for_uri (uri);
+				resolved_uri = totem_pl_parser_resolve_uri (base_file, uri);
+				resolved = g_file_new_for_uri (resolved_uri);
+				g_free (resolved_uri);
 
 				totem_pl_parser_add_uri (parser,
 							 TOTEM_PL_PARSER_FIELD_FILE, resolved,
diff --git a/plparse/totem-pl-parser-wm.c b/plparse/totem-pl-parser-wm.c
index d177396..beae8d5 100644
--- a/plparse/totem-pl-parser-wm.c
+++ b/plparse/totem-pl-parser-wm.c
@@ -166,6 +166,7 @@ parse_asx_entry (TotemPlParser *parser, GFile *base_file, xml_node_t *parent)
 	xml_node_t *node;
 	TotemPlParserResult retval = TOTEM_PL_PARSER_RESULT_SUCCESS;
 	GFile *resolved;
+	char *resolved_uri;
 	const char *uri;
 	const char *title, *duration, *starttime, *author;
 	const char *moreinfo, *abstract, *copyright;
@@ -256,11 +257,9 @@ parse_asx_entry (TotemPlParser *parser, GFile *base_file, xml_node_t *parent)
 	if (uri == NULL)
 		return TOTEM_PL_PARSER_RESULT_ERROR;
 
-
-	if (base_file != NULL && strstr (uri, "://") == NULL)
-		resolved = g_file_resolve_relative_path (base_file, uri);
-	else
-		resolved = g_file_new_for_uri (uri);
+	resolved_uri = totem_pl_parser_resolve_uri (base_file, uri);
+	resolved = g_file_new_for_uri (resolved_uri);
+	g_free (resolved_uri);
 
 	/* .asx files can contain references to other .asx files */
 	retval = totem_pl_parser_parse_internal (parser, resolved, NULL);
@@ -289,16 +288,16 @@ parse_asx_entryref (TotemPlParser *parser, GFile *base_file, xml_node_t *node)
 	TotemPlParserResult retval = TOTEM_PL_PARSER_RESULT_SUCCESS;
 	const char *uri;
 	GFile *resolved;
+	char *resolved_uri;
 
 	uri = xml_parser_get_property (node, "href");
 
 	if (uri == NULL)
 		return TOTEM_PL_PARSER_RESULT_ERROR;
 
-	if (base_file != NULL && strstr (uri, "://") == NULL)
-		resolved = g_file_resolve_relative_path (base_file, uri);
-	else
-		resolved = g_file_new_for_uri (uri);
+	resolved_uri = totem_pl_parser_resolve_uri (base_file, uri);
+	resolved = g_file_new_for_uri (resolved_uri);
+	g_free (resolved_uri);
 
 	/* .asx files can contain references to other .asx files */
 	retval = totem_pl_parser_parse_internal (parser, resolved, NULL);
diff --git a/plparse/totem-pl-parser-xspf.c b/plparse/totem-pl-parser-xspf.c
index 89ebb08..434b095 100644
--- a/plparse/totem-pl-parser-xspf.c
+++ b/plparse/totem-pl-parser-xspf.c
@@ -164,6 +164,7 @@ parse_xspf_track (TotemPlParser *parser, GFile *base_file, xmlDocPtr doc,
 	xmlChar *title, *uri, *image_uri, *artist, *album, *duration, *moreinfo;
 	xmlChar *download_uri, *id;
 	GFile *resolved;
+	char *resolved_uri;
 	TotemPlParserResult retval = TOTEM_PL_PARSER_RESULT_ERROR;
 	
 	title = NULL;
@@ -217,10 +218,10 @@ parse_xspf_track (TotemPlParser *parser, GFile *base_file, xmlDocPtr doc,
 		goto bail;
 	}
 
-	if (base_file != NULL && strstr ((char *) uri, "://") == NULL)
-		resolved = g_file_resolve_relative_path (base_file, (const char *) uri);
-	else
-		resolved = g_file_new_for_uri ((const char *) uri);
+	resolved_uri = totem_pl_parser_resolve_uri (base_file, (char *) uri);
+	resolved = g_file_new_for_uri (resolved_uri);
+	g_free (resolved_uri);
+
 	totem_pl_parser_add_uri (parser,
 				 TOTEM_PL_PARSER_FIELD_FILE, resolved,
 				 TOTEM_PL_PARSER_FIELD_TITLE, title,
diff --git a/plparse/totem-pl-parser.c b/plparse/totem-pl-parser.c
index 4645e2f..2b4d21b 100644
--- a/plparse/totem-pl-parser.c
+++ b/plparse/totem-pl-parser.c
@@ -858,6 +858,143 @@ totem_pl_parser_relative (GFile *output, const char *filepath)
 	return retval;
 }
 
+static char *
+relative_uri_remove_query (const char *uri, char **query)
+{
+	char *qmark;
+
+	/* Look for '?' */
+	qmark = strrchr (uri, '?');
+	if (qmark == NULL)
+		return NULL;
+
+	if (query != NULL)
+		*query = g_strdup (qmark);
+	return g_strndup (uri, qmark - uri);
+}
+
+static const char *suffixes[] = {
+	".jsp",
+	".php",
+	".asp"
+};
+
+static gboolean
+is_probably_dir (const char *filename)
+{
+	gboolean ret;
+	char *content_type, *short_name;
+
+	short_name = relative_uri_remove_query (filename, NULL);
+	if (short_name == NULL)
+		short_name = g_strdup (filename);
+	content_type = g_content_type_guess (short_name, NULL, -1, NULL);
+	if (g_content_type_is_unknown (content_type) != FALSE) {
+		guint i;
+		for (i = 0; i < G_N_ELEMENTS (suffixes); i++) {
+			if (g_str_has_suffix (short_name, suffixes[i]) != FALSE) {
+				g_free (content_type);
+				g_free (short_name);
+				return FALSE;
+			}
+		}
+		ret = TRUE;
+	} else {
+		ret = FALSE;
+	}
+	g_free (content_type);
+	g_free (short_name);
+
+	return ret;
+}
+
+char *
+totem_pl_parser_resolve_uri (GFile *base_gfile,
+			     const char *relative_uri)
+{
+	char *uri, *scheme, *query, *new_relative_uri, *base_uri;
+	GFile *base_parent_gfile, *resolved_gfile;
+
+	if (relative_uri == NULL) {
+		if (base_gfile == NULL)
+			return NULL;
+		return g_file_get_uri (base_gfile);
+	}
+
+	if (base_gfile == NULL)
+		return g_strdup (relative_uri);
+
+	/* If |relative_uri| has a scheme, it's a full URI, just return it */
+	scheme = g_uri_parse_scheme (relative_uri);
+	if (scheme != NULL) {
+		g_free (scheme);
+		return g_strdup (relative_uri);
+	}
+
+	/* Check whether we need to get the parent for the base or not */
+	base_uri = g_file_get_path (base_gfile);
+	if (base_uri == NULL)
+		base_uri = g_file_get_uri (base_gfile);
+	if (is_probably_dir (base_uri) == FALSE)
+		base_parent_gfile = g_file_get_parent (base_gfile);
+	else
+		base_parent_gfile = g_object_ref (base_gfile);
+	g_free (base_uri);
+
+	if (base_parent_gfile == NULL) {
+		resolved_gfile = g_file_resolve_relative_path (base_gfile, relative_uri);
+		uri = g_file_get_uri (resolved_gfile);
+		g_object_unref (resolved_gfile);
+		return uri;
+	}
+
+	/* Remove the query portion of the URI, to transplant it again
+	 * if there is any */
+	query = NULL;
+	new_relative_uri = relative_uri_remove_query (relative_uri, &query);
+
+	if (new_relative_uri) {
+		char *tmpuri;
+
+		resolved_gfile = g_file_resolve_relative_path (base_parent_gfile, new_relative_uri);
+		g_object_unref (base_parent_gfile);
+		if (!resolved_gfile) {
+			char *base_uri;
+			base_uri = g_file_get_uri (base_gfile);
+			g_warning ("Failed to resolve relative URI '%s' against base '%s'\n", relative_uri, base_uri);
+			g_free (base_uri);
+			g_free (new_relative_uri);
+			g_free (query);
+			return NULL;
+		}
+
+		tmpuri = g_file_get_uri (resolved_gfile);
+		g_object_unref (resolved_gfile);
+		uri = g_strdup_printf ("%s%s", tmpuri, query);
+
+		g_free (tmpuri);
+		g_free (new_relative_uri);
+		g_free (query);
+
+		return uri;
+	} else {
+		resolved_gfile = g_file_resolve_relative_path (base_parent_gfile, relative_uri);
+		g_object_unref (base_parent_gfile);
+		if (!resolved_gfile) {
+			char *base_uri;
+			base_uri = g_file_get_uri (base_gfile);
+			g_warning ("Failed to resolve relative URI '%s' against base '%s'\n", relative_uri, base_uri);
+			g_free (base_uri);
+			return NULL;
+		}
+
+		uri = g_file_get_uri (resolved_gfile);
+		g_object_unref (resolved_gfile);
+
+		return uri;
+	}
+}
+
 #ifndef TOTEM_PL_PARSER_MINI
 /**
  * totem_pl_parser_write_with_title:



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