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 2014/08/25 01:01:07 UTC

svn commit: r1620228 - in /portals/applications/webcontent/trunk: portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/ reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/builder/ reverse-proxy/src...

Author: woonsan
Date: Sun Aug 24 23:01:07 2014
New Revision: 1620228

URL: http://svn.apache.org/r1620228
Log:
APA-60: Also supports Filter implementation as well as Servlet for reverse proxying.

Added:
    portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/builder/
    portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/builder/ProxyProcessingChainBuilder.java
    portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/builder/ProxyServices.java
    portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/filter/
    portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/filter/DefaultReverseProxyFilter.java
    portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/filter/SimpleReverseProxyFilter.java
    portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/util/ProxyCommandUtils.java
    portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/util/RequestUtils.java
    portals/applications/webcontent/trunk/reverse-proxy/src/test/webapp/WEB-INF/rproxy-mappings.yaml
      - copied unchanged from r1620173, portals/applications/webcontent/trunk/reverse-proxy/src/test/webapp/WEB-INF/ReverseProxyServlet-mappings.yaml
    portals/applications/webcontent/trunk/reverse-proxy/src/test/webapp/portals-includes-filter.jsp
    portals/applications/webcontent/trunk/reverse-proxy/src/test/webapp/portals-includes-servlet.jsp
      - copied, changed from r1620173, portals/applications/webcontent/trunk/reverse-proxy/src/test/webapp/portals-includes.jsp
Removed:
    portals/applications/webcontent/trunk/reverse-proxy/src/test/webapp/WEB-INF/ReverseProxyServlet-mappings.yaml
    portals/applications/webcontent/trunk/reverse-proxy/src/test/webapp/portals-includes.jsp
Modified:
    portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/SimpleReverseProxyPortlet.java
    portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/command/AddHeadersToResponseCommand.java
    portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/command/HandleRedirectionCommand.java
    portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/command/ResolveRemoteURICommand.java
    portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/command/SerializeHttpEntityContentCommand.java
    portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/ServletRequestContext.java
    portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/rewriter/DefaultReverseProxyTextLineContentRewriter.java
    portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/servlet/SimpleReverseProxyServlet.java
    portals/applications/webcontent/trunk/reverse-proxy/src/test/webapp/WEB-INF/web.xml
    portals/applications/webcontent/trunk/reverse-proxy/src/test/webapp/index.jsp

Modified: portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/SimpleReverseProxyPortlet.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/SimpleReverseProxyPortlet.java?rev=1620228&r1=1620227&r2=1620228&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/SimpleReverseProxyPortlet.java (original)
+++ portals/applications/webcontent/trunk/portlets/src/main/java/org/apache/portals/applications/webcontent2/portlet/proxy/SimpleReverseProxyPortlet.java Sun Aug 24 23:01:07 2014
@@ -16,45 +16,26 @@
  */
 package org.apache.portals.applications.webcontent2.portlet.proxy;
 
-import java.util.List;
-
 import javax.portlet.PortletConfig;
 import javax.portlet.PortletException;
 
 import org.apache.http.impl.client.HttpClientBuilder;
 import org.apache.http.impl.client.HttpClients;
 import org.apache.portals.applications.webcontent2.proxy.ProxyMappingRegistry;
-import org.apache.portals.applications.webcontent2.proxy.command.AddCookiesToResponseCommand;
-import org.apache.portals.applications.webcontent2.proxy.command.AddHeaderToHttpRequestCommand;
-import org.apache.portals.applications.webcontent2.proxy.command.AddHeadersToResponseCommand;
-import org.apache.portals.applications.webcontent2.proxy.command.CleanupCommand;
-import org.apache.portals.applications.webcontent2.proxy.command.ExecuteHttpClientCommand;
-import org.apache.portals.applications.webcontent2.proxy.command.HandleNotModifiedCommand;
-import org.apache.portals.applications.webcontent2.proxy.command.HandleRedirectionCommand;
-import org.apache.portals.applications.webcontent2.proxy.command.InitHttpClientCommand;
-import org.apache.portals.applications.webcontent2.proxy.command.InitHttpRequestCommand;
-import org.apache.portals.applications.webcontent2.proxy.command.InitializationCommand;
-import org.apache.portals.applications.webcontent2.proxy.command.ResolveContentRewriterCommand;
-import org.apache.portals.applications.webcontent2.proxy.command.ResolveLocalPathCommand;
-import org.apache.portals.applications.webcontent2.proxy.command.ResolveProxyMappingCommand;
-import org.apache.portals.applications.webcontent2.proxy.command.ResolveRemoteURICommand;
-import org.apache.portals.applications.webcontent2.proxy.command.SerializeHttpEntityContentCommand;
-import org.apache.portals.applications.webcontent2.proxy.impl.AbstractProxyCommand;
+import org.apache.portals.applications.webcontent2.proxy.builder.ProxyServices;
 import org.apache.portals.applications.webcontent2.proxy.impl.DefaultProxyMappingRegistry;
 import org.apache.portals.applications.webcontent2.proxy.impl.DefaultReverseProxyService;
-import org.apache.portals.applications.webcontent2.proxy.impl.DefaultURICleaner;
 import org.apache.portals.applications.webcontent2.proxy.impl.ProxyProcessingChain;
