Skip to content

Commit

Permalink
Cherry pick feature: Add outboundProxyHost/Port settings to enable co…
Browse files Browse the repository at this point in the history
…mmunication with html swapper via a proxy. (#173)
  • Loading branch information
bstewart00 authored May 12, 2021
1 parent 6bfc7a0 commit a77ba7c
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 60 deletions.
34 changes: 26 additions & 8 deletions README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ defaultLang | yes |
supportedLangs | yes |
urlPattern | yes |
useProxy | | false
outboundProxyPort | |
outboundProxyHost | |
originalUrlHeader | |
originalQueryStringHeader | |
ignoreClasses | |
Expand Down Expand Up @@ -169,7 +171,23 @@ Set useProxy to true as follows

Note that if the reverse proxy may also rewrite the request path or query, configuring the originalUrlHeader and/or originalQueryStringHeader may also be necessary.

### 2.6. originalUrlHeader, originalQueryStringHeader
### 2.6. outboundProxyHost, outboundProxyPort

WovnServletFilter needs to send requests to Wovn's translation API server. This setting should be used if your server requires all outbound requests to be routed through a proxy. Both ``outboundProxyHost`` (host or IP address of the proxy) and ``outboundProxyPort`` (port number of the proxy) are required to be set.

```xml
<init-param>
<param-name>outboundProxyHost</param-name>
<param-value>proxy.company.com</param-value>
</init-param>
<init-param>
<param-name>outboundProxyPort</param-name>
<param-value>8080</param-value>
</init-param>
```


### 2.7. originalUrlHeader, originalQueryStringHeader

Name of HTTP headers for declaring the original request path and query.

Expand Down Expand Up @@ -204,7 +222,7 @@ 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. ignorePaths
### 2.8. ignorePaths

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

Expand Down Expand Up @@ -234,7 +252,7 @@ https://my-website.com/user/admin
https://my-website.com/adminpage
```

### 2.8. ignoreClasses
### 2.9. 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 @@ -261,7 +279,7 @@ Including three classes, `email-address-element`, `my-secret-class`, and `noshow
</init-param>
```

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

This parameter is set to `false` by default (recommended).
Expand All @@ -270,7 +288,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.10. sitePrefixPath
### 2.11. 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 @@ -300,7 +318,7 @@ Furthermore, it is highly recommended to also configure your `web.xml` with a co
</filter-mapping>
```

### 2.11. langCodeAliases
### 2.12. langCodeAliases

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

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

### 2.12. customDomainLangs
### 2.13. customDomainLangs

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

Expand Down Expand Up @@ -376,7 +394,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.13. debugMode
### 2.14. debugMode

A flag to enable extra debugging features.

Expand Down
5 changes: 3 additions & 2 deletions 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.6.1</version>
<version>1.7.0</version>
<url>https://github.com/WOVNio/wovnjava</url>

<licenses>
Expand Down Expand Up @@ -51,7 +51,7 @@
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations-java5</artifactId>
<version>RELEASE</version>
<version>16.0.2</version>
</dependency>

<dependency>
Expand Down Expand Up @@ -123,6 +123,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M1</version>
<configuration>
<useSystemClassLoader>false</useSystemClassLoader>
</configuration>
Expand Down
7 changes: 6 additions & 1 deletion src/main/java/com/github/wovnio/wovnjava/Api.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
import java.io.UnsupportedEncodingException;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.URL;
import java.net.URLEncoder;
import java.net.MalformedURLException;
import java.net.Proxy;
import java.net.SocketTimeoutException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
Expand Down Expand Up @@ -40,7 +42,10 @@ String translate(String lang, String html) throws ApiException {
HttpURLConnection con = null;
try {
URL url = getApiUrl(lang, html);
con = (HttpURLConnection) url.openConnection();
Proxy proxy = this.settings.outboundProxyHost== null
? Proxy.NO_PROXY
: new Proxy(Proxy.Type.HTTP, new InetSocketAddress(this.settings.outboundProxyHost, this.settings.outboundProxyPort));
con = (HttpURLConnection) url.openConnection(proxy);
con.setConnectTimeout(settings.connectTimeout);
con.setReadTimeout(settings.readTimeout);
return translate(lang, html, con);
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/com/github/wovnio/wovnjava/Settings.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ class Settings {
public final int connectTimeout;
public final int readTimeout;

public final String outboundProxyHost;
public final int outboundProxyPort;

Settings(FilterConfig config) throws ConfigurationError {
FilterConfigReader reader = new FilterConfigReader(config);

Expand Down Expand Up @@ -78,6 +81,9 @@ class Settings {

this.connectTimeout = positiveIntOrDefault(reader.getIntParameter("connectTimeout"), DefaultTimeout);
this.readTimeout = positiveIntOrDefault(reader.getIntParameter("readTimeout"), DefaultTimeout);

this.outboundProxyHost = nonEmptyString(reader, "outboundProxyHost");
this.outboundProxyPort = reader.getIntParameter("outboundProxyPort");
}

private String verifyToken(String declaredUserToken, String declaredProjectToken) throws ConfigurationError {
Expand Down Expand Up @@ -196,6 +202,14 @@ private int positiveIntOrDefault(int declaredValue, int defaultValue) {
return declaredValue > 0 ? declaredValue : defaultValue;
}

private String nonEmptyString(FilterConfigReader reader, String key) throws ConfigurationError {
String value = reader.getStringParameter(key);
if (value != null && value.isEmpty()) {
throw new ConfigurationError(String.format("Invalid configuration for \"%s\", value cannot be empty.", value));
}
return value;
}

String hash() throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(projectToken.getBytes());
Expand Down
111 changes: 62 additions & 49 deletions src/test/java/com/github/wovnio/wovnjava/SettingsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,8 @@ public void testRequiredSettings__MissingProjectToken__ThrowError() throws Confi
put("defaultLang", "en");
put("supportedLangs", "en,ja");
}});
boolean errorThrown = false;
try {
Settings s = new Settings(config);
} catch (ConfigurationError e) {
errorThrown = true;
}
assertEquals(true, errorThrown);

assertErrorThrown(config);
}

public void testRequiredSettings__MissingUrlPattern__ThrowError() throws ConfigurationError {
Expand All @@ -76,13 +71,8 @@ public void testRequiredSettings__MissingUrlPattern__ThrowError() throws Configu
put("defaultLang", "en");
put("supportedLangs", "en,ja");
}});
boolean errorThrown = false;
try {
Settings s = new Settings(config);
} catch (ConfigurationError e) {
errorThrown = true;
}
assertEquals(true, errorThrown);

