diff --git a/.gitignore b/.gitignore
index a07b178..6109265 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,7 @@
*.class
-
+.classpath
+.project
+.settings
# Package Files #
*.jar
*.war
diff --git a/pom.xml b/pom.xml
index 9602d04..506fbb0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,10 +1,9 @@
-
+
4.0.0
de.latlon
j2ep
- 1.0.0-SNAPSHOT
- war
+ jar
+ 1.2-securityproxy-master
j2ep
Fork of jEasy Extensible Proxy - svn://svn.code.sf.net/p/j2ep/code/trunk
@@ -17,7 +16,7 @@
org.apache.maven.plugins
maven-surefire-plugin
- 2.15
+ 2.22.1
**/PostTest*
@@ -31,14 +30,22 @@
-
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.0
+
+
+ 1.8
+
+
commons-digester
commons-digester
- 1.7
+ 1.8.1
commons-logging
@@ -49,12 +56,12 @@
commons-codec
commons-codec
- 1.3
+ 1.11
commons-beanutils
commons-beanutils
- 1.5
+ 1.9.3
commons-logging
@@ -80,20 +87,26 @@
commons-logging
commons-logging
- 1.0.3
+ 1.1.3
javax.servlet
servlet-api
- 2.4
+ 2.5
provided
junit
junit
- 3.8.1
+ 3.8.2
test
+
+ org.mockito
+ mockito-core
+ 1.9.5
+ test
+
cactus
cactus
@@ -101,9 +114,9 @@
test
- aspectj
+ org.aspectj
aspectjrt
- 1.2.1
+ 1.5.4
test
@@ -111,4 +124,43 @@
http://localhost:8080
-
\ No newline at end of file
+
+
+ scm:git:git@github.com:lat-lon/j2ep.git
+ scm:git:git@github.com:lat-lon/j2ep.git
+ https://github.com/lat-lon/j2ep.git
+
+
+
+
+ latlon-repo
+ http://repo.lat-lon/nexus/content/groups/public/
+
+
+ j2ep-releases
+ http://repo.lat-lon/nexus/content/repositories/j2ep-release/
+
+
+ j2ep-snapshots
+ http://repo.lat-lon/nexus/content/repositories/j2ep-snapshots/
+
+
+
+
+
+ j2ep-releases
+ http://repo.lat-lon/nexus/content/repositories/j2ep-release/
+
+
+ j2ep-snapshots
+ http://repo.lat-lon/nexus/content/repositories/j2ep-snapshots/
+
+
+
+
+
+ latlon-repo
+ http://repo.lat-lon/nexus/content/groups/public/
+
+
+
diff --git a/src/main/java/net/sf/j2ep/ConfigParser.java b/src/main/java/net/sf/j2ep/ConfigParser.java
index 9aa2e31..555ee8d 100644
--- a/src/main/java/net/sf/j2ep/ConfigParser.java
+++ b/src/main/java/net/sf/j2ep/ConfigParser.java
@@ -17,6 +17,10 @@
package net.sf.j2ep;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
import java.util.Iterator;
import java.util.LinkedList;
@@ -53,11 +57,45 @@ public class ConfigParser {
* mappings included.
*
* @param data The config file containing the XML data structure
+ * @throws FileNotFoundException
*/
- public ConfigParser(File data) {
+ public ConfigParser( File data ) {
+ createServerChain( data );
+ }
+
+ /**
+ * Standard constructor only specifying the input file. The constructor will
+ * parse the config and build a corresponding rule chain with the server
+ * mappings included.
+ *
+ * @param data The config file containing the XML data structure
+ */
+ public ConfigParser(InputStream data) {
+ createServerChain( data );
+ }
+
+
+ private void createServerChain( File data ) {
+ log = LogFactory.getLog( ConfigParser.class );
+ FileInputStream fileInputStream = null;
+ try {
+ fileInputStream = new FileInputStream( data );
+ createServerChain( fileInputStream );
+ } catch ( Exception e ) {
+ throw new RuntimeException( e );
+ } finally {
+ if ( fileInputStream != null )
+ try {
+ fileInputStream.close();
+ } catch ( IOException e ) {
+ }
+ }
+ }
+
+ private void createServerChain( InputStream data ) {
log = LogFactory.getLog(ConfigParser.class);
try {
- LinkedList serverContainer = createServerList(data);
+ LinkedList> serverContainer = createServerList(data);
if (log.isDebugEnabled()) {
debugServers(serverContainer);
}
@@ -66,7 +104,6 @@ public ConfigParser(File data) {
throw new RuntimeException(e);
}
}
-
/**
* Returns the parsed server chain.
*
@@ -81,7 +118,7 @@ public ServerChain getServerChain() {
*
* @return The rules all put into a rule chain
*/
- private LinkedList createServerList(File data) throws Exception {
+ private LinkedList> createServerList(InputStream data) throws Exception {
Digester digester = new Digester();
digester.setUseContextClassLoader(true);
@@ -133,7 +170,7 @@ private LinkedList createServerList(File data) throws Exception {
// Add server to list
digester.addSetNext("config/cluster-server", "add");
- return (LinkedList) digester.parse(data);
+ return (LinkedList>) digester.parse(data);
}
/**
@@ -142,8 +179,8 @@ private LinkedList createServerList(File data) throws Exception {
*
* @param servers The server to debug
*/
- private void debugServers(LinkedList servers) {
- Iterator itr = servers.iterator();
+ private void debugServers(LinkedList> servers) {
+ Iterator> itr = servers.iterator();
while (itr.hasNext()) {
ServerContainer container = (ServerContainer) itr.next();
diff --git a/src/main/java/net/sf/j2ep/ProxyFilter.java b/src/main/java/net/sf/j2ep/ProxyFilter.java
index 8d57642..964bbed 100644
--- a/src/main/java/net/sf/j2ep/ProxyFilter.java
+++ b/src/main/java/net/sf/j2ep/ProxyFilter.java
@@ -18,9 +18,15 @@
import java.io.File;
import java.io.IOException;
+import java.io.InputStream;
import java.net.UnknownHostException;
-import javax.servlet.*;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -31,8 +37,14 @@
import net.sf.j2ep.model.RequestHandler;
import net.sf.j2ep.model.ResponseHandler;
import net.sf.j2ep.model.Server;
+import net.sf.j2ep.servers.BaseServerFromUrlCreator;
-import org.apache.commons.httpclient.*;
+import org.apache.commons.httpclient.Header;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpException;
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.HttpMethodBase;
+import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.params.HttpClientParams;
import org.apache.commons.logging.Log;
@@ -41,178 +53,233 @@
/**
* A reverse proxy using a set of Rules to identify which resource to proxy.
*
- * At first the rule chain is traversed trying to find a matching rule.
- * When the rule is found it is given the option to rewrite the URL.
- * The rewritten URL is then sent to a Server creating a Response Handler
- * that can be used to process the response with streams and headers.
+ * At first the rule chain is traversed trying to find a matching rule. When the rule is found it is given the option to
+ * rewrite the URL. The rewritten URL is then sent to a Server creating a Response Handler that can be used to process
+ * the response with streams and headers.
*
- * The rules and servers are created dynamically and are specified in the
- * XML data file. This allows the proxy to be easily extended by creating
- * new rules and new servers.
+ * The rules and servers are created dynamically and are specified in the XML data file. This allows the proxy to be
+ * easily extended by creating new rules and new servers.
*
* @author Anders Nyman
*/
public class ProxyFilter implements Filter {
- /**
+ private static final String CONFIG_XML = "/config.xml";
+
+ private static final String DEFAULT_PATH = "/WEB-INF/config/data.xml";
+
+ private static final String REQUEST_ATTRIBUTE_SERVICE_URL = "net.sf.j2ep.serviceurl";
+
+ /**
* The server chain, will be traversed to find a matching server.
*/
private ServerChain serverChain;
-
- /**
+
+ /**
* Logging element supplied by commons-logging.
*/
private static Log log;
-
- /**
+
+ /**
* The httpclient used to make all connections with, supplied by commons-httpclient.
*/
private HttpClient httpClient;
/**
- * Implementation of a reverse-proxy. All request go through here. This is
- * the main class where are handling starts.
+ * Implementation of a reverse-proxy. All request go through here. This is the main class where are handling starts.
*
- * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
- * javax.servlet.ServletResponse, javax.servlet.FilterChain)
+ * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse,
+ * javax.servlet.FilterChain)
*/
- public void doFilter(ServletRequest request, ServletResponse response,
- FilterChain filterChain) throws IOException, ServletException {
+ public void doFilter( ServletRequest request, ServletResponse response, FilterChain filterChain )
+ throws IOException, ServletException {
HttpServletResponse httpResponse = (HttpServletResponse) response;
HttpServletRequest httpRequest = (HttpServletRequest) request;
- Server server = (Server) httpRequest.getAttribute("proxyServer");
- if (server == null) {
- server = serverChain.evaluate(httpRequest);
+ Server server = (Server) httpRequest.getAttribute( "proxyServer" );
+ if ( server == null ) {
+ Object requestAttributeServiceUrl = request.getAttribute( REQUEST_ATTRIBUTE_SERVICE_URL );
+ if ( requestAttributeServiceUrl != null ) {
+ BaseServerFromUrlCreator baseServerCreator = new BaseServerFromUrlCreator();
+ server = baseServerCreator.createServer( requestAttributeServiceUrl.toString(), request );
+ } else {
+ server = serverChain.evaluate( httpRequest );
+ }
}
-
- if (server == null) {
- filterChain.doFilter(request, response);
+
+ if ( server == null ) {
+ filterChain.doFilter( request, response );
} else {
- String uri = server.getRule().process(getURI(httpRequest));
+ String uri = server.getRule().process( getURI( httpRequest ) );
String url = request.getScheme() + "://" + server.getDomainName() + server.getPath() + uri;
- log.debug("Connecting to " + url);
-
+ log.debug( "Connecting to " + url );
+
ResponseHandler responseHandler = null;
-
+
try {
- httpRequest = server.preExecute(httpRequest);
- responseHandler = executeRequest(httpRequest, url);
- httpResponse = server.postExecute(httpResponse);
-
- responseHandler.process(httpResponse);
- } catch (HttpException e) {
- log.error("Problem while connecting to server", e);
- httpResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- server.setConnectionExceptionRecieved(e);
- } catch (UnknownHostException e) {
- log.error("Could not connection to the host specified", e);
- httpResponse.setStatus(HttpServletResponse.SC_GATEWAY_TIMEOUT);
- server.setConnectionExceptionRecieved(e);
- } catch (IOException e) {
- log.error( "Problem probably with the input being send, either with a Header or the Stream", e);
- httpResponse .setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- } catch (MethodNotAllowedException e) {
- log.error("Incoming method could not be handled", e);
- httpResponse.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
- httpResponse.setHeader("Allow", e.getAllowedMethods());
+ httpRequest = server.preExecute( httpRequest );
+ responseHandler = executeRequest( httpRequest, url );
+ httpResponse = server.postExecute( httpResponse );
+
+ responseHandler.process( httpResponse );
+ } catch ( HttpException e ) {
+ log.error( "Problem while connecting to server", e );
+ httpResponse.setStatus( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
+ server.setConnectionExceptionRecieved( e );
+ } catch ( UnknownHostException e ) {
+ log.error( "Could not connection to the host specified", e );
+ httpResponse.setStatus( HttpServletResponse.SC_GATEWAY_TIMEOUT );
+ server.setConnectionExceptionRecieved( e );
+ } catch ( IOException e ) {
+ log.error( "Problem probably with the input being send, either with a Header or the Stream", e );
+ httpResponse.setStatus( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
+ } catch ( MethodNotAllowedException e ) {
+ log.error( "Incoming method could not be handled", e );
+ httpResponse.setStatus( HttpServletResponse.SC_METHOD_NOT_ALLOWED );
+ httpResponse.setHeader( "Allow", e.getAllowedMethods() );
} finally {
- if (responseHandler != null) {
+ if ( responseHandler != null ) {
responseHandler.close();
}
}
}
}
-
+
/**
- * Will build a URI but including the Query String. That means that it really
- * isn't a URI, but quite near.
+ * Will build a URI but including the Query String. That means that it really isn't a URI, but quite near.
*
- * @param httpRequest Request to get the URI and query string from
+ * @param httpRequest
+ * Request to get the URI and query string from
* @return The URI for this request including the query string
*/
- private String getURI(HttpServletRequest httpRequest) {
+ private String getURI( HttpServletRequest httpRequest ) {
String contextPath = httpRequest.getContextPath();
- String uri = httpRequest.getRequestURI().substring(contextPath.length());
- if (httpRequest.getQueryString() != null) {
+ String uri = httpRequest.getRequestURI().substring( contextPath.length() );
+ if ( httpRequest.getQueryString() != null ) {
uri += "?" + httpRequest.getQueryString();
}
return uri;
}
/**
- * Will create the method and execute it. After this the method
- * is sent to a ResponseHandler that is returned.
+ * Will create the method and execute it. After this the method is sent to a ResponseHandler that is returned.
*
- * @param httpRequest Request we are receiving from the client
- * @param url The location we are proxying to
+ * @param httpRequest
+ * Request we are receiving from the client
+ * @param url
+ * The location we are proxying to
* @return A ResponseHandler that can be used to write the response
- * @throws MethodNotAllowedException If the method specified by the request isn't handled
- * @throws IOException When there is a problem with the streams
- * @throws HttpException The httpclient can throw HttpExcetion when executing the method
+ * @throws MethodNotAllowedException
+ * If the method specified by the request isn't handled
+ * @throws IOException
+ * When there is a problem with the streams
+ * @throws HttpException
+ * The httpclient can throw HttpExcetion when executing the method
*/
- private ResponseHandler executeRequest(HttpServletRequest httpRequest,
- String url) throws MethodNotAllowedException, IOException,
- HttpException {
- RequestHandler requestHandler = RequestHandlerFactory
- .createRequestMethod(httpRequest.getMethod());
+ private ResponseHandler executeRequest( HttpServletRequest httpRequest, String url )
+ throws MethodNotAllowedException, IOException, HttpException {
+ RequestHandler requestHandler = RequestHandlerFactory.createRequestMethod( httpRequest.getMethod() );
- HttpMethod method = requestHandler.process(httpRequest, url);
- method.setFollowRedirects(false);
+ HttpMethod method = requestHandler.process( httpRequest, url );
+ method.setFollowRedirects( false );
/*
- * Why does method.validate() return true when the method has been
- * aborted? I mean, if validate returns true the API says that means
- * that the method is ready to be executed.
- * TODO I don't like doing type casting here, see above.
+ * Why does method.validate() return true when the method has been aborted? I mean, if validate returns true the
+ * API says that means that the method is ready to be executed. TODO I don't like doing type casting here, see
+ * above.
*/
- if (!((HttpMethodBase) method).isAborted()) {
- httpClient.executeMethod(method);
+ if ( !( (HttpMethodBase) method ).isAborted() ) {
+ httpClient.executeMethod( method );
- if (method.getStatusCode() == 405) {
- Header allow = method.getResponseHeader("allow");
+ if ( method.getStatusCode() == 405 ) {
+ Header allow = method.getResponseHeader( "allow" );
String value = allow.getValue();
- throw new MethodNotAllowedException(
- "Status code 405 from server", AllowedMethodHandler
- .processAllowHeader(value));
+ throw new MethodNotAllowedException( "Status code 405 from server",
+ AllowedMethodHandler.processAllowHeader( value ) );
}
}
- return ResponseHandlerFactory.createResponseHandler(method);
+ return ResponseHandlerFactory.createResponseHandler( method );
}
/**
- * Called upon initialization, Will create the ConfigParser and get the
- * RuleChain back. Will also configure the httpclient.
+ * Called upon initialization, Will create the ConfigParser and get the RuleChain back. Will also configure the
+ * httpclient.
*
* @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
*/
- public void init(FilterConfig filterConfig) throws ServletException {
- log = LogFactory.getLog(ProxyFilter.class);
- AllowedMethodHandler.setAllowedMethods("OPTIONS,GET,HEAD,POST,PUT,DELETE,TRACE");
-
- httpClient = new HttpClient(new MultiThreadedHttpConnectionManager());
- httpClient.getParams().setBooleanParameter(HttpClientParams.USE_EXPECT_CONTINUE, false);
- httpClient.getParams().setCookiePolicy(CookiePolicy.IGNORE_COOKIES);
-
- String data = filterConfig.getInitParameter("dataUrl");
- if (data == null) {
- serverChain = null;
+ public void init( FilterConfig filterConfig )
+ throws ServletException {
+ log = LogFactory.getLog( ProxyFilter.class );
+ AllowedMethodHandler.setAllowedMethods( "OPTIONS,GET,HEAD,POST,PUT,DELETE,TRACE" );
+
+ httpClient = new HttpClient( new MultiThreadedHttpConnectionManager() );
+ httpClient.getParams().setBooleanParameter( HttpClientParams.USE_EXPECT_CONTINUE, false );
+ httpClient.getParams().setCookiePolicy( CookiePolicy.IGNORE_COOKIES );
+
+ String proxyConfigFile = filterConfig.getInitParameter( "proxyConfigResource" );
+ String proxyConfigEnv = filterConfig.getInitParameter( "proxyConfigEnv" );
+ if ( proxyConfigFile != null ) {
+ parseConfigFromFileInClasspath( proxyConfigFile );
+ } else if ( proxyConfigEnv != null ) {
+ parseConfigFileFromSystemEnvDirectory( proxyConfigEnv );
} else {
- try {
- File dataFile = new File(filterConfig.getServletContext().getRealPath(data));
- ConfigParser parser = new ConfigParser(dataFile);
- serverChain = parser.getServerChain();
- } catch (Exception e) {
- throw new ServletException(e);
- }
+ parseConfigFileFromDefaultPath( filterConfig );
+ }
+ }
+
+ private void parseConfigFromFileInClasspath( String proxyConfigFile )
+ throws ServletException {
+ try {
+ InputStream resourceAsStream = ProxyFilter.class.getResourceAsStream( proxyConfigFile );
+ ConfigParser parser = new ConfigParser( resourceAsStream );
+ serverChain = parser.getServerChain();
+ } catch ( Exception e ) {
+ log.error( "j2ep configuration could not be read from classpath resource!", e );
+ throw new ServletException( e );
+ }
+ }
+
+ private void parseConfigFileFromSystemEnvDirectory( String proxyConfigEnv )
+ throws ServletException {
+ try {
+ String path = buildConfigFilePath( proxyConfigEnv );
+ processConfiguration( path );
+ } catch ( Exception e ) {
+ log.error( "j2ep configuration could not be read from system environment variable!", e );
+ throw new ServletException( e );
}
}
+ private void parseConfigFileFromDefaultPath( FilterConfig filterConfig )
+ throws ServletException {
+ String path = null;
+ try {
+ path = filterConfig.getServletContext().getRealPath( DEFAULT_PATH );
+ processConfiguration( path );
+ } catch ( Exception e ) {
+ log.error( "j2ep configuration could not be read from default path " + path, e );
+ throw new ServletException( e );
+ }
+ }
+
+ private void processConfiguration( String path ) {
+ File dataFile = new File( path );
+ ConfigParser parser = new ConfigParser( dataFile );
+ serverChain = parser.getServerChain();
+ }
+
+ private String buildConfigFilePath( String proxyConfigEnv ) {
+ String path = System.getenv( proxyConfigEnv );
+ if ( !path.endsWith( "/" ) )
+ path += "/";
+ path += CONFIG_XML;
+ return path;
+ }
+
/**
- * Called when this filter is destroyed.
- * Releases the fields.
+ * Called when this filter is destroyed. Releases the fields.
*
* @see javax.servlet.Filter#destroy()
*/
@@ -221,4 +288,4 @@ public void destroy() {
httpClient = null;
serverChain = null;
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/net/sf/j2ep/rules/DirectoryRule.java b/src/main/java/net/sf/j2ep/rules/DirectoryRule.java
index c8e80c1..a6833de 100644
--- a/src/main/java/net/sf/j2ep/rules/DirectoryRule.java
+++ b/src/main/java/net/sf/j2ep/rules/DirectoryRule.java
@@ -19,82 +19,121 @@
import javax.servlet.http.HttpServletRequest;
/**
- * A rule that will check the start of the URI for a specifed
- * starting directory/directories. If the directory is at the start this
- * rule matches. The process method will then remove this directory
- * from the URI, making it easy to map various servers to directory
- * structures.
- * If one needs some more advanced types of rewriting use the RewriteRule.
- *
+ * A rule that will check the start of the URI for a specifed starting directory/directories. If the directory is at the
+ * start this rule matches. The process method will then remove this directory from the URI, making it easy to map
+ * various servers to directory structures. If one needs some more advanced types of rewriting use the RewriteRule.
+ *
* @author Anders Nyman
*/
public class DirectoryRule extends BaseRule {
- /**
+ /**
* The directory structure.
*/
private String directory;
-
+
+ /**
+ * The originally set directory structure before appending and prepending slashes
+ */
+ private String originalDirectory;
+
+ private boolean isAppendTrailingSlash = true;
+
+ /**
+ * Decide whether a trailing slash should be appended to directory settings without a trailing slash.
+ *
+ * @param isAppendTrailingSlash
+ */
+ public void setIsAppendTrailingSlash( String isAppendTrailingSlash ) {
+ if ( isAppendTrailingSlash != null && isAppendTrailingSlash.equals( "false" ) ) {
+ this.isAppendTrailingSlash = false;
+ directory = prependSlashIfNeccessary( originalDirectory );
+ }
+ }
+
+ /**
+ * Return the trailing slash setting
+ *
+ * @return true if slashes are appended to directory settings that do not end with a slash, false if not
+ */
+ public boolean getAppendTrailingSlash() {
+ return isAppendTrailingSlash;
+ }
+
/**
- * Sets the directory structure that will
- * be mapped to a specified server.
- *
- * @param directory The directory string
+ * Sets the directory structure that will be mapped to a specified server.
+ *
+ * @param directory
+ * The directory string
*/
- public void setDirectory(String directory) {
- if (directory == null) {
- throw new IllegalArgumentException(
- "The directory string cannot be null.");
+ public void setDirectory( String directory ) {
+ if ( directory == null ) {
+ throw new IllegalArgumentException( "The directory string cannot be null." );
} else {
- if (!directory.startsWith("/")) {
+ if ( !directory.startsWith( "/" ) ) {
directory = "/" + directory;
}
- if (!directory.endsWith(("/"))) {
- directory += "/";
- }
+ originalDirectory = directory;
+ directory = prependSlashIfNeccessary( directory );
+ directory = appendSlashIfNeccessary( directory );
this.directory = directory;
}
}
+ private String appendSlashIfNeccessary( String directory ) {
+ if ( !directory.endsWith( ( "/" ) ) && isAppendTrailingSlash ) {
+ directory += "/";
+ }
+ return directory;
+ }
+
+ private String prependSlashIfNeccessary( String directory ) {
+ if ( !directory.startsWith( "/" ) ) {
+ directory = "/" + directory;
+ }
+ return directory;
+ }
+
/**
- * Returns the directory structure that
- * this rule will match on.
- *
+ * Returns the directory structure that this rule will match on.
+ *
* @return The directory string
*/
public String getDirectory() {
return directory;
}
-
+
/**
- * Will see if the directory for the incoming URI is the same
- * as this rule is set to match on.
+ * Will see if the directory for the incoming URI is the same as this rule is set to match on.
*
* @see net.sf.j2ep.model.Rule#matches(javax.servlet.http.HttpServletRequest)
*/
- public boolean matches(HttpServletRequest request) {
+ public boolean matches( HttpServletRequest request ) {
String uri = request.getServletPath();
- return (uri.startsWith(directory));
+ return ( uri.startsWith( directory ) );
}
-
+
/**
* Removes the specified mapping directory from the URI.
*
* @see net.sf.j2ep.model.Rule#process(java.lang.String)
*/
- public String process(String uri) {
- return uri.substring(directory.length()-1);
+ public String process( String uri ) {
+ if ( !isAppendTrailingSlash )
+ return uri.substring( directory.length() );
+ else
+ return uri.substring( directory.length() - 1 );
}
-
+
/**
- * Does the opposite of process. revert(String URI) will add the directory
- * specified to the start of the incoming URI.
+ * Does the opposite of process. revert(String URI) will add the directory specified to the start of the incoming
+ * URI.
*
* @see net.sf.j2ep.model.Rule#revert(java.lang.String)
*/
- public String revert(String uri) {
- if (uri.startsWith("/")) {
- return directory + uri.substring(1);
+ public String revert( String uri ) {
+ if ( uri.startsWith( "/" ) ) {
+ return directory + uri.substring( 1 );
} else {
return uri;
}
diff --git a/src/main/java/net/sf/j2ep/servers/BaseServerFromUrlCreator.java b/src/main/java/net/sf/j2ep/servers/BaseServerFromUrlCreator.java
new file mode 100644
index 0000000..9070e5d
--- /dev/null
+++ b/src/main/java/net/sf/j2ep/servers/BaseServerFromUrlCreator.java
@@ -0,0 +1,94 @@
+package net.sf.j2ep.servers;
+
+import net.sf.j2ep.model.Server;
+import net.sf.j2ep.rules.DirectoryRule;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * Creates a BaseServer-object from passed url.
+ *
+ * @author Dirk Stenger
+ * @author last edited by: $Author: stenger $
+ * @version $Revision: $, $Date: $
+ */
+public class BaseServerFromUrlCreator {
+
+ private static final String BASE_SERVER_IS_REWRITING = "true";
+
+ private static final String DIRECTORY_RULE_IS_APPENDING_TRAILING_SLASH = "false";
+
+ /**
+ * Create a BaseServer-object from url and request.
+ *
+ * @param url, never null
+ * @param request, never null
+ * @return Server
+ */
+ public Server createServer( String url, ServletRequest request ) {
+ checkRequiredParameters( url, request );
+ String urlWithoutProtocol = retrieveUrlWithoutProtocol( url );
+ int divideDomainNameAndPathIndex = urlWithoutProtocol.indexOf( "/" );
+ String domainName = urlWithoutProtocol.substring( 0, divideDomainNameAndPathIndex );
+ String path = retrievePath( urlWithoutProtocol, divideDomainNameAndPathIndex );
+ String directoryPath = retrieveDirectoryPath( request );
+ return createServer( domainName, path, directoryPath );
+ }
+
+ private String retrieveUrlWithoutProtocol( String url ) {
+ if ( url.contains( "//" ) ) {
+ int protocolIndex = url.indexOf( "//" );
+ return url.substring( protocolIndex + 2 );
+ } else {
+ return url;
+ }
+ }
+
+ private String retrievePath( String urlWithoutProtocol, int divideDomainNameAndPathIndex ) {
+ String path = urlWithoutProtocol.substring( divideDomainNameAndPathIndex );
+ if ( path.endsWith( "?" ) )
+ return path.substring( 0, path.length() - 1 );
+ else
+ return path;
+ }
+
+ private String retrieveDirectoryPath( ServletRequest request ) {
+ String directoryPath = ( (HttpServletRequest) request ).getServletPath();
+ if ( directoryPath.contains( "/" ) ) {
+ int directoryPathIndex = directoryPath.lastIndexOf( "/" );
+ return directoryPath.substring( directoryPathIndex );
+ } else {
+ return directoryPath;
+ }
+ }
+
+ private Server createServer( String domainName, String path, String directoryPath ) {
+ BaseServer baseServer = createBaseServer( domainName, path );
+ DirectoryRule directoryRule = createDirectoryRule( directoryPath );
+ baseServer.setRule( directoryRule );
+ return baseServer;
+ }
+
+ private BaseServer createBaseServer( String domainName, String path ) {
+ BaseServer baseServer = new BaseServer();
+ baseServer.setDomainName( domainName );
+ baseServer.setPath( path );
+ baseServer.setIsRewriting( BASE_SERVER_IS_REWRITING );
+ return baseServer;
+ }
+
+ private DirectoryRule createDirectoryRule( String directoryPath ) {
+ DirectoryRule directoryRule = new DirectoryRule();
+ directoryRule.setDirectory( directoryPath );
+ directoryRule.setIsAppendTrailingSlash( DIRECTORY_RULE_IS_APPENDING_TRAILING_SLASH );
+ return directoryRule;
+ }
+
+ private void checkRequiredParameters( String url, ServletRequest request ) {
+ if ( url == null )
+ throw new IllegalArgumentException( "Url must not be null!" );
+ if ( request == null )
+ throw new IllegalArgumentException( "Request must not be null!" );
+ }
+}
diff --git a/src/main/resources/logging.properties b/src/main/resources/logging.properties
index f732ee5..393446e 100644
--- a/src/main/resources/logging.properties
+++ b/src/main/resources/logging.properties
@@ -1,14 +1,8 @@
-handlers = org.apache.juli.FileHandler
-
############################################################
# Handler specific properties.
# Describes specific configuration info for Handlers.
############################################################
-org.apache.juli.FileHandler.level = FINEST
-org.apache.juli.FileHandler.directory = /logs
-org.apache.juli.FileHandler.prefix = j2ep.
-
.level=INFO
httpclient.wire.header.level=INFO
diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml
index 20dbb1a..5cf3c17 100644
--- a/src/main/webapp/WEB-INF/web.xml
+++ b/src/main/webapp/WEB-INF/web.xml
@@ -14,8 +14,8 @@
Proxy
net.sf.j2ep.ProxyFilter
- dataUrl
- /WEB-INF/config/data.xml
+ proxyConfigEnv
+ PROXY_CONFIG
diff --git a/src/test/java/net/sf/j2ep/servers/BaseServerFromUrlCreatorTest.java b/src/test/java/net/sf/j2ep/servers/BaseServerFromUrlCreatorTest.java
new file mode 100644
index 0000000..cb7d7c4
--- /dev/null
+++ b/src/test/java/net/sf/j2ep/servers/BaseServerFromUrlCreatorTest.java
@@ -0,0 +1,98 @@
+package net.sf.j2ep.servers;
+
+import junit.framework.TestCase;
+import net.sf.j2ep.model.Server;
+import net.sf.j2ep.rules.DirectoryRule;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+/**
+ * Tests for BaseServerFromUrlCreator.
+ *
+ * @author Dirk Stenger
+ * @author last edited by: $Author: stenger $
+ * @version $Revision: $, $Date: $
+ */
+public class BaseServerFromUrlCreatorTest extends TestCase {
+
+ private static final String URL = "http://www.test.de/url/j2ep?";
+
+ private static final String URL_WITHOUT_PROTOCOL = "www.test.de/url/j2ep?";
+
+ private static final String URL_WITHOUT_QUESTION_MARK = "http://www.test.de/url/j2ep";
+
+ private static final String REQUEST_SERVLET_PATH = "/path";
+
+ private static final String EXPECTED_DOMAIN_NAME = "www.test.de";
+
+ private static final String EXPECTED_PATH = "/url/j2ep";
+
+ private static final String EXPECTED_DIRECTORY = "/path";
+
+ private final BaseServerFromUrlCreator serverCreator = new BaseServerFromUrlCreator();
+
+ public void testCreateServer() {
+ ServletRequest request = mockServletRequest();
+ Server server = serverCreator.createServer( URL, request );
+
+ assertEquals( EXPECTED_DOMAIN_NAME, server.getDomainName() );
+ assertEquals( EXPECTED_PATH, server.getPath() );
+ DirectoryRule rule = (DirectoryRule) server.getRule();
+ assertEquals( EXPECTED_DIRECTORY, rule.getDirectory() );
+ }
+
+ public void testCreateServerWithoutProtocol() {
+ ServletRequest request = mockServletRequest();
+ Server server = serverCreator.createServer( URL_WITHOUT_PROTOCOL, request );
+
+ assertEquals( EXPECTED_DOMAIN_NAME, server.getDomainName() );
+ assertEquals( EXPECTED_PATH, server.getPath() );
+ DirectoryRule rule = (DirectoryRule) server.getRule();
+ assertEquals( EXPECTED_DIRECTORY, rule.getDirectory() );
+ }
+
+ public void testCreateServerWithoutQuestionMark() {
+ ServletRequest request = mockServletRequest();
+ Server server = serverCreator.createServer( URL_WITHOUT_QUESTION_MARK, request );
+
+ assertEquals( EXPECTED_DOMAIN_NAME, server.getDomainName() );
+ assertEquals( EXPECTED_PATH, server.getPath() );
+ DirectoryRule rule = (DirectoryRule) server.getRule();
+ assertEquals( EXPECTED_DIRECTORY, rule.getDirectory() );
+ }
+
+ public void testCreateServerWithNullValues() {
+ try {
+ serverCreator.createServer( null, null );
+ fail( "Expected an IllegalArugmentException to be thrown" );
+ } catch ( IllegalArgumentException exception ) {
+ }
+ }
+
+ public void testCreateServerWithUrlNullValue() {
+ ServletRequest request = mockServletRequest();
+ try {
+ serverCreator.createServer( null, request );
+ fail( "Expected an IllegalArugmentException to be thrown" );
+ } catch ( IllegalArgumentException exception ) {
+ }
+ }
+
+ public void testCreateServerWithRequestNullValue() {
+ try {
+ serverCreator.createServer( URL, null );
+ fail( "Expected an IllegalArugmentException to be thrown" );
+ } catch ( IllegalArgumentException exception ) {
+ }
+ }
+
+ private ServletRequest mockServletRequest() {
+ HttpServletRequest request = mock( HttpServletRequest.class );
+ doReturn( REQUEST_SERVLET_PATH ).when( request ).getServletPath();
+ return request;
+ }
+}