2

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.

2

1 Answer 1

2

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:

http://www.example-without-ssl.com/images/example.jpg

with the new URLs such as

https://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.

1
  • Thank you for your answer. I'm actually testing the second server with SSL so I'm going with the better option of having it all secure. Thanks for your input.
    – omega1
    Mar 31, 2017 at 12:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.