diff --git a/config-templates/config.php b/config-templates/config.php index f6de5cba9ef599b0a417640d3dda6d748a74177b..9d267be49d2f608b3e9b3d17d279ae3146b183f2 100644 --- a/config-templates/config.php +++ b/config-templates/config.php @@ -861,6 +861,31 @@ $config = [ */ 'production' => true, + /* + * SimpleSAMLphp modules can host static resources which are served through PHP. + * The serving of the resources can be configured through these settings. + */ + 'assets' => [ + /* + * These settings adjust the caching headers that are sent + * when serving static resources. + */ + 'caching' => [ + /* + * Amount of seconds before the resource should be fetched again + */ + 'max_age' => 86400, + /* + * Calculate a checksum of every file and send it to the browser + * This allows the browser to avoid downloading assets again in situations + * where the Last-Modified header cannot be trusted, + * for example in cluster setups + * + * Defaults false + */ + 'etag' => false, + ], + ], /********************* diff --git a/lib/SimpleSAML/Module.php b/lib/SimpleSAML/Module.php index e0bf063a5c4f59b7da97ed64927f250333936786..31e970bbb031e758a488bea57779fecd0dafd2da 100644 --- a/lib/SimpleSAML/Module.php +++ b/lib/SimpleSAML/Module.php @@ -264,12 +264,21 @@ class Module } } + $assetConfig = $config->getConfigItem('assets', new Configuration([], '[assets]')); + $cacheConfig = $assetConfig->getConfigItem('caching', new Configuration([], '[assets][caching]')); $response = new BinaryFileResponse($path); - $response->setCache(['public' => true, 'max_age' => 86400]); - $response->setExpires(new \DateTime(gmdate('D, j M Y H:i:s \G\M\T', time() + 10 * 60))); - $response->setLastModified(new \DateTime(gmdate('D, j M Y H:i:s \G\M\T', filemtime($path)))); + $response->setCache([ + // "public" allows response caching even if the request was authenticated, + // which is exactly what we want for static resources + 'public' => true, + 'max_age' => (string)$cacheConfig->getInteger('max_age', 86400) + ]); + $response->setAutoLastModified(); + if ($cacheConfig->getBoolean('etag', false)) { + $response->setAutoEtag(); + } + $response->isNotModified($request); $response->headers->set('Content-Type', $contentType); - $response->headers->set('Content-Length', sprintf('%u', filesize($path))); // force file size to an unsigned $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_INLINE); $response->prepare($request); return $response;