+import org.apache.portals.applications.webcontent2.proxy.util.ProxyCommandUtils;
 import org.apache.portals.applications.webcontent2.proxy.util.YamlConfigUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 public class SimpleReverseProxyPortlet extends DefaultReverseProxyPortlet
 {
 
-    private static Logger log = LoggerFactory.getLogger(SimpleReverseProxyPortlet.class);
-
     public static final String MAPPINGS_PARAM_NAME = "mappings";
 
+    private ProxyMappingRegistry proxyMappingRegistry;
+    private HttpClientBuilder httpClientBuilder;
     private ProxyProcessingChain proxyServiceCommand;
 
     public SimpleReverseProxyPortlet()
@@ -67,117 +48,48 @@ public class SimpleReverseProxyPortlet e
     {
         super.init(portletConfig);
 
-        proxyServiceCommand = createProxyServiceCommand();
-
-        List<AbstractProxyCommand> allProxyCommands = proxyServiceCommand.getAllProxyCommands();
-
-        for (AbstractProxyCommand proxyCommand : allProxyCommands)
-        {
-            proxyCommand.initialize();
-        }
+        proxyServiceCommand = ProxyServices.createDefault(getProxyMappingRegistry(), getHttpClientBuilder()).build();
+        ProxyCommandUtils.initializeAllCommands(proxyServiceCommand);
 
         DefaultReverseProxyService proxyService = new DefaultReverseProxyService(proxyServiceCommand);
         setProxyService(proxyService);
     }
 
-    protected ProxyProcessingChain createProxyServiceCommand()
+    public ProxyMappingRegistry getProxyMappingRegistry()
     {
-        ProxyProcessingChain proxyServiceChain = new ProxyProcessingChain();
-
-        proxyServiceChain.addCommand(createPreprocessingCommand());
-        proxyServiceChain.addCommand(createProcessingCommand());
-        proxyServiceChain.addCommand(createPostprocessingCommand());
-
-        return proxyServiceChain;
-    }
+        if (proxyMappingRegistry == null)
+        {
+            proxyMappingRegistry = new DefaultProxyMappingRegistry();
+            final String param = getPortletConfig().getInitParameter(MAPPINGS_PARAM_NAME);
+            proxyMappingRegistry.addAllProxyMappings(YamlConfigUtils.loadProxyMappings(param, getPortletContext()));
+        }
 
-    protected ProxyProcessingChain createPreprocessingCommand()
-    {
-        ProxyProcessingChain preprocessingChain = new ProxyProcessingChain();
-        InitializationCommand initializationCommand = new InitializationCommand();
-        preprocessingChain.addCommand(initializationCommand);
-        return preprocessingChain;
+        return proxyMappingRegistry;
     }
 
-    protected ProxyProcessingChain createProcessingCommand()
+    public void setProxyMappingRegistry(ProxyMappingRegistry proxyMappingRegistry)
     {
-        ProxyProcessingChain processingChain = new ProxyProcessingChain();
-
-        ResolveLocalPathCommand resolveLocalPathCommand = new ResolveLocalPathCommand();
-
-        ResolveProxyMappingCommand resolveProxyMappingCommand = new ResolveProxyMappingCommand(createProxyMappingRegistry());
-
-        ResolveRemoteURICommand resolveRemoteURICommand = new ResolveRemoteURICommand();
-        resolveRemoteURICommand.setUriCleaner(new DefaultURICleaner());
-
-        InitHttpClientCommand initHttpClientCommand = new InitHttpClientCommand();
-        initHttpClientCommand.setHttpClientBuilder(createHttpClientBuilder());
-
-        InitHttpRequestCommand initHttpRequestCommand = new InitHttpRequestCommand();
-        AddHeaderToHttpRequestCommand addHeaderToHttpRequestCommand = new AddHeaderToHttpRequestCommand();
-        ExecuteHttpClientCommand executeHttpClientCommand = new ExecuteHttpClientCommand();
-        ResolveContentRewriterCommand resolveContentRewriterCommand = new ResolveContentRewriterCommand();
-        AddHeadersToResponseCommand addHeadersToResponseCommand = new AddHeadersToResponseCommand();
-        AddCookiesToResponseCommand addCookiesToResponseCommand = new AddCookiesToResponseCommand();
-        HandleRedirectionCommand handleRedirectionCommand = new HandleRedirectionCommand();
-        HandleNotModifiedCommand handleNotModifiedCommand = new HandleNotModifiedCommand();
-        SerializeHttpEntityContentCommand serializeHttpEntityContentCommand = new SerializeHttpEntityContentCommand();
-
-        processingChain.addCommand(resolveLocalPathCommand);
-        processingChain.addCommand(resolveProxyMappingCommand);
-        processingChain.addCommand(resolveRemoteURICommand);
-        processingChain.addCommand(initHttpClientCommand);
-        processingChain.addCommand(initHttpRequestCommand);
-        processingChain.addCommand(addHeaderToHttpRequestCommand);
-        processingChain.addCommand(executeHttpClientCommand);
-        processingChain.addCommand(resolveContentRewriterCommand);
-        processingChain.addCommand(addHeadersToResponseCommand);
-        processingChain.addCommand(addCookiesToResponseCommand);
-        processingChain.addCommand(handleRedirectionCommand);
-        processingChain.addCommand(handleNotModifiedCommand);
-        processingChain.addCommand(serializeHttpEntityContentCommand);
-
-        return processingChain;
+        this.proxyMappingRegistry = proxyMappingRegistry;
     }
 
-    protected ProxyProcessingChain createPostprocessingCommand()
+    public HttpClientBuilder getHttpClientBuilder()
     {
-        ProxyProcessingChain postprocessingChain = new ProxyProcessingChain();
-        CleanupCommand cleanupCommand = new CleanupCommand();
-        postprocessingChain.addCommand(cleanupCommand);
-        return postprocessingChain;
-    }
+        if (httpClientBuilder == null)
+        {
+            httpClientBuilder = HttpClients.custom();
+        }
 
-    protected HttpClientBuilder createHttpClientBuilder()
-    {
-        return HttpClients.custom();
+        return httpClientBuilder;
     }
 
-    protected ProxyMappingRegistry createProxyMappingRegistry()
+    public void setHttpClientBuilder(HttpClientBuilder httpClientBuilder)
     {
-        ProxyMappingRegistry proxyMappingRegistry = new DefaultProxyMappingRegistry();
-        final String param = getPortletConfig().getInitParameter(MAPPINGS_PARAM_NAME);
-        proxyMappingRegistry.addAllProxyMappings(YamlConfigUtils.loadProxyMappings(param, getPortletContext()));
-        return proxyMappingRegistry;
+        this.httpClientBuilder = httpClientBuilder;
     }
 
     @Override
     public void destroy() {
-        List<AbstractProxyCommand> allProxyCommands = proxyServiceCommand.getAllProxyCommands();
-
-        for (AbstractProxyCommand proxyCommand : allProxyCommands)
-        {
-            try
-            {
-                proxyCommand.destroy();
-            }
-            catch (Exception e)
-            {
-                log.error("Failed to destroy proxy command, " + proxyCommand, e);
-            }
-        }
-
+        ProxyCommandUtils.destroyAllCommands(proxyServiceCommand);
         super.destroy();
     }
-
 }

