You are viewing a plain text version of this content. The canonical link for it is here.
Posted to portalapps-dev@portals.apache.org by wo...@apache.org on 2009/10/05 19:50:07 UTC
svn commit: r821934 [1/2] - in /portals/applications/webcontent/trunk:
webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/
webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/
webcontent-jar/src...
Author: woonsan
Date: Mon Oct 5 17:50:07 2009
New Revision: 821934
URL: http://svn.apache.org/viewvc?rev=821934&view=rev
Log:
APA-17: Improves reverse proxy component.
- Proper 404 handling
- Omitting Content-Length when rewriting happens
- Request headers are configurable for each proxy target host.
- Enhances the default text line based parser adaptor classes hierarchy
- Rewriters, ParserAdaptors are properties-settable for sophisticated uses.
- Optimizing proxy path mapper selection.
Added:
portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyException.java (with props)
portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyNotFoundException.java (with props)
portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/AbstractReverseProxyTextLinesParserAdaptor.java (with props)
portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/DefaultReverseProxyLinkRewritingParserAaptor.java (contents, props changed)
- copied, changed from r821705, portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/PassMappingLinkRewritingParserAaptor.java
portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/AbstractTextLinesParserAdaptor.java (with props)
Removed:
portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/PassMappingLinkRewritingParserAaptor.java
portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/SimpleLinkRewritingParserAaptor.java
Modified:
portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyPathMapper.java
portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyPathMapperProvider.java
portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyService.java
portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/SSOSiteCredentialsProvider.java
portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/DefaultHttpReverseProxyPathMapperImpl.java
portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/DefaultHttpReverseProxyPathMapperProviderImpl.java
portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/DefaultHttpReverseProxyServlet.java
portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/RewritableHttpReverseProxyServiceImpl.java
portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/MappingClasspathRewriterController.java
portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/rewriter/MappingRewriterController.java
portals/applications/webcontent/trunk/webcontent-jar/src/test/java/org/apache/portals/applications/webcontent/proxy/TestProxyPathMappings.java
portals/applications/webcontent/trunk/webcontent-jar/src/test/java/org/apache/portals/applications/webcontent/proxy/TestReverseProxyLinkRewritingParserAaptor.java
portals/applications/webcontent/trunk/webcontent-war/src/main/webapp/WEB-INF/conf/reverseproxy.properties
Added: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyException.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyException.java?rev=821934&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyException.java (added)
+++ portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyException.java Mon Oct 5 17:50:07 2009
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.portals.applications.webcontent.proxy;
+
+/**
+ * The <CODE>HttpReverseProxyException</CODE> class defines a general exception
+ * that an http reverse proxy component can throw when it is unable to perform its operation
+ * successfully.
+ *
+ * @version $Id$
+ */
+public class HttpReverseProxyException extends Exception {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructs a new HttpReverseProxyException exception.
+ */
+ public HttpReverseProxyException() {
+ super();
+ }
+
+ /**
+ * Constructs a new HttpReverseProxyException exception with the given message.
+ *
+ * @param message
+ * the exception message
+ */
+ public HttpReverseProxyException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a new HttpReverseProxyException exception with the nested exception.
+ *
+ * @param nested
+ * the nested exception
+ */
+ public HttpReverseProxyException(Throwable nested) {
+ super(nested);
+ }
+
+ /**
+ * Constructs a new HttpReverseProxyException exception when the container needs to do
+ * the following:
+ * <ul>
+ * <li>throw an exception
+ * <li>include the "nested" exception
+ * <li>include a description message
+ * </ul>
+ *
+ * @param msg
+ * the exception message
+ * @param nested
+ * the nested exception
+ */
+ public HttpReverseProxyException(String msg, Throwable nested) {
+ super(msg, nested);
+ }
+
+}
Propchange: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyException.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyException.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyException.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyNotFoundException.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyNotFoundException.java?rev=821934&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyNotFoundException.java (added)
+++ portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyNotFoundException.java Mon Oct 5 17:50:07 2009
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.portals.applications.webcontent.proxy;
+
+/**
+ * The <CODE>HttpReverseProxyNotFoundException</CODE> class defines a not-found-exception
+ * that an http reverse proxy component can throw when it is unable to find web resources
+ * successfully.
+ *
+ * @version $Id$
+ */
+public class HttpReverseProxyNotFoundException extends HttpReverseProxyException {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructs a new HttpReverseProxyNotFoundException exception.
+ */
+ public HttpReverseProxyNotFoundException() {
+ super();
+ }
+
+ /**
+ * Constructs a new HttpReverseProxyNotFoundException exception with the given message.
+ *
+ * @param message
+ * the exception message
+ */
+ public HttpReverseProxyNotFoundException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a new HttpReverseProxyNotFoundException exception with the nested exception.
+ *
+ * @param nested
+ * the nested exception
+ */
+ public HttpReverseProxyNotFoundException(Throwable nested) {
+ super(nested);
+ }
+
+ /**
+ * Constructs a new HttpReverseProxyNotFoundException exception when the container needs to do
+ * the following:
+ * <ul>
+ * <li>throw an exception
+ * <li>include the "nested" exception
+ * <li>include a description message
+ * </ul>
+ *
+ * @param msg
+ * the exception message
+ * @param nested
+ * the nested exception
+ */
+ public HttpReverseProxyNotFoundException(String msg, Throwable nested) {
+ super(msg, nested);
+ }
+
+}
Propchange: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyNotFoundException.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyNotFoundException.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyNotFoundException.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyPathMapper.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyPathMapper.java?rev=821934&r1=821933&r2=821934&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyPathMapper.java (original)
+++ portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyPathMapper.java Mon Oct 5 17:50:07 2009
@@ -16,6 +16,8 @@
*/
package org.apache.portals.applications.webcontent.proxy;
+import java.util.Map;
+
/**
* proxy path mapper interface for http reverse proxy service.
@@ -59,4 +61,10 @@
*/
public String getLocalPath(String remoteURL);
+ /**
+ * Returns default request headers to the remote URL target.
+ * @return
+ */
+ public Map<String, String> getDefaultRequestHeaders();
+
}
\ No newline at end of file
Modified: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyPathMapperProvider.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyPathMapperProvider.java?rev=821934&r1=821933&r2=821934&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyPathMapperProvider.java (original)
+++ portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyPathMapperProvider.java Mon Oct 5 17:50:07 2009
@@ -16,8 +16,6 @@
*/
package org.apache.portals.applications.webcontent.proxy;
-import java.util.List;
-
import org.apache.portals.applications.webcontent.rewriter.RewriterController;
import org.apache.portals.applications.webcontent.rewriter.rules.Ruleset;
@@ -54,9 +52,9 @@
public Ruleset getRewriterRuleset(HttpReverseProxyPathMapper proxyPathMapper);
/**
- * Returns unmodifiable proxy path mappers.
+ * Returns the maximum matching path part count.
* @return
*/
- public List<HttpReverseProxyPathMapper> getProxyPathMappers();
+ public int getMaxMatchingPathPartCount();
}
\ No newline at end of file
Modified: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyService.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyService.java?rev=821934&r1=821933&r2=821934&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyService.java (original)
+++ portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/HttpReverseProxyService.java Mon Oct 5 17:50:07 2009
@@ -34,6 +34,6 @@
public void destroy();
- public void invoke(HttpServletRequest request, HttpServletResponse response) throws IOException;
+ public void invoke(HttpServletRequest request, HttpServletResponse response) throws HttpReverseProxyException, IOException;
}
Modified: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/SSOSiteCredentialsProvider.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/SSOSiteCredentialsProvider.java?rev=821934&r1=821933&r2=821934&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/SSOSiteCredentialsProvider.java (original)
+++ portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/SSOSiteCredentialsProvider.java Mon Oct 5 17:50:07 2009
@@ -16,7 +16,6 @@
*/
package org.apache.portals.applications.webcontent.proxy;
-import java.net.URI;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
Added: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/AbstractReverseProxyTextLinesParserAdaptor.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/AbstractReverseProxyTextLinesParserAdaptor.java?rev=821934&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/AbstractReverseProxyTextLinesParserAdaptor.java (added)
+++ portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/AbstractReverseProxyTextLinesParserAdaptor.java Mon Oct 5 17:50:07 2009
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.portals.applications.webcontent.proxy.impl;
+
+import org.apache.portals.applications.webcontent.proxy.HttpReverseProxyPathMapper;
+import org.apache.portals.applications.webcontent.proxy.HttpReverseProxyPathMapperProvider;
+import org.apache.portals.applications.webcontent.proxy.ReverseProxyRewritingContext;
+import org.apache.portals.applications.webcontent.proxy.ReverseProxyRewritingContextAware;
+import org.apache.portals.applications.webcontent.rewriter.AbstractTextLinesParserAdaptor;
+
+
+/**
+ * AbstractReverseProxyTextLinesParserAdaptor
+ *
+ * @version $Id$
+ */
+public abstract class AbstractReverseProxyTextLinesParserAdaptor extends AbstractTextLinesParserAdaptor implements ReverseProxyRewritingContextAware
+{
+
+ private ReverseProxyRewritingContext reverseProxyRewritingContext;
+ private String rewritingContextPath;
+ private HttpReverseProxyPathMapperProvider proxyPathMapperProvider;
+ private int maxMatchingPathPartCount;
+ private HttpReverseProxyPathMapper proxyPathMapper;
+
+ public void setReverseProxyRewritingContext(ReverseProxyRewritingContext reverseProxyRewritingContext)
+ {
+ this.reverseProxyRewritingContext = reverseProxyRewritingContext;
+
+ if (this.reverseProxyRewritingContext != null)
+ {
+ rewritingContextPath = reverseProxyRewritingContext.getRewritingContextPath();
+ proxyPathMapperProvider = this.reverseProxyRewritingContext.getHttpReverseProxyPathMapperProvider();
+ maxMatchingPathPartCount = proxyPathMapperProvider.getMaxMatchingPathPartCount();
+ proxyPathMapper = this.reverseProxyRewritingContext.getHttpReverseProxyPathMapper();
+ }
+ }
+
+ protected ReverseProxyRewritingContext getReverseProxyRewritingContext()
+ {
+ return reverseProxyRewritingContext;
+ }
+
+ protected String getRewritingContextPath()
+ {
+ return rewritingContextPath;
+ }
+
+ protected HttpReverseProxyPathMapperProvider getHttpReverseProxyPathMapperProvider()
+ {
+ return proxyPathMapperProvider;
+ }
+
+ protected int getMaxMatchingPathPartCount()
+ {
+ return maxMatchingPathPartCount;
+ }
+
+ protected HttpReverseProxyPathMapper getHttpReverseProxyPathMapper()
+ {
+ return proxyPathMapper;
+ }
+
+}
Propchange: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/AbstractReverseProxyTextLinesParserAdaptor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/AbstractReverseProxyTextLinesParserAdaptor.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/AbstractReverseProxyTextLinesParserAdaptor.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/DefaultHttpReverseProxyPathMapperImpl.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/DefaultHttpReverseProxyPathMapperImpl.java?rev=821934&r1=821933&r2=821934&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/DefaultHttpReverseProxyPathMapperImpl.java (original)
+++ portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/DefaultHttpReverseProxyPathMapperImpl.java Mon Oct 5 17:50:07 2009
@@ -16,6 +16,8 @@
*/
package org.apache.portals.applications.webcontent.proxy.impl;
+import java.util.Map;
+
import org.apache.commons.lang.StringUtils;
import org.apache.portals.applications.webcontent.proxy.HttpReverseProxyPathMapper;
@@ -29,14 +31,16 @@
private String name;
private String localBasePath;
private String remoteBaseURL;
+ private Map<String, String> defaultRequestHeaders;
private int hash;
- public DefaultHttpReverseProxyPathMapperImpl(String name, String localBasePath, String remoteBaseURL)
+ public DefaultHttpReverseProxyPathMapperImpl(String name, String localBasePath, String remoteBaseURL, Map<String, String> defaultRequestHeaders)
{
this.name = name;
this.localBasePath = localBasePath;
this.remoteBaseURL = remoteBaseURL;
+ this.defaultRequestHeaders = defaultRequestHeaders;
hash = new StringBuilder(40).append(name).append(':').append(localBasePath).append(':').append(remoteBaseURL).toString().hashCode();
}
@@ -75,6 +79,11 @@
return null;
}
+ public Map<String, String> getDefaultRequestHeaders()
+ {
+ return defaultRequestHeaders;
+ }
+
@Override
public int hashCode()
{
@@ -99,4 +108,5 @@
return false;
}
+
}
Modified: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/DefaultHttpReverseProxyPathMapperProviderImpl.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/DefaultHttpReverseProxyPathMapperProviderImpl.java?rev=821934&r1=821933&r2=821934&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/DefaultHttpReverseProxyPathMapperProviderImpl.java (original)
+++ portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/DefaultHttpReverseProxyPathMapperProviderImpl.java Mon Oct 5 17:50:07 2009
@@ -24,6 +24,7 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.apache.commons.collections.map.LRUMap;
import org.apache.commons.lang.StringUtils;
import org.apache.portals.applications.webcontent.proxy.HttpReverseProxyPathMapper;
import org.apache.portals.applications.webcontent.proxy.HttpReverseProxyPathMapperProvider;
@@ -42,18 +43,34 @@
private static String [] GLOB_EXPR_SEARCHES = { "*", ".", "/", "?", "+" };
- private static String [] GLOB_EXPR_REPLACES = { "(.+)", "\\.", "\\/", "\\?", "\\+" };
+ private static String [] GLOB_EXPR_REPLACES = { "([^\\/]+)", "\\.", "\\/", "\\?", "\\+" };
private static String [] GROUP_REF_SEARCHES = { "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9" };
- private static String [] GROUP_REF_REPLACES = { "(.+)", "(.+)", "(.+)", "(.+)", "(.+)", "(.+)", "(.+)", "(.+)", "(.+)" };
+ private static String [] GROUP_REF_REPLACES = { "([^\\/]+)", "([^\\/]+)", "([^\\/]+)", "([^\\/]+)", "([^\\/]+)",
+ "([^\\/]+)", "([^\\/]+)", "([^\\/]+)", "([^\\/]+)" };
private static Logger log = LoggerFactory.getLogger(DefaultHttpReverseProxyPathMapperProviderImpl.class);
/**
- * Proxy path mappers
+ * Maximum matching path part count
*/
- private List<HttpReverseProxyPathMapper> proxyPathMappers;
+ private int maxMatchingPathPartCount = 2;
+
+ /**
+ * Static proxy path mappers
+ */
+ private Map<String, HttpReverseProxyPathMapper> staticProxyPathMappersMap;
+
+ /**
+ * Dynamic proxy path mappers
+ */
+ private Map dynamicProxyPathMappersMap;
+
+ /**
+ * Maximum size of dynamic proxy path map
+ */
+ private int dynamicProxyPathMapperCacheCount;
/**
* Proxy path Glob mappers
@@ -78,37 +95,93 @@
Map<HttpReverseProxyPathMapper, RewriterController> rewriterControllerMap,
Map<HttpReverseProxyPathMapper, Ruleset> rewriterRulesetMap)
{
+ this(proxyPathMappers, 1000, rewriterControllerMap, rewriterRulesetMap);
+ }
+
+ public DefaultHttpReverseProxyPathMapperProviderImpl(List<HttpReverseProxyPathMapper> proxyPathMappers,
+ int dynamicProxyPathMapperCacheCount,
+ Map<HttpReverseProxyPathMapper, RewriterController> rewriterControllerMap,
+ Map<HttpReverseProxyPathMapper, Ruleset> rewriterRulesetMap)
+ {
+ this.dynamicProxyPathMapperCacheCount = dynamicProxyPathMapperCacheCount;
this.rewriterControllerMap = rewriterControllerMap;
this.rewriterRulesetMap = rewriterRulesetMap;
- this.proxyPathMappers = Collections.synchronizedList(new ArrayList<HttpReverseProxyPathMapper>());
+ this.staticProxyPathMappersMap = new HashMap<String, HttpReverseProxyPathMapper>();
+ this.dynamicProxyPathMappersMap = Collections.synchronizedMap(new LRUMap(this.dynamicProxyPathMapperCacheCount));
this.proxyPathGlobMappers = new ArrayList<HttpReverseProxyPathMapper>();
+ this.localBasePathGlobPatternMap = Collections.synchronizedMap(new HashMap<HttpReverseProxyPathMapper, Pattern>());
+ this.remoteBaseURLGlobPatternMap = Collections.synchronizedMap(new HashMap<HttpReverseProxyPathMapper, Pattern>());
+
for (HttpReverseProxyPathMapper proxyPathMapper : proxyPathMappers)
{
+ String localBasePath = proxyPathMapper.getLocalBasePath();
+ String remoteBaseURL = proxyPathMapper.getRemoteBaseURL();
+
if (!StringUtils.contains(proxyPathMapper.getLocalBasePath(), '*'))
{
- this.proxyPathMappers.add(proxyPathMapper);
+ staticProxyPathMappersMap.put(StringUtils.removeEnd(localBasePath, "/"), proxyPathMapper);
+ staticProxyPathMappersMap.put(StringUtils.removeEnd(remoteBaseURL, "/"), proxyPathMapper);
}
else
{
this.proxyPathGlobMappers.add(proxyPathMapper);
+
+ try
+ {
+ String expr = StringUtils.replaceEach(proxyPathMapper.getLocalBasePath(), GLOB_EXPR_SEARCHES, GLOB_EXPR_REPLACES);
+ localBasePathGlobPatternMap.put(proxyPathMapper, Pattern.compile(expr));
+ expr = StringUtils.replaceEach(proxyPathMapper.getRemoteBaseURL(), GLOB_EXPR_SEARCHES, GLOB_EXPR_REPLACES);
+ expr = StringUtils.replaceEach(expr, GROUP_REF_SEARCHES, GROUP_REF_REPLACES);
+ remoteBaseURLGlobPatternMap.put(proxyPathMapper, Pattern.compile(expr));
+ }
+ catch (Exception e)
+ {
+ if (log.isDebugEnabled())
+ {
+ log.error("Failed to create regular expression pattern for " + proxyPathMapper.getLocalBasePath(), e);
+ }
+ else
+ {
+ log.error("Failed to create regular expression pattern for {}. {}", proxyPathMapper.getLocalBasePath(), e);
+ }
+ }
}
}
-
- this.localBasePathGlobPatternMap = Collections.synchronizedMap(new HashMap<HttpReverseProxyPathMapper, Pattern>());
- this.remoteBaseURLGlobPatternMap = Collections.synchronizedMap(new HashMap<HttpReverseProxyPathMapper, Pattern>());
+ }
+
+ public void setMaxMatchingPathPartCount(int maxMatchingPathPartCount)
+ {
+ this.maxMatchingPathPartCount = maxMatchingPathPartCount;
+ }
+
+ public int getMaxMatchingPathPartCount()
+ {
+ return maxMatchingPathPartCount;
}
public HttpReverseProxyPathMapper findMapper(String pathInfo)
{
- int mapperCount = proxyPathMappers.size();
+ String [] pathParts = StringUtils.split(pathInfo, "/", maxMatchingPathPartCount + 1);
+ int pathPartCount = (pathParts != null ? pathParts.length : 0);
- for (int i = 0; i < mapperCount; i++)
+ if (pathPartCount == 0)
{
- HttpReverseProxyPathMapper proxyPathMapper = proxyPathMappers.get(i);
+ return null;
+ }
+
+ for (int i = Math.min(pathPartCount, maxMatchingPathPartCount); i > 0; i--)
+ {
+ String localBasePathKey = "/" + StringUtils.join(pathParts, "/", 0, i);
+ HttpReverseProxyPathMapper proxyPathMapper = staticProxyPathMappersMap.get(localBasePathKey);
- if (StringUtils.startsWith(pathInfo, proxyPathMapper.getLocalBasePath()))
+ if (proxyPathMapper == null)
+ {
+ proxyPathMapper = (HttpReverseProxyPathMapper) dynamicProxyPathMappersMap.get(localBasePathKey);
+ }
+
+ if (proxyPathMapper != null)
{
return proxyPathMapper;
}
@@ -122,74 +195,52 @@
if (pattern == null)
{
- try
+ continue;
+ }
+
+ Matcher matcher = pattern.matcher(pathInfo);
+
+ if (matcher.lookingAt())
+ {
+ int groupCount = matcher.groupCount();
+ String [] replaces = new String[groupCount];
+ String [] searches = new String[groupCount];
+
+ for (int i = 0; i < groupCount; i++)
{
- pattern = Pattern.compile(StringUtils.replaceEach(proxyPathMapper.getLocalBasePath(), GLOB_EXPR_SEARCHES, GLOB_EXPR_REPLACES));
+ replaces[i] = matcher.group(i + 1);
+ searches[i] = "$" + (i + 1);
}
- catch (Exception e)
+
+ //HttpReverseProxyPathMapper cloned = (HttpReverseProxyPathMapper) proxyPathMapper.clone();
+ String localBasePath = matcher.group(0);
+ String remoteBaseURL = StringUtils.replaceEach(proxyPathMapper.getRemoteBaseURL(), searches, replaces);
+ HttpReverseProxyPathMapper derivedMapper =
+ new DefaultHttpReverseProxyPathMapperImpl(proxyPathMapper.getName() + ":" + localBasePath,
+ localBasePath,
+ remoteBaseURL,
+ proxyPathMapper.getDefaultRequestHeaders());
+
+ RewriterController rewriterController = rewriterControllerMap.get(proxyPathMapper);
+ Ruleset rewriterRules = rewriterRulesetMap.get(proxyPathMapper);
+
+ if (rewriterController != null)
{
- if (log.isDebugEnabled())
- {
- log.error("Failed to create regular expression pattern. Blacklisted: " + proxyPathMapper.getLocalBasePath(), e);
- }
- else
- {
- log.error("Failed to create regular expression pattern. Blacklisted: {}. {}", proxyPathMapper.getLocalBasePath(), e);
- }
+ rewriterControllerMap.put(derivedMapper, rewriterController);
}
- if (pattern != null)
+ if (rewriterRules != null)
{
- localBasePathGlobPatternMap.put(proxyPathMapper, pattern);
+ rewriterRulesetMap.put(derivedMapper, rewriterRules);
}
- }
-
- if (pattern != null)
- {
- Matcher matcher = pattern.matcher(pathInfo);
- if (matcher.lookingAt())
+ synchronized (dynamicProxyPathMappersMap)
{
- int groupCount = matcher.groupCount();
- String [] replaces = new String[groupCount];
- String [] searches = new String[groupCount];
-
- for (int i = 0; i < groupCount; i++)
- {
- replaces[i] = matcher.group(i + 1);
- searches[i] = "$" + (i + 1);
- }
-
- //HttpReverseProxyPathMapper cloned = (HttpReverseProxyPathMapper) proxyPathMapper.clone();
- String localBasePath = matcher.group(0);
- HttpReverseProxyPathMapper derivedMapper =
- new DefaultHttpReverseProxyPathMapperImpl(proxyPathMapper.getName() + ":" + localBasePath,
- localBasePath,
- StringUtils.replaceEach(proxyPathMapper.getRemoteBaseURL(), searches, replaces));
-
- RewriterController rewriterController = rewriterControllerMap.get(proxyPathMapper);
- Ruleset rewriterRules = rewriterRulesetMap.get(proxyPathMapper);
-
- if (rewriterController != null)
- {
- rewriterControllerMap.put(derivedMapper, rewriterController);
- }
-
- if (rewriterRules != null)
- {
- rewriterRulesetMap.put(derivedMapper, rewriterRules);
- }
-
- synchronized (proxyPathMappers)
- {
- if (!proxyPathMappers.contains(derivedMapper))
- {
- proxyPathMappers.add(derivedMapper);
- }
- }
-
- return derivedMapper;
+ dynamicProxyPathMappersMap.put(StringUtils.removeEnd(localBasePath, "/"), derivedMapper);
+ dynamicProxyPathMappersMap.put(StringUtils.removeEnd(remoteBaseURL, "/"), derivedMapper);
}
+
+ return derivedMapper;
}
}
}
@@ -199,18 +250,27 @@
public HttpReverseProxyPathMapper findMapperByRemoteURL(String remoteURL)
{
- if (remoteURL == null)
+ String [] pathParts = StringUtils.split(remoteURL, "/", maxMatchingPathPartCount + 2);
+ int pathPartCount = (pathParts != null ? pathParts.length : 0);
+
+ if (pathPartCount < 2)
{
return null;
}
-
- int mapperCount = proxyPathMappers.size();
-
- for (int i = 0; i < mapperCount; i++)
+
+ String scheme = pathParts[0];
+
+ for (int i = Math.min(pathPartCount, maxMatchingPathPartCount + 1); i > 1; i--)
{
- HttpReverseProxyPathMapper proxyPathMapper = proxyPathMappers.get(i);
+ String remoteBaseURLKey = scheme + "//" + StringUtils.join(pathParts, "/", 1, i);
+ HttpReverseProxyPathMapper proxyPathMapper = (HttpReverseProxyPathMapper) staticProxyPathMappersMap.get(remoteBaseURLKey);
- if (StringUtils.startsWith(remoteURL, proxyPathMapper.getRemoteBaseURL()))
+ if (proxyPathMapper == null)
+ {
+ proxyPathMapper = (HttpReverseProxyPathMapper) dynamicProxyPathMappersMap.get(remoteBaseURLKey);
+ }
+
+ if (proxyPathMapper != null)
{
return proxyPathMapper;
}
@@ -224,83 +284,58 @@
if (pattern == null)
{
- try
+ continue;
+ }
+
+ Matcher matcher = pattern.matcher(remoteURL);
+
+ if (matcher.lookingAt())
+ {
+ int groupCount = matcher.groupCount();
+ String [] replaces = new String[groupCount];
+ String [] searches = new String[groupCount];
+
+ for (int i = 0; i < groupCount; i++)
+ {
+ replaces[i] = matcher.group(i + 1);
+ searches[i] = "$" + (i + 1);
+ }
+
+ String remoteBaseURL = matcher.group(0);
+ String localBasePath = proxyPathMapper.getLocalBasePath();
+
+ for (int i = 1; StringUtils.contains(localBasePath, '*'); i++)
{
- String expr = StringUtils.replaceEach(proxyPathMapper.getRemoteBaseURL(), GLOB_EXPR_SEARCHES, GLOB_EXPR_REPLACES);
- expr = StringUtils.replaceEach(expr, GROUP_REF_SEARCHES, GROUP_REF_REPLACES);
- pattern = Pattern.compile(expr);
+ localBasePath = StringUtils.replaceOnce(localBasePath, "*", "$" + i);
}
- catch (Exception e)
+
+ localBasePath = StringUtils.replaceEach(localBasePath, searches, replaces);
+ HttpReverseProxyPathMapper derivedMapper =
+ new DefaultHttpReverseProxyPathMapperImpl(proxyPathMapper.getName() + ":" + localBasePath,
+ localBasePath,
+ remoteBaseURL,
+ proxyPathMapper.getDefaultRequestHeaders());
+
+ RewriterController rewriterController = rewriterControllerMap.get(proxyPathMapper);
+ Ruleset rewriterRules = rewriterRulesetMap.get(proxyPathMapper);
+
+ if (rewriterController != null)
{
- if (log.isDebugEnabled())
- {
- log.error("Failed to create regular expression pattern: " + proxyPathMapper.getRemoteBaseURL(), e);
- }
- else
- {
- log.error("Failed to create regular expression pattern: {}. {}", proxyPathMapper.getRemoteBaseURL(), e);
- }
+ rewriterControllerMap.put(derivedMapper, rewriterController);
}
- if (pattern != null)
+ if (rewriterRules != null)
{
- remoteBaseURLGlobPatternMap.put(proxyPathMapper, pattern);
+ rewriterRulesetMap.put(derivedMapper, rewriterRules);
}
- }
-
- if (pattern != null)
- {
- Matcher matcher = pattern.matcher(remoteURL);
- if (matcher.lookingAt())
+ synchronized (dynamicProxyPathMappersMap)
{
- int groupCount = matcher.groupCount();
- String [] replaces = new String[groupCount];
- String [] searches = new String[groupCount];
-
- for (int i = 0; i < groupCount; i++)
- {
- replaces[i] = matcher.group(i + 1);
- searches[i] = "$" + (i + 1);
- }
-
- String remoteBaseURL = matcher.group(0);
- String localBasePath = proxyPathMapper.getLocalBasePath();
-
- for (int i = 1; StringUtils.contains(localBasePath, '*'); i++)
- {
- localBasePath = StringUtils.replaceOnce(localBasePath, "*", "$" + i);
- }
-
- localBasePath = StringUtils.replaceEach(localBasePath, searches, replaces);
- HttpReverseProxyPathMapper derivedMapper =
- new DefaultHttpReverseProxyPathMapperImpl(proxyPathMapper.getName() + ":" + localBasePath,
- localBasePath,
- remoteBaseURL);
-
- RewriterController rewriterController = rewriterControllerMap.get(proxyPathMapper);
- Ruleset rewriterRules = rewriterRulesetMap.get(proxyPathMapper);
-
- if (rewriterController != null)
- {
- rewriterControllerMap.put(derivedMapper, rewriterController);
- }
-
- if (rewriterRules != null)
- {
- rewriterRulesetMap.put(derivedMapper, rewriterRules);
- }
-
- synchronized (proxyPathMappers)
- {
- if (!proxyPathMappers.contains(derivedMapper))
- {
- proxyPathMappers.add(derivedMapper);
- }
- }
-
- return derivedMapper;
+ dynamicProxyPathMappersMap.put(StringUtils.removeEnd(localBasePath, "/"), derivedMapper);
+ dynamicProxyPathMappersMap.put(StringUtils.removeEnd(remoteBaseURL, "/"), derivedMapper);
}
+
+ return derivedMapper;
}
}
}
@@ -318,9 +353,4 @@
return rewriterRulesetMap.get(proxyPathMapper);
}
- public List<HttpReverseProxyPathMapper> getProxyPathMappers()
- {
- return Collections.unmodifiableList(proxyPathMappers);
- }
-
}
Modified: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/DefaultHttpReverseProxyServlet.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/DefaultHttpReverseProxyServlet.java?rev=821934&r1=821933&r2=821934&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/DefaultHttpReverseProxyServlet.java (original)
+++ portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/DefaultHttpReverseProxyServlet.java Mon Oct 5 17:50:07 2009
@@ -59,6 +59,8 @@
import org.apache.http.conn.routing.RouteInfo;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
+import org.apache.portals.applications.webcontent.proxy.HttpReverseProxyException;
+import org.apache.portals.applications.webcontent.proxy.HttpReverseProxyNotFoundException;
import org.apache.portals.applications.webcontent.proxy.HttpReverseProxyPathMapper;
import org.apache.portals.applications.webcontent.proxy.HttpReverseProxyPathMapperProvider;
import org.apache.portals.applications.webcontent.proxy.HttpReverseProxyService;
@@ -166,12 +168,26 @@
if (StringUtils.isBlank(localBasePath) || StringUtils.isBlank(remoteBaseURL))
{
log.error("Wrong configuration for pass mapping of " + pathName + ". local={}, remove={}.", localBasePath, remoteBaseURL);
+ continue;
}
try
{
+ Map<String, String> defaultRequestHeaders = null;
+ Configuration defaultRequestHeadersConf = pathPassConf.subset("request.header");
+ if (!defaultRequestHeadersConf.isEmpty())
+ {
+ defaultRequestHeaders = new HashMap<String, String>();
+
+ for (Iterator it = defaultRequestHeadersConf.getKeys(); it.hasNext(); )
+ {
+ String key = (String) it.next();
+ defaultRequestHeaders.put(key, defaultRequestHeadersConf.getString(key));
+ }
+ }
+
HttpReverseProxyPathMapper proxyPathMapper =
- new DefaultHttpReverseProxyPathMapperImpl(pathName, localBasePath, remoteBaseURL);
+ new DefaultHttpReverseProxyPathMapperImpl(pathName, localBasePath, remoteBaseURL, defaultRequestHeaders);
proxyPathMappers.add(proxyPathMapper);
Configuration rewritersConf = pathPassConf.subset("rewriter");
@@ -207,8 +223,30 @@
}
}
- HttpReverseProxyPathMapperProvider proxyPathMapperProvider =
- new DefaultHttpReverseProxyPathMapperProviderImpl(proxyPathMappers, rewriterControllerMap, rewriterRulesetMap);
+ int dynamicProxyPathMapperCacheCount = 1000;
+ try
+ {
+ dynamicProxyPathMapperCacheCount = passConf.getInt("dynamicProxyPathMapperCacheCount", dynamicProxyPathMapperCacheCount);
+ }
+ catch (Exception ignore)
+ {
+ }
+
+ int maxMatchingPathPartCount = 2;
+ try
+ {
+ maxMatchingPathPartCount = passConf.getInt("maxMatchingPathPartCount", maxMatchingPathPartCount);
+ }
+ catch (Exception ignore)
+ {
+ }
+
+ DefaultHttpReverseProxyPathMapperProviderImpl proxyPathMapperProvider =
+ new DefaultHttpReverseProxyPathMapperProviderImpl(proxyPathMappers, dynamicProxyPathMapperCacheCount,
+ rewriterControllerMap, rewriterRulesetMap);
+
+ proxyPathMapperProvider.setMaxMatchingPathPartCount(maxMatchingPathPartCount);
+
HttpReverseProxyService tempProxyService = new RewritableHttpReverseProxyServiceImpl(proxyPathMapperProvider);
Configuration serverConf = configuration.subset("proxy.server");
@@ -319,6 +357,14 @@
{
proxyService.invoke(request, response);
}
+ catch (HttpReverseProxyNotFoundException e)
+ {
+ response.sendError(404, e.getLocalizedMessage());
+ }
+ catch (HttpReverseProxyException e)
+ {
+ throw new ServletException(e);
+ }
finally
{
try
@@ -339,6 +385,9 @@
Class basicRewriterClass = null;
Class ruleBasedRewriterClass = null;
Map<String, Class> adaptorMimeTypeClassMap = new HashMap<String, Class>();
+ Map<String, Object> basicRewriterProps = null;
+ Map<String, Object> rulesetRewriterProps = null;
+ Map<String, Map<String, Object>> parserAdaptorMimeTypeMap = null;
try
{
@@ -349,22 +398,43 @@
ruleMappingsFilePath = getServletContext().getRealPath(ruleMappings);
}
- String basicRewriter = rewriterConf.getString("basic");
+ Configuration basicRewriterConf = rewriterConf.subset("basic");
+ String basicRewriter = basicRewriterConf.getString("");
if (!StringUtils.isBlank(basicRewriter))
{
basicRewriterClass = Thread.currentThread().getContextClassLoader().loadClass(basicRewriter);
+ Configuration propsConf = basicRewriterConf.subset("property");
+ if (!propsConf.isEmpty())
+ {
+ basicRewriterProps = new HashMap<String, Object>();
+ for (Iterator it = propsConf.getKeys(); it.hasNext(); )
+ {
+ String propName = (String) it.next();
+ basicRewriterProps.put(propName, propsConf.getString(propName));
+ }
+ }
}
- String ruleBasedRewriter = rewriterConf.getString("rulebased");
+ Configuration ruleBasedRewriterConf = rewriterConf.subset("rulebased");
+ String ruleBasedRewriter = ruleBasedRewriterConf.getString("");
if (!StringUtils.isBlank(ruleBasedRewriter))
{
ruleBasedRewriterClass = Thread.currentThread().getContextClassLoader().loadClass(ruleBasedRewriter);
+ Configuration propsConf = ruleBasedRewriterConf.subset("property");
+ if (!propsConf.isEmpty())
+ {
+ rulesetRewriterProps = new HashMap<String, Object>();
+ for (Iterator it = propsConf.getKeys(); it.hasNext(); )
+ {
+ String propName = (String) it.next();
+ rulesetRewriterProps.put(propName, propsConf.getString(propName));
+ }
+ }
}
Configuration parserAdaptorsConf = rewriterConf.subset("parserAdaptor");
-
String [] parserAdaptorNames = parserAdaptorsConf.getStringArray("");
if (!ArrayUtils.isEmpty(parserAdaptorNames))
@@ -378,14 +448,35 @@
if (!StringUtils.isBlank(parserAdaptor))
{
Class parserAdaptorClass = Thread.currentThread().getContextClassLoader().loadClass(parserAdaptor);
+ Configuration propsConf = parserAdaptorConf.subset("property");
+ if (!propsConf.isEmpty())
+ {
+ Map<String, Object> parserAdaptorProps = new HashMap<String, Object>();
+ for (Iterator it = propsConf.getKeys(); it.hasNext(); )
+ {
+ String propName = (String) it.next();
+ parserAdaptorProps.put(propName, propsConf.getString(propName));
+ }
+ if (parserAdaptorMimeTypeMap == null)
+ {
+ parserAdaptorMimeTypeMap = new HashMap<String, Map<String, Object>>();
+ }
+ parserAdaptorMimeTypeMap.put(mimeType, parserAdaptorProps);
+ }
adaptorMimeTypeClassMap.put(mimeType, parserAdaptorClass);
}
}
}
- return new MappingRewriterController(ruleMappingsFilePath,
- basicRewriterClass, ruleBasedRewriterClass,
- adaptorMimeTypeClassMap);
+ MappingRewriterController rewriterController = new MappingRewriterController(ruleMappingsFilePath,
+ basicRewriterClass, ruleBasedRewriterClass,
+ adaptorMimeTypeClassMap);
+
+ rewriterController.setBasicRewriterProps(basicRewriterProps);
+ rewriterController.setRulesetRewriterProps(basicRewriterProps);
+ rewriterController.setParserAdaptorMimeTypePropsMap(parserAdaptorMimeTypeMap);
+
+ return rewriterController;
}
catch (Exception e)
{
Copied: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/DefaultReverseProxyLinkRewritingParserAaptor.java (from r821705, portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/PassMappingLinkRewritingParserAaptor.java)
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/DefaultReverseProxyLinkRewritingParserAaptor.java?p2=portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/DefaultReverseProxyLinkRewritingParserAaptor.java&p1=portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/PassMappingLinkRewritingParserAaptor.java&r1=821705&r2=821934&rev=821934&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/PassMappingLinkRewritingParserAaptor.java (original)
+++ portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/DefaultReverseProxyLinkRewritingParserAaptor.java Mon Oct 5 17:50:07 2009
@@ -16,32 +16,16 @@
*/
package org.apache.portals.applications.webcontent.proxy.impl;
-import java.io.BufferedWriter;
-import java.io.PrintWriter;
-import java.io.Reader;
-import java.io.Writer;
-import java.util.ArrayList;
+import java.util.HashMap;
import java.util.HashSet;
-import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import org.apache.commons.collections.KeyValue;
-import org.apache.commons.collections.keyvalue.DefaultKeyValue;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.io.LineIterator;
import org.apache.commons.lang.StringUtils;
import org.apache.portals.applications.webcontent.proxy.HttpReverseProxyPathMapper;
-import org.apache.portals.applications.webcontent.proxy.HttpReverseProxyPathMapperProvider;
-import org.apache.portals.applications.webcontent.proxy.ReverseProxyRewritingContext;
-import org.apache.portals.applications.webcontent.proxy.ReverseProxyRewritingContextAware;
-import org.apache.portals.applications.webcontent.rewriter.ParserAdaptor;
-import org.apache.portals.applications.webcontent.rewriter.Rewriter;
-import org.apache.portals.applications.webcontent.rewriter.RewriterException;
import org.apache.portals.applications.webcontent.util.CharArraySegment;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* A simple reverse proxy link rewriting parser adaptor implementation.
@@ -51,39 +35,39 @@
*
* @version $Id$
*/
-public class PassMappingLinkRewritingParserAaptor implements ParserAdaptor, ReverseProxyRewritingContextAware
+public class DefaultReverseProxyLinkRewritingParserAaptor extends AbstractReverseProxyTextLinesParserAdaptor
{
protected static final Pattern LINK_ABS_PATH_PATTERN =
Pattern.compile("(\\s|^)(href|src|action)\\s*=\\s*(['\"])((\\/)[^'\"]*)['\"]", Pattern.CASE_INSENSITIVE);
protected static final Pattern LINK_HTTP_ABS_URL_PATTERN =
- Pattern.compile("(\\s|^)(href|src|action)\\s*=\\s*['\"](https?:\\/\\/[^\\/'\"]+)[^'\"]*['\"]", Pattern.CASE_INSENSITIVE);
+ Pattern.compile("(\\s|^)(href|src|action)\\s*=\\s*['\"](https?:\\/\\/[^'\"]+)['\"]", Pattern.CASE_INSENSITIVE);
protected static final Pattern HTTP_DOMAIN_ADDRESS_ONLY_PATTERN =
Pattern.compile("^https?:\\/\\/[^\\/]+$", Pattern.CASE_INSENSITIVE);
- private static Logger log = LoggerFactory.getLogger(PassMappingLinkRewritingParserAaptor.class);
-
protected boolean lookUpAllMappings;
- protected ReverseProxyRewritingContext reverseProxyRewritingContext;
+ protected String localPathMatchingReplaces;
protected String [] linkRemoteBaseURLSearches = { "/", "." };
protected String [] linkRemoteBaseURLReplaces = { "\\/", "\\." };
- private List<HttpReverseProxyPathMapper> proxyPathMappers;
- private List<KeyValue> remoteURLPatternReplacesPairs;
- private KeyValue myURLPatternReplacesPair;
+ private Pattern defaultRemoteURLPattern;
+ private String defaultRemoteURLReplaces;
private Set<String> blacklist;
- public PassMappingLinkRewritingParserAaptor()
+ private Map<HttpReverseProxyPathMapper, Pattern> remoteURLMatchingPatternMap;
+ private Map<HttpReverseProxyPathMapper, String> localPathMatchingReplacesMap;
+
+ public DefaultReverseProxyLinkRewritingParserAaptor()
{
this(true, null);
}
- public PassMappingLinkRewritingParserAaptor(boolean lookUpAllMappings, Set<String> blacklist)
+ public DefaultReverseProxyLinkRewritingParserAaptor(boolean lookUpAllMappings, Set<String> blacklist)
{
setLookUpAllMappings(lookUpAllMappings);
setBlacklist(blacklist);
@@ -99,151 +83,110 @@
this.blacklist = blacklist;
}
- public void setReverseProxyRewritingContext(ReverseProxyRewritingContext reverseProxyRewritingContext)
+ @Override
+ protected String rewriteLine(String line) throws Exception
{
- this.reverseProxyRewritingContext = reverseProxyRewritingContext;
- }
-
- public void rewrite(Rewriter rewriter, Reader reader, Writer writer) throws RewriterException
- {
- HttpReverseProxyPathMapperProvider proxyPathMapperProvider = reverseProxyRewritingContext.getHttpReverseProxyPathMapperProvider();
- String myLocalPathMatchingReplaces = createLocalPathMatchingReplaces(reverseProxyRewritingContext.getHttpReverseProxyPathMapper());
-
- if (lookUpAllMappings && blacklist == null)
+ if (defaultRemoteURLPattern == null)
{
- blacklist = new HashSet<String>();
+ defaultRemoteURLPattern = createRemoteURLMatchingPattern(getHttpReverseProxyPathMapper());
+ defaultRemoteURLReplaces = createLocalPathMatchingReplaces(getHttpReverseProxyPathMapper());
}
- PrintWriter out = new PrintWriter(new BufferedWriter(writer));
+ // first, replace slash leading relative paths by slash leading reverse proxying relative paths.
+ Matcher linkBasePathMatcher = LINK_ABS_PATH_PATTERN.matcher(line);
+ line = linkBasePathMatcher.replaceAll("$1$2=$3" + defaultRemoteURLReplaces + "$4$3");
- for (LineIterator lineIt = IOUtils.lineIterator(reader); lineIt.hasNext(); )
+ // if there's any https? absolute url link, try to find the proxy path mapper again...
+ if (lookUpAllMappings)
{
- String line = lineIt.nextLine();
- String tempLine = line;
+ CharSequence segment = new CharArraySegment(line);
- if (!StringUtils.isBlank(line))
+ for (Matcher absURLMatcher = LINK_HTTP_ABS_URL_PATTERN.matcher(segment); absURLMatcher.find(); )
{
- try
+ HttpReverseProxyPathMapper proxyMapper = null;
+ String absURL = absURLMatcher.group(3);
+ int maxMatchingPathPartCount = getMaxMatchingPathPartCount();
+ String [] pathParts = StringUtils.split(absURL, "/", maxMatchingPathPartCount + 2);
+ int pathPartCount = (pathParts != null ? pathParts.length : 0);
+
+ if (pathPartCount < 2)
{
- // first, replace slash leading relative paths by slash leading reverse proxying relative paths.
- Matcher linkBasePathMatcher = LINK_ABS_PATH_PATTERN.matcher(tempLine);
- tempLine = linkBasePathMatcher.replaceAll("$1$2=$3" + myLocalPathMatchingReplaces + "$4$3");
+ continue;
+ }
+
+ String scheme = pathParts[0];
+
+ for (int i = Math.min(pathPartCount, maxMatchingPathPartCount + 1); i > 1; i--)
+ {
+ String remoteBaseURLKey = scheme + "//" + StringUtils.join(pathParts, "/", 1, i);
+
+ if (blacklist != null && blacklist.contains(remoteBaseURLKey))
+ {
+ continue;
+ }
+
+ proxyMapper = getHttpReverseProxyPathMapperProvider().findMapperByRemoteURL(remoteBaseURLKey + "/");
- // second, replace absolute urls by slash leading relative paths.
- if (lookUpAllMappings)
+ if (proxyMapper == null)
{
- for (KeyValue pair : getRemoteURLPatternReplacesPairs())
+ if (blacklist == null)
{
- Matcher matcher = ((Pattern) pair.getKey()).matcher(tempLine);
- tempLine = replaceRemoteLinkValues(matcher, "$1$2=$3" + ((String) pair.getValue()) + "$6$3", tempLine);
+ blacklist = new HashSet<String>();
}
- // if there's any https? absolute url link, try to find the proxy path mapper again...
+ blacklist.add(remoteBaseURLKey);
+ }
+ else
+ {
+ if (remoteURLMatchingPatternMap == null)
+ {
+ remoteURLMatchingPatternMap = new HashMap<HttpReverseProxyPathMapper, Pattern>();
+ localPathMatchingReplacesMap = new HashMap<HttpReverseProxyPathMapper, String>();
+ }
- CharSequence segment = new CharArraySegment(tempLine);
+ Pattern pattern = remoteURLMatchingPatternMap.get(proxyMapper);
+ if (pattern == null)
+ {
+ pattern = createRemoteURLMatchingPattern(proxyMapper);
+ remoteURLMatchingPatternMap.put(proxyMapper, pattern);
+ }
- for (Matcher absURLMatcher = LINK_HTTP_ABS_URL_PATTERN.matcher(segment); absURLMatcher.find(); )
+ String localPathMatchingReplaces = localPathMatchingReplacesMap.get(proxyMapper);
+ if (localPathMatchingReplaces == null)
{
- String domainURL = absURLMatcher.group(3);
-
- if (blacklist.contains(domainURL))
- {
- continue;
- }
-
- HttpReverseProxyPathMapper proxyMapper = proxyPathMapperProvider.findMapperByRemoteURL(domainURL + "/");
-
- if (proxyMapper == null)
- {
- blacklist.add(domainURL);
- }
- else
- {
- if (!proxyPathMappers.contains(proxyMapper))
- {
- KeyValue pair = new DefaultKeyValue(createRemoteURLMatchingPattern(proxyMapper),
- createLocalPathMatchingReplaces(proxyMapper));
-
- Matcher matcher = ((Pattern) pair.getKey()).matcher(tempLine);
- tempLine = replaceRemoteLinkValues(matcher, "$1$2=$3" + ((String) pair.getValue()) + "$6$3", tempLine);
-
- remoteURLPatternReplacesPairs.add(pair);
- proxyPathMappers.add(proxyMapper);
- }
- }
-
- segment = segment.subSequence(absURLMatcher.end(), segment.length());
- absURLMatcher.reset(segment);
+ localPathMatchingReplaces = createLocalPathMatchingReplaces(proxyMapper);
+ localPathMatchingReplacesMap.put(proxyMapper, localPathMatchingReplaces);
}
+
+ Matcher matcher = pattern.matcher(line);
+ line = replaceRemoteLinkValues(matcher, "$1$2=$3" + localPathMatchingReplaces + "$6$3", line);
+
+ break;
}
- else
- {
- KeyValue pair = getMyURLPatternReplacesPair();
- Matcher matcher = ((Pattern) pair.getKey()).matcher(tempLine);
- tempLine = matcher.replaceAll("$1$2=$3" + ((String) pair.getValue()) + "$6$3");
- }
-
- line = tempLine;
- }
- catch (Exception e)
- {
- log.warn("Error during {}: {}", "replacement", e);
}
+
+ segment = segment.subSequence(absURLMatcher.end(), segment.length());
+ absURLMatcher.reset(segment);
}
-
- out.println(line);
+ }
+ else
+ {
+ Matcher matcher = defaultRemoteURLPattern.matcher(line);
+ line = matcher.replaceAll("$1$2=$3" + defaultRemoteURLReplaces + "$6$3");
}
- out.flush();
+ return line;
}
protected Pattern createRemoteURLMatchingPattern(HttpReverseProxyPathMapper proxyMapper)
{
- Pattern pattern = null;
- String remoteBaseURLPattern = null;
-
- log.info("remoteBaseURL: {}", proxyMapper.getRemoteBaseURL());
- log.info("replaced: {}", StringUtils.replaceEach(StringUtils.removeEnd(proxyMapper.getRemoteBaseURL(), "/"), linkRemoteBaseURLSearches, linkRemoteBaseURLReplaces));
-
- remoteBaseURLPattern = StringUtils.replaceEach(StringUtils.removeEnd(proxyMapper.getRemoteBaseURL(), "/"), linkRemoteBaseURLSearches, linkRemoteBaseURLReplaces);
- pattern = Pattern.compile("(\\s|^)(href|src|action)\\s*=\\s*(['\"])((" + remoteBaseURLPattern + ")([^'\"]*))['\"]", Pattern.CASE_INSENSITIVE);
-
- return pattern;
+ String remoteBaseURLPattern = StringUtils.replaceEach(StringUtils.removeEnd(proxyMapper.getRemoteBaseURL(), "/"), linkRemoteBaseURLSearches, linkRemoteBaseURLReplaces);
+ return Pattern.compile("(\\s|^)(href|src|action)\\s*=\\s*(['\"])((" + remoteBaseURLPattern + ")([^'\"]*))['\"]", Pattern.CASE_INSENSITIVE);
}
protected String createLocalPathMatchingReplaces(HttpReverseProxyPathMapper proxyMapper)
{
- return reverseProxyRewritingContext.getRewritingContextPath() + StringUtils.removeEnd(proxyMapper.getLocalBasePath(), "/");
- }
-
- protected List<KeyValue> getRemoteURLPatternReplacesPairs()
- {
- if (remoteURLPatternReplacesPairs == null)
- {
- HttpReverseProxyPathMapperProvider mapperProvider = reverseProxyRewritingContext.getHttpReverseProxyPathMapperProvider();
- proxyPathMappers = new ArrayList<HttpReverseProxyPathMapper>(mapperProvider.getProxyPathMappers());
- int proxyMappersCount = proxyPathMappers.size();
- remoteURLPatternReplacesPairs = new ArrayList<KeyValue>();
-
- for (HttpReverseProxyPathMapper proxyMapper : proxyPathMappers)
- {
- remoteURLPatternReplacesPairs.add(new DefaultKeyValue(createRemoteURLMatchingPattern(proxyMapper),
- createLocalPathMatchingReplaces(proxyMapper)));
- }
- }
-
- return remoteURLPatternReplacesPairs;
- }
-
- protected KeyValue getMyURLPatternReplacesPair()
- {
- if (myURLPatternReplacesPair == null)
- {
- HttpReverseProxyPathMapper proxyMapper = reverseProxyRewritingContext.getHttpReverseProxyPathMapper();
- myURLPatternReplacesPair = new DefaultKeyValue(createRemoteURLMatchingPattern(proxyMapper), createLocalPathMatchingReplaces(proxyMapper));
- }
-
- return myURLPatternReplacesPair;
+ return getRewritingContextPath() + StringUtils.removeEnd(proxyMapper.getLocalBasePath(), "/");
}
protected String replaceRemoteLinkValues(Matcher matcher, String replacement, String text)
@@ -282,9 +225,4 @@
return text;
}
- public void parse(Rewriter rewriter, Reader reader) throws RewriterException
- {
- throw new UnsupportedOperationException();
- }
-
}
Propchange: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/DefaultReverseProxyLinkRewritingParserAaptor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/DefaultReverseProxyLinkRewritingParserAaptor.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: portals/applications/webcontent/trunk/webcontent-jar/src/main/java/org/apache/portals/applications/webcontent/proxy/impl/DefaultReverseProxyLinkRewritingParserAaptor.java
------------------------------------------------------------------------------
svn:mime-type = text/plain