Save state
authorMatthias Schmidt <gravatronics@live.com>
Mon, 3 Aug 2015 18:36:46 +0000 (20:36 +0200)
committerMatthias Schmidt <gravatronics@live.com>
Wed, 12 Aug 2015 17:03:13 +0000 (19:03 +0200)
wcfsetup/install/files/lib/action/ImageProxyAction.class.php [new file with mode: 0644]

diff --git a/wcfsetup/install/files/lib/action/ImageProxyAction.class.php b/wcfsetup/install/files/lib/action/ImageProxyAction.class.php
new file mode 100644 (file)
index 0000000..f2d5e0a
--- /dev/null
@@ -0,0 +1,90 @@
+<?php
+namespace wcf\action;
+use wcf\system\exception\IllegalLinkException;
+use wcf\system\exception\SystemException;
+use wcf\util\FileUtil;
+use wcf\util\HTTPRequest;
+use wcf\util\StringUtil;
+
+/**
+ * Caches external images locally.
+ * 
+ * @author     Matthias Schmidt
+ * @copyright  2001-2015 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    com.woltlab.wcf
+ * @subpackage action
+ * @category   Community Framework
+ */
+class ImageProxyAction extends AbstractAction {
+       /**
+        * hashed image proxy secret and image url
+        * @var string
+        */
+       public $hash = '';
+       
+       /**
+        * url-encoded image url
+        * @var string
+        */
+       public $url = '';
+       
+       /**
+        * @see \wcf\action\IAction::readParameters()
+        */
+       public function readParameters() {
+               parent::readParameters();
+               
+               if (isset($_REQUEST['url'])) $this->url = StringUtil::trim($_REQUEST['url']);
+               if (isset($_REQUEST['hash'])) $this->hash = StringUtil::trim($_REQUEST['hash']);
+       }
+       
+       /**
+        * @see \wcf\action\IAction::execute()
+        */
+       public function execute() {
+               parent::execute();
+               
+               $url = urldecode($this->url);
+               $hash = sha1(IMAGE_PROXY_SECRET.$url);
+               if ($this->hash != $hash) {
+                       throw new IllegalLinkException();
+               }
+               
+               try {
+                       $request = new HTTPRequest($url);
+                       $request->execute();
+                       $reply = $request->getReply();
+                       
+                       $fileExtension = '';
+                       if (($position = mb_strrpos($url, '.')) !== false) {
+                               $fileExtension = mb_strtolower(mb_substr($url, $position + 1));
+                       }
+                       
+                       // check if requested content is image
+                       if (!isset($reply['headers']['Content-Type']) || !StringUtil::startsWith($reply['headers']['Content-Type'], 'image/')) {
+                               throw new IllegalLinkException();
+                       }
+                       
+                       // save image
+                       $fileLocation = WCF_DIR.'images/proxy/'.substr($hash, 0, 2).'/'.$hash.($fileExtension ? '.'.$fileExtension : '');
+                       $dir = dirname($fileLocation);
+                       if (!@file_exists($dir)) {
+                               FileUtil::makePath($dir, 0777);
+                       }
+                       file_put_contents($fileLocation, $reply['body']);
+                       
+                       // update mtime for correct expiration calculation
+                       @touch($fileLocation);
+                       
+                       $this->executed();
+                       
+                       @header('Content-Type: '.$reply['headers']['Content-Type']);
+                       @readfile($fileLocation);
+                       exit;
+               }
+               catch (SystemException $e) {
+                       throw new IllegalLinkException();
+               }
+       }
+}