Added: portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/builder/ProxyProcessingChainBuilder.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/builder/ProxyProcessingChainBuilder.java?rev=1620228&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/builder/ProxyProcessingChainBuilder.java (added)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/builder/ProxyProcessingChainBuilder.java Sun Aug 24 23:01:07 2014
@@ -0,0 +1,70 @@
+/*
+ * 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.webcontent2.proxy.builder;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.chain.Command;
+import org.apache.portals.applications.webcontent2.proxy.impl.ProxyProcessingChain;
+
+public class ProxyProcessingChainBuilder
+{
+
+    private ProxyProcessingChain chain;
+    private List<Command> commands;
+
+    protected ProxyProcessingChainBuilder()
+    {
+    }
+
+    public ProxyProcessingChain build()
+    {
+        if (chain == null)
+        {
+            chain = new ProxyProcessingChain();
+        }
+
+        if (commands != null)
+        {
+            for (Command command : commands)
+            {
+                chain.addCommand(command);
+            }
+        }
+
+        return chain;
+    }
+
+    public ProxyProcessingChain addProxyProcessingChain(ProxyProcessingChain subChain)
+    {
+        addCommand(subChain);
+        return subChain;
+    }
+
+    public Command addCommand(Command command)
+    {
+        if (commands == null)
+        {
+            commands = new ArrayList<Command>();
+        }
+
+        commands.add(command);
+
+        return command;
+    }
+}

Added: portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/builder/ProxyServices.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/builder/ProxyServices.java?rev=1620228&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/builder/ProxyServices.java (added)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/builder/ProxyServices.java Sun Aug 24 23:01:07 2014
@@ -0,0 +1,114 @@
+/*
+ * 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.webcontent2.proxy.builder;
+
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.portals.applications.webcontent2.proxy.ProxyMappingRegistry;
+import org.apache.portals.applications.webcontent2.proxy.command.AddCookiesToResponseCommand;
+import org.apache.portals.applications.webcontent2.proxy.command.AddHeaderToHttpRequestCommand;
+import org.apache.portals.applications.webcontent2.proxy.command.AddHeadersToResponseCommand;
+import org.apache.portals.applications.webcontent2.proxy.command.CleanupCommand;
+import org.apache.portals.applications.webcontent2.proxy.command.ExecuteHttpClientCommand;
+import org.apache.portals.applications.webcontent2.proxy.command.HandleNotModifiedCommand;
+import org.apache.portals.applications.webcontent2.proxy.command.HandleRedirectionCommand;
+import org.apache.portals.applications.webcontent2.proxy.command.InitHttpClientCommand;
+import org.apache.portals.applications.webcontent2.proxy.command.InitHttpRequestCommand;
+import org.apache.portals.applications.webcontent2.proxy.command.InitializationCommand;
+import org.apache.portals.applications.webcontent2.proxy.command.ResolveContentRewriterCommand;
+import org.apache.portals.applications.webcontent2.proxy.command.ResolveLocalPathCommand;
+import org.apache.portals.applications.webcontent2.proxy.command.ResolveProxyMappingCommand;
+import org.apache.portals.applications.webcontent2.proxy.command.ResolveRemoteURICommand;
+import org.apache.portals.applications.webcontent2.proxy.command.SerializeHttpEntityContentCommand;
+import org.apache.portals.applications.webcontent2.proxy.impl.DefaultURICleaner;
+import org.apache.portals.applications.webcontent2.proxy.impl.ProxyProcessingChain;
+
+public class ProxyServices
+{
+
+    private ProxyServices()
+    {
+    }
+
+    public static ProxyProcessingChainBuilder createDefault(ProxyMappingRegistry proxyMappingRegistry, HttpClientBuilder httpClientBuilder)
+    {
+        ProxyProcessingChainBuilder builder = new ProxyProcessingChainBuilder();
+
+        builder.addCommand(createDefaultPreprocessingCommand(proxyMappingRegistry, httpClientBuilder));
+        builder.addCommand(createDefaultProcessingCommand(proxyMappingRegistry, httpClientBuilder));
+        builder.addCommand(createDefaultPostprocessingCommand(proxyMappingRegistry, httpClientBuilder));
+
+        return builder;
+    }
+
+    private static ProxyProcessingChain createDefaultPreprocessingCommand(ProxyMappingRegistry proxyMappingRegistry, HttpClientBuilder httpClientBuilder)
+    {
+        ProxyProcessingChain preprocessingChain = new ProxyProcessingChain();
+        InitializationCommand initializationCommand = new InitializationCommand();
+        preprocessingChain.addCommand(initializationCommand);
+        return preprocessingChain;
+    }
+
+    private static ProxyProcessingChain createDefaultProcessingCommand(ProxyMappingRegistry proxyMappingRegistry, HttpClientBuilder httpClientBuilder)
+    {
+        ProxyProcessingChain processingChain = new ProxyProcessingChain();
+
+        ResolveLocalPathCommand resolveLocalPathCommand = new ResolveLocalPathCommand();
+
+        ResolveProxyMappingCommand resolveProxyMappingCommand = new ResolveProxyMappingCommand(proxyMappingRegistry);
+
+        ResolveRemoteURICommand resolveRemoteURICommand = new ResolveRemoteURICommand();
+        resolveRemoteURICommand.setUriCleaner(new DefaultURICleaner());
+
+        InitHttpClientCommand initHttpClientCommand = new InitHttpClientCommand();
+        initHttpClientCommand.setHttpClientBuilder(httpClientBuilder);
+
+        InitHttpRequestCommand initHttpRequestCommand = new InitHttpRequestCommand();
+        AddHeaderToHttpRequestCommand addHeaderToHttpRequestCommand = new AddHeaderToHttpRequestCommand();
+        ExecuteHttpClientCommand executeHttpClientCommand = new ExecuteHttpClientCommand();
+        ResolveContentRewriterCommand resolveContentRewriterCommand = new ResolveContentRewriterCommand();
+        AddHeadersToResponseCommand addHeadersToResponseCommand = new AddHeadersToResponseCommand();
+        AddCookiesToResponseCommand addCookiesToResponseCommand = new AddCookiesToResponseCommand();
+        HandleRedirectionCommand handleRedirectionCommand = new HandleRedirectionCommand();
+        HandleNotModifiedCommand handleNotModifiedCommand = new HandleNotModifiedCommand();
+        SerializeHttpEntityContentCommand serializeHttpEntityContentCommand = new SerializeHttpEntityContentCommand();
+
+        processingChain.addCommand(resolveLocalPathCommand);
+        processingChain.addCommand(resolveProxyMappingCommand);
+        processingChain.addCommand(resolveRemoteURICommand);
+        processingChain.addCommand(initHttpClientCommand);
+        processingChain.addCommand(initHttpRequestCommand);
+        processingChain.addCommand(addHeaderToHttpRequestCommand);
+        processingChain.addCommand(executeHttpClientCommand);
+        processingChain.addCommand(resolveContentRewriterCommand);
+        processingChain.addCommand(addHeadersToResponseCommand);
+        processingChain.addCommand(addCookiesToResponseCommand);
+        processingChain.addCommand(handleRedirectionCommand);
+        processingChain.addCommand(handleNotModifiedCommand);
+        processingChain.addCommand(serializeHttpEntityContentCommand);
+
+        return processingChain;
+    }
+
+    private static ProxyProcessingChain createDefaultPostprocessingCommand(ProxyMappingRegistry proxyMappingRegistry, HttpClientBuilder httpClientBuilder)
+    {
+        ProxyProcessingChain postprocessingChain = new ProxyProcessingChain();
+        CleanupCommand cleanupCommand = new CleanupCommand();
+        postprocessingChain.addCommand(cleanupCommand);
+        return postprocessingChain;
+    }
+
+}

Modified: portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/command/AddHeadersToResponseCommand.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/command/AddHeadersToResponseCommand.java?rev=1620228&r1=1620227&r2=1620228&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/command/AddHeadersToResponseCommand.java (original)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/command/AddHeadersToResponseCommand.java Sun Aug 24 23:01:07 2014
@@ -28,6 +28,7 @@ import org.apache.http.protocol.HTTP;
 import org.apache.portals.applications.webcontent2.proxy.ReverseProxyException;
 import org.apache.portals.applications.webcontent2.proxy.impl.AbstractProxyCommand;
 import org.apache.portals.applications.webcontent2.proxy.impl.ProxyContext;
+import org.apache.portals.applications.webcontent2.proxy.util.RequestUtils;
 
 
 public class AddHeadersToResponseCommand extends AbstractProxyCommand
@@ -70,7 +71,7 @@ public class AddHeadersToResponseCommand
 
                 if (StringUtils.equalsIgnoreCase(headerName, HTTP.CONTENT_LEN) || StringUtils.equalsIgnoreCase(headerName, HTTP.CONTENT_ENCODING))
                 {
-                    if (context.getContentRewriter() != null || isDispatched(context))
+                    if (context.getContentRewriter() != null || RequestUtils.isDispatched(context.getRequestContext()))
                     {
                         continue;
                     }
@@ -115,10 +116,4 @@ public class AddHeadersToResponseCommand
     {
         this.hostHeaderValue = hostHeaderValue;
     }
-
-    private boolean isDispatched(final ProxyContext context)
-    {
-        return context.getRequestContext().getAttribute("javax.servlet.include.servlet_path") != null;
-    }
-
 }

Modified: portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/command/HandleRedirectionCommand.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/command/HandleRedirectionCommand.java?rev=1620228&r1=1620227&r2=1620228&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/command/HandleRedirectionCommand.java (original)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/command/HandleRedirectionCommand.java Sun Aug 24 23:01:07 2014
@@ -79,7 +79,17 @@ public class HandleRedirectionCommand ex
             location = uriBuilder.toString();
         }
 
-        URI locationURI = URI.create(location);
+        URI locationURI = null;
+
+        try
+        {
+            locationURI = URI.create(location);
+        }
+        catch (Exception e)
+        {
+            log.error("Invalid redirect location: '{}'.", location);
+            return true;
+        }
 
         // Modify the redirect to go to this proxy servlet rather that the proxied host
         String localPath = context.getResolvedMapping().resolveLocalFromRemote(locationURI);

Modified: portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/command/ResolveRemoteURICommand.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/command/ResolveRemoteURICommand.java?rev=1620228&r1=1620227&r2=1620228&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/command/ResolveRemoteURICommand.java (original)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/command/ResolveRemoteURICommand.java Sun Aug 24 23:01:07 2014
@@ -25,11 +25,15 @@ import org.apache.portals.applications.w
 import org.apache.portals.applications.webcontent2.proxy.URICleaner;
 import org.apache.portals.applications.webcontent2.proxy.impl.AbstractProxyCommand;
 import org.apache.portals.applications.webcontent2.proxy.impl.ProxyContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 public class ResolveRemoteURICommand extends AbstractProxyCommand
 {
 
+    private static Logger log = LoggerFactory.getLogger(ResolveRemoteURICommand.class);
+
     private URICleaner uriCleaner;
 
     @Override
@@ -57,7 +61,19 @@ public class ResolveRemoteURICommand ext
             remoteURI = uriCleaner.clean(remoteURI);
         }
 
-        context.setRemoteURI(URI.create(remoteURI));
+        URI remoteURIObj = null;
+
+        try
+        {
+            remoteURIObj = URI.create(remoteURI);
+        }
+        catch (Exception e)
+        {
+            log.error("Invalid remote target URI: '{}'.", remoteURI);
+            return true;
+        }
+
+        context.setRemoteURI(remoteURIObj);
 
         return false;
     }

Modified: portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/command/SerializeHttpEntityContentCommand.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/command/SerializeHttpEntityContentCommand.java?rev=1620228&r1=1620227&r2=1620228&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/command/SerializeHttpEntityContentCommand.java (original)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/command/SerializeHttpEntityContentCommand.java Sun Aug 24 23:01:07 2014
@@ -38,6 +38,7 @@ import org.apache.portals.applications.w
 import org.apache.portals.applications.webcontent2.proxy.impl.GzippedSource;
 import org.apache.portals.applications.webcontent2.proxy.impl.HttpEntitySource;
 import org.apache.portals.applications.webcontent2.proxy.impl.ProxyContext;
+import org.apache.portals.applications.webcontent2.proxy.util.RequestUtils;
 import org.apache.portals.applications.webcontent2.rewriter.ContentRewriter;
 import org.apache.portals.applications.webcontent2.rewriter.ContentRewritingContext;
 import org.apache.portals.applications.webcontent2.rewriter.Sink;
@@ -58,7 +59,7 @@ public class SerializeHttpEntityContentC
 
         if (httpEntity != null)
         {
-            if (isDispatched(context))
+            if (RequestUtils.isDispatched(context.getRequestContext()))
             {
                 writeHttpEntityToDispatcher(context, httpEntity);
             }
@@ -236,11 +237,6 @@ public class SerializeHttpEntityContentC
         return contentRewritingContext;
     }
 
-    private boolean isDispatched(final ProxyContext context)
-    {
-        return context.getRequestContext().getAttribute("javax.servlet.include.servlet_path") != null;
-    }
-
     private boolean isGzipEncodedContent(final HttpEntity httpEntity) 
     {
         boolean gzipEncoded = false;

Added: portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/filter/DefaultReverseProxyFilter.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/filter/DefaultReverseProxyFilter.java?rev=1620228&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/filter/DefaultReverseProxyFilter.java (added)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/filter/DefaultReverseProxyFilter.java Sun Aug 24 23:01:07 2014
@@ -0,0 +1,180 @@
+/*
+ * 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.webcontent2.proxy.filter;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+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;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpHead;
+import org.apache.http.client.methods.HttpOptions;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.client.methods.HttpTrace;
+import org.apache.portals.applications.webcontent2.proxy.ReverseProxyException;
+import org.apache.portals.applications.webcontent2.proxy.ReverseProxyService;
+import org.apache.portals.applications.webcontent2.proxy.impl.ProxyContext;
+import org.apache.portals.applications.webcontent2.proxy.impl.ServletRequestContext;
+import org.apache.portals.applications.webcontent2.proxy.util.RequestUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DefaultReverseProxyFilter implements Filter
+{
+
+    private static final Set<String> AVAILABLE_HTTP_METHOD_SET = 
+                    new HashSet<String>(Arrays.asList(HttpGet.METHOD_NAME, 
+                                                      HttpHead.METHOD_NAME, 
+                                                      HttpPost.METHOD_NAME, 
+                                                      HttpPut.METHOD_NAME, 
+                                                      HttpDelete.METHOD_NAME,
+                                                      HttpOptions.METHOD_NAME,
+                                                      HttpTrace.METHOD_NAME));
+
+    private static Logger log = LoggerFactory.getLogger(DefaultReverseProxyFilter.class);
+
+    private FilterConfig filterConfig;
+
+    private ReverseProxyService proxyService;
+
+    private String filterPath;
+
+    public DefaultReverseProxyFilter()
+    {
+    }
+
+    public ReverseProxyService getProxyService()
+    {
+        return proxyService;
+    }
+
+    public void setProxyService(ReverseProxyService proxyService)
+    {
+        this.proxyService = proxyService;
+    }
+
+    public void init(FilterConfig filterConfig) throws ServletException
+    {
+        this.filterConfig = filterConfig;
+
+        filterPath = StringUtils.trim(filterConfig.getInitParameter("filterPath"));
+    }
+
+    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException
+    {
+        if (!(req instanceof HttpServletRequest) || !(res instanceof HttpServletResponse))
+        {
+            chain.doFilter(req, res);
+            return;
+        }
+
+        HttpServletRequest request = (HttpServletRequest) req;
+        HttpServletResponse response = (HttpServletResponse) res;
+
+        if (!AVAILABLE_HTTP_METHOD_SET.contains(request.getMethod()))
+        {
+            chain.doFilter(request, response);
+        }
+        else
+        {
+            try
+            {
+                ServletRequestContext requestContext = new ServletRequestContext(request, response);
+
+                String requestBasePath = getRequestBasePath(request);
+
+                if (requestBasePath == null)
+                {
+                    requestBasePath = request.getContextPath();
+                }
+
+                requestContext.setRequestBasePath(requestBasePath);
+
+                ProxyContext proxyContext = new ProxyContext(requestContext);
+                proxyService.invoke(proxyContext);
+            }
+            catch (ReverseProxyException e)
+            {
+                if (e.getStatusCode() > 0)
+                {
+                    if (log.isDebugEnabled())
+                    {
+                        log.error("Response proxy processing exception occurred.", e);
+                    }
+                    else
+                    {
+                        log.error("Response proxy processing exception occurred. " + e);
+                    }
+
+                    response.sendError(e.getStatusCode(), e.getLocalizedMessage());
+                }
+                else
+                {
+                    throw new ServletException(e);
+                }
+            }
+            catch (IOException e)
+            {
+                throw e;
+            }
+            catch (Exception e)
+            {
+                throw new ServletException(e);
+            }
+        }
+    }
+
+    public void destroy()
+    {
+    }
+
+    protected FilterConfig getFilterConfig()
+    {
+        return filterConfig;
+    }
+
+    protected String getFilterPath()
+    {
+        return filterPath;
+    }
+
+    protected String getRequestBasePath(HttpServletRequest request)
+    {
+        StringBuilder sb = new StringBuilder();
+        sb.append(RequestUtils.getContextPath(request));
+
+        if (filterPath != null)
+        {
+            sb.append(filterPath);
+        }
+
+        return sb.toString();
+    }
+}

Added: portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/filter/SimpleReverseProxyFilter.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/filter/SimpleReverseProxyFilter.java?rev=1620228&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/filter/SimpleReverseProxyFilter.java (added)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/filter/SimpleReverseProxyFilter.java Sun Aug 24 23:01:07 2014
@@ -0,0 +1,97 @@
+/*
+ * 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.webcontent2.proxy.filter;
+
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.portals.applications.webcontent2.proxy.ProxyMappingRegistry;
+import org.apache.portals.applications.webcontent2.proxy.builder.ProxyServices;
+import org.apache.portals.applications.webcontent2.proxy.impl.DefaultProxyMappingRegistry;
+import org.apache.portals.applications.webcontent2.proxy.impl.DefaultReverseProxyService;
+import org.apache.portals.applications.webcontent2.proxy.impl.ProxyProcessingChain;
+import org.apache.portals.applications.webcontent2.proxy.util.ProxyCommandUtils;
+import org.apache.portals.applications.webcontent2.proxy.util.YamlConfigUtils;
+
+public class SimpleReverseProxyFilter extends DefaultReverseProxyFilter
+{
+
+    public static final String MAPPINGS_PARAM_NAME = "mappings";
+
+    private ProxyMappingRegistry proxyMappingRegistry;
+    private HttpClientBuilder httpClientBuilder;
+    private ProxyProcessingChain proxyServiceCommand;
+
+    public SimpleReverseProxyFilter()
+    {
+        super();
+    }
+
+    @Override
+    public void init(FilterConfig filterConfig) throws ServletException
+    {
+        super.init(filterConfig);
+
+        proxyServiceCommand = ProxyServices.createDefault(getProxyMappingRegistry(), getHttpClientBuilder()).build();
+        ProxyCommandUtils.initializeAllCommands(proxyServiceCommand);
+
+        DefaultReverseProxyService proxyService = new DefaultReverseProxyService(proxyServiceCommand);
+        setProxyService(proxyService);
+    }
+
+    public ProxyMappingRegistry getProxyMappingRegistry()
+    {
+        if (proxyMappingRegistry == null)
+        {
+            proxyMappingRegistry = new DefaultProxyMappingRegistry();
+            final String param = getFilterConfig().getInitParameter(MAPPINGS_PARAM_NAME);
+            proxyMappingRegistry.addAllProxyMappings(YamlConfigUtils.loadProxyMappings(param, getFilterConfig().getServletContext()));
+            return proxyMappingRegistry;
+        }
+
+        return proxyMappingRegistry;
+    }
+
+    public void setProxyMappingRegistry(ProxyMappingRegistry proxyMappingRegistry)
+    {
+        this.proxyMappingRegistry = proxyMappingRegistry;
+    }
+
+    public HttpClientBuilder getHttpClientBuilder()
+    {
+        if (httpClientBuilder == null)
+        {
+            return HttpClients.custom().disableRedirectHandling();
+        }
+
+        return httpClientBuilder;
+    }
+
+    public void setHttpClientBuilder(HttpClientBuilder httpClientBuilder)
+    {
+        this.httpClientBuilder = httpClientBuilder;
+    }
+
+    @Override
+    public void destroy()
+    {
+        ProxyCommandUtils.destroyAllCommands(proxyServiceCommand);
+        super.destroy();
+    }
+}

Modified: portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/ServletRequestContext.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/ServletRequestContext.java?rev=1620228&r1=1620227&r2=1620228&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/ServletRequestContext.java (original)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/impl/ServletRequestContext.java Sun Aug 24 23:01:07 2014
@@ -25,6 +25,7 @@ import javax.servlet.http.HttpServletReq
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.portals.applications.webcontent2.proxy.RequestContext;
+import org.apache.portals.applications.webcontent2.proxy.util.RequestUtils;
 import org.apache.portals.applications.webcontent2.rewriter.Sink;
 
 public class ServletRequestContext implements RequestContext
@@ -69,22 +70,9 @@ public class ServletRequestContext imple
         }
 
         StringBuilder sb = new StringBuilder(20);
+        sb.append(RequestUtils.getContextPath(request));
 
-        String contextPath = (String) request.getAttribute("javax.servlet.include.context_path");
-
-        if (contextPath == null)
-        {
-            contextPath = request.getContextPath();
-        }
-
-        sb.append(contextPath);
-
-        String servletPath = (String) request.getAttribute("javax.servlet.include.servlet_path");
-
-        if (servletPath == null)
-        {
-            servletPath = request.getServletPath();
-        }
+        String servletPath = RequestUtils.getServletPath(request);
 
         if (servletPath != null)
         {
@@ -103,7 +91,7 @@ public class ServletRequestContext imple
     {
         if (requestBasePath != null)
         {
-            String requestURI = request.getRequestURI();
+            String requestURI = RequestUtils.getRequestURI(request);
 
             if (requestURI.startsWith(requestBasePath))
             {
@@ -111,14 +99,7 @@ public class ServletRequestContext imple
             }
         }
 
-        String pathInfo = (String) request.getAttribute("javax.servlet.include.path_info");
-
-        if (pathInfo != null)
-        {
-            return pathInfo;
-        }
-
-        return request.getPathInfo();
+        return RequestUtils.getPathInfo(request);
     }
 
     public Object getAttribute(final String name)

Modified: portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/rewriter/DefaultReverseProxyTextLineContentRewriter.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/rewriter/DefaultReverseProxyTextLineContentRewriter.java?rev=1620228&r1=1620227&r2=1620228&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/rewriter/DefaultReverseProxyTextLineContentRewriter.java (original)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/rewriter/DefaultReverseProxyTextLineContentRewriter.java Sun Aug 24 23:01:07 2014
@@ -99,7 +99,22 @@ public class DefaultReverseProxyTextLine
             return uri;
         }
 
-        URI uriObj = URI.create(uri);
+        if (!isRewritableURI(uri))
+        {
+            return uri;
+        }
+
+        URI uriObj = null;
+
+        try
+        {
+            uriObj = URI.create(uri);
+        }
+        catch (Exception e)
+        {
+            log.warn("Invalid uri: '{}'.", uri);
+            return uri;
+        }
 
         String scheme = uriObj.getScheme();
 
@@ -107,7 +122,7 @@ public class DefaultReverseProxyTextLine
         {
             if (!StringUtils.equalsIgnoreCase(scheme, "http") && !StringUtils.equalsIgnoreCase(scheme, "https"))
             {
-                // no http(s) url is not rewritten. e.g. data: or mail
+                // non http(s) urls are not supported.
                 return uri;
             }
         }
@@ -156,4 +171,17 @@ public class DefaultReverseProxyTextLine
 
         return uri;
     }
+
+    protected boolean isRewritableURI(String uri)
+    {
+        // mailto: URIs often contain invalid characters in web pages to avoid spams
+        // and data: URIs do not need to be parsed at all.
+        // These should be avoided in URI rewriting.
+        if (StringUtils.startsWith(uri, "mailto:") || StringUtils.startsWith(uri, "data:"))
+        {
+            return false;
+        }
+
+        return true;
+    }
 }

Modified: portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/servlet/SimpleReverseProxyServlet.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/servlet/SimpleReverseProxyServlet.java?rev=1620228&r1=1620227&r2=1620228&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/servlet/SimpleReverseProxyServlet.java (original)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/servlet/SimpleReverseProxyServlet.java Sun Aug 24 23:01:07 2014
@@ -16,37 +16,18 @@
  */
 package org.apache.portals.applications.webcontent2.proxy.servlet;
 
