[HOWTO] Implement an image proxy to speedup your SMF forum

Started by Mr. Jinx, September 20, 2014, 05:03:38 AM

Previous topic - Next topic

Mr. Jinx

This is an easy way to implement an image proxy (cache). All images that users embed in posts come from different locations. By using this image proxy you make sure everything comes from one reliable and fast source.

The main reason I needed this was because I converted my site to HTTPS only. However, most user embedded content comes from HTTP sources, so you'll get mixed content which might give a warning in your browser. So I wanted to make sure all content comes from one reliable https source.

I could not find any mod that does this. Inspire by another forum using an external proxy I came up with this tip.

Benefits of using an image proxy

  • Make sure all images come from one fast and reliable source
  • Prevent mixed content by forcing SSL (or plain if you like)
  • Give users more privacy, images can be used to collect stats/ip. A proxy prevents this.
  • Reduce data traffic and a small speed boost because images are loaded from another domain

Example

A user adds an image like this:
[img]http://www.example.com/image.png[/img]

After applying the small modification, SMF will replace it with the following code:
[img]https://images.weserv.nl/?url=www.example.com/image.png[/img]

Images.weserv.nl is the free service I use for this. It grabs the image from the source and serves it over https. You can also change it to http, and do some other stuff like resizing or changing the output format.

Modification

Open Sources/Subs.php

Find:
'content' => '<img src="$1" alt="{alt}"{width}{height} class="bbc_img resized" />',
'validate' => create_function('&$tag, &$data, $disabled', '
$data = strtr($data, array(\'<br />\' => \'\'));
if (strpos($data, \'http://\') !== 0 && strpos($data, \'https://\') !== 0)
$data = \'http://\' . $data;


Replace with:
'content' => '<img src="$1" alt="{alt}"{width}{height} class="bbc_img resized" />',
                                'validate' => create_function('&$tag, &$data, $disabled', '
                                        $data = strtr($data, array(\'<br />\' => \'\'));
                                        if (strpos($data, \'https://images.weserv.nl/?url=\') !== 0)
                                         if (strpos($data, \'http://images.weserv.nl/?url=\') === 0) $data = \'https://\' . substr($data, strlen(\'http://\')).\'\';
                                         else if (strpos($data, \'http://\') !== 0 && strpos($data, \'https://\') !== 0) $data = \'https://images.weserv.nl/?url=\' . $data;
                                         else if (strpos($data, \'http://\') === 0) $data = \'https://images.weserv.nl/?url=\' . substr($data, strlen(\'http://\')).\'\';
                                         else if (strpos($data, \'https://\') === 0) $data = \'https://images.weserv.nl/?url=ssl:\' . substr($data, strlen(\'https://\')).\'\';



Find:
'content' => '<img src="$1" alt="" class="bbc_img" />',
'validate' => create_function('&$tag, &$data, $disabled', '
$data = strtr($data, array(\'<br />\' => \'\'));
if (strpos($data, \'http://\') !== 0 && strpos($data, \'https://\') !== 0)
$data = \'http://\' . $data;


Replace with:
'content' => '<img src="$1" alt="" class="bbc_img" />',
                                'validate' => create_function('&$tag, &$data, $disabled', '
                                        $data = strtr($data, array(\'<br />\' => \'\'));
                                        if (strpos($data, \'https://images.weserv.nl/?url=\') !== 0)
                                         if (strpos($data, \'http://images.weserv.nl/?url=\') === 0) $data = \'https://\' . substr($data, strlen(\'http://\')).\'\';
                                         else if (strpos($data, \'http://\') !== 0 && strpos($data, \'https://\') !== 0) $data = \'https://images.weserv.nl/?url=\' . $data;
                                         else if (strpos($data, \'http://\') === 0) $data = \'https://images.weserv.nl/?url=\' . substr($data, strlen(\'http://\')).\'\';
                                         else if (strpos($data, \'https://\') === 0) $data = \'https://images.weserv.nl/?url=ssl:\' . substr($data, strlen(\'https://\')).\'\';


This change in code will add the prefix "https://images.weserv.nl/?url=" to all img tags and automatically upload/proxy the images.

About images.weserv.nl

Images.weserv.nl is a free service you can use to proxy images. They run this proxy since 2007, making part of cloudflare with 28 datacenters: "This ensures the fastest load times and best performance".  You can check https://images.weserv.nl/ for more features. Or read why they offer this for free over here.

ps1: I am in no way related to this company.
ps2: If someone has better optimized code, please share it.

chrishicks

Sorry for the bump but I applied this code to my forum yesterday and just now noticed that this breaks gifs and turns them into still images. Is there a way to have gifs skipped when using this?

Mr. Jinx

Animated gifs, isn't that something from the 90's? ;D
The free service from images.weserv.nl doesn't support animated gifs.

I guess there are some options:

1) Wait until SMF 2.1 is released. It should come with a builtin image proxy.
2) Use a paid service. Although I haven't found any service as easy as Weserv, this one looks nice: Imgix.com. It supports animated gifs. This would require some small code changes.
3) Filter gifs in this modification, but that seems to be quit some work. I don't know how to easily do this.

njtweb

Quote from: Mr. Jinx on November 30, 2015, 12:26:21 PM
Animated gifs, isn't that something from the 90's? ;D
The free service from images.weserv.nl doesn't support animated gifs.

I guess there are some options:

1) Wait until SMF 2.1 is released. It should come with a builtin image proxy.
2) Use a paid service. Although I haven't found any service as easy as Weserv, this one looks nice: Imgix.com. It supports animated gifs. This would require some small code changes.
3) Filter gifs in this modification, but that seems to be quit some work. I don't know how to easily do this.

They're actually huge on sports websites now because it eliminates the need to embed video code from other sites which use watermarks and can redirect on click back to their site. They convert the videos to GIFs so there's no ability to click and be reverted to an external or the originating site anymore.

Mr. Jinx

I was just joking about the .gifs :)

You can skip the .gifs by using this:

Replace this:

                                        if (strpos($data, \'https://images.weserv.nl/?url=\') !== 0)


with this:

                                        if (strpos($data, \'https://images.weserv.nl/?url=\') !== 0 && strpos($data, \'.gif\', strlen($data) - 4) === false)

(you need to modify this two times in Subs.php)

Let me know if that worked.

chrishicks

That works!! Thank you for the update/fix. I really appreciate it.

ZamaTata

Very Nice... thanks for the idea

FYI
The proxy caches images in different ways, depending on the rate of requests, no more than 31 days, and at least 14 days. Most images refresh every 14 days.

underc0de

Hi,

I applied this code in my forum, but the signatures and avatars have not ssl.
Any solution?

Regards

itsprabhucbe

I implemented this method but I have some GIFs images on my website. I have no problem with this method. This GIF images converted to normal images.

Advertisement: