1<?php
2// cacheable.php -- HotCRP cacheability helper
3// Copyright (c) 2006-2018 Eddie Kohler; see LICENSE.
4
5session_cache_limiter("");
6header("Cache-Control: max-age=315576000, public");
7header("Expires: " . gmdate("D, d M Y H:i:s", time() + 315576000) . " GMT");
8
9// *** NB This file does not include all of the HotCRP infrastructure! ***
10$zlib_output_compression = false;
11if (function_exists("zlib_get_coding_type"))
12    $zlib_output_compression = zlib_get_coding_type();
13if ($zlib_output_compression) {
14    header("Content-Encoding: $zlib_output_compression");
15    header("Vary: Accept-Encoding", false);
16}
17
18function fail($reason, $file) {
19    global $zlib_output_compression;
20    header("HTTP/1.0 $reason");
21    header("Content-Type: text/plain; charset=utf-8");
22    $result = "$file\r\n";
23    if (!$zlib_output_compression)
24        header("Content-Length: " . strlen($result));
25    echo $result;
26    exit;
27}
28
29$file = isset($_GET["file"]) ? $_GET["file"] : null;
30if (!$file) {
31    fail("400 Bad Request", "File missing");
32}
33
34$prefix = "";
35if (preg_match(',\A(?:images|scripts|stylesheets)(?:/[^./][^/]+)+\z,', $file)
36    && preg_match(',.*(\.[a-z0-9]*)\z,', $file, $m)) {
37    $s = $m[1];
38    if ($s === ".js") {
39        header("Content-Type: text/javascript; charset=utf-8");
40        if (isset($_GET["strictjs"]) && $_GET["strictjs"])
41            $prefix = "\"use strict\";\n";
42    } else if ($s === ".map")
43        header("Content-Type: application/json; charset=utf-8");
44    else if ($s === ".css")
45        header("Content-Type: text/css; charset=utf-8");
46    else if ($s === ".gif")
47        header("Content-Type: image/gif");
48    else if ($s === ".jpg")
49        header("Content-Type: image/jpeg");
50    else if ($s === ".png")
51        header("Content-Type: image/png");
52    else if ($s === ".svg")
53        header("Content-Type: image/svg+xml");
54    else if ($s === ".mp3")
55        header("Content-Type: audio/mpeg");
56    else if ($s === ".woff")
57        header("Content-Type: application/font-woff");
58    else if ($s === ".woff2")
59        header("Content-Type: application/font-woff2");
60    else if ($s === ".ttf")
61        header("Content-Type: application/x-font-ttf");
62    else if ($s === ".otf")
63        header("Content-Type: font/opentype");
64    else if ($s === ".eot")
65        header("Content-Type: application/vnd.ms-fontobject");
66    else
67        fail("403 Forbidden", "File cannot be served");
68    header("Access-Control-Allow-Origin: *");
69} else
70    fail("403 Forbidden", "File cannot be served");
71
72$mtime = @filemtime($file);
73if ($mtime === false)
74    fail("404 Not Found", "File not found");
75$last_modified = gmdate("D, d M Y H:i:s", $mtime) . " GMT";
76$etag = '"' . md5("$file $last_modified") . '"';
77header("Last-Modified: $last_modified");
78header("ETag: $etag");
79
80// check for a conditional request
81$if_modified_since = isset($_SERVER["HTTP_IF_MODIFIED_SINCE"]) ? $_SERVER["HTTP_IF_MODIFIED_SINCE"] : 0;
82$if_none_match = isset($_SERVER["HTTP_IF_NONE_MATCH"]) ? $_SERVER["HTTP_IF_NONE_MATCH"] : 0;
83if (($if_modified_since || $if_none_match)
84    && (!$if_modified_since || $if_modified_since === $last_modified)
85    && (!$if_none_match || $if_none_match === $etag))
86    header("HTTP/1.0 304 Not Modified");
87else if (function_exists("ob_gzhandler") && !$zlib_output_compression) {
88    ob_start("ob_gzhandler");
89    echo $prefix;
90    readfile($file);
91    ob_end_flush();
92} else {
93    if (!$zlib_output_compression)
94        header("Content-Length: " . (filesize($file) + strlen($prefix)));
95    echo $prefix;
96    readfile($file);
97}
98