-import java.util.List;
-
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletException;
 
 import org.apache.http.impl.client.HttpClientBuilder;
 import org.apache.http.impl.client.HttpClients;
 import org.apache.portals.applications.webcontent2.proxy.ProxyMappingRegistry;
-import org.apache.portals.applications.webcontent2.proxy.command.AddCookiesToResponseCommand;
-import org.apache.portals.applications.webcontent2.proxy.command.AddHeaderToHttpRequestCommand;
-import org.apache.portals.applications.webcontent2.proxy.command.AddHeadersToResponseCommand;
-import org.apache.portals.applications.webcontent2.proxy.command.CleanupCommand;
-import org.apache.portals.applications.webcontent2.proxy.command.ExecuteHttpClientCommand;
-import org.apache.portals.applications.webcontent2.proxy.command.HandleNotModifiedCommand;
-import org.apache.portals.applications.webcontent2.proxy.command.HandleRedirectionCommand;
-import org.apache.portals.applications.webcontent2.proxy.command.InitHttpClientCommand;
-import org.apache.portals.applications.webcontent2.proxy.command.InitHttpRequestCommand;
-import org.apache.portals.applications.webcontent2.proxy.command.InitializationCommand;
-import org.apache.portals.applications.webcontent2.proxy.command.ResolveContentRewriterCommand;
-import org.apache.portals.applications.webcontent2.proxy.command.ResolveLocalPathCommand;
-import org.apache.portals.applications.webcontent2.proxy.command.ResolveProxyMappingCommand;
-import org.apache.portals.applications.webcontent2.proxy.command.ResolveRemoteURICommand;
-import org.apache.portals.applications.webcontent2.proxy.command.SerializeHttpEntityContentCommand;
-import org.apache.portals.applications.webcontent2.proxy.impl.AbstractProxyCommand;
+import org.apache.portals.applications.webcontent2.proxy.builder.ProxyServices;
 import org.apache.portals.applications.webcontent2.proxy.impl.DefaultProxyMappingRegistry;
 import org.apache.portals.applications.webcontent2.proxy.impl.DefaultReverseProxyService;
