There's an issue with imagecache that if you run your website under SSL, imagecache still creates absolute URL's using http:// . This causes warnings in browsers like IE6 about insecure content. Yes, I know that IE is lame and probably shouldn't be complaining, but I feel that imagecache if it's going to provide absolute URL's should at least respect and create HTTPS urls.

The problem comes in the funciton imagecache_create_url in which absolute => "TRUE" gets passed. Not sure why this is going on, but I bet it's a hack so that imagecache will work in the exceptional cases where a full URL is required. Well this work around for that bug, creates the https:// bug and we should resolve this as well.

This is important to me as I will lose sales from stupid people using IE in my stores from these warnings.

CommentFileSizeAuthor
#21 imagecache-548858.patch1021 bytesjwilson3
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

deepak.cms’s picture

Please comment the base URL in the settings.php file. (sites/default/settings.php). This will help imagecache to recognize http or https and will generate URLs on that basis. Hope this helps to resolve the issue.

j0rd’s picture

I don't think this fixes the issue. If I set base_url to https:// it will set all my imagecaches to https:// even when I'm browsing on http://

I think what should happen is imagecache should figure out which protocol we're surfing on and appropriately set http:// or https:// accordingly.

I host the same mirror of my site with http and https and I use the secure pages module to bounce my users between http & https depending if that page should be secure or not (credit cards, user login) , but imagecache will always give me http links based on how it currently works.

rohnjeynolds’s picture

You could write a little check in your settings.php to see if it's an SSL request or not, and set $base_url accordingly. I haven't tested it, but maybe try something like this:

if (!empty($_SERVER['HTTPS'])) {
    $base_url = 'https://' . $_SERVER['HTTP_HOST'];
}
JimBroad’s picture

Quite sure this is actually related to --> http://drupal.org/node/597432

Bartezz’s picture

j0rd,

Have you manage to find a fix for this? I have problems with imagecache breaking my secure pages as well.
Have tried #3 and the patch from the link of #4, both haven't helped fixing the problem.

Help is greatly appreciated!

Cheers

Bartezz’s picture

Found a solution to my imagecached images causing problems

My secure pages setup:

- enabled
- checked: Switch back to http pages when there are no matches
- Non-secure Base URL: (nothing)
- Secure Base URL: (nothing)
- checked: Make secure only the listed pages.
- pages: (the pages you want secured)
- Ignore pages:
*/autocomplete/*
*/ajax/*
*/imagecache/*

Special attention for */imagecache/*

This worked for me!

Cheers

j0rd’s picture

Thanks for your work on this Bartezz. I ran into it again today.

My issue was resolved by the patch. Your solution and adding this to my NGINX conf.

fastcgi_param HTTPS on

Since it doesn't get set in nginx and securepages requires it. Not sure which actually resolved my problem though :D

lunarlogic’s picture

adding */imagecache/* to the ignore list worked for me as well. Thanks for posting.

Bartezz’s picture

No worries, was happy to find it after searching long for a solution!
Wanted to make sure no one else had to search so long for a solution :)

Cheers

mrfelton’s picture

a combination of #3, #6, #7 & #8 seems to have fixed it for me!

phreestilr’s picture

Thanks! #3 and #6 together fixed the problem for me

BradGriffith’s picture

These fixes didn't work for me. The imagecache image in the shopping cart still shows up using HTTP on the first page load (i.e. from a link to the cart), but when the cart page is refreshed, the images then use HTTPS. I assume this is a problem with when $GLOBAL['base_url'] is being set by securepages?

I tried lowering the weight of the securepages module in the system table so that it would init before imagecache, but that didn't help.

Why does ImageCache need to use an absolute path, anyway? I can't think of any "exceptional cases" when that would be necessary--I'm sure someone else thought of at least one case, though.

Until we have a better solution, I have patched imagecache.module to use a relative path (starting with /) instead of absolute. If anyone is interested in the patch file, I can post it. I don't want to post it if I'm not approaching this in an appropriate way :-)

Thanks!

mrfelton’s picture

@BradGriffith: I think it'd be better to use relative paths too. Please can you post your patch. Thanks

gramie’s picture

I think that in the case of RSS feeds and e-mailed pages it makes a great deal of sense to use absolute paths. Maybe that's why imagecache always creates them, because it never knows if the image source will be used in one of those other places.

vorbian’s picture

I found that with my site & server setup, I was able to comment out the $base_url line in my settings.php file, and that was enough to solve the issue with ImageCache. Now the images have https on secure pages and http on non-secure pages.

leilyrken’s picture

I did the change and it seems to works but IE still show me the same error.

When I open the source and search for HTTP:// source I can see nothing, all the source in the website are load from HTTPS. Any idea of what can be the problem or at least how to find the "non secure" source ?

fehin’s picture

subscribing

rickmanelius’s picture

Still not a working solution...
Ubercart SSL doesn't work with this.

It seems that base_url isn't properly set when this module is enabled.

Tis very frustrating!

rgs’s picture

I added */imagecache/* to my secure pages/igonore setting and set my base url to https in settings.php and it worked like a charm. Make sure you use the Nov dev version of the Secure Pages module.

drewish’s picture

One thing you might want to try is replacing "http://" with "://" it allows the browser to treat the path as absolute but use the protocol of the page.

jwilson3’s picture

FileSize
1021 bytes

The issue, for me, anyway, seems to be in part because I don't have different caches for http / https and am using views to pull in images via imagecache and show them in a cached block.

The source of the issue comes from imagecache_create_url.

This function suffers in exactly the same way that core file_create_url suffers, in that it has logic for handling absolute URLs, but fails to implement it intelligently, always inserting $GLOBAL['base_url'], when it could be using the url function to create root-relative URLs where appropriate. Its possible that I'm missing something on the importance of using absolute URIs for file downloads as opposed to root-relative URLs... if so, someone please enlighten me :)

Here is a patch that uses the url() function consistently to adjusts the link path intelligently while opting for root-relative URLs. Private Downloads functionality is left as is.

jwilson3’s picture

Status: Active » Needs review

update status.

Renee S’s picture

I can confirm this patch worked for me. I use another module that has this problem, and solved it by setting an option in settings.php - insert_relative_paths = true - but I'm not really sure why they're ever needed :) This solution works great.

jwilson3’s picture

I've been trying to think of cases that would require an absolute canonical URI generated by Imagecache.

So far I've come up with:

1) CDNs -- the absolute url is going to be completely different from the $base_url anyway.
2) RSS feeds with embedded images -- not totally sure on this, it prolly depends on the reader.
3) Emails with embedded images --seems like an edge case, is there any module that can actually do this?

The patch in #21 would break case 2 and 3 for sure, without other special handling. Case 1 is not supported natively by imagecache anyway.

pounard’s picture

Hello, absolute URL are evil.

@#21 You are totally right, absolute URLs are evil, they never, ever should be used for many reasons:

  • They break proxies behavior. Proxies are made to serve pages from one namespace to another, therefore modifying URLs. With hardcoded absolute URLs in generated HTML code, it will break proxies namespaces and eventually serve content with non existing URLs in the client namespace., See http://www.makina-corpus.org/blog/relativeabsolute-url-and-proxies
  • Absolute generated URLs get in cached pieces of HTML junk, therefore break the HTTP/HTTPS by forcing context switching, creating real security issues.

When are you going to commit this patch?

EDIT: Some typo.

pounard’s picture

BTW, got bugs about this too, but in custom code. This is why I'm commenting this issue.

pounard’s picture

PS: This is still anormal that even in D7 (image module and file.inc) they still force absolute URLs for files, it make this part of the core looking like an early 90's old PHP 3 application.

jwilson3’s picture

Obviously some time was spent to rethink the entire core file system code using the new public:// and private:// protocols... but i agree with #27. Why force absolute URLs? The application should default to root relative, with the responsibility on module developers to force absolute URLs if they need it for a particular implementation (such as those presented in #24).

I'm hoping a module maintainer might like to chime in here, but my guess is the patch and idea proposed here will get shot down until a change happens in core.

For those that want a clean solution, I can also work up a code example that can be implemented at the theme layer so the imagecache module doesn't need to be patched. Just let me know here if you're interested.

pounard’s picture

Thanks. It won't help me because I'm using ImageCache as an API, not a frontend module. My problem is that imagecache_create_url() returns absolute URLs, so my only solution is doing my own implementation of this method using imagecache_create_path() instead (which is wrong, because whenever the site I'm working on will switch to private file download, my method will break things).

Bensbury’s picture

I have a case where absolute urls are needed, and that's for Japanese mobile when you are not on the default language, as it appears to not pay attention to the base url.

--- ignore this, I found the url being rewritten in a template file.
New Year's Day recovery is not a good time to be coding...

pounard’s picture

Never a good time to code indead :) At least you tried, it probably worth the shot :)

TimelessDomain’s picture

Any update?

So #3 & #6 are the recommended solutions right now?

&

#21 & #23 also solves the problem, but create other problems as described in #24 (so best to use #3 & #6?)

pounard’s picture

A bit of history: core stream wrappers in D7 inherited from this deffective design, and they provide a method which is getExternalUrl() (which forces every file to have an absolute URL). I think they did a getExternalUrl() but no getUrl() because of the old file_create_url() D6 function that forces absolute, whithout really thinking why.

maarten_l’s picture

That base_url seems to be quite a good solution. We've got something like this currently:

$base_url = (isset($_SERVER["HTTPS"]) ? 'https://' : 'http://') . $_SERVER["SERVER_NAME"];

With some Pathologic module into the mix for relative paths.

arvana’s picture

Installing Secure Pages Hijack Prevention also worked for me in Chrome.

dejan.maric.max’s picture

Make relative paths with simple hook.

Best thing with Drupal is that you can use HOOKs in so many places so you don't have to patch things.

After all img HTML is rendered in theme_imagecache() function so all you have to do is make your own function in:
* your custom module
* or even in template.php (of selected theme).

function bellow is simple copy paste of `theme_imagecache` from imagecache.module with only one line added :

+ $imagecache_url = str_replace($GLOBALS['base_url'] ,'',$imagecache_url);
which removes the base_url and by doing that makes path relative.

function phptemplate_imagecache($presetname, $path, $alt = '', $title = '', $attributes = NULL, $getsize = TRUE) {
// Check is_null() so people can intentionally pass an empty array of
// to override the defaults completely.
if (is_null($attributes)) {
$attributes = array('class' => 'imagecache imagecache-'. $presetname);
}
if ($getsize && ($image = image_get_info(imagecache_create_path($presetname, $path)))) {
$attributes['width'] = $image['width'];
$attributes['height'] = $image['height'];
}

$attributes = drupal_attributes($attributes);
$imagecache_url = imagecache_create_url($presetname, $path);
$imagecache_url = str_replace($GLOBALS['base_url'] ,'',$imagecache_url);
return 'Only local images are allowed.';
}

m2calabr’s picture

#36 works great

This is how I implemented the instructions:

I went in to imagecache.module, copied the function theme_imagecache to my theme.php file and renamed the function to {theme name}_imagecache. Then I added the line as above "$imagecache_url = str_replace($GLOBALS['base_url'] ,'',$imagecache_url);"

We tested under IE6-9, Chrome, Firefox.

jelo’s picture

Thanks to all for providing suggested solutions. I am wondering if using relative paths is always desired. The initial poster said

Not sure why this is going on, but I bet it's a hack so that imagecache will work in the exceptional cases where a full URL is required.

What are the exceptional cases that require a full URL? I am concerned about #36 causing problems by using relative paths, e.g. with RSS feeds or modules that allow you to email the content of a node (which require a full path). I am not sure if those modules just grab page content and email it out or process the content to check for relative links and adjust it to absolute links? If they do, how is determined for those purposes which protocol gets used?

pounard’s picture

Every time you send the link in order to be seen outside of the site itself (RSS is the case, mails are too) you have to put an aboslute URL.

jwilson3’s picture

To elaborate on punard's statement, and to more directly answer jelo's question in #38: there is no such automatic processing of links for RSS feeds, to ensure they are Absolute. I've seen sites on Drupal Planet that have relative paths to images (presumably inserted by hand or a wysiwyg editor) inline on blog posts...

Remember, if you go with any solutions proposed here, you need to know the system-wide impact of what you're doing, and account for it yourself.

fizk’s picture

Issue tags: +ImageCache 2.x Todo

Marking as ImageCache 2.x Todo.

allisonc’s picture

Adding */imagecache/* to Ignore pages worked for me.

Status: Needs review » Needs work
Issue tags: -ImageCache 2.x Todo

The last submitted patch, imagecache-548858.patch, failed testing.