140 lines
4.7 KiB
PHP
140 lines
4.7 KiB
PHP
<?php
|
|
// ithumb Endpoint
|
|
// This endpoint creates (if needed) and returns a smaller version of an image share as binary data that can be the source of an HTML img element
|
|
include ("common.php");
|
|
require __DIR__ . '/vendor/autoload.php';
|
|
|
|
//Handle more specific queries
|
|
$itemid = null;
|
|
$imgSize = 128;
|
|
if (isset($_GET["size"]))
|
|
$imgSize = $_GET["size"];
|
|
if (isset($_GET['itemid']) && $_GET['itemid'] != "") {
|
|
$itemid = $_GET['itemid'];
|
|
} else { //Accept a blanket query
|
|
if (isset($_SERVER['QUERY_STRING']) && $_SERVER['QUERY_STRING'] != "")
|
|
$itemid = $_SERVER['QUERY_STRING'];
|
|
}
|
|
if (!isset($itemid)) { //Deal with no usable request
|
|
gracefuldeath_httpcode(400);
|
|
}
|
|
|
|
$sharehandle = base64url_decode($itemid);
|
|
$shareparts = explode("|", $sharehandle);
|
|
if (count($shareparts) > 1) {
|
|
$username = strtolower($shareparts[0]);
|
|
$contentid = $shareparts[1];
|
|
|
|
if (!is_dir("data/" . $username)) {
|
|
gracefuldeath_httpcode(417);
|
|
}
|
|
|
|
//Make sure the file exists and can be loaded
|
|
$jsondata = get_share_data($username, $config['readonlykey'], 'gracefuldeath_httpcode');
|
|
$found = false;
|
|
foreach ($jsondata['shares'] as $share => $value) {
|
|
if ($contentid == $value['guid'])
|
|
{
|
|
$found = true;
|
|
// Validate source file path to prevent path traversal
|
|
if (!validate_file_path($value['content'], $username)) {
|
|
error_log("Path traversal attempt in ithumb.php (source): " . $value['content']);
|
|
gracefuldeath_httpcode(403);
|
|
}
|
|
|
|
//Prepare the cache name
|
|
$cacheID = "thumb-" . $value['guid'];
|
|
$path = "data/" . $username;
|
|
|
|
//Fetch and cache the file if its not already cached
|
|
$path = $path . "/" . $cacheID . ".png";
|
|
|
|
// Validate cache path to prevent path traversal
|
|
if (!validate_file_path($path, $username)) {
|
|
error_log("Path traversal attempt in ithumb.php (cache): " . $path);
|
|
gracefuldeath_httpcode(403);
|
|
}
|
|
|
|
if (!file_exists($path)) {
|
|
resize_img($imgSize, $path, $value['content']);
|
|
}
|
|
|
|
//Send the right headers
|
|
$info = getimagesize($path);
|
|
header("Content-Type: " . $info['mime']);
|
|
header("Content-Length: " . filesize($path));
|
|
//Dump the file and stop the script
|
|
$fp = fopen($path, 'r');
|
|
fpassthru($fp);
|
|
exit;
|
|
}
|
|
}
|
|
if (!$found) {
|
|
gracefuldeath_httpcode(410);
|
|
}
|
|
|
|
} else {
|
|
gracefuldeath_httpcode(400);
|
|
}
|
|
|
|
//Function to resize common image formats
|
|
// Found on https://stackoverflow.com/questions/13596794/resize-images-with-php-support-png-jpg
|
|
function resize_img($newWidth, $targetFile, $originalFile) {
|
|
|
|
$info = getimagesize($originalFile);
|
|
if (is_array($info))
|
|
$mime = $info['mime'];
|
|
else
|
|
$mime = "unknown";
|
|
|
|
switch ($mime) {
|
|
case 'image/jpeg':
|
|
$image_create_func = 'imagecreatefromjpeg';
|
|
$image_save_func = 'imagejpeg';
|
|
$new_image_ext = 'jpg';
|
|
break;
|
|
|
|
case 'image/png':
|
|
$image_create_func = 'imagecreatefrompng';
|
|
$image_save_func = 'imagepng';
|
|
$new_image_ext = 'png';
|
|
break;
|
|
|
|
case 'image/gif':
|
|
$image_create_func = 'imagecreatefromgif';
|
|
$image_save_func = 'imagegif';
|
|
$new_image_ext = 'gif';
|
|
break;
|
|
|
|
default:
|
|
$fileIsHeic = Maestroerror\HeicToJpg::isHeic($originalFile);
|
|
if ($fileIsHeic) {
|
|
error_log("HEIC detected, attempting conversion!");
|
|
Maestroerror\HeicToJpg::convert($originalFile, __DIR__ . "/vendor/bin/heif-converter-linux")->saveAs($originalFile);
|
|
$image_create_func = 'imagecreatefromjpeg';
|
|
$image_save_func = 'imagejpeg';
|
|
$new_image_ext = 'jpg';
|
|
} else {
|
|
throw new Exception('Unknown image type.');
|
|
}
|
|
break;
|
|
}
|
|
|
|
$img = $image_create_func($originalFile);
|
|
list($width, $height) = getimagesize($originalFile);
|
|
|
|
$newHeight = ($height / $width) * $newWidth;
|
|
$tmp = imagecreatetruecolor($newWidth, $newHeight);
|
|
imagesavealpha($tmp, true);
|
|
$trans_colour = imagecolorallocatealpha($tmp, 0, 0, 0, 127);
|
|
imagefill($tmp, 0, 0, $trans_colour);
|
|
|
|
imagecopyresampled($tmp, $img, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
|
|
|
|
if (file_exists($targetFile)) {
|
|
unlink($targetFile);
|
|
}
|
|
$image_save_func($tmp, $targetFile);
|
|
}
|
|
?>
|