-import org.apache.portals.applications.webcontent2.proxy.impl.DefaultURICleaner;
 import org.apache.portals.applications.webcontent2.proxy.impl.ProxyProcessingChain;
+import org.apache.portals.applications.webcontent2.proxy.util.ProxyCommandUtils;
 import org.apache.portals.applications.webcontent2.proxy.util.YamlConfigUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * Simple reverse proxy servlet implementation as an example.
@@ -56,10 +37,10 @@ public class SimpleReverseProxyServlet e
 
     private static final long serialVersionUID = 1L;
 
-    private static Logger log = LoggerFactory.getLogger(SimpleReverseProxyServlet.class);
-
     public static final String MAPPINGS_PARAM_NAME = "mappings";
 
+    private ProxyMappingRegistry proxyMappingRegistry;
+    private HttpClientBuilder httpClientBuilder;
     private ProxyProcessingChain proxyServiceCommand;
 
     public SimpleReverseProxyServlet()
@@ -72,116 +53,50 @@ public class SimpleReverseProxyServlet e
     {
         super.init(servletConfig);
 
-        proxyServiceCommand = createProxyServiceCommand();
-
-        List<AbstractProxyCommand> allProxyCommands = proxyServiceCommand.getAllProxyCommands();
-
-        for (AbstractProxyCommand proxyCommand : allProxyCommands)
-        {
-            proxyCommand.initialize();
-        }
+        proxyServiceCommand = ProxyServices.createDefault(getProxyMappingRegistry(), getHttpClientBuilder()).build();
+        ProxyCommandUtils.initializeAllCommands(proxyServiceCommand);
 
         DefaultReverseProxyService proxyService = new DefaultReverseProxyService(proxyServiceCommand);
         setProxyService(proxyService);
     }
 
