Hosting a GWT Webapp in IIS
-
03-12-2019 - |
Question
I am currently trying to configure an ASP.net Web Application through Web.config, to host a GWT WebApp in a specific folder. I've managed to configure the mimeMap for the .manifest file extension in the system.Webserver/staticContent section however, i'm stuck with the clientCache. I want to add a caching rule so that files with ".nocache." are served with the following headers:
"Expires", "Sat, 21 Jan 2012 12:12:02 GMT" (today -1);
"Pragma", "no-cache"
"Cache-control", "no-cache, no-store, must-revalidate"
Anyone knows how to do this within IIS 7+ ?
Solution 2
I ended up creating a custom httphandler to handle all the requests to the path .nocache. using a solution similar to the one described in here:
OTHER TIPS
The file time stamp is automatically checked in IIS and the browser always requests the server for updated file based on the timestamp, so the .nocache. files don't need anything special in IIS.
However if you wanted the browser to cache the .cache. files then the following HttpModule sets the cache expiration date to 30 days from now for files that end in .cache.js or .cache.html (or any extension). The browser won't even request for updated versions of these files.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace CacheModulePlayground
{
public class CacheModule : IHttpModule
{
private HttpApplication _context;
public void Init(HttpApplication context)
{
_context = context;
context.PreSendRequestHeaders += context_PreSendRequestHeaders;
}
void context_PreSendRequestHeaders(object sender, EventArgs e)
{
if (_context.Response.StatusCode == 200 || _context.Response.StatusCode == 304)
{
var path = _context.Request.Path;
var dotPos = path.LastIndexOf('.');
if (dotPos > 5)
{
var preExt = path.Substring(dotPos - 6, 7);
if (preExt == ".cache.")
{
_context.Response.Cache.SetExpires(DateTime.UtcNow.Add(TimeSpan.FromDays(30)));
}
}
}
}
public void Dispose()
{
_context = null;
}
}
}
The web.config for this is:
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
<system.webServer>
<modules>
<add name="cacheExtension" type="CacheModulePlayground.CacheModule"/>
</modules>
</system.webServer>
</configuration>
Create an HTTP module class in GwtCacheHttpModuleImpl.cs file
using System; using System.Web; using System.Text.RegularExpressions; namespace YourNamespace { /// <summary> /// Classe GwtCacheHttpModuleImpl /// /// Permet de mettre en cache pour un an ou pas du tout les fichiers générés par GWT /// </summary> public class GwtCacheHttpModuleImpl : IHttpModule { private HttpApplication _context; private static String GWT_FILE_EXTENSIONS_REGEX_STRING = "\\.(js|html|png|bmp|jpg|gif|htm|css|ttf|svg|woff|txt)$"; private static Regex GWT_CACHE_OR_NO_CACHE_FILE_REGEX = new Regex(".*\\.(no|)cache" + GWT_FILE_EXTENSIONS_REGEX_STRING); private static Regex GWT_CACHE_FILE_REGEX = new Regex(".*\\.cache" + GWT_FILE_EXTENSIONS_REGEX_STRING); #region IHttpModule Membres public void Dispose() { _context = null; } public void Init(HttpApplication context) { context.PreSendRequestHeaders += context_PreSendRequestHeaders; _context = context; } #endregion private void context_PreSendRequestHeaders(object sender, EventArgs e) { int responseStatusCode = _context.Response.StatusCode; switch (responseStatusCode) { case 200: case 304: // Réponse gérée break; default: // Réponse non gérée return; } /* end..switch */ String requestPath = _context.Request.Path; if (!GWT_CACHE_OR_NO_CACHE_FILE_REGEX.IsMatch(requestPath)) { // Fichier non géré return; } HttpCachePolicy cachePolicy = _context.Response.Cache; if (GWT_CACHE_FILE_REGEX.IsMatch(requestPath)) { // Fichier à mettre en cache cachePolicy.SetExpires(DateTime.UtcNow.Add(TimeSpan.FromDays(365))); /* now plus 1 year */ } else { // Fichier à ne pas mettre en cache cachePolicy.SetExpires(DateTime.UtcNow); /* ExpiresDefault "now" */ cachePolicy.SetMaxAge(TimeSpan.Zero); /* max-age=0 */ cachePolicy.SetCacheability(HttpCacheability.Public); /* Cache-Control public */ cachePolicy.SetRevalidation(HttpCacheRevalidation.AllCaches); /* must-revalidate */ } } } }
Reference your HTTP module in Web.Config file :
Handle GWT file extention via ISAPI module
You should configure your application via IIS UI ( IIS 5.x and .NET 3.5 in my case ). You could add other GWT file extensions like png, css, ...
a) Handle .js extension
Executable : c:\windows\microsoft.net\framework\v2.0.50727\aspnet_isapi.dll
Extension : .js
Limit to : GET,HEAD
b) Handle .html extension
Executable : c:\windows\microsoft.net\framework\v2.0.50727\aspnet_isapi.dll
Extension : .html
Limit to : GET,HEAD
Reference : GWT Perfect Caching for Apache server