mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
GUACAMOLE-275: Automatically attempt to refresh browser cache if index.html does not match current build.
This commit is contained in:
@@ -154,6 +154,7 @@
|
|||||||
<excludes>
|
<excludes>
|
||||||
<exclude>translations/*.json</exclude>
|
<exclude>translations/*.json</exclude>
|
||||||
<exclude>index.html</exclude>
|
<exclude>index.html</exclude>
|
||||||
|
<exclude>verifyCachedVersion.js</exclude>
|
||||||
</excludes>
|
</excludes>
|
||||||
</resource>
|
</resource>
|
||||||
|
|
||||||
@@ -164,6 +165,7 @@
|
|||||||
<includes>
|
<includes>
|
||||||
<include>translations/*.json</include>
|
<include>translations/*.json</include>
|
||||||
<include>index.html</include>
|
<include>index.html</include>
|
||||||
|
<include>verifyCachedVersion.js</include>
|
||||||
</includes>
|
</includes>
|
||||||
</resource>
|
</resource>
|
||||||
|
|
||||||
|
@@ -24,6 +24,7 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, target-densitydpi=medium-dpi">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, target-densitydpi=medium-dpi">
|
||||||
<meta name="mobile-web-app-capable" content="yes">
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="build" content="${guacamole.build.identifier}">
|
||||||
<link rel="icon" type="image/png" href="images/logo-64.png">
|
<link rel="icon" type="image/png" href="images/logo-64.png">
|
||||||
<link rel="icon" type="image/png" sizes="144x144" href="images/logo-144.png">
|
<link rel="icon" type="image/png" sizes="144x144" href="images/logo-144.png">
|
||||||
<link rel="apple-touch-icon" type="image/png" href="images/logo-144.png">
|
<link rel="apple-touch-icon" type="image/png" href="images/logo-144.png">
|
||||||
@@ -34,7 +35,7 @@
|
|||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
<!-- Extension CSS (must be able to override webapp CSS) -->
|
<!-- Extension CSS (must be able to override webapp CSS) -->
|
||||||
<link rel="stylesheet" type="text/css" href="app.css?v=${project.version}">
|
<link rel="stylesheet" type="text/css" href="app.css?b=${guacamole.build.identifier}">
|
||||||
|
|
||||||
<title ng-bind="page.title | translate"></title>
|
<title ng-bind="page.title | translate"></title>
|
||||||
</head>
|
</head>
|
||||||
@@ -105,7 +106,7 @@
|
|||||||
<script type="text/javascript" src="templates.js"></script>
|
<script type="text/javascript" src="templates.js"></script>
|
||||||
|
|
||||||
<!-- Extension JavaScript -->
|
<!-- Extension JavaScript -->
|
||||||
<script type="text/javascript" src="app.js?v=${project.version}"></script>
|
<script type="text/javascript" src="app.js?b=${guacamole.build.identifier}"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
85
guacamole/src/main/frontend/src/verifyCachedVersion.js
Normal file
85
guacamole/src/main/frontend/src/verifyCachedVersion.js
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Automatically reloads the current page and clears relevant browser cache if
|
||||||
|
* the build that produced index.html is different/older than the build that
|
||||||
|
* produced the JavaScript loaded by index.html.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Location} location
|
||||||
|
* The Location object representing the URL of the current page.
|
||||||
|
*
|
||||||
|
* @param {Storate} [sessionStorage]
|
||||||
|
* The Storage object that should optionally be used to avoid reloading the
|
||||||
|
* current page in a loop if it proves impossible to clear cache.
|
||||||
|
*/
|
||||||
|
(function verifyCachedVersion(location, sessionStorage) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The meta element containing the build identifier of the Guacamole build
|
||||||
|
* that produced index.html.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @type {HTMLMetaElement}
|
||||||
|
*/
|
||||||
|
var buildMeta = document.head.querySelector('meta[name=build]');
|
||||||
|
|
||||||
|
// Verify that index.html came from the same build as this JavaScript file,
|
||||||
|
// forcing a reload if out-of-date
|
||||||
|
if (!buildMeta || buildMeta.content !== '${guacamole.build.identifier}') {
|
||||||
|
|
||||||
|
if (sessionStorage) {
|
||||||
|
|
||||||
|
// Bail out if we have already tried to automatically refresh the
|
||||||
|
// cache but were unsuccessful
|
||||||
|
if (sessionStorage.getItem('reloadedFor') === '${guacamole.build.identifier}') {
|
||||||
|
console.warn('The version of Guacamole cached by your '
|
||||||
|
+ 'browser does not match the version of Guacamole on the '
|
||||||
|
+ 'server. To avoid unexpected errors, please clear your '
|
||||||
|
+ 'browser cache.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sessionStorage.setItem('reloadedFor', '${guacamole.build.identifier}');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force refresh of cache by issuing an HTTP request with headers that
|
||||||
|
// request revalidation of cached content
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('GET', '', true);
|
||||||
|
xhr.setRequestHeader('Cache-Control', 'no-cache');
|
||||||
|
xhr.setRequestHeader('Pragma', 'no-cache');
|
||||||
|
|
||||||
|
xhr.onreadystatechange = function readyStateChanged() {
|
||||||
|
|
||||||
|
// Reload current page when ready (this call to reload MAY be
|
||||||
|
// sufficient in itself to clear cache, but this is not
|
||||||
|
// guaranteed by any standard)
|
||||||
|
if (xhr.readyState === XMLHttpRequest.DONE)
|
||||||
|
location.reload(true);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
xhr.send();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
})(window.location, window.sessionStorage);
|
@@ -121,7 +121,8 @@ module.exports = {
|
|||||||
{ from: 'fonts/**/*' },
|
{ from: 'fonts/**/*' },
|
||||||
{ from: 'images/**/*' },
|
{ from: 'images/**/*' },
|
||||||
{ from: 'layouts/**/*' },
|
{ from: 'layouts/**/*' },
|
||||||
{ from: 'translations/**/*' }
|
{ from: 'translations/**/*' },
|
||||||
|
{ from: 'verifyCachedVersion.js' }
|
||||||
], {
|
], {
|
||||||
context: 'src/'
|
context: 'src/'
|
||||||
}),
|
}),
|
||||||
|
@@ -41,6 +41,7 @@ import org.apache.guacamole.properties.StringSetProperty;
|
|||||||
import org.apache.guacamole.resource.Resource;
|
import org.apache.guacamole.resource.Resource;
|
||||||
import org.apache.guacamole.resource.ResourceServlet;
|
import org.apache.guacamole.resource.ResourceServlet;
|
||||||
import org.apache.guacamole.resource.SequenceResource;
|
import org.apache.guacamole.resource.SequenceResource;
|
||||||
|
import org.apache.guacamole.resource.WebApplicationResource;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -598,6 +599,9 @@ public class ExtensionModule extends ServletModule {
|
|||||||
Collection<Resource> javaScriptResources = new ArrayList<Resource>();
|
Collection<Resource> javaScriptResources = new ArrayList<Resource>();
|
||||||
Collection<Resource> cssResources = new ArrayList<Resource>();
|
Collection<Resource> cssResources = new ArrayList<Resource>();
|
||||||
|
|
||||||
|
// Veriffy that the possibly-cached index.html matches the current build
|
||||||
|
javaScriptResources.add(new WebApplicationResource(getServletContext(), "/verifyCachedVersion.js"));
|
||||||
|
|
||||||
// Load all extensions
|
// Load all extensions
|
||||||
final Set<String> toleratedAuthProviders = getToleratedAuthenticationProviders();
|
final Set<String> toleratedAuthProviders = getToleratedAuthenticationProviders();
|
||||||
loadExtensions(javaScriptResources, cssResources, toleratedAuthProviders);
|
loadExtensions(javaScriptResources, cssResources, toleratedAuthProviders);
|
||||||
|
22
pom.xml
22
pom.xml
@@ -115,19 +115,37 @@
|
|||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<!-- Define a "rootlocation" property that can be used to reference
|
|
||||||
the location of the main guacamole-client directory -->
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
<artifactId>build-helper-maven-plugin</artifactId>
|
<artifactId>build-helper-maven-plugin</artifactId>
|
||||||
<version>3.2.0</version>
|
<version>3.2.0</version>
|
||||||
<executions>
|
<executions>
|
||||||
|
|
||||||
|
<!-- Define a "rootlocation" property that can be used to
|
||||||
|
reference the location of the main guacamole-client
|
||||||
|
directory -->
|
||||||
<execution>
|
<execution>
|
||||||
<id>define-project-root</id>
|
<id>define-project-root</id>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>rootlocation</goal>
|
<goal>rootlocation</goal>
|
||||||
</goals>
|
</goals>
|
||||||
</execution>
|
</execution>
|
||||||
|
|
||||||
|
<!-- Define a "guacamole.build.identifier" property that
|
||||||
|
can be used to uniquely identify the current build
|
||||||
|
relative to previous builds -->
|
||||||
|
<execution>
|
||||||
|
<id>define-build-timestamp</id>
|
||||||
|
<configuration>
|
||||||
|
<name>guacamole.build.identifier</name>
|
||||||
|
<timeSource>build</timeSource>
|
||||||
|
<pattern>yyyyMMddHHmmss</pattern>
|
||||||
|
</configuration>
|
||||||
|
<goals>
|
||||||
|
<goal>timestamp-property</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user