diff --git a/README.md b/README.md
index 0a7b4f82..947a9320 100644
--- a/README.md
+++ b/README.md
@@ -37,7 +37,7 @@ HTTP POST. Other application parameters can be in your POSTed url-encoded-form s
proxyArgs.
Build & Installation
-------------
+--------------------
Simply build the jar using "mvn package" at the command line.
The jar is built to "target/smiley-http-proxy-servlet-VERSION.jar".
@@ -49,7 +49,7 @@ add this to your dependencies in your pom like so:
org.mitre.dsmiley.httpproxy
smiley-http-proxy-servlet
- 1.7
+ 1.9.1
Ivy and other dependency managers can be used as well.
@@ -136,4 +136,43 @@ proxy:
solr:
servlet_url: /solr/*
target_url: http://solrserver:8983/solr
+```
+
+Here is an example of using the proxy with an externalized properties file `http-proxy.properties` and / or `http-proxy-override.properties` which would be plugged into the `web.xml` if it is available in the classpath:
+
+```xml
+ ...
+
+ solr
+ org.mitre.dsmiley.httpproxy.ProxyServlet
+
+ targetUri
+ ${some-url}
+
+
+ log
+ true
+
+
+ ...
+```
+
+make sure you put **${**some-url**}** is used if you want to pickup values from the properties file.
+
+The properties file could be:
+
+**http-proxy.properties**:
+
+```properties
+some-url=http://www.cisco.com/{x-some-parameter}/someEndpoint
+```
+
+Assuming `x-some-parameter` is a custom header parameter.
+
+If this property needs to be overridden for some reason for a different environment for example, then the override properties file could be:
+
+**http-proxy-override.properties**
+
+```properties
+some-url=http://www.cisco.com/someContext/someEndpoint
```
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 7a6cdf4c..02220dc3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
org.mitre.dsmiley.httpproxy
smiley-http-proxy-servlet
- 1.9-SNAPSHOT
+ 1.9.1
jar
Smiley's HTTP Proxy Servlet
@@ -35,7 +35,7 @@
https://github.com/dsmiley/HTTP-Proxy-Servlet
scm:git:https://dsmiley@github.com/dsmiley/HTTP-Proxy-Servlet.git
scm:git:git@github.com:dsmiley/HTTP-Proxy-Servlet.git
- HEAD
+ smiley-http-proxy-servlet-1.9
diff --git a/src/main/java/org/mitre/dsmiley/httpproxy/ProxyServlet.java b/src/main/java/org/mitre/dsmiley/httpproxy/ProxyServlet.java
index dc927338..e8791a94 100644
--- a/src/main/java/org/mitre/dsmiley/httpproxy/ProxyServlet.java
+++ b/src/main/java/org/mitre/dsmiley/httpproxy/ProxyServlet.java
@@ -36,16 +36,13 @@
import org.apache.http.message.BasicHttpRequest;
import org.apache.http.message.HeaderGroup;
import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;
-import javax.servlet.ServletException;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
import java.io.Closeable;
import java.io.IOException;
+import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Constructor;
import java.net.HttpCookie;
@@ -54,6 +51,13 @@
import java.util.Enumeration;
import java.util.Formatter;
import java.util.List;
+import java.util.Properties;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
/**
* An HTTP reverse proxy/gateway servlet. It is designed to be extended for customization
@@ -112,6 +116,8 @@ public class ProxyServlet extends HttpServlet {
private HttpClient proxyClient;
+ private Properties configurationProperties = null;
+
@Override
public String getServletInfo() {
return "A proxy servlet by David Smiley, dsmiley@apache.org";
@@ -129,9 +135,80 @@ protected HttpHost getTargetHost(HttpServletRequest servletRequest) {
/**
* Reads a configuration parameter. By default it reads servlet init parameters but
* it can be overridden.
+ * In case if you are using an externalized properties file http-proxy.properties and / or
+ * http-proxy-override.properties which would be plugged into the web.xml if it is available in the classpath:
+ *
+ * ...
+ * <servlet>
+ * <servlet-name>solr</servlet-name>
+ * <servlet-class>org.mitre.dsmiley.httpproxy.ProxyServlet</servlet-class>
+ * <init-param>
+ * <param-name>targetUri</param-name>
+ * <param-value>${some-url}</param-value>
+ * </init-param>
+ * <init-param>
+ * <param-name>log</param-name>
+ * <param-value>true</param-value>
+ * </init-param>
+ * </servlet>
+ * ...
+ *
+ * make sure you put ${some-url} is used if you want to pickup values from the properties file.
+ *
+ * The properties file could be:
+ *
+ * http-proxy.properties:
+ *
+ * some-url=http://www.cisco.com/{x-some-parameter}/someEndpoint
+ *
+ * Assuming x-some-parameter is a custom header parameter.
+ *
+ * If this property needs to be overridden for some reason for a different environment for example, then the override properties file could be:
+ *
+ * http-proxy-override.properties
+ *
+ * some-url=http://www.cisco.com/someContext/someEndpoint
*/
+
protected String getConfigParam(String key) {
- return getServletConfig().getInitParameter(key);
+ if(configurationProperties == null) {
+ configurationProperties = getConfigurationProperties();
+ }
+ return getValue(configurationProperties, getServletConfig().getInitParameter(key));
+ }
+
+ protected String getValue(Properties configurationProperties, String value){
+ if(value == null){
+ return value;
+ }
+ if(value.startsWith("${") && value.endsWith("}")){
+ String key = value.replaceAll("\\$\\{(.*)\\}", "$1");
+ return (String) configurationProperties.get(key);
+ }
+ return value;
+ }
+ protected Properties getConfigurationProperties()
+ {
+ Properties configurationProperties = new Properties();
+ try
+ {
+ InputStream proxyPropertiesResource = Thread.currentThread().getContextClassLoader().getResourceAsStream("http-proxy.properties");
+ if (proxyPropertiesResource != null) {
+ configurationProperties.load(proxyPropertiesResource);
+ }
+ }
+ catch (IOException e) {}
+ Properties proxyOverrideProperties = new Properties();
+ try
+ {
+ InputStream proxyOverridePropertiesResource = Thread.currentThread().getContextClassLoader().getResourceAsStream("http-proxy-override.properties");
+ if (proxyOverridePropertiesResource != null) {
+ proxyOverrideProperties.load(proxyOverridePropertiesResource);
+ }
+ }
+ catch (IOException e) {}
+ configurationProperties.putAll(proxyOverrideProperties);
+ return configurationProperties;
}
@Override
@@ -161,6 +238,12 @@ public void init() throws ServletException {
hcParams.setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.IGNORE_COOKIES);
hcParams.setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, false); // See #70
readConfigParam(hcParams, ClientPNames.HANDLE_REDIRECTS, Boolean.class);
+ readConfigParam(hcParams, ClientPNames.ALLOW_CIRCULAR_REDIRECTS, Boolean.class);
+ readConfigParam(hcParams, "http.conn-manager.timeout", Integer.class);
+ readConfigParam(hcParams, ClientPNames.MAX_REDIRECTS, Integer.class);
+ readConfigParam(hcParams, CoreConnectionPNames.CONNECTION_TIMEOUT, Integer.class);
+ readConfigParam(hcParams, CoreConnectionPNames.SO_TIMEOUT, Integer.class);
+ readConfigParam(hcParams, CoreConnectionPNames.STALE_CONNECTION_CHECK, Boolean.class);
proxyClient = createHttpClient(hcParams);
}
@@ -650,6 +733,10 @@ protected static CharSequence encodeUriQuery(CharSequence in) {
formatter.format("%%%02X",(int)c);//TODO
}
}
+
+ if(formatter!= null){
+ formatter.close();
+ }
return outBuf != null ? outBuf : in;
}
diff --git a/src/main/java/org/mitre/dsmiley/httpproxy/URITemplateProxyServlet.java b/src/main/java/org/mitre/dsmiley/httpproxy/URITemplateProxyServlet.java
index 95354d66..90fb226d 100644
--- a/src/main/java/org/mitre/dsmiley/httpproxy/URITemplateProxyServlet.java
+++ b/src/main/java/org/mitre/dsmiley/httpproxy/URITemplateProxyServlet.java
@@ -20,9 +20,6 @@
import org.apache.http.client.utils.URIUtils;
import org.apache.http.client.utils.URLEncodedUtils;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
@@ -32,6 +29,10 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
/**
* A proxy servlet in which the target URI is templated from incoming request parameters. The
* format adheres to the URI Template RFC, "Level
@@ -55,7 +56,7 @@ public class URITemplateProxyServlet extends ProxyServlet {
* But that's not how the spec works. So for now we will require a proxy arg to be present
* if defined for this proxy URL.
*/
- protected static final Pattern TEMPLATE_PATTERN = Pattern.compile("\\{([a-zA-Z0-9_%.]+)\\}");
+ protected static final Pattern TEMPLATE_PATTERN = Pattern.compile("\\{(.+?)\\}");
private static final String ATTR_QUERY_STRING =
URITemplateProxyServlet.class.getSimpleName() + ".queryString";
@@ -107,7 +108,10 @@ protected void service(HttpServletRequest servletRequest, HttpServletResponse se
String arg = matcher.group(1);
String replacement = params.remove(arg);//note we remove
if (replacement == null) {
- throw new ServletException("Missing HTTP parameter "+arg+" to fill the template");
+ replacement = servletRequest.getHeader(arg) ;
+ if (replacement == null) {
+ throw new ServletException("Missing HTTP parameter " + arg + " to fill the template");
+ }
}
matcher.appendReplacement(urlBuf, replacement);
}
@@ -140,4 +144,5 @@ protected void service(HttpServletRequest servletRequest, HttpServletResponse se
protected String rewriteQueryStringFromRequest(HttpServletRequest servletRequest, String queryString) {
return (String) servletRequest.getAttribute(ATTR_QUERY_STRING);
}
+
}