Mobile app version of vmapp.org
Login or Join
Goswami781

: Serving HTTP images in a HTTPS site. Can I add a "safe domain"? I know that by the title this may have been asked many times, but I haven't really found a similar situation asked (well,

@Goswami781

Posted in: #Https #Php

I know that by the title this may have been asked many times, but I haven't really found a similar situation asked (well, one) and I wondered if there could be a different approach?

I have a dashboard which is SSL enabled (https), but I have the need to display images from another of my own sites which is related to the dashboard, but hosted under a different domain and a different server, which is not yet SSL enabled (http).

I'm thinking along two different possible solutions apart from the obvious 'get the other site SSL enabled' (which I'm working on, but is complex).

My first thought is, can I 'allow' certain domains at a server level, somewhere in my https server to 'allow' non-https traffic from a particular domain that is deemed as safe? Or is it more a browser thing that will not allow this to happen?

If that is not possible, is there a way that I could 'get' the image in the background (when the page loads) from the http site to the https site for the purpose of displaying it? I've been reading about proxies and how it could be done, but I'm not sure if this would be the right approach. My programming language is PHP. I'm wondering if I could do a 'file_get_contents' on the image, but would then need to worry about how/where it is provisionally stored. Could this be into memory somehow, or how would I temporarily store it on a 'per-user' basis?

Just to be clear, these are images from my own sites TO my own sites. I'm not trying to do anything weird or wrong (apart from not yet having the 2nd site SSL enabled, which is of course the correct solution). I've seen plenty of people asking how to get images from other non-owned sites/servers, whereas I do have control over both of these as they are my own sites.

10.01% popularity Vote Up Vote Down


Login to follow query

More posts by @Goswami781

1 Comments

Sorted by latest first Latest Oldest Best

 

@Cugini213

Realistically your options really are as follows:

(a) Get the second website setup with SSL as you have already mentioned. This is probably the best long-term solution.

(b) Use a proxy script on your SSL-enabled website to serve the images from the other server. This method will increase your overall bandwidth usage and make your server running the secure website work harder, but in reality this could work very well for you as a short to medium term solution. I've used this method before a few times and it can be very effective for certain purposes.

An example PHP script hosted on your SSL-enabled website to achieve this might look like this:

<?php
const PROXY_DOMAIN = 'http://www.example-without-ssl.com/';

class AssetProxy {
private $aHeaders;
private $sData;

public function __construct($sURL) {
$this->aHeaders = array();
$this->sData = '';

/* HTTP 404 if resource does not exist */
if ($this->RemoteFileExists($sURL) == false) {
header('HTTP/1.0 404 Not Found');
exit;
}

/* HTTP 304 if resource same as held in browser cache */
$sData = @file_get_contents ($sURL);
$sETag = md5($sData);
$this->aHeaders[] = sprintf('ETag: %s', $sETag);
$sSuppliedETag = isset($_SERVER['HTTP_IF_NONE_MATCH']) ?
$_SERVER['HTTP_IF_NONE_MATCH'] : '';
if ($sSuppliedETag == $sETag) {
header('HTTP/1.1 304 Not Modified');
header('Content-Length: 0');
exit;
}

/* Send asset with gzip compression */
$this->DetectFileType($sURL);
$this->SetBrowserCache(60 * 60 * 24 * 35); // 35 days
if (!ob_start('ob_gzhandler')) ob_start();
foreach ($this->aHeaders as $sHeader) header($sHeader);
echo($sData);
}

private function RemoteFileExists($sURL) {
$hCURL = curl_init($sURL);
curl_setopt($hCURL, CURLOPT_NOBODY, true);
$bResult = curl_exec($hCURL);
if (!$bResult) return false;
$iStatus = (int)curl_getinfo($hCURL, CURLINFO_HTTP_CODE);
return ($iStatus == 200);
}

private function DetectFileType($sURL) {
$sFileExtension = strtolower(substr($sURL, 1 + strripos($sURL, '.')));
switch ($sFileExtension) {
case 'js': $sMimeType = 'text/javascript'; break;
case 'css': $sMimeType = 'text/css'; break;
case 'swf': $sMimeType = 'application/x-shockwave-flash'; break;
case 'png': $sMimeType = 'image/png'; break;
case 'jpg': $sMimeType = 'image/jpeg'; break;
case 'eot': $sMimeType = 'application/vnd.ms-fontobject'; break;
default: $sMimeType = 'text/plain'; break;
}
$this->aHeaders[] = 'Content-Type: ' . $sMimeType . '; charset: UTF-8';
}

private function SetBrowserCache($iSeconds) {
$dtNow = time();
$dtExpires = strtotime(sprintf('+%s seconds', $iSeconds));
$this->aHeaders[] = 'Expires: ' . date('r', $dtExpires);
$this->aHeaders[] = 'Last-Modified: ' . date('r', $dtNow);
$this->aHeaders[] = 'Cache-Control: public, must-revalidate, ' .
sprintf(max-age=%s', $iSeconds);
}

}

$sAsset = isset($_GET['asset']) ? $_GET['asset'] : '';
$oProxy = new AssetProxy(PROXY_DOMAIN . $sAsset);
exit;


I like to call this script gzip.php rather than anything that gives away its actually a proxy script. Next, in your HTML change all occurrences of URLs:
www.example-without-ssl.com/images/example.jpg
with the new URLs such as
www.example-with-ssl.com/gzip.php?asset=images/example.jpg
I have kept this script file-type agnostic so that it can serve a few different types of static asset, including javascripts, stylesheets, fonts aswell as images. To add more file-types just add the MIME types into the DetectFileType() function otherwise they will be served with a text/plain MIME-type by default.

10% popularity Vote Up Vote Down


Back to top | Use Dark Theme