I finally got around to writing a filter for the nocache file, to use the
ETag method:
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import team.drift.server.managers.ServerUtils;
import java.io.IOException;
@Component
@Order(1)
public class ServletFilter implements Filter {
private static final String NO_CACHE = ".nocache.js";
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain
chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)res;
if (request.getRequestURI() .endsWith(NO_CACHE) && handleNoCacheFile(
request, response)) {
return;
}
chain.doFilter(request, response);
}
private static boolean handleNoCacheFile(HttpServletRequest httpRequest,
HttpServletResponse
httpResponse) {
String serverVersion = getServerVersion();
String quotedETag = "\"" + serverVersion + "\"";
httpResponse.setHeader("ETag", quotedETag);
httpResponse.setHeader("Cache-Control", "no-cache, must-revalidate");
String ifNoneMatch = httpRequest.getHeader("If-None-Match");
if (quotedETag.equals(ifNoneMatch)) {
httpResponse.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
return true;
}
return false;
}
}
This "getServerVersion()" is up to you on how you get your deployed unique
version string. If you are using Google App Engine, you can do
System.getenv("GAE_VERSION");
It seems to work well. Please let me know if I've messed anything up.
On Wednesday, 8 January 2025 at 4:31:04 am UTC+11 Colin Alworth wrote:
> Thanks - I knew that Maven was explicitly opt-in, but several Gradle
> projects I've worked on have hit this issue so I assumed it was a facet of
> Gradle itself. Turns out instead, a single plugin shared among these
> projects, only referenced indirectly, was traversing the tasks of all
> projects and applying this. I guess you can draw an analogy to a maven
> parent pom doing configuration you didn't expect, except any plugin with
> access to the Project instance could technically have done this.
>
> I also excluded Bazel, as the few developers who use it beyond trivial
> examples already will need to deeply understand its internals, and so would
> already expect this.
>
> On Tuesday, January 7, 2025 at 3:52:48 AM UTC-6 Thomas Broyer wrote:
>
>> On Monday, January 6, 2025 at 4:46:51 PM UTC+1 Colin Alworth wrote:
>>
>> Take a little care with testing/validating etag though - stock Jetty at
>> least does not hash the file to produce this (to avoid the expense of
>> reading the entire file to produce the hash, then re-reading it from start
>> to stream it), but uses the file modification date assuming is a valid
>> proxy for changes.
>>
>>
>> Apache HTTPD (https://httpd.apache.org/docs/2.4/mod/core.html#fileetag)
>> and Nginx (
>> https://github.com/nginx/nginx/blob/e3a9b6ad08a86e799a3d77da3f2fc507d3c9699e/src/http/ngx_http_core_module.c#L1701-L1704)
>>
>> do something similar
>>
>>
>> Thwarting this, gradle helpfully sets file metadata in a jar/war to a
>> point decades in the past, regardless of actual values, to ensure its own
>> caching isn't impacted by files being refreshed.
>>
>>
>> Gradle doesn't do that by default, this is part of an explicit
>> configuration to get reproducible builds:
>> https://docs.gradle.org/current/dsl/org.gradle.api.tasks.bundling.Jar.html#org.gradle.api.tasks.bundling.Jar:preserveFileTimestamps
>> You'd have the same issues with Bazel (does reproducible builds by
>> default) or Maven (
>> https://maven.apache.org/guides/mini/guide-reproducible-builds.html)
>>
>>
--
You received this message because you are subscribed to the Google Groups "GWT
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/google-web-toolkit/facb6a0f-b569-41a9-a3c7-5f6775b17210n%40googlegroups.com.