From 422c17eb6547753afec07c4f6b228b266dc164e9 Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 24 Aug 2023 23:09:59 +0200 Subject: [PATCH] Added new setting to force JPGs sent as WebP if supported by the client --- .../image/image.controller.php | 34 +++++++++++++++---- docker/rootfs/start.sh | 12 ++++--- rtfm/CONFIG.md | 2 ++ rtfm/DOCKER.md | 10 ++++++ 4 files changed, 47 insertions(+), 11 deletions(-) diff --git a/content-controllers/image/image.controller.php b/content-controllers/image/image.controller.php index 584c1a2..33a4a68 100644 --- a/content-controllers/image/image.controller.php +++ b/content-controllers/image/image.controller.php @@ -123,7 +123,7 @@ class ImageController implements ContentController } } - if(in_array('webp',$url) && $type!='webp') + if( (in_array('webp',$url) && $type!='webp') || ( $this->shouldAlwaysBeWebp() && $type=='jpg' ) ) $modifiers['webp'] = true; if(in_array('forcesize',$url) && $modifiers['size']) $modifiers['forcesize'] = true; @@ -218,10 +218,13 @@ class ImageController implements ContentController $this->saveObjOfImage($im,$newpath,$type); } + else if($modifiers['webp']) + { + $type = 'webp'; + } $path = $newpath; } - switch($type) { @@ -281,22 +284,41 @@ class ImageController implements ContentController function saveObjOfImage($im,$path,$type) { + $tmppath = '/tmp/'.getNewHash($type,12); switch($type) { case 'jpeg': case 'jpg': - imagejpeg($im,$path,(defined('JPEG_COMPRESSION')?JPEG_COMPRESSION:90)); + imagejpeg($im,$tmppath,(defined('JPEG_COMPRESSION')?JPEG_COMPRESSION:90)); break; case 'png': - imagepng($im,$path,(defined('PNG_COMPRESSION')?PNG_COMPRESSION:6)); + imagepng($im,$tmppath,(defined('PNG_COMPRESSION')?PNG_COMPRESSION:6)); break; case 'webp': - imagewebp($im,$path,(defined('WEBP_COMPRESSION')?WEBP_COMPRESSION:80)); + imagewebp($im,$tmppath,(defined('WEBP_COMPRESSION')?WEBP_COMPRESSION:80)); break; } - return $im; + if(file_exists($tmppath) && filesize($tmppath)>0) + { + rename($tmppath,$path); + return $im; + } + else + { + return false; + } + + + } + + function shouldAlwaysBeWebp() + { + if(defined('ALWAYS_WEBP') && ALWAYS_WEBP && strpos( $_SERVER['HTTP_ACCEPT'], 'image/webp' ) !== false ) + return true; + else + return false; } } \ No newline at end of file diff --git a/docker/rootfs/start.sh b/docker/rootfs/start.sh index c42c9ca..aa51b21 100644 --- a/docker/rootfs/start.sh +++ b/docker/rootfs/start.sh @@ -18,6 +18,8 @@ _maxUploadSize() { _filePermissions() { chown -R nginx:nginx /var/www + touch data/sha1.csv + chown nginx:nginx data/sha1.csv } _buildConfig() { @@ -65,16 +67,16 @@ if [[ ${MAX_UPLOAD_SIZE:=100} =~ ^[0-9]+$ ]]; then _maxUploadSize fi +# run _filePermissions function unless SKIP_FILEPERMISSIONS is set to true +if [[ ${SKIP_FILEPERMISSIONS:=false} != true ]]; then + _filePermissions +fi + echo ' [+] Starting php' php-fpm7 -chown -R nginx:nginx /var/www/ - echo ' [+] Creating config' -touch data/sha1.csv -chown nginx:nginx data/sha1.csv - _buildConfig > inc/config.inc.php echo ' [+] Starting nginx' diff --git a/rtfm/CONFIG.md b/rtfm/CONFIG.md index 65b40e2..251eed5 100644 --- a/rtfm/CONFIG.md +++ b/rtfm/CONFIG.md @@ -18,10 +18,12 @@ In this file you can set the following options. For a simple working example con | MASTER_DELETE_IP | IP addr | If set, allows deletion of image no matter what delete code you provided if request is coming from this single IP | | UPLOAD_FORM_LOCATION | string | If set, will only show the upload form if this url is requested. eg if you set it to /secret/upload then you only see the form if you go to http://your.pictshare.server/secret/upload but bare in mind that the uploads [via API](/rtfm/API.md) will still work for anyone| | ALLOWED_SUBNET | IPv4 or IPv6 CIDR | If set, will limit uploads to IPs that match this CIDR | +| ALWAYS_WEBP | bool | If set to `true`, JPGs will always be served as WebP, if the client supports it (if `image/webp` is in header `HTTP_ACCEPT`) | | UPLOAD_QUOTA (NOT IMPLEMENTED) | int | Size in MB. If set, will only allow uploads if combined size of uploads on Server is smaller than this value. Does not account for ALT_FOLDER data and resized versions of original uploads won't be added to calculation | | UPLOAD_CODE (NOT IMPLEMENTED | string | If set, all uploads require this code via GET or POST variable "uploadcode" or upload will fail | | MAX_RESIZED_IMAGES (NOT IMPLEMENTED | string | If set, limits count of resized images/videos per file on server | + # Content controllers PictShare is not limited to handling just images. Various content types including txt,mp4 and even url shortenings are supported. By default all of these are enabled but if you only need one or more, you can whitelist them and all others won't be accessible. diff --git a/rtfm/DOCKER.md b/rtfm/DOCKER.md index 214ad8d..03f4f88 100644 --- a/rtfm/DOCKER.md +++ b/rtfm/DOCKER.md @@ -33,6 +33,14 @@ chown 1000 -R /data/pictshareuploads docker run -d -e "MAX_UPLOAD_SIZE=1024" -v /data/pictshareuploads:/var/www/data -p 80:80 --name=pictshare ghcr.io/hascheksolutions/pictshare ``` +### Development +Using these commands it will mount the current directory in the docker container so you can develop locally without building after each change. + +```bash +docker build -t pictshare -f docker/Dockerfile . +docker run -it --rm --name pictshare-dev -p 8080:80 -v $(pwd):/var/www -v $(pwd)/data:/var/www/data -e "URL=http://localhost:8080/" -e "SKIP_FILEPERMISSIONS=true" pictshare +``` + ## ENV Variables There are some ENV variables that only apply to the Docker image - MAX_UPLOAD_SIZE (int | size in MB that will be used for nginx. default 50) @@ -53,6 +61,8 @@ Every other variable can be referenced against the [default PictShare configurat - LOG_UPLOADER (true/false | log IPs of uploaders) - MAX_RESIZED_IMAGES (int | how many versions of a single image may exist? -1 for infinite) - SHOW_ERRORS (true/false | show upload/size/server errors?) +- SKIP_FILEPERMISSIONS (true/false | enables/disables fixing file permissions on start. default is false) +- ALWAYS_WEBP (true/false | Always tries to server JPGs as WEBp if the client supports it. Default is false) - ALT_FOLDER (path to a folder where all hashes will be copied to and looked for offsite backup via nfs for example) - S3_BUCKET (string | Name of your S3 bucket) - S3_ACCESS_KEY (string | Access Key for your Bucket)