-    protected ProxyProcessingChain createProxyServiceCommand()
+    public ProxyMappingRegistry getProxyMappingRegistry()
     {
-        ProxyProcessingChain proxyServiceChain = new ProxyProcessingChain();
-
-        proxyServiceChain.addCommand(createPreprocessingCommand());
-        proxyServiceChain.addCommand(createProcessingCommand());
-        proxyServiceChain.addCommand(createPostprocessingCommand());
+        if (proxyMappingRegistry == null)
+        {
+            proxyMappingRegistry = new DefaultProxyMappingRegistry();
+            final String param = getServletConfig().getInitParameter(MAPPINGS_PARAM_NAME);
+            proxyMappingRegistry.addAllProxyMappings(YamlConfigUtils.loadProxyMappings(param, getServletContext()));
+            return proxyMappingRegistry;
+        }
 
-        return proxyServiceChain;
+        return proxyMappingRegistry;
     }
 
-    protected ProxyProcessingChain createPreprocessingCommand()
+    public void setProxyMappingRegistry(ProxyMappingRegistry proxyMappingRegistry)
     {
-        ProxyProcessingChain preprocessingChain = new ProxyProcessingChain();
-        InitializationCommand initializationCommand = new InitializationCommand();
-        preprocessingChain.addCommand(initializationCommand);
-        return preprocessingChain;
+        this.proxyMappingRegistry = proxyMappingRegistry;
     }
 
