Changeset 6562


Ignore:
Timestamp:
Oct 14, 2014, 7:53:51 AM (9 years ago)
Author:
Nicklas Nordborg
Message:

Fixes #1867: Prevent browsers from caching scripts and style sheets between releases

Append version numbers to URLs for scripts and style sheets. Uses BASE version (?v=3.3.2) except for files in /extensions directory which uses the extension version (?v=2.16.1).

Location:
branches/3.3-stable/src/clients/web/net/sf/basedb/clients/web
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/3.3-stable/src/clients/web/net/sf/basedb/clients/web/extensions/WebClientRegisterExtensionsProcessor.java

    r6417 r6562  
    2323
    2424import net.sf.basedb.clients.web.servlet.ContentSecurityPolicyFilter;
     25import net.sf.basedb.clients.web.taglib.Head;
    2526import net.sf.basedb.core.plugin.About;
    2627import net.sf.basedb.util.Values;
     
    9899      ContentSecurityPolicyFilter.setSafeResources(xtFile.getName(), safeResources);
    99100    }
     101    // Register the version of this extension so
     102    // we can append ?version to script and css URLs
     103    if (about != null && about.getVersion() != null)
     104    {
     105      Head.setExtensionVersion(xtFile.getName(), about.getVersion());
     106    }
    100107
    101108    super.processFile(manager, wFile);
  • branches/3.3-stable/src/clients/web/net/sf/basedb/clients/web/taglib/Head.java

    r6525 r6562  
    2323package net.sf.basedb.clients.web.taglib;
    2424
     25import net.sf.basedb.clients.web.extensions.ExtensionsControl;
     26import net.sf.basedb.clients.web.util.HTML;
    2527import net.sf.basedb.core.SessionControl;
     28import net.sf.basedb.core.Version;
    2629import net.sf.basedb.util.Values;
    2730
     31import java.util.HashMap;
    2832import java.util.LinkedHashSet;
    2933import java.util.Arrays;
    30 
     34import java.util.Map;
     35import java.util.regex.Matcher;
     36import java.util.regex.Pattern;
     37
     38import javax.servlet.http.HttpServletRequest;
    3139import javax.servlet.jsp.JspException;
    3240import javax.servlet.jsp.JspTagException;
     41import javax.servlet.jsp.PageContext;
    3342import javax.servlet.jsp.tagext.TagSupport;
    3443
     
    91100  private static final long serialVersionUID = 948719986796860767L;
    92101
     102  // Contain the file name of extension JAR files mapped to versions
     103  private static final Map<String, String> xtVersions = new HashMap<String, String>();
     104
     105  // Match files under /extensions path. group 2 is the JAR file name
     106  private static final Pattern PATH_MATCH =
     107      Pattern.compile("(" + ExtensionsControl.RESOURCES_URL + "/([^/]+)/(.*))");
     108
     109  /**
     110    Register the version for an exteniosn JAR file
     111    @since 3.3.2
     112  */
     113  public static void setExtensionVersion(String jarName, String version)
     114  {
     115    synchronized (xtVersions)
     116    {
     117      xtVersions.put(jarName, "v="+HTML.urlEncode(version));
     118    }
     119  }
     120
    93121  /**
    94122    The parent &lt;base:page&gt; tag.
     
    105133  */
    106134  private String scripts = null;
     135 
     136  private static final String globalVersion = "v=" + Version.getMajor()+"."+Version.getMinor()+"."+Version.getMaintenance();
     137  private String localVersion;
    107138 
    108139  /*
     
    143174    for (String style : allStyles)
    144175    {
     176      char pp = style.indexOf('?') == -1 ? '?' : '&';
    145177      sb.append("\t<link rel=\"stylesheet\" type=\"text/css\" href=\"");
    146178      if (style.startsWith(appRoot))
    147179      {
    148180        // Full absolute path
    149         sb.append(style);
     181        sb.append(style).append(pp).append(globalVersion);
    150182      }
    151183      else if (style.startsWith("/"))
    152184      {
    153185        // Absolute path is relative the page root (eg. /foo/bar.css --> /base/foo/bar.css)
    154         sb.append(appRoot).append(style.substring(1));
     186        sb.append(appRoot).append(style.substring(1)).append(pp).append(globalVersion);
    155187      }
    156188      else if (style.startsWith("~"))
    157189      {
    158190        // Relative path is relative the current page (eg. ~bar.css --> bar.css)
    159         sb.append(style.substring(1));
     191        sb.append(style.substring(1)).append(pp).append(localVersion);
    160192      }
    161193      else
    162194      {
    163195        // All other style sheets are in the /include/styles folder
    164         sb.append(appRoot).append("include/styles/").append(style);
     196        sb.append(appRoot).append("include/styles/").append(style).append(pp).append(globalVersion);
    165197      }
    166198      sb.append("\">\n");
     
    192224    for (String script : allScripts)
    193225    {
     226      char pp = script.indexOf('?') == -1 ? '?' : '&';
    194227      sb.append("\t<script type=\"text/javascript\" charset=\"UTF-8\" src=\"");
    195228      if (script.startsWith(appRoot))
    196229      {
    197230        // Full absolute path
    198         sb.append(script);
     231        sb.append(script).append(pp).append(globalVersion);
    199232      }
    200233      else if (script.startsWith("/"))
    201234      {
    202235        // Absolute path that is relative the BASE root (eg. /foo/bar.js --> /base/foo/bar.js)
    203         sb.append(appRoot).append(script.substring(1));
     236        sb.append(appRoot).append(script.substring(1)).append(pp).append(globalVersion);
    204237      }
    205238      else if (script.startsWith("~"))
    206239      {
    207240        // Relative path is relative the current page (eg. ~bar.js --> bar.js)
    208         sb.append(script.substring(1));
     241        sb.append(script.substring(1)).append(pp).append(localVersion);
    209242      }
    210243      else
    211244      {
    212245        // All other scripts are in the /include/scripts folder
    213         sb.append(appRoot).append("include/scripts/").append(script);
     246        sb.append(appRoot).append("include/scripts/").append(script).append(pp).append(globalVersion);
    214247      }
    215248      sb.append("\"></script>\n");
     
    217250  }
    218251
     252  @Override
     253  public void setPageContext(PageContext pageContext)
     254  {
     255    super.setPageContext(pageContext);
     256
     257    // If we are on /extension subpage, the localVersion is the
     258    // version for the extension, otherwise we use the global version
     259    localVersion = globalVersion;
     260    HttpServletRequest req = (HttpServletRequest)pageContext.getRequest();
     261    Matcher m = PATH_MATCH.matcher(req.getServletPath());
     262    if (m.matches())
     263    {
     264      String jarFile = m.group(2);
     265      if (xtVersions.containsKey(jarFile))
     266      {
     267        localVersion = xtVersions.get(jarFile);
     268      }
     269    }
     270  }
     271 
     272 
    219273  @Override
    220274  public int doStartTag()
Note: See TracChangeset for help on using the changeset viewer.