Sanjay
Sanjay

Reputation: 1745

Remote image display is not working (now working using file_get_contents and curl)

Note: Please read the whole question and understand the scenario carefully before directly jumping into the answer section

I think this is a very simple problem, which I am not able to figure out.

Basically this one is working just fine.

Example url: http://localhost/test/image.php

Filename: image.php file

<?php
// $url = $_GET['url'];
$url = 'http://google.com/images/srpr/logo11w.png'; 
function data_uri($file) 
{  
    $contents = file_get_contents($file);

    $finfo = new finfo(FILEINFO_MIME);
    $mime = $finfo->buffer($contents);
    PHP_EOL; 

    $base64   = base64_encode($contents); 
    return ('data:' . $mime . ';base64,' . $base64);
}
echo '<img src="' .  data_uri($url) . '" alt="Test image" />';
?>

But when I did this (i.e. the below one), it is not working, I can't figure out what went wrong or what I am missing in the process.

Example url: http://localhost/test/displayimage.php

Filename: displayimage.php

<img src="http://localhost/test/imageserver.php" alt="image not displaying">

Image server file Filename: imageserver.php

<?php
// $url = $_GET['url'];
$url = 'http://google.com/images/srpr/logo11w.png'; 
function data_uri($file) 
{  
    $contents = file_get_contents($file);

    $finfo = new finfo(FILEINFO_MIME);
    $mime = $finfo->buffer($contents);
    PHP_EOL; 

    $base64   = base64_encode($contents); 
    return ('data:' . $mime . ';base64,' . $base64);
}
echo data_uri($url);
?>

Do I need to set any type of headers or something like that before echo ing data_uri. Any quick suggestions will be welcome to make it work in second url.

Reason why I am trying to achieve this

I am trying to display client website content which might be served over http but my server is in SSL and it is giving me this error: Mixed Content: The page at 'http://***/applist.css'. This request has been blocked; the content must be served over HTTPS. And by this methodology, I am trying to serve the http content as a wrapper to my page which is inside my server ie calling page as an https request, so that I can get rid of this warning message and content blocking by the browsers... I'm trying to server the non SSL (http) content to my SSL (https) server like this:

<img src="https://mywebsite.com/imageserver.php?url=http://php.net/images/logo.php" /> 

so that it will not block content and doesnot display warning message

Note: Hope this message will be helpful to others who are facing the same problem

Edited: Solution

Silly mistake i made. I tried to use data: mimetype while displaying image using url. The solution from Remote image display is not working (now working using file_get_contents and curl) works great and special mention to this answer as well Remote image display is not working (now working using file_get_contents and curl)

The solution code:

<?php
// $url = $_GET['url'];
$url = 'http://google.com/images/srpr/logo11w.png';   
function data_uri($file) 
{   
    $contents = file_get_contents($file);

    $finfo = new finfo(FILEINFO_MIME);
    $mime = $finfo->buffer($contents);

    return array($mime, $contents);
}
list($mime, $content) = data_uri($url);
header('Content-type: '.$mime);
die($content);
?>

If someone is interested in the solution using curl rather than file_get_contents, the below alternate solution will work perfectly which I have found while waiting for the solution of the above code. (http://ryansechrest.com/2012/07/send-and-receive-binary-files-using-php-and-curl/)

Filename: imageserver_curl.php

<?php 
// $url = $_GET['url'];
$url = 'http://php.net/images/logo.php';    
$token = 'N43feedfggsaedwufvworuworjslfurw';

$resource = curl_init();
curl_setopt($resource, CURLOPT_URL, $url);
curl_setopt($resource, CURLOPT_HEADER, 1);
curl_setopt($resource, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($resource, CURLOPT_BINARYTRANSFER, 1);
curl_setopt($resource, CURLOPT_COOKIE, 'apiToken=' . $token);
$file = curl_exec($resource);
curl_close($resource);

$file_array = explode("\n\r", $file, 2);
$header_array = explode("\n", $file_array[0]);

foreach($header_array as $header_value) {
    $header_pieces = explode(':', $header_value);
    if(count($header_pieces) == 2) {
        $headers[$header_pieces[0]] = trim($header_pieces[1]);
    }
}

header('Content-type: ' . $headers['Content-Type']);
// header('Content-Disposition: ' . $headers['Content-Disposition']); #download option

echo substr($file_array[1], 1);

Use it like this

Filename and url: http://localhost/test/displayimage.php

<img src="http://localhost/sandbox/securecontent/imageserver_curl.php"> 

Upvotes: 1

Views: 2844

Answers (2)

mathieu
mathieu

Reputation: 477

You are trying to send remotely inlined data... It's a weird idea, and i'm not sure the browser understand what are you trying to achieve...

imageserver.php

<?php
$url = 'http://google.com/images/srpr/logo11w.png';   
function data_uri($file) 
{  
    $contents = file_get_contents($file);

    $finfo = new finfo(FILEINFO_MIME);
    $mime = $finfo->buffer($contents);

    return array($mime, $contents);
}
list($mime, $content) = data_uri($url);
header('Content-type: '.$mime);
die($content);

?>

Upvotes: 1

Kristiyan
Kristiyan

Reputation: 1663

EDITED:

Your imageserver.php should be:

header('Content-Type: image/png');
$url = 'http://php.net/images/logo.php';   
function data_uri($file) 
{  
    $contents = file_get_contents($file);
    return $contents;
}
echo  data_uri($url);

Your view: <img src="imageserver.php" alt="Test image" /> Tips: You have to use header content type, because webserver have to know what is your output. It's not necessary to use base64. You must return only the content.

OLD:

Tested and working. PHP 5.6.3 JPG and PNG files.

$url = 'http://php.net/images/logo.php';   
function data_uri($file) 
{  
    $contents = file_get_contents($file);
    $base64   = base64_encode($contents); 
    return ('data:;base64,' . $base64);
}
echo '<img src="' .  data_uri($url) . '" alt="Test image" />';

Upvotes: 2

Related Questions