-    protected ProxyProcessingChain createProcessingCommand()
+    public HttpClientBuilder getHttpClientBuilder()
     {
-        ProxyProcessingChain processingChain = new ProxyProcessingChain();
-
-        ResolveLocalPathCommand resolveLocalPathCommand = new ResolveLocalPathCommand();
-
-        ResolveProxyMappingCommand resolveProxyMappingCommand = new ResolveProxyMappingCommand(createProxyMappingRegistry());
-
-        ResolveRemoteURICommand resolveRemoteURICommand = new ResolveRemoteURICommand();
-        resolveRemoteURICommand.setUriCleaner(new DefaultURICleaner());
-
-        InitHttpClientCommand initHttpClientCommand = new InitHttpClientCommand();
-        initHttpClientCommand.setHttpClientBuilder(createHttpClientBuilder());
-
-        InitHttpRequestCommand initHttpRequestCommand = new InitHttpRequestCommand();
-        AddHeaderToHttpRequestCommand addHeaderToHttpRequestCommand = new AddHeaderToHttpRequestCommand();
-        ExecuteHttpClientCommand executeHttpClientCommand = new ExecuteHttpClientCommand();
-        ResolveContentRewriterCommand resolveContentRewriterCommand = new ResolveContentRewriterCommand();
-        AddHeadersToResponseCommand addHeadersToResponseCommand = new AddHeadersToResponseCommand();
-        AddCookiesToResponseCommand addCookiesToResponseCommand = new AddCookiesToResponseCommand();
-        HandleRedirectionCommand handleRedirectionCommand = new HandleRedirectionCommand();
-        HandleNotModifiedCommand handleNotModifiedCommand = new HandleNotModifiedCommand();
-        SerializeHttpEntityContentCommand serializeHttpEntityContentCommand = new SerializeHttpEntityContentCommand();
-
-        processingChain.addCommand(resolveLocalPathCommand);
-        processingChain.addCommand(resolveProxyMappingCommand);
-        processingChain.addCommand(resolveRemoteURICommand);
-        processingChain.addCommand(initHttpClientCommand);
-        processingChain.addCommand(initHttpRequestCommand);
-        processingChain.addCommand(addHeaderToHttpRequestCommand);
-        processingChain.addCommand(executeHttpClientCommand);
-        processingChain.addCommand(resolveContentRewriterCommand);
-        processingChain.addCommand(addHeadersToResponseCommand);
-        processingChain.addCommand(addCookiesToResponseCommand);
-        processingChain.addCommand(handleRedirectionCommand);
-        processingChain.addCommand(handleNotModifiedCommand);
-        processingChain.addCommand(serializeHttpEntityContentCommand);
-
-        return processingChain;
-    }
-
-    protected ProxyProcessingChain createPostprocessingCommand()
-    {
-        ProxyProcessingChain postprocessingChain = new ProxyProcessingChain();
-        CleanupCommand cleanupCommand = new CleanupCommand();
-        postprocessingChain.addCommand(cleanupCommand);
-        return postprocessingChain;
-    }
+        if (httpClientBuilder == null)
+        {
+            return HttpClients.custom().disableRedirectHandling();
+        }
 
-    protected HttpClientBuilder createHttpClientBuilder()
-    {
-        return HttpClients.custom().disableRedirectHandling();
+        return httpClientBuilder;
     }
 
-    protected ProxyMappingRegistry createProxyMappingRegistry()
+    public void setHttpClientBuilder(HttpClientBuilder httpClientBuilder)
     {
-        ProxyMappingRegistry proxyMappingRegistry = new DefaultProxyMappingRegistry();
-        final String param = getServletConfig().getInitParameter(MAPPINGS_PARAM_NAME);
-        proxyMappingRegistry.addAllProxyMappings(YamlConfigUtils.loadProxyMappings(param, getServletContext()));
-        return proxyMappingRegistry;
+        this.httpClientBuilder = httpClientBuilder;
     }
 
     @Override
     public void destroy()
     {
-        List<AbstractProxyCommand> allProxyCommands = proxyServiceCommand.getAllProxyCommands();
-
-        for (AbstractProxyCommand proxyCommand : allProxyCommands)
-        {
-            try
-            {
-                proxyCommand.destroy();
-            }
-            catch (Exception e)
-            {
-                log.error("Failed to destroy proxy command, " + proxyCommand, e);
-            }
-        }
+        ProxyCommandUtils.destroyAllCommands(proxyServiceCommand);
+        super.destroy();
     }
-
 }

