Commit ea5b1663 authored by Matija Obreza's avatar Matija Obreza

UrlRewriter and default locale permanent redirection

parent 5b572ebc
......@@ -503,6 +503,11 @@
<artifactId>xml-apis</artifactId>
<version>1.4.01</version>
</dependency>
<dependency>
<groupId>org.tuckey</groupId>
<artifactId>urlrewritefilter</artifactId>
<version>4.0.4</version>
</dependency>
</dependencies>
<build>
......
......@@ -24,9 +24,11 @@ public class LocaleURLFilter implements Filter {
public static final String REQUEST_LOCALE_ATTR = LocaleURLFilter.class.getName() + ".LOCALE";
private static final String REQUEST_INTERNAL_URL = LocaleURLFilter.class.getName() + ".INTERNALURL";
private Locale defaultLocale;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
String excludePaths = filterConfig.getInitParameter("excludePaths");
String excludePaths = filterConfig.getInitParameter("exclude-paths");
if (StringUtils.isNotBlank(excludePaths)) {
LOG.info("Excluding paths: " + excludePaths);
String[] ex = excludePaths.split("\\s+");
......@@ -35,6 +37,14 @@ public class LocaleURLFilter implements Filter {
}
localeUrlMatcher.setExcludedPaths(ex);
}
String defaultLocale = filterConfig.getInitParameter("default-locale");
if (defaultLocale != null) {
this.defaultLocale = Locale.forLanguageTag(defaultLocale);
} else {
this.defaultLocale = Locale.getDefault();
}
LOG.info("Using default locale: " + this.defaultLocale);
}
@Override
......@@ -46,8 +56,9 @@ public class LocaleURLFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
final HttpServletRequest request = (HttpServletRequest) servletRequest;
final String url = request.getRequestURI().substring(request.getContextPath().length());
final HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
final String url = httpRequest.getRequestURI().substring(httpRequest.getContextPath().length());
if (localeUrlMatcher.isExcludedPath(url)) {
filterChain.doFilter(servletRequest, servletResponse);
......@@ -64,22 +75,33 @@ public class LocaleURLFilter implements Filter {
String remainingUrl = matcher.group(2);
Locale urlLocale = Locale.forLanguageTag(urlLanguage);
request.setAttribute(REQUEST_LOCALE_ATTR, urlLocale);
request.setAttribute(REQUEST_INTERNAL_URL, getInternalUrl(remainingUrl, request.getQueryString()));
if (urlLocale.equals(this.defaultLocale)) {
String defaultLocaleUrl = getInternalUrl(remainingUrl, httpRequest.getQueryString());
LOG.warn("Default locale requested, permanent-redirect to " + defaultLocaleUrl);
httpResponse.reset();
httpResponse.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
httpResponse.setHeader("Location", defaultLocaleUrl);
return;
}
httpRequest.setAttribute(REQUEST_LOCALE_ATTR, urlLocale);
httpRequest.setAttribute(REQUEST_INTERNAL_URL, getInternalUrl(remainingUrl, httpRequest.getQueryString()));
if (LOG.isDebugEnabled()) {
LOG.debug("URL matches! lang=" + urlLanguage + " remaining=" + remainingUrl);
LOG.debug("Country: " + urlLocale.getCountry() + " Lang: " + urlLocale.getLanguage() + " locale=" + urlLocale);
}
Enumeration<String> attrNames = request.getAttributeNames();
Enumeration<String> attrNames = httpRequest.getAttributeNames();
while (attrNames.hasMoreElements()) {
String attrName = attrNames.nextElement();
LOG.info("Request attr " + attrName + " = " + request.getAttribute(attrName));
LOG.info("Request attr " + attrName + " = " + httpRequest.getAttribute(attrName));
}
LocaleWrappedServletResponse localeResponse = new LocaleWrappedServletResponse((HttpServletResponse) servletResponse, localeUrlMatcher, urlLanguage);
LocaleWrappedServletRequest localeRequest = new LocaleWrappedServletRequest((HttpServletRequest) servletRequest, url, remainingUrl);
LocaleWrappedServletResponse localeResponse = new LocaleWrappedServletResponse(httpResponse, localeUrlMatcher, urlLanguage, defaultLocale.toLanguageTag());
LocaleWrappedServletRequest localeRequest = new LocaleWrappedServletRequest(httpRequest, url, remainingUrl);
LOG.info("Proxying request to remaining URL " + remainingUrl);
// request.getRequestDispatcher(remainingUrl == null ? "/" :
......@@ -89,7 +111,7 @@ public class LocaleURLFilter implements Filter {
if (LOG.isDebugEnabled()) {
LOG.debug("No match on url " + url);
}
request.setAttribute(REQUEST_INTERNAL_URL, getInternalUrl(url, request.getQueryString()));
httpRequest.setAttribute(REQUEST_INTERNAL_URL, getInternalUrl(url, httpRequest.getQueryString()));
filterChain.doFilter(servletRequest, servletResponse);
}
}
......
......@@ -9,13 +9,14 @@ public class LocaleWrappedServletResponse extends HttpServletResponseWrapper {
private static final Logger LOG = Logger.getLogger(LocaleWrappedServletResponse.class);
private String prefix;
private LocaleURLMatcher localeUrlMatcher;
private String defaultLanguagePrefix;
public LocaleWrappedServletResponse(HttpServletResponse response, LocaleURLMatcher localeUrlMatcher, String urlLanguage) {
public LocaleWrappedServletResponse(HttpServletResponse response, LocaleURLMatcher localeUrlMatcher, String urlLanguage, String defaultLanguage) {
super(response);
this.localeUrlMatcher = localeUrlMatcher;
this.prefix = updatePrefix(urlLanguage);
this.defaultLanguagePrefix = "/" + defaultLanguage + "/";
}
private boolean isExcluded(String url) {
......@@ -26,7 +27,7 @@ public class LocaleWrappedServletResponse extends HttpServletResponseWrapper {
@Override
public String encodeURL(String url) {
if (isExcluded(url)) {
if (url.startsWith("/en/")) {
if (url.startsWith(defaultLanguagePrefix)) {
return super.encodeURL(url.substring(3));
}
return super.encodeURL(url);
......
......@@ -37,4 +37,5 @@ log4j.category.org.genesys2.server.servlet.filter=debug
#log4j.category.com.hazelcast=warn
#log4j.category.com.hazelcast.web=debug
#log4j.category.com.hazelcast.aws=trace
#log4j.category.org.eclipse.jetty.servlets=trace
\ No newline at end of file
#log4j.category.org.eclipse.jetty.servlets=trace
log4j.category.org.tuckey.web=trace
\ No newline at end of file
......@@ -4,7 +4,7 @@
<div class="container">
<div class="navbar-collapse">
<ul class="nav navbar-nav">
<li class="notimportant"><a href="<c:url value="/" />"><spring:message code="menu.home" /></a></li>
<li class="notimportant"><a href="<c:url value="/welcome" />"><spring:message code="menu.home" /></a></li>
<li><a href="<c:url value="/explore" />"><spring:message code="menu.browse" /></a></li>
<li><a href="<c:url value="/data/" />"><spring:message code="menu.datasets" /></a></li>
<%-- <li><a href="<c:url value="/descriptors/" />"><spring:message code="menu.descriptors" /></a></li> --%>
......
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite
PUBLIC "-//tuckey.org//DTD UrlRewrite 4.0//EN"
"http://www.tuckey.org/res/dtds/urlrewrite4.0.dtd">
<urlrewrite use-query-string="true">
<rule>
<name>Ignore JSP requests</name>
<from>^/WEB-INF/(jsp|decorator)/</from>
<to last="true">-</to>
</rule>
<rule>
<name>Ignore proper localized requests</name>
<from>^/[a-z]{2}(?:\-[a-z]{2})?/</from>
<to last="true">-</to>
</rule>
<!-- English -->
<rule>
<from>^/([^?]+)\?lang=en$</from>
<to last="true" type="permanent-redirect">/$1</to>
</rule>
<rule>
<from>^/([^?]+)(?:\?(.*)&amp;|\?)lang=en(.*)$</from>
<to last="true" type="permanent-redirect">/$1?$2$3</to>
</rule>
<!-- Other -->
<rule>
<from>^/([^?]+)\?lang=([a-z]{2})$</from>
<to last="true" type="permanent-redirect">/$2/$1</to>
</rule>
<rule>
<from>^/([^?]+)(?:\?(.*)&amp;|\?)lang=([a-z]{2})(.*)$</from>
<to last="true" type="permanent-redirect">/$3/$1?$2$4</to>
</rule>
</urlrewrite>
......@@ -45,15 +45,36 @@
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
<init-param>
<param-name>confReloadCheckInterval</param-name>
<param-value>10</param-value>
</init-param>
<init-param>
<param-name>logLevel</param-name>
<param-value>sysout:DEBUG</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<filter>
<filter-name>localeURLFilter</filter-name>
<filter-class>org.genesys2.server.servlet.filter.LocaleURLFilter</filter-class>
<init-param>
<param-name>excludePaths</param-name>
<param-name>exclude-paths</param-name>
<param-value>/html</param-value>
</init-param>
<init-param>
<param-name>default-locale</param-name>
<param-value>en</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>localeURLFilter</filter-name>
......
package org.genesys2.server.test;
import static org.junit.Assert.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.junit.Test;
public class UrlrewriteTest {
@Test
public void testOnlyLang() {
Pattern p = Pattern.compile("^/([^?]+)\\?lang=([a-z]{2})$");
Matcher m;
m = p.matcher("/hello.world");
assertFalse(m.matches());
m = p.matcher("/some/url?lang=de");
assertTrue(m.matches());
System.err.println(m.group(1));
assertTrue("some/url".equals(m.group(1)));
assertTrue("de".equals(m.group(2)));
}
@Test
public void test1() {
Pattern p = Pattern.compile("^/([^?]+)(?:\\?(.*)&|\\?)lang=([a-z]{2})(.*)$");
Matcher m;
m = p.matcher("/some/url?lang=de&foo=bar&1=2");
assertTrue(m.matches());
System.err.println(m.group(1));
assertTrue("some/url".equals(m.group(1)));
assertTrue(m.group(2) == null || "".equals(m.group(2)));
assertTrue("de".equals(m.group(3)));
assertTrue("&foo=bar&1=2".equals(m.group(4)));
m = p.matcher("/some/url?demo=1,2,3&lang=de&foo=bar&1=2");
assertTrue(m.matches());
System.err.println(m.group(1));
assertTrue("some/url".equals(m.group(1)));
assertTrue("demo=1,2,3".equals(m.group(2)));
assertTrue("de".equals(m.group(3)));
assertTrue("&foo=bar&1=2".equals(m.group(4)));
m = p.matcher("/some/url?demo=1,2,3&foo=bar&1=2&lang=de");
assertTrue(m.matches());
System.err.println(m.group(1));
assertTrue("some/url".equals(m.group(1)));
assertTrue("demo=1,2,3&foo=bar&1=2".equals(m.group(2)));
assertTrue("de".equals(m.group(3)));
assertTrue(m.group(4)==null || "".equals(m.group(4)));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment