public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; // create input/output dir patterns String contextPath = httpRequest.getContextPath(); if (this.inDirPattern == null) { // NOTE: Have to do this here because the context path is not // available in init(). this.inDirPattern = Pattern.compile("^" + escape(contextPath) + escape(this.inDirName) + "/(.*)"); this.outDirPattern = Pattern.compile("^" + escape(contextPath) + "/help/[a-z]{2}(?:_[A-Z]{2})?/.*"); if (ZimbraLog.webclient.isDebugEnabled()) { ZimbraLog.webclient.debug("### indir pattern: " + this.inDirPattern.pattern()); ZimbraLog.webclient.debug("### outdir pattern: " + this.outDirPattern.pattern()); } } // check to see if we need to redirect this request String requestUri = httpRequest.getRequestURI(); if (this.outDirPattern.matcher(requestUri).matches()) { // allow it to go through chain.doFilter(request, response); return; } // make list of potential locales to check Locale preferredLocale = getLocale(httpRequest); String language = preferredLocale.getLanguage(); String country = preferredLocale.getCountry(); Locale[] locales = {preferredLocale, country != null ? new Locale(language) : null, Locale.US}; if (ZimbraLog.webclient.isDebugEnabled()) { for (Locale locale : locales) { ZimbraLog.webclient.debug("locale: " + locale); } } // find out which version of the requested file exists Locale actualLocale = preferredLocale; Matcher matcher = this.inDirPattern.matcher(requestUri); if (!matcher.matches()) { httpResponse.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Help URL doesn't match input pattern."); return; } if (ZimbraLog.webclient.isDebugEnabled()) { ZimbraLog.webclient.debug("### filename: " + matcher.group(1)); } String filename = decode(matcher.group(1)).replace('/', File.separatorChar); if (ZimbraLog.webclient.isDebugEnabled()) { ZimbraLog.webclient.debug("### filename: " + filename); } File baseDir = new File(this.context.getRealPath("/")); if (ZimbraLog.webclient.isDebugEnabled()) { ZimbraLog.webclient.debug("### basedir: " + baseDir); } for (Locale locale : locales) { if (locale == null) continue; File file = new File( baseDir, this.outDirName.replaceAll("\\{locale\\}", locale.toString()) + File.separatorChar + filename); if (file.exists()) { actualLocale = locale; break; } } // redirect String redirectUrl = contextPath + this.outDirName.replaceAll("\\{locale\\}", actualLocale.toString()) + "/" + filename; if (ZimbraLog.webclient.isDebugEnabled()) { ZimbraLog.webclient.debug("redirecting to: " + redirectUrl); } httpResponse.sendRedirect(redirectUrl); }