Skip to content

Commit

Permalink
Add ignorePaths option feature (#153)
Browse files Browse the repository at this point in the history
* Add `ignorePaths` option feature
* Bump up version
  • Loading branch information
iwai-wovn authored May 14, 2020
1 parent d70b2c1 commit edf4ea6
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 15 deletions.
42 changes: 36 additions & 6 deletions README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,37 @@ Configure WovnServletFilter to determine request path and query from the same HT
_The sample request header shown above was referenced from the following site:_
https://coderwall.com/p/jhkw7w/passing-request-uri-into-request-header

### 2.7. ignoreClasses
### 2.7. ignorePaths

A comma-separated list of URL path for which you would like WOVN to not translation content withing given directories.

Ignored paths and their contents will not be processed by WovnServletFilter, and will not be sent to Wovn.io for translation.

For instance, if you want to not translation the admin directory of your website, you should configure as below.

```XML
<init-param>
<param-name>ignorePaths</param-name>
<param-value>/admin,/wp-admin</param-value>
</init-param>
```
With this configuration, WOVN.java will ignore the following URLs
```Text
https://my-wesite.com/admin
https://my-wesite.com/admin/
https://my-website.com/admin/plugin.html
https://my-wesite.com/wp-admin
https://my-wesite.com/wp-admin/
https://my-website.com/wp-admin/anypages
```
but allow the following
```Text
https://my-website.com/index.html
https://my-website.com/user/admin
https://my-website.com/adminpage
```

### 2.8. ignoreClasses

A comma-separated list of HTML classes for which you would like WOVN to skip the elements of.
(This setting is used to prevent confidential data contained in the page to be translated from being sent to WOVN)
Expand All @@ -229,7 +259,7 @@ Including three classes, `email-address-element`, `my-secret-class`, and `noshow
</init-param>
```

### 2.8. enableFlushBuffer
### 2.9. enableFlushBuffer
A flag to adjust the behavior of `ServletResponse.flushBuffer()`.

This parameter is set to `false` by default (recommended).
Expand All @@ -238,7 +268,7 @@ When `enableFlushBuffer` is set to `false`, WovnServletFilter will capture calls
immediately writing content to the client. Only when the complete HTML response is ready will the filter translate the content
and send it to the client. This is necessary in order to translate the content properly.

### 2.9. sitePrefixPath
### 2.10. sitePrefixPath

This parameter lets you set a prefix path to use as an anchor for which WOVN will translate pages. With this setting, WOVN will only translate pages that match the prefix path, and the path language code will be added _after_ the prefix path.

Expand Down Expand Up @@ -268,7 +298,7 @@ Furthermore, it is highly recommended to also configure your `web.xml` with a co
</filter-mapping>
```

### 2.10. langCodeAliases
### 2.11. langCodeAliases

This setting lets you specify the language identifier for your supported languages.

Expand Down Expand Up @@ -303,7 +333,7 @@ To illustrate, here is an example:
Achieve this result by configuring `jp` as an alias for Japanese.

### 2.11. customDomainLangs
### 2.12. customDomainLangs

This setting lets you define the domain and path that corresponds to each of your supported languages.

Expand Down Expand Up @@ -344,7 +374,7 @@ If this setting is used, each language declared in `supportedLangs` must be give
Lastly, the path declared for your original language must match the structure of the underlying web server.
In other words, you cannot use this setting to change the request path of your content in original language.

### 2.12. debugMode
### 2.13. debugMode

A flag to enable extra debugging features.

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<groupId>com.github.wovnio</groupId>
<artifactId>wovnjava</artifactId>
<name>wovnjava</name>
<version>1.1.3</version>
<version>1.2.0</version>
<url>https://github.com/WOVNio/wovnjava</url>

<licenses>
Expand Down
19 changes: 18 additions & 1 deletion src/main/java/com/github/wovnio/wovnjava/Headers.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.wovnio.wovnjava;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.net.URL;
import java.net.MalformedURLException;
Expand Down Expand Up @@ -52,7 +53,7 @@ class Headers {

this.shouldRedirectExplicitDefaultLangUrl = this.urlLanguagePatternHandler.shouldRedirectExplicitDefaultLangUrl(clientRequestUrl);

this.isValidRequest = this.requestLang != null && this.urlContext != null;
this.isValidRequest = this.requestLang != null && this.urlContext != null && !this.isIgnoredPath(this.urlContext.getURL().getPath());
}

/*
Expand Down Expand Up @@ -127,4 +128,20 @@ public LinkedHashMap<String, String> getHreflangUrlMap() {
hreflangs.put(hreflangCodeDefaultLang, urlDefaultLang);
return hreflangs;
}

private boolean isIgnoredPath(String contextPath) {
ArrayList<String> ignorePaths = this.settings.ignorePaths;

contextPath = contextPath.toLowerCase();

for (String ignorePath : ignorePaths) {

String prefixPath = ignorePath;
String prefixPathTrailingSlash = ignorePath + "/";

if (contextPath.equals(prefixPath) || contextPath.startsWith(prefixPathTrailingSlash))
return true;
}
return false;
}
}
27 changes: 27 additions & 0 deletions src/main/java/com/github/wovnio/wovnjava/Settings.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class Settings {
public final String originalUrlHeader;
public final String originalQueryStringHeader;

public final ArrayList<String> ignorePaths;
public final ArrayList<String> ignoreClasses;

public final int connectTimeout;
Expand Down Expand Up @@ -68,6 +69,7 @@ class Settings {
this.snippetUrl = this.devMode ? DefaultSnippetUrlDevelopment : DefaultSnippetUrlProduction;

this.ignoreClasses = reader.getArrayParameter("ignoreClasses");
this.ignorePaths = normalizeIgnorePaths(reader.getArrayParameter("ignorePaths"));

this.originalUrlHeader = stringOrDefault(reader.getStringParameter("originalUrlHeader"), "");
this.originalQueryStringHeader = stringOrDefault(reader.getStringParameter("originalQueryStringHeader"), "");
Expand Down Expand Up @@ -146,6 +148,28 @@ private String normalizeSitePrefixPath(String value) throws ConfigurationError {
}
}

private ArrayList<String> normalizeIgnorePaths(ArrayList<String> values) {

ArrayList<String> ignorePaths = new ArrayList<String>();

for (String path : values) {
if (path.isEmpty()) {
continue;
}

path = path.toLowerCase();

if (!path.startsWith("/")) path = "/" + path;
if (path.endsWith("/")) {
path = path.substring(0, path.length() - 1);
}

ignorePaths.add(path);
}

return ignorePaths;
}

private Map<Lang, String> parseLangCodeAliases(String rawLangCodeAliases) throws ConfigurationError {
return LanguageAliasSerializer.deserializeFilterConfig(rawLangCodeAliases);
}
Expand Down Expand Up @@ -179,6 +203,9 @@ String hash() throws NoSuchAlgorithmException {
for (Lang lang : supportedLangs) {
md.update(lang.code.getBytes());
}
for (String path : ignorePaths) {
md.update(path.getBytes());
}
md.update(useProxy ? new byte[]{ 0 } : new byte[] { 1 });
md.update(originalUrlHeader.getBytes());
md.update(originalQueryStringHeader.getBytes());
Expand Down
56 changes: 49 additions & 7 deletions src/test/java/com/github/wovnio/wovnjava/HeadersTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ public void testConvertToDefaultLanguage__QueryPattern() throws ConfigurationErr
}

public void testConvertToDefaultLanguage__PathPatternWithSitePrefixPath() throws ConfigurationError, MalformedURLException {
Headers h = makeHeaderWithSitePrefixPath("/global/en/foo", "/global/");
Headers h = createHeaders("/global/en/foo", "/global/", "");
URL url;

url = new URL("http://site.com/global/en/");
Expand Down Expand Up @@ -221,7 +221,7 @@ public void testLocationWithSubdomain() throws ConfigurationError {
}

public void testLocationWithSitePrefixPath() throws ConfigurationError {
Headers h = makeHeaderWithSitePrefixPath("/global/ja/foo", "/global/");
Headers h = createHeaders("/global/ja/foo", "/global/", "");
assertEquals("http://example.com/", h.locationWithLangCode("http://example.com/"));
assertEquals("http://example.com/global/ja/", h.locationWithLangCode("http://example.com/global/"));
assertEquals("https://example.com/global/ja/", h.locationWithLangCode("https://example.com/global/"));
Expand All @@ -240,24 +240,66 @@ public void testLocationWithSitePrefixPath() throws ConfigurationError {

public void testGetIsValidRequest() throws ConfigurationError {
Headers h;
h = makeHeaderWithSitePrefixPath("/", "global");
h = createHeaders("/", "global", "");
assertEquals(false, h.getIsValidRequest());

h = makeHeaderWithSitePrefixPath("/global", "global");
h = createHeaders("/global", "global", "");
assertEquals(true, h.getIsValidRequest());

h = makeHeaderWithSitePrefixPath("/global/ja/foo", "global");
h = createHeaders("/global/ja/foo", "global", "");
assertEquals(true, h.getIsValidRequest());

h = makeHeaderWithSitePrefixPath("/ja/global/foo", "global");
h = createHeaders("/ja/global/foo", "global", "");
assertEquals(false, h.getIsValidRequest());
}

private Headers makeHeaderWithSitePrefixPath(String requestPath, String sitePrefixPath) throws ConfigurationError {
public void testGetIsValidRequest__withIgnoredPaths() throws ConfigurationError {
Headers h;

h = createHeaders("/", "", "/admin,/wp-admin");
assertEquals(true, h.getIsValidRequest());

h = createHeaders("/user/admin", "", "/admin,/wp-admin");
assertEquals(true, h.getIsValidRequest());

h = createHeaders("/adminpage", "", "/admin,/wp-admin");
assertEquals(true, h.getIsValidRequest());

h = createHeaders("/admin", "", "/admin,/wp-admin");
assertEquals(false, h.getIsValidRequest());

h = createHeaders("/wp-admin/", "", "/admin,/wp-admin");
assertEquals(false, h.getIsValidRequest());

h = createHeaders("/wp-admin/page", "", "/admin,/wp-admin");
assertEquals(false, h.getIsValidRequest());

h = createHeaders("/ja/admin", "", "/admin,/wp-admin");
assertEquals(false, h.getIsValidRequest());

h = createHeaders("/ja/wp-admin/", "", "/admin,/wp-admin");
assertEquals(false, h.getIsValidRequest());

h = createHeaders("/en/admin", "", "/admin,/wp-admin");
assertEquals(false, h.getIsValidRequest());

h = createHeaders("/en/wp-admin/", "", "/admin,/wp-admin");
assertEquals(false, h.getIsValidRequest());


h = createHeaders("/city/wp-admin", "city", "/admin,/wp-admin");
assertEquals(true, h.getIsValidRequest());

h = createHeaders("/city/wp-admin", "city", "/city/admin,/city/wp-admin");
assertEquals(false, h.getIsValidRequest());
}

private Headers createHeaders(String requestPath, String sitePrefixPath, String ignorePaths) throws ConfigurationError {
HttpServletRequest mockRequest = MockHttpServletRequest.create("https://example.com" + requestPath);
HashMap<String, String> option = new HashMap<String, String>() {{
put("urlPattern", "path");
put("sitePrefixPath", sitePrefixPath);
put("ignorePaths", ignorePaths);
}};
Settings s = TestUtil.makeSettings(option);
UrlLanguagePatternHandler ulph = UrlLanguagePatternHandlerFactory.create(s);
Expand Down
39 changes: 39 additions & 0 deletions src/test/java/com/github/wovnio/wovnjava/SettingsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import java.util.HashMap;
import java.util.ArrayList;
import java.util.Arrays;

import javax.servlet.FilterConfig;

Expand Down Expand Up @@ -45,6 +46,7 @@ public void testDefaultSettings__MinimalConfiguration__DefaultValuesOK() throws

ArrayList<String> emptyArrayList = new ArrayList<String>();
assertEquals(emptyArrayList, s.ignoreClasses);
assertEquals(emptyArrayList, s.ignorePaths);

assertEquals(Settings.DefaultSnippetUrlProduction, s.snippetUrl);
assertEquals(Settings.DefaultApiUrlProduction, s.apiUrl);
Expand Down Expand Up @@ -328,6 +330,39 @@ public void testSnippetUrl__DevelopmentMode__DefaultValue() throws Configuration
assertEquals(Settings.DefaultSnippetUrlDevelopment, s.snippetUrl);
}

public void testIgnorePaths__DeclareEmptyString__UseDefaultEmptyArray() throws ConfigurationError {
FilterConfig config = TestUtil.makeConfigWithValidDefaults(new HashMap<String, String>() {{
put("ignorePaths", "");
}});
Settings s = new Settings(config);
ArrayList<String> emptyArrayList = new ArrayList<String>();
assertEquals(emptyArrayList, s.ignorePaths);
}

public void testIgnorePaths__emptyValues__areExcluded() throws ConfigurationError {
Settings s = createSettings(new HashMap<String, String>() {{
put("ignorePaths", ",,,");
}});
ArrayList<String> emptyArrayList = new ArrayList<String>();
assertEquals(emptyArrayList, s.ignorePaths);
}

public void testIgnorePaths__pathsWithoutLeadingSlash__slashAdded() throws ConfigurationError {
Settings s = createSettings(new HashMap<String, String>() {{
put("ignorePaths", ",path1/,path2/,pa/th3/");
}});
ArrayList<String> expectedArrayList = new ArrayList<String>(Arrays.asList("/path1", "/path2", "/pa/th3"));
assertEquals(expectedArrayList, s.ignorePaths);
}

public void testIgnorePaths__pathsWithTrailingSlash__slashRemoved() throws ConfigurationError {
Settings s = createSettings(new HashMap<String, String>() {{
put("ignorePaths", ",/path1/,/path2/,/pa/th3/");
}});
ArrayList<String> expectedArrayList = new ArrayList<String>(Arrays.asList("/path1", "/path2", "/pa/th3"));
assertEquals(expectedArrayList, s.ignorePaths);
}

public void testIgnoreClasses__DeclareEmptyString__UseDefaultEmptyArray() throws ConfigurationError {
FilterConfig config = TestUtil.makeConfigWithValidDefaults(new HashMap<String, String>() {{
put("ignoreClasses", "");
Expand Down Expand Up @@ -438,4 +473,8 @@ public void testReadTimeout__InvalidInteger__ThrowError() throws ConfigurationEr
}
assertEquals(true, errorThrown);
}

private Settings createSettings(HashMap<String, String> values) throws ConfigurationError {
return new Settings(TestUtil.makeConfigWithValidDefaults(values));
}
}

0 comments on commit edf4ea6

Please sign in to comment.