assertErrorThrown(config);
}

public void testRequiredSettings__MissingDefaultLang__ThrowError() throws ConfigurationError {
Expand All @@ -91,13 +81,8 @@ public void testRequiredSettings__MissingDefaultLang__ThrowError() throws Config
put("urlPattern", "path");
put("supportedLangs", "en,ja");
}});
boolean errorThrown = false;
try {
Settings s = new Settings(config);
} catch (ConfigurationError e) {
errorThrown = true;
}
assertEquals(true, errorThrown);

assertErrorThrown(config);
}

public void testRequiredSettings__InvalidDefaultLangCode__ThrowError() throws ConfigurationError {
Expand All @@ -107,13 +92,8 @@ public void testRequiredSettings__InvalidDefaultLangCode__ThrowError() throws Co
put("defaultLang", "English");
put("supportedLangs", "en,ja");
}});
boolean errorThrown = false;
try {
Settings s = new Settings(config);
} catch (ConfigurationError e) {
errorThrown = true;
}
assertEquals(true, errorThrown);

assertErrorThrown(config);
}

public void testRequiredSettings__MissingSupportedLangs__ThrowError() throws ConfigurationError {
Expand All @@ -122,13 +102,8 @@ public void testRequiredSettings__MissingSupportedLangs__ThrowError() throws Con
put("urlPattern", "path");
put("defaultLang", "en");
}});
boolean errorThrown = false;
try {
Settings s = new Settings(config);
} catch (ConfigurationError e) {
errorThrown = true;
}
assertEquals(true, errorThrown);

assertErrorThrown(config);
}

public void testRequiredSettings__InvalidSupportedLangCode__ThrowError() throws ConfigurationError {
Expand All @@ -138,13 +113,8 @@ public void testRequiredSettings__InvalidSupportedLangCode__ThrowError() throws
put("defaultLang", "en");
put("supportedLangs", "en,Japanese");
}});
boolean errorThrown = false;
try {
Settings s = new Settings(config);
} catch (ConfigurationError e) {
errorThrown = true;
}
assertEquals(true, errorThrown);

assertErrorThrown(config);
}

public void testRequiredSettings__SupportedLangDeclaredMultipleTimes__throwError() throws ConfigurationError {
Expand Down Expand Up @@ -452,19 +422,62 @@ public void testConnectTimeout__InvalidInteger__ThrowError() throws Configuratio
FilterConfig config = TestUtil.makeConfigWithValidDefaults(new HashMap<String, String>() {{
put("connectTimeout", "hoge");
}});
boolean errorThrown = false;
try {
Settings s = new Settings(config);
} catch (ConfigurationError e) {
errorThrown = true;
}
assertEquals(true, errorThrown);

assertErrorThrown(config);
}

public void testReadTimeout__InvalidInteger__ThrowError() throws ConfigurationError {
FilterConfig config = TestUtil.makeConfigWithValidDefaults(new HashMap<String, String>() {{
put("readTimeout", "");
}});

assertErrorThrown(config);
}

public void testOutboundProxyHost__Empty_ThrowsError() throws ConfigurationError {
FilterConfig config = TestUtil.makeConfigWithValidDefaults(new HashMap<String, String>() {{
put("outboundProxyHost", "");
}});

assertErrorThrown(config);
}

public void testOutboundProxyHost__NonEmpty_AcceptSetting() throws ConfigurationError {
FilterConfig config = TestUtil.makeConfigWithValidDefaults(new HashMap<String, String>() {{
put("outboundProxyHost", "proxy.com");
}});

Settings settings = new Settings(config);

assertEquals("proxy.com", settings.outboundProxyHost);
}

public void testOutboundProxyPort__Empty_ThrowsError() throws ConfigurationError {
FilterConfig config = TestUtil.makeConfigWithValidDefaults(new HashMap<String, String>() {{
put("outboundProxyPort", "");
}});

assertErrorThrown(config);
}

public void testOutboundProxyPort__NonInteger_ThrowsError() throws ConfigurationError {
FilterConfig config = TestUtil.makeConfigWithValidDefaults(new HashMap<String, String>() {{
put("outboundProxyPort", "abc");
}});
assertErrorThrown(config);
}

public void testOutboundProxyPort__Integer_AcceptSetting() throws ConfigurationError {
FilterConfig config = TestUtil.makeConfigWithValidDefaults(new HashMap<String, String>() {{
put("outboundProxyPort", "4000");
}});

Settings settings = new Settings(config);

assertEquals(4000, settings.outboundProxyPort);
}

private void assertErrorThrown(FilterConfig config) {
boolean errorThrown = false;
try {
Settings s = new Settings(config);
Expand Down

0 comments on commit a77ba7c

Please sign in to comment.