aboutsummaryrefslogtreecommitdiffstats
path: root/embed/ephy-favicon-cache.c
diff options
context:
space:
mode:
authorChristian Persch <chpe@cvs.gnome.org>2005-07-09 04:37:36 +0800
committerChristian Persch <chpe@src.gnome.org>2005-07-09 04:37:36 +0800
commite1af86afc3b7cc733fcb0b86f623106bdbeee7d2 (patch)
treee57531a629bc405e9824afe334238204dcd6aa08 /embed/ephy-favicon-cache.c
parent77bfef25b822b4aa865ba9fd44a5dc22efafe690 (diff)
downloadgsoc2013-epiphany-e1af86afc3b7cc733fcb0b86f623106bdbeee7d2.tar
gsoc2013-epiphany-e1af86afc3b7cc733fcb0b86f623106bdbeee7d2.tar.gz
gsoc2013-epiphany-e1af86afc3b7cc733fcb0b86f623106bdbeee7d2.tar.bz2
gsoc2013-epiphany-e1af86afc3b7cc733fcb0b86f623106bdbeee7d2.tar.lz
gsoc2013-epiphany-e1af86afc3b7cc733fcb0b86f623106bdbeee7d2.tar.xz
gsoc2013-epiphany-e1af86afc3b7cc733fcb0b86f623106bdbeee7d2.tar.zst
gsoc2013-epiphany-e1af86afc3b7cc733fcb0b86f623106bdbeee7d2.zip
Rename favicons so they don't have extensions. Work around broken mime
2005-07-08 Christian Persch <chpe@cvs.gnome.org> * embed/ephy-favicon-cache.c: (ephy_favicon_cache_download), (ephy_favicon_cache_get): Rename favicons so they don't have extensions. Work around broken mime detection which cannot detect that a .ico file with HTML content is really no icon file.
Diffstat (limited to 'embed/ephy-favicon-cache.c')
-rw-r--r--embed/ephy-favicon-cache.c165
1 files changed, 126 insertions, 39 deletions
diff --git a/embed/ephy-favicon-cache.c b/embed/ephy-favicon-cache.c
index 034ec305d..f73b1251c 100644
--- a/embed/ephy-favicon-cache.c
+++ b/embed/ephy-favicon-cache.c
@@ -35,6 +35,8 @@
#include "ephy-file-helpers.h"
#include "ephy-node-common.h"
#include "ephy-node.h"
+#include <glib/gstdio.h>
+#include <libgnomeui/libgnomeui.h>
#include "ephy-debug.h"
#define EPHY_FAVICON_CACHE_XML_ROOT (const xmlChar *)"ephy_favicons_cache"
@@ -42,6 +44,9 @@
#define EPHY_FAVICON_CACHE_OBSOLETE_DAYS 30
+/* this is very generous, most files are 4k */
+#define EPHY_FAVICON_MAX_SIZE 64 * 1024 /* byte */
+
static void ephy_favicon_cache_class_init (EphyFaviconCacheClass *klass);
static void ephy_favicon_cache_init (EphyFaviconCache *cache);
static void ephy_favicon_cache_finalize (GObject *object);
@@ -71,7 +76,16 @@ enum
EPHY_NODE_FAVICON_PROP_FILENAME = 3,
EPHY_NODE_FAVICON_PROP_LAST_USED = 4,
EPHY_NODE_FAVICON_PROP_STATE = 5,
- EPHY_NODE_FAVICON_PROP_CHECKED = 6
+ EPHY_NODE_FAVICON_PROP_CHECKOLD = 6,
+ EPHY_NODE_FAVICON_PROP_CHECKED = 7
+};
+
+enum
+{
+ NEEDS_TYPE_CHECK = 1 << 0,
+ NEEDS_RENAME = 1 << 1,
+ NEEDS_ICO_CHECK = 1 << 2,
+ NEEDS_MASK = 0x3f
};
static guint signals[LAST_SIGNAL] = { 0 };
@@ -320,21 +334,6 @@ ephy_favicon_cache_finalize (GObject *object)
G_OBJECT_CLASS (parent_class)->finalize (object);
}
-static char *
-favicon_name_build (const char *url)
-{
- char *result;
-
- result = g_filename_from_utf8 (url, -1, NULL, NULL, NULL);
-
- if (result == NULL)
- {
- return NULL;
- }
-
- return g_strdelimit (result, "/", '_');
-}
-
static void
favicon_download_completed_cb (EphyEmbedPersist *persist,
EphyFaviconCache *cache)
@@ -397,7 +396,7 @@ ephy_favicon_cache_download (EphyFaviconCache *cache,
ephy_embed_persist_set_dest (persist, dest);
ephy_embed_persist_set_flags (persist, EPHY_EMBED_PERSIST_NO_VIEW |
EPHY_EMBED_PERSIST_DO_CONVERSION);
- ephy_embed_persist_set_max_size (persist, 100 * 1024);
+ ephy_embed_persist_set_max_size (persist, EPHY_FAVICON_MAX_SIZE);
ephy_embed_persist_set_source (persist, favicon_url);
g_free (dest);
@@ -421,8 +420,8 @@ ephy_favicon_cache_get (EphyFaviconCache *cache,
EphyNode *icon;
GValue value = { 0, };
char *pix_file;
- GdkPixbuf *pixbuf;
- gboolean valid = FALSE;
+ GdkPixbuf *pixbuf = NULL;
+ guint checklevel = NEEDS_MASK;
if (url == NULL) return NULL;
@@ -434,11 +433,7 @@ ephy_favicon_cache_get (EphyFaviconCache *cache,
{
char *filename;
- filename = favicon_name_build (url);
- if (filename == NULL)
- {
- return NULL;
- }
+ filename = gnome_thumbnail_md5 (url);
icon = ephy_node_new (cache->priv->db);
g_value_init (&value, G_TYPE_STRING);
@@ -453,6 +448,12 @@ ephy_favicon_cache_get (EphyFaviconCache *cache,
&value);
g_value_unset (&value);
+ g_value_init (&value, G_TYPE_INT);
+ g_value_set_int (&value, (int) NEEDS_MASK & ~NEEDS_RENAME);
+ ephy_node_set_property (icon, EPHY_NODE_FAVICON_PROP_CHECKED,
+ &value);
+ g_value_unset (&value);
+
ephy_node_add_child (cache->priv->icons, icon);
ephy_favicon_cache_download (cache, url, filename);
@@ -460,6 +461,7 @@ ephy_favicon_cache_get (EphyFaviconCache *cache,
g_free (filename);
}
+ /* update timestamp */
g_value_init (&value, G_TYPE_INT);
g_value_set_int (&value, now);
ephy_node_set_property (icon, EPHY_NODE_FAVICON_PROP_LAST_USED,
@@ -477,15 +479,55 @@ ephy_favicon_cache_get (EphyFaviconCache *cache,
ephy_node_get_property_string (icon, EPHY_NODE_FAVICON_PROP_FILENAME),
NULL);
+ /* FIXME queue re-download? */
+ if (g_file_test (pix_file, G_FILE_TEST_EXISTS) == FALSE)
+ {
+ g_free (pix_file);
+ return NULL;
+ }
+
/* Check for supported icon types */
- if (ephy_node_get_property (icon, EPHY_NODE_FAVICON_PROP_CHECKED, &value))
+ if (ephy_node_get_property (icon, EPHY_NODE_FAVICON_PROP_CHECKED, &value) &&
+ G_VALUE_HOLDS (&value, G_TYPE_INT))
+ {
+ checklevel = (guint) g_value_get_int (&value);
+ g_value_unset (&value);
+ }
+
+ /* First, update the filename */
+ if (checklevel & NEEDS_RENAME)
{
- valid = g_value_get_boolean (&value);
+ char *new_pix_file, *urlhash;
+
+ urlhash = gnome_thumbnail_md5 (url);
+ new_pix_file = g_build_filename (cache->priv->directory, urlhash, NULL);
+
+ g_value_init (&value, G_TYPE_STRING);
+ g_value_take_string (&value, urlhash);
+ ephy_node_set_property (icon, EPHY_NODE_FAVICON_PROP_FILENAME, &value);
+ g_value_unset (&value);
+
+ /* rename the file */
+ g_rename (pix_file, new_pix_file);
+
+ g_free (pix_file);
+ pix_file = new_pix_file;
+
+ checklevel &= ~NEEDS_RENAME;
+ g_value_init (&value, G_TYPE_INT);
+ g_value_set_int (&value, (int) checklevel);
+ ephy_node_set_property (icon, EPHY_NODE_FAVICON_PROP_CHECKED, &value);
g_value_unset (&value);
}
- else
+
+ /* Now check the type. We renamed the file above, so gnome-vfs does NOT
+ * fall back to extension checking if the slow mime check fails for
+ * whatever reason
+ */
+ if (checklevel & NEEDS_TYPE_CHECK)
{
GnomeVFSFileInfo *info;
+ gboolean valid = FALSE, is_ao = FALSE;;
/* Sniff mime type and check if it's safe to open */
info = gnome_vfs_file_info_new ();
@@ -498,32 +540,77 @@ ephy_favicon_cache_get (EphyFaviconCache *cache,
valid = strcmp (info->mime_type, "image/x-ico") == 0 ||
strcmp (info->mime_type, "image/png") == 0 ||
strcmp (info->mime_type, "image/gif") == 0;
+ is_ao = strcmp (info->mime_type, "application/octet-stream") == 0;
}
gnome_vfs_file_info_unref (info);
- g_value_init (&value, G_TYPE_BOOLEAN);
- g_value_set_boolean (&value, valid);
- ephy_node_set_property (icon, EPHY_NODE_FAVICON_PROP_CHECKED, &value);
- g_value_unset (&value);
+ /* As a special measure, we try to load an application/octet-stream file
+ * as an ICO file, since we cannot detect a ICO file without .ico extension
+ * (the mime system has no magic for it).
+ */
+ if (is_ao)
+ {
+ GdkPixbufLoader *loader;
+ char *buf = NULL;
+ gsize count = 0;
+
+ loader = gdk_pixbuf_loader_new_with_type ("ico", NULL);
+ if (loader != NULL)
+ {
+ if (g_file_get_contents (pix_file, &buf, &count, NULL))
+ {
+ gdk_pixbuf_loader_write (loader, buf, count, NULL);
+ g_free (buf);
+ }
+
+ gdk_pixbuf_loader_close (loader, NULL);
+
+ pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+ if (pixbuf != NULL)
+ {
+ g_object_ref (pixbuf);
+ valid = TRUE;
+ }
+
+ g_object_unref (loader);
+ }
+ }
- /* remove invalid files from cache */
- if (valid == FALSE)
+ /* persist the check value */
+ if (valid)
+ {
+ checklevel &= ~NEEDS_TYPE_CHECK;
+ }
+ else
{
- gnome_vfs_unlink (pix_file);
+ /* remove invalid file from cache */
+ /* gnome_vfs_unlink (pix_file); */
}
- LOG ("%s icon file %s", valid ? "Validated" : "Invalidated", pix_file);
+ g_value_init (&value, G_TYPE_INT);
+ g_value_set_int (&value, (int) checklevel);
+ ephy_node_set_property (icon, EPHY_NODE_FAVICON_PROP_CHECKED, &value);
+ g_value_unset (&value);
+
+ /* epiphany 1.6 compat */
+ g_value_init (&value, G_TYPE_BOOLEAN);
+ g_value_set_boolean (&value, valid);
+ ephy_node_set_property (icon, EPHY_NODE_FAVICON_PROP_CHECKOLD, &value);
+ g_value_unset (&value);
}
- if (valid == FALSE)
+ /* if it still needs the check, mime type couldn't be checked. Deny! */
+ if (checklevel & NEEDS_TYPE_CHECK)
{
g_free (pix_file);
return NULL;
}
- LOG ("Create pixbuf for %s", pix_file);
-
- pixbuf = gdk_pixbuf_new_from_file (pix_file, NULL);
+ /* we could already have a pixbuf from the application/octet-stream check */
+ if (pixbuf == NULL)
+ {
+ pixbuf = gdk_pixbuf_new_from_file (pix_file, NULL);
+ }
g_free (pix_file);