package com.github.mizool.technology.web;

import java.io.IOException;
import java.util.Calendar;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CacheHeaderFilter extends HttpFilterAdapter
{
    private static final Pattern STATIC_ELEMENTS_PATH_PATTERN = Pattern.compile(
        "^/(webjars|\\d+(\\.\\d+)*(-[\\dA-Za-z]+)?)/.+$");

    @Override
    protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
        throws IOException, ServletException
    {
        if (isStaticPathElement(request))
        {
            addForeverCacheHeaders(response);
        }
        else
        {
            addNeverCacheHeaders(response);
        }
        chain.doFilter(request, response);
    }

    private boolean isStaticPathElement(HttpServletRequest request)
    {
        String path = request.getServletPath();
        Matcher staticElementsPathMatcher = STATIC_ELEMENTS_PATH_PATTERN.matcher(path);
        boolean result = (staticElementsPathMatcher.matches() && !path.contains("-SNAPSHOT"));
        return result;
    }

    private void addForeverCacheHeaders(HttpServletResponse response)
    {
        response.setDateHeader("Expires", createExpiresTimestamp());
    }

    private long createExpiresTimestamp()
    {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.YEAR, 5);
        long result = calendar.getTimeInMillis();
        return result;
    }

    private void addNeverCacheHeaders(HttpServletResponse response)
    {
        response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
        response.setHeader("Pragma", "no-cache");
        response.setDateHeader("Expires", 0);
    }
}

@@ -473,16 +473,18 @@
       %22%5E
+%5C%5C
 /(webjar
@@ -499,16 +499,17 @@
 %5C.%5C%5Cd+)*
++
 (-%5B%5C%5CdA-
@@ -517,16 +517,18 @@
 a-z%5D+)?)
+%5C%5C
 /.+$%22);%0A

Add escaping for literal slashes to make it very clear, that we want literal slashes; add possessive quantifier (*+) allowing the regex engine to fail faster (java:S5998)