Repository: struts-extras Updated Branches: refs/heads/master 8e1aadda4 -> c056b516a
added HttpsOffloadAwareServletRedirectResult Project: http://git-wip-us.apache.org/repos/asf/struts-extras/repo Commit: http://git-wip-us.apache.org/repos/asf/struts-extras/commit/1a64217f Tree: http://git-wip-us.apache.org/repos/asf/struts-extras/tree/1a64217f Diff: http://git-wip-us.apache.org/repos/asf/struts-extras/diff/1a64217f Branch: refs/heads/master Commit: 1a64217f87566831864371622673951d29dca79a Parents: 8e1aadd Author: Stefaan Dutry <stefaan.du...@gmail.com> Authored: Mon Mar 27 23:20:48 2017 +0200 Committer: Stefaan Dutry <stefaan.du...@gmail.com> Committed: Mon Mar 27 23:20:48 2017 +0200 ---------------------------------------------------------------------- struts2-custom-results-plugin/pom.xml | 104 +++++++++++++ .../HttpsOffloadAwareServletRedirectResult.java | 146 +++++++++++++++++++ 2 files changed, 250 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/struts-extras/blob/1a64217f/struts2-custom-results-plugin/pom.xml ---------------------------------------------------------------------- diff --git a/struts2-custom-results-plugin/pom.xml b/struts2-custom-results-plugin/pom.xml new file mode 100644 index 0000000..44eadde --- /dev/null +++ b/struts2-custom-results-plugin/pom.xml @@ -0,0 +1,104 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <parent> + <groupId>org.apache.struts</groupId> + <artifactId>struts-master</artifactId> + <version>10</version> + </parent> + + <modelVersion>4.0.0</modelVersion> + + <artifactId>struts2-custom-results-plugin</artifactId> + <version>1.2-SNAPSHOT</version> + <packaging>jar</packaging> + <name>struts2 custom results plugin</name> + + <description> + This plugin defines some additional result types + </description> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <scm> + <connection>scm:git:git://git.apache.org/struts-extras.git</connection> + <developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/struts-extras.git</developerConnection> + <url>http://git.apache.org/struts-extras.git</url> + <tag>HEAD</tag> + </scm> + + <issueManagement> + <system>JIRA</system> + <url>https://issues.apache.org/jira/browse/WW</url> + </issueManagement> + + <ciManagement> + <system>Jenkins</system> + <url>https://builds.apache.org/hudson/view/S-Z/view/Struts</url> + <notifiers> + <notifier> + <type>mail</type> + <configuration> + <address>d...@struts.apache.org</address> + </configuration> + </notifier> + </notifiers> + </ciManagement> + + <dependencies> + + <dependency> + <groupId>org.apache.struts</groupId> + <artifactId>struts2-core</artifactId> + <version>2.3.20.1</version> + </dependency> + + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-api</artifactId> + <version>2.8</version> + </dependency> + + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>servlet-api</artifactId> + <version>2.4</version> + <scope>provided</scope> + </dependency> + + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>1.6</source> + <target>1.6</target> + </configuration> + </plugin> + </plugins> + </build> + +</project> http://git-wip-us.apache.org/repos/asf/struts-extras/blob/1a64217f/struts2-custom-results-plugin/src/main/java/org/apache/struts2/dispatcher/HttpsOffloadAwareServletRedirectResult.java ---------------------------------------------------------------------- diff --git a/struts2-custom-results-plugin/src/main/java/org/apache/struts2/dispatcher/HttpsOffloadAwareServletRedirectResult.java b/struts2-custom-results-plugin/src/main/java/org/apache/struts2/dispatcher/HttpsOffloadAwareServletRedirectResult.java new file mode 100644 index 0000000..751e783 --- /dev/null +++ b/struts2-custom-results-plugin/src/main/java/org/apache/struts2/dispatcher/HttpsOffloadAwareServletRedirectResult.java @@ -0,0 +1,146 @@ +/* + * $Id$ + * + * 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.struts2.dispatcher; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.struts2.ServletActionContext; +import org.apache.struts2.dispatcher.Dispatcher; +import org.apache.struts2.dispatcher.ServletRedirectResult; +import org.apache.struts2.dispatcher.mapper.ActionMapping; +import org.apache.struts2.views.util.UrlHelper; + +import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.config.entities.ResultConfig; +import com.opensymphony.xwork2.inject.Inject; + +public class HttpsOffloadAwareServletRedirectResult extends ServletRedirectResult { + private static final long serialVersionUID = -5384946213381645549L; + private static final Logger LOG = LogManager.getLogger(HttpsOffloadAwareServletRedirectResult.class); + + private UrlHelper urlHelper; + + @Inject + public void setUrlHelper(UrlHelper urlHelper) { + this.urlHelper = urlHelper; + } + + /** + * Redirects to the location specified by calling + * {@link HttpServletResponse#sendRedirect(String)}. + * + * @param finalLocation + * the location to redirect to. + * @param invocation + * an encapsulation of the action execution state. + * @throws Exception + * if an error occurs when redirecting. + */ + protected void doExecute(String finalLocation, ActionInvocation invocation) throws Exception { + ActionContext ctx = invocation.getInvocationContext(); + HttpServletRequest request = (HttpServletRequest) ctx.get(ServletActionContext.HTTP_REQUEST); + HttpServletResponse response = (HttpServletResponse) ctx.get(ServletActionContext.HTTP_RESPONSE); + + if (isPathUrl(finalLocation)) { + if (!finalLocation.startsWith("/")) { + ActionMapping mapping = actionMapper.getMapping(request, + Dispatcher.getInstance().getConfigurationManager()); + String namespace = null; + if (mapping != null) { + namespace = mapping.getNamespace(); + } + + if ((namespace != null) && (namespace.length() > 0) && (!"/".equals(namespace))) { + finalLocation = namespace + "/" + finalLocation; + } else { + finalLocation = "/" + finalLocation; + } + } + + // if the URL's are relative to the servlet context, append the + // servlet context path + if (prependServletContext && (request.getContextPath() != null) + && (request.getContextPath().length() > 0)) { + finalLocation = request.getContextPath() + finalLocation; + } + + finalLocation = fixSchemeIfNeeded(finalLocation, request); + } + ResultConfig resultConfig = invocation.getProxy().getConfig().getResults().get(invocation.getResultCode()); + if (resultConfig != null) { + Map<String, String> resultConfigParams = resultConfig.getParams(); + + List<String> prohibitedResultParams = getProhibitedResultParams(); + for (Map.Entry<String, String> e : resultConfigParams.entrySet()) { + if (!prohibitedResultParams.contains(e.getKey())) { + Collection<String> values = conditionalParseCollection(e.getValue(), invocation, + suppressEmptyParameters); + if (!suppressEmptyParameters || !values.isEmpty()) { + requestParameters.put(e.getKey(), values); + } + } + } + } + + StringBuilder tmpLocation = new StringBuilder(finalLocation); + urlHelper.buildParametersString(requestParameters, tmpLocation, "&"); + + // add the anchor + if (anchor != null) { + tmpLocation.append('#').append(anchor); + } + + finalLocation = response.encodeRedirectURL(tmpLocation.toString()); + + LOG.debug("Redirecting to finalLocation: {}", finalLocation); + + sendRedirect(response, finalLocation); + } + + private String fixSchemeIfNeeded(String location, HttpServletRequest request) { + if ("https".equals(request.getHeader("X-Forwarded-Proto"))) { + LOG.debug("https offloading happened, fixing redirectlocation"); + StringBuilder fixedLocation = new StringBuilder(); + fixedLocation.append("https"); + fixedLocation.append("://"); + fixedLocation.append(request.getServerName()); + if (request.getServerPort() != 80) { + fixedLocation.append(':'); + fixedLocation.append(request.getServerPort()); + } + fixedLocation.append(location); + + return fixedLocation.toString(); + } else { + return location; + } + } + +}