Added: portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/util/ProxyCommandUtils.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/util/ProxyCommandUtils.java?rev=1620228&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/util/ProxyCommandUtils.java (added)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/util/ProxyCommandUtils.java Sun Aug 24 23:01:07 2014
@@ -0,0 +1,71 @@
+/*
+ * 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.webcontent2.proxy.util;
+
+import java.util.List;
+
+import org.apache.portals.applications.webcontent2.proxy.impl.AbstractProxyCommand;
+import org.apache.portals.applications.webcontent2.proxy.impl.ProxyProcessingChain;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ProxyCommandUtils
+{
+
+    private static Logger log = LoggerFactory.getLogger(ProxyCommandUtils.class);
+
+    private ProxyCommandUtils()
+    {
+    }
+
+    public static void initializeAllCommands(ProxyProcessingChain chain)
+    {
+        if (chain == null)
+        {
+            return;
+        }
+
+        List<AbstractProxyCommand> allProxyCommands = chain.getAllProxyCommands();
+
+        for (AbstractProxyCommand proxyCommand : allProxyCommands)
+        {
+            proxyCommand.initialize();
+        }
+    }
+
+    public static void destroyAllCommands(ProxyProcessingChain chain)
+    {
+        if (chain == null)
+        {
+            return;
+        }
+
+        List<AbstractProxyCommand> allProxyCommands = chain.getAllProxyCommands();
+
+        for (AbstractProxyCommand proxyCommand : allProxyCommands)
+        {
+            try
+            {
+                proxyCommand.destroy();
+            }
+            catch (Exception e)
+            {
+                log.error("Failed to destroy proxy command, " + proxyCommand, e);
+            }
+        }
+    }
+}

Added: portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/util/RequestUtils.java
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/util/RequestUtils.java?rev=1620228&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/util/RequestUtils.java (added)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/main/java/org/apache/portals/applications/webcontent2/proxy/util/RequestUtils.java Sun Aug 24 23:01:07 2014
@@ -0,0 +1,103 @@
+/*
+ * 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.webcontent2.proxy.util;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.portals.applications.webcontent2.proxy.RequestContext;
+
+public class RequestUtils
+{
+
+    private RequestUtils()
+    {
+    }
+
+    public static String getContextPath(HttpServletRequest request)
+    {
+        String contextPath = (String) request.getAttribute("javax.servlet.include.context_path");
+
+        if (contextPath == null)
+        {
+            contextPath = (String) request.getAttribute("javax.servlet.forward.context_path");
+        }
+
+        if (contextPath != null)
+        {
+            return contextPath;
+        }
+
+        return request.getContextPath();
+    }
+
+    public static String getRequestURI(HttpServletRequest request)
+    {
+        String requestURI = (String) request.getAttribute("javax.servlet.include.request_uri");
+
+        if (requestURI == null)
+        {
+            requestURI = (String) request.getAttribute("javax.servlet.forward.request_uri");
+        }
+
+        if (requestURI != null)
+        {
+            return requestURI;
+        }
+
+        return request.getRequestURI();
+    }
+
+    public static String getServletPath(HttpServletRequest request)
+    {
+        String servletPath = (String) request.getAttribute("javax.servlet.include.servlet_path");
+
+        if (servletPath == null)
+        {
+            servletPath = (String) request.getAttribute("javax.servlet.forward.servlet_path");
+        }
+
+        if (servletPath != null)
+        {
+            return servletPath;
+        }
+
+        return request.getServletPath();
+    }
+
+    public static String getPathInfo(HttpServletRequest request)
+    {
+        String pathInfo = (String) request.getAttribute("javax.servlet.include.path_info");
+
+        if (pathInfo == null)
+        {
+            pathInfo = (String) request.getAttribute("javax.servlet.forward.path_info");
+        }
+
+        if (pathInfo != null)
+        {
+            return pathInfo;
+        }
+
+        return request.getPathInfo();
+    }
+
+    public static boolean isDispatched(RequestContext requestContext)
+    {
+        return (requestContext.getAttribute("javax.servlet.include.context_path") != null 
+                        || requestContext.getAttribute("javax.servlet.forward.context_path") != null);
+    }
+}

Modified: portals/applications/webcontent/trunk/reverse-proxy/src/test/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/test/webapp/WEB-INF/web.xml?rev=1620228&r1=1620227&r2=1620228&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/test/webapp/WEB-INF/web.xml (original)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/test/webapp/WEB-INF/web.xml Sun Aug 24 23:01:07 2014
@@ -21,6 +21,31 @@
   <display-name>WebContent Servlet Application</display-name>
   <description>WebContent Servlet Application</description>
 
+  <!-- Reverse Proxy Filter -->
+  <filter>
+    <filter-name>ReverseProxyFilter</filter-name>
+    <filter-class>org.apache.portals.applications.webcontent2.proxy.filter.SimpleReverseProxyFilter</filter-class>
+    <init-param>
+      <param-name>filterPath</param-name>
+      <param-value>/rproxyfilter</param-value>
+    </init-param>
+    <init-param>
+      <param-name>mappings</param-name>
+      <param-value>
+        /WEB-INF/rproxy-mappings.yaml
+      </param-value>
+    </init-param>
+  </filter>
+
+  <!-- Map /rproxyfilter/* path to the Reverse Proxy Filter -->
+  <filter-mapping>
+    <filter-name>ReverseProxyFilter</filter-name>
+    <url-pattern>/rproxyfilter/*</url-pattern>
+    <dispatcher>REQUEST</dispatcher>
+    <dispatcher>INCLUDE</dispatcher>
+    <dispatcher>FORWARD</dispatcher>
+  </filter-mapping>
+
   <!-- Reverse Proxy Servlet -->
   <servlet>
     <servlet-name>ReverseProxyServlet</servlet-name>
@@ -28,16 +53,15 @@
     <init-param>
       <param-name>mappings</param-name>
       <param-value>
-        /WEB-INF/ReverseProxyServlet-mappings.yaml
+        /WEB-INF/rproxy-mappings.yaml
       </param-value>
     </init-param>
-    <load-on-startup>0</load-on-startup>
   </servlet>
-  
-  <!-- Map /* path to the Reverse Proxy Servlet -->
+
+  <!-- Map /rproxyservlet/* path to the Reverse Proxy Servlet -->
   <servlet-mapping>
     <servlet-name>ReverseProxyServlet</servlet-name>
     <url-pattern>/rproxyservlet/*</url-pattern>
   </servlet-mapping>
-  
+
 </web-app>

Modified: portals/applications/webcontent/trunk/reverse-proxy/src/test/webapp/index.jsp
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/test/webapp/index.jsp?rev=1620228&r1=1620227&r2=1620228&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/test/webapp/index.jsp (original)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/test/webapp/index.jsp Sun Aug 24 23:01:07 2014
@@ -25,12 +25,24 @@ limitations under the License.
 
 <hr/>
 
+<h3>Reverse proxy servlet test</h3>
 <ul>
   <li><a href="/webcontent2/rproxyservlet/portals/applications/" target="_blank">Apache Portals Applications (reverse proxied)</a></li>
   <li><a href="/webcontent2/rproxyservlet/portals/bridges/" target="_blank">Apache Portals Bridges (reverse proxied)</a></li>
   <li><a href="/webcontent2/rproxyservlet/apache/portals/" target="_blank">Apache Portals (reverse proxied)</a></li>
   <li><a href="/webcontent2/rproxyservlet/" target="_blank">Apache Software Foundation (reverse proxied)</a></li>
-  <li><a href="portals-includes.jsp" target="_blank">JSP Include for Apache Portals Applications (reverse proxied)</a></li>
+  <li><a href="portals-includes-servlet.jsp" target="_blank">JSP Include for Apache Portals Applications (reverse proxied)</a></li>
+</ul>
+
+<hr/>
+
+<h3>Reverse proxy filter test</h3>
+<ul>
+  <li><a href="/webcontent2/rproxyfilter/portals/applications/" target="_blank">Apache Portals Applications (reverse proxied)</a></li>
+  <li><a href="/webcontent2/rproxyfilter/portals/bridges/" target="_blank">Apache Portals Bridges (reverse proxied)</a></li>
+  <li><a href="/webcontent2/rproxyfilter/apache/portals/" target="_blank">Apache Portals (reverse proxied)</a></li>
+  <li><a href="/webcontent2/rproxyfilter/" target="_blank">Apache Software Foundation (reverse proxied)</a></li>
+  <li><a href="portals-includes-filter.jsp" target="_blank">JSP Include for Apache Portals Applications (reverse proxied)</a></li>
 </ul>
 
 </body>

Added: portals/applications/webcontent/trunk/reverse-proxy/src/test/webapp/portals-includes-filter.jsp
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/test/webapp/portals-includes-filter.jsp?rev=1620228&view=auto
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/test/webapp/portals-includes-filter.jsp (added)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/test/webapp/portals-includes-filter.jsp Sun Aug 24 23:01:07 2014
@@ -0,0 +1,31 @@
+<%--
+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.
+--%>
+<%@ page language="java"%>
+<html>
+<head>
+<title>Apache Portals Applications (Reverse proxy filter)</title>
+</head>
+<body>
+
+<h1>Apache Portals Applications (Reverse proxy filter)</h1>
+
+<hr/>
+
+<jsp:include page="/rproxyfilter/portals/applications/" />
+
+</body>
+</html>

Copied: portals/applications/webcontent/trunk/reverse-proxy/src/test/webapp/portals-includes-servlet.jsp (from r1620173, portals/applications/webcontent/trunk/reverse-proxy/src/test/webapp/portals-includes.jsp)
URL: http://svn.apache.org/viewvc/portals/applications/webcontent/trunk/reverse-proxy/src/test/webapp/portals-includes-servlet.jsp?p2=portals/applications/webcontent/trunk/reverse-proxy/src/test/webapp/portals-includes-servlet.jsp&p1=portals/applications/webcontent/trunk/reverse-proxy/src/test/webapp/portals-includes.jsp&r1=1620173&r2=1620228&rev=1620228&view=diff
==============================================================================
--- portals/applications/webcontent/trunk/reverse-proxy/src/test/webapp/portals-includes.jsp (original)
+++ portals/applications/webcontent/trunk/reverse-proxy/src/test/webapp/portals-includes-servlet.jsp Sun Aug 24 23:01:07 2014
@@ -17,11 +17,11 @@ limitations under the License.
 <%@ page language="java"%>
 <html>
 <head>
-<title>Apache Portals Applications</title>
+<title>Apache Portals Applications (Reverse proxy servlet)</title>
 </head>
 <body>
 
-<h1>Apache Portals Applications</h1>
+<h1>Apache Portals Applications (Reverse proxy servlet)</h1>
 
 <hr/>