Added a proxy script to allow CORS access for `manifest.json`
authorAlexander Ebert <ebert@woltlab.com>
Fri, 20 Oct 2017 11:36:18 +0000 (13:36 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Fri, 20 Oct 2017 11:36:18 +0000 (13:36 +0200)
wcfsetup/install/files/images/favicon/corsProxy.php [new file with mode: 0644]
wcfsetup/install/files/lib/data/style/Style.class.php

diff --git a/wcfsetup/install/files/images/favicon/corsProxy.php b/wcfsetup/install/files/images/favicon/corsProxy.php
new file mode 100644 (file)
index 0000000..37cdf3c
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Serves the manifest.json to properly allow cross-domain (CORS) fetching.
+ * 
+ * @author     Alexander
+ * @copyright  2001-2017 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ */
+$types = [
+       'manifest' => [
+               'filename' => 'manifest.json',
+               'type' => 'application/json'
+       ]
+];
+if (!empty($_GET['type']) || !isset($types[$_GET['type']])) {
+       // get parameters
+       $type = $_GET['type'];
+       $styleID = (!empty($_GET['styleID'])) ? intval($_GET['styleID']) : 'default';
+       if ($styleID === 'default' || $styleID > 0) {
+               $filename = $styleID . '.' . $types[$type]['filename'];
+               if (file_exists($filename)) {
+                       $filemtime = filemtime($filename);
+                       
+                       $etag = '"' . md5($filemtime . $filename) . '"';
+                       $clientEtag = (!empty($_SERVER['HTTP_IF_NONE_MATCH'])) ? trim($_SERVER['HTTP_IF_NONE_MATCH']) : '';
+                       $clientLastModified = (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE'])) ? trim($_SERVER['HTTP_IF_MODIFIED_SINCE']) : 0;
+                       $clientLastModified = @strtotime($clientLastModified);
+                       
+                       // ignore request if client seems to already have fetched this file
+                       if (($clientLastModified && $clientEtag) ? (($clientLastModified == $filemtime) && ($clientEtag == $etag)) : ($clientLastModified == $filemtime) ) {
+                               header("HTTP/1.1 304 Not Modified");
+                               exit;
+                       }
+                       
+                       $data = file_get_contents($filename);
+                       
+                       // send cache and type headers
+                       // allow font fetching from all domains (CORS)
+                       header('Access-Control-Allow-Origin: *');
+                       header('Content-Type: ' . $types[$type]['type']);
+                       header('Cache-Control: max-age=31536000, private');
+                       header('ETag: ' . $etag);
+                       header('Expires: ' . gmdate("D, d M Y H:i:s", time() + 31536000) . ' GMT');
+                       header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $filemtime) . ' GMT');
+                       header('Content-Length: ' . strlen($data));
+                       
+                       die($data);
+               }
+               
+               header("HTTP/1.1 404 Not Found");
+               die("Unknown file '" . $filename . "' requested.");
+       }
+       
+       header("HTTP/1.1 400 Bad Request");
+       die("Invalid styleID '" . $styleID . "' given");
+}
+
+header("HTTP/1.1 400 Bad Request");
+die("Missing type parameter");
index ea485f0f321c21b2a8077f50de7bd5bd440b248d..99e8791b7a38d6cc1a6ae85a72a3a0eb8cb30585 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 namespace wcf\data\style;
 use wcf\data\DatabaseObject;
+use wcf\system\application\ApplicationHandler;
 use wcf\system\WCF;
 
 /**
@@ -152,6 +153,12 @@ class Style extends DatabaseObject {
        }
        
        protected function getFaviconPath($filename, $absolutePath = true) {
+               if ($filename === 'manifest.json') {
+                       if (ApplicationHandler::getInstance()->getActiveApplication()->domainName !== ApplicationHandler::getInstance()->getApplicationByID(1)->domainName) {
+                               return WCF::getPath() . 'images/favicon/corsProxy.php?type=manifest' . ($this->hasFavicon ? '&amp;styleID=' . $this->styleID : '');
+                       }
+               }
+               
                $path = 'images/favicon/'. ($this->hasFavicon ? $this->styleID : 'default') . ".{$filename}";
                if ($absolutePath) {
                        return WCF::getPath() . $path;