Created
January 6, 2018 08:45
-
-
Save searsia/e141c4aca4ca1f3bd8a2c04877f4b26e to your computer and use it in GitHub Desktop.
Simple PHP image proxy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$PROXY = 'https://yourdomain.top/proxy.php?url='; | |
# This script forwards the call | |
# Check for url parameter, and prevent file transfer | |
if (isset($_GET['url']) and preg_match('#^https?://#', $_GET['url']) === 1) { | |
$url .= $_GET['url']; | |
} else { | |
header('HTTP/1.1 404 Not Found'); | |
exit; | |
} | |
# Check if the client already has the requested item | |
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) or | |
isset($_SERVER['HTTP_IF_NONE_MATCH'])) { | |
header('HTTP/1.1 304 Not Modified'); | |
exit; | |
} | |
$ch = curl_init(); | |
curl_setopt($ch, CURLOPT_URL, $url); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | |
curl_setopt($ch, CURLOPT_HEADER, true); | |
curl_setopt($ch, CURLOPT_USERAGENT, 'Searsia/1.0'); | |
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true); | |
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); | |
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 4); | |
curl_setopt($ch, CURLOPT_BUFFERSIZE, 12800); | |
curl_setopt($ch, CURLOPT_NOPROGRESS, false); | |
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, function($DownloadSize, $Downloaded, $UploadSize, $Uploaded) { return ($Downloaded > 1024 * 512) ? 1 : 0; } ); # max 500kb | |
$out = curl_exec ($ch); | |
curl_close ($ch); | |
$file_array = explode("\r\n\r\n", $out, 2); | |
$header_array = explode("\r\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]); | |
} | |
} | |
if (array_key_exists('Location', $headers)) { | |
$newurl = urlencode($headers['Location']); | |
header("HTTP/1.1 301 Moved Permanently"); | |
header('Location: ' . $PROXY . $newurl); | |
} else { | |
if (array_key_exists('Content-Type', $headers)) { | |
$ct = $headers['Content-Type']; | |
if (preg_match('#image/png|image/.*icon|image/jpe?g|image/gif#', $ct) !== 1) { | |
header('HTTP/1.1 404 Not Found'); | |
exit; | |
} | |
header('Content-Type: ' . $ct); | |
} | |
if (array_key_exists('Content-Length', $headers)) | |
header('Content-Length: ' . $headers['Content-Length']); | |
if (array_key_exists('Expires', $headers)) | |
header('Expires: ' . $headers['Expires']); | |
if (array_key_exists('Cache-Control', $headers)) | |
header('Cache-Control: ' . $headers['Cache-Control']); | |
if (array_key_exists('Last-Modified', $headers)) | |
header('Last-Modified: ' . $headers['Last-Modified']); | |
echo $file_array[1]; | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Many thanks for script!
I have some suggestions to improve script:
$header_array = explode("\n", $header_blocks[array_key_last($header_blocks)]);
change to$header_array = explode("\n", array_pop($header_blocks));
sincearray_key_last()
is only supported in PHP 7 and higher.you did
strtolower($header_pieces[0])
and then usesif (array_key_exists('Expires', $headers))
in upper case. Its need to be changed to lowercase.add the WEBP and SVG image types:
if (preg_match('#image/png|image/.*icon|image/jpe?g|image/gif|image/webp|image/svg\+xml#', strtolower($ct)) !== 1) {
, and you don't needstrtolower
there since all$headers[]
already have lowercase.the
$header_pieces = explode(': ', $header_value);
change': '
to':'
(without trailing space). It can help to handle some wrong headers. Anyway you dotrim()
after.add the
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36');
to set useragent otherwise something likecurl/7.29.0
will be used by default and a lot of hostings treat it as bot (an ban it).its heplful to add
CURLOPT_SSL_VERIFYPEER
andCURLOPT_SSL_VERIFYHOST
options to avoid SSL problems with some hostings:$version = curl_version();
if ($version !==FALSE && ($version['features'] & CURL_VERSION_SSL)) { // Curl do support SSL
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
}