Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: Add outboundProxyHost/Port settings to enable communication with html swapper via a proxy. #171

Merged
merged 10 commits into from
Apr 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
sudo apt-get update
sudo apt install -y maven
cd ~/
curl -O https://bootstrap.pypa.io/get-pip.py
curl -O https://bootstrap.pypa.io/pip/2.7/get-pip.py
python get-pip.py --user
export PATH=~/.local/bin/:$PATH
pip install awscli --upgrade --user
Expand Down Expand Up @@ -82,7 +82,7 @@ jobs:
sudo apt-get update
sudo apt install -y maven
cd ~/
curl -O https://bootstrap.pypa.io/get-pip.py
curl -O https://bootstrap.pypa.io/pip/2.7/get-pip.py
python get-pip.py --user
export PATH=~/.local/bin/:$PATH
pip install awscli --upgrade --user
Expand All @@ -96,6 +96,7 @@ jobs:
export PATH=${JAVA_HOME}/bin:$PATH
export M2_HOME=~/.m2
export MAVEN_HOME=~/.m2
export MAVEN_OPTS=-Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2

- restore_cache:
key: circleci-wovnjava-oraclejdk-pom-{{ checksum "pom.xml" }}
Expand Down Expand Up @@ -144,6 +145,7 @@ jobs:
sudo apt update; sudo apt install -y zulu-7
export M2_HOME=~/.m2
export MAVEN_HOME=~/.m2
export MAVEN_OPTS=-Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2

- restore_cache:
key: circleci-wovnjava-openjdk-pom-{{ checksum "pom.xml" }}
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,8 @@
/.vagrant/
.idea/
*.swp
bin/
.settings
.classpath
.project
.vscode
32 changes: 25 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ defaultLang | yes |
supportedLangs | yes |
urlPattern | yes |
useProxy | | false
outboundProxyPort | |
outboundProxyHost | |
originalUrlHeader | |
originalQueryStringHeader | |
ignoreClasses | |
Expand Down Expand Up @@ -167,7 +169,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 @@ -202,7 +220,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. ignoreClasses
### 2.8. ignoreClasses

A comma-separated list of HTML classes for which you would like WOVN to skip the elements of.

Expand All @@ -228,7 +246,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 @@ -237,7 +255,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 @@ -267,7 +285,7 @@ Furthermore, it is highly recommended to also configure your `web.xml` with a co
</filter-mapping>
```

### 2.10. customDomainLangs
### 2.11. customDomainLangs

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

Expand Down Expand Up @@ -308,7 +326,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.11. debugMode
### 2.12. debugMode

A flag to enable extra debugging features.

Expand Down Expand Up @@ -337,7 +355,7 @@ This is intended to better understand what the problem is if something is not wo

_Note that `wovnCacheDisable` and `wovnDebugMode` is only available when debugMode is turned on in your wovnjava configuration._

### 2.12. showVersion
### 2.13. showVersion

A flag to control whether or not to show wovnjava version number in the `X-Wovn-Handler` HTTP response header.

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.1.3-java7</version>
<version>1.2.0-java7</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 @@ -43,6 +43,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 @@ -73,6 +76,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 @@ -165,6 +171,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 @@ -60,13 +60,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 @@ -75,13 +70,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 @@ -90,13 +80,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 @@ -106,13 +91,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 @@ -121,13 +101,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 @@ -137,13 +112,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 @@ -420,19 +390,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