diff options
Diffstat (limited to 'jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/proxy/FastCGIProxyServlet.java')
-rw-r--r-- | jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/proxy/FastCGIProxyServlet.java | 92 |
1 files changed, 74 insertions, 18 deletions
diff --git a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/proxy/FastCGIProxyServlet.java b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/proxy/FastCGIProxyServlet.java index b725ccfb9b..8587042304 100644 --- a/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/proxy/FastCGIProxyServlet.java +++ b/jetty-fcgi/fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/proxy/FastCGIProxyServlet.java @@ -19,29 +19,35 @@ package org.eclipse.jetty.fcgi.server.proxy; import java.net.URI; +import java.util.List; +import java.util.TreeMap; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; + import javax.servlet.RequestDispatcher; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.fcgi.FCGI; import org.eclipse.jetty.fcgi.client.http.HttpClientTransportOverFCGI; +import org.eclipse.jetty.http.HttpField; import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.proxy.AsyncProxyServlet; -import org.eclipse.jetty.proxy.ProxyServlet; /** - * Specific implementation of {@link ProxyServlet.Transparent} for FastCGI. - * <p /> + * Specific implementation of {@link org.eclipse.jetty.proxy.AsyncProxyServlet.Transparent} for FastCGI. + * <p> * This servlet accepts a HTTP request and transforms it into a FastCGI request * that is sent to the FastCGI server specified in the <code>proxyTo</code> * init-param. - * <p /> + * <p> * This servlet accepts two additional init-params: * <ul> * <li><code>scriptRoot</code>, mandatory, that must be set to the directory where @@ -64,6 +70,7 @@ public class FastCGIProxyServlet extends AsyncProxyServlet.Transparent { public static final String SCRIPT_ROOT_INIT_PARAM = "scriptRoot"; public static final String SCRIPT_PATTERN_INIT_PARAM = "scriptPattern"; + public static final String ORIGINAL_URI_ATTRIBUTE_INIT_PARAM = "originalURIAttribute"; public static final String FASTCGI_HTTPS_INIT_PARAM = "fastCGI.HTTPS"; private static final String REMOTE_ADDR_ATTRIBUTE = FastCGIProxyServlet.class.getName() + ".remoteAddr"; @@ -75,6 +82,7 @@ public class FastCGIProxyServlet extends AsyncProxyServlet.Transparent private static final String REQUEST_URI_ATTRIBUTE = FastCGIProxyServlet.class.getName() + ".requestURI"; private Pattern scriptPattern; + private String originalURIAttribute; private boolean fcgiHTTPS; @Override @@ -87,6 +95,8 @@ public class FastCGIProxyServlet extends AsyncProxyServlet.Transparent value = "(.+?\\.php)"; scriptPattern = Pattern.compile(value); + originalURIAttribute = getInitParameter(ORIGINAL_URI_ATTRIBUTE_INIT_PARAM); + fcgiHTTPS = Boolean.parseBoolean(getInitParameter(FASTCGI_HTTPS_INIT_PARAM)); } @@ -101,33 +111,69 @@ public class FastCGIProxyServlet extends AsyncProxyServlet.Transparent } @Override - protected void customizeProxyRequest(Request proxyRequest, HttpServletRequest request) + protected void sendProxyRequest(HttpServletRequest request, HttpServletResponse proxyResponse, Request proxyRequest) { proxyRequest.attribute(REMOTE_ADDR_ATTRIBUTE, request.getRemoteAddr()); proxyRequest.attribute(REMOTE_PORT_ATTRIBUTE, String.valueOf(request.getRemotePort())); proxyRequest.attribute(SERVER_NAME_ATTRIBUTE, request.getServerName()); proxyRequest.attribute(SERVER_ADDR_ATTRIBUTE, request.getLocalAddr()); proxyRequest.attribute(SERVER_PORT_ATTRIBUTE, String.valueOf(request.getLocalPort())); - proxyRequest.attribute(SCHEME_ATTRIBUTE, request.getScheme()); - // If we are forwarded or included, retain the original request URI. - String originalPath = (String)request.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI); - String originalQuery = (String)request.getAttribute(RequestDispatcher.FORWARD_QUERY_STRING); - if (originalPath == null) + // Has the original URI been rewritten ? + String originalURI = null; + if (originalURIAttribute != null) + originalURI = (String)request.getAttribute(originalURIAttribute); + + if (originalURI == null) { - originalPath = (String)request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI); - originalQuery = (String)request.getAttribute(RequestDispatcher.INCLUDE_QUERY_STRING); + // If we are forwarded or included, retain the original request URI. + String originalPath = (String)request.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI); + String originalQuery = (String)request.getAttribute(RequestDispatcher.FORWARD_QUERY_STRING); + if (originalPath == null) + { + originalPath = (String)request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI); + originalQuery = (String)request.getAttribute(RequestDispatcher.INCLUDE_QUERY_STRING); + } + if (originalPath != null) + { + originalURI = originalPath; + if (originalQuery != null) + originalURI += "?" + originalQuery; + } } - if (originalPath != null) - { - String originalURI = originalPath; - if (originalQuery != null) - originalURI += "?" + originalQuery; + + if (originalURI != null) proxyRequest.attribute(REQUEST_URI_ATTRIBUTE, originalURI); + + // If the Host header is missing, add it. + if (!proxyRequest.getHeaders().containsKey(HttpHeader.HOST.asString())) + { + String host = request.getServerName(); + int port = request.getServerPort(); + if (!getHttpClient().isDefaultPort(request.getScheme(), port)) + host += ":" + port; + proxyRequest.header(HttpHeader.HOST, host); + proxyRequest.header(HttpHeader.X_FORWARDED_HOST, host); + } + + // PHP does not like multiple Cookie headers, coalesce into one. + List<String> cookies = proxyRequest.getHeaders().getValuesList(HttpHeader.COOKIE.asString()); + if (cookies.size() > 1) + { + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < cookies.size(); ++i) + { + if (i > 0) + builder.append("; "); + String cookie = cookies.get(i); + builder.append(cookie); + } + proxyRequest.header(HttpHeader.COOKIE, null); + proxyRequest.header(HttpHeader.COOKIE, builder.toString()); } - super.customizeProxyRequest(proxyRequest, request); + super.sendProxyRequest(request, proxyResponse, proxyRequest); } protected void customizeFastCGIHeaders(Request proxyRequest, HttpFields fastCGIHeaders) @@ -183,6 +229,16 @@ public class FastCGIProxyServlet extends AsyncProxyServlet.Transparent { super.customize(request, fastCGIHeaders); customizeFastCGIHeaders(request, fastCGIHeaders); + if (_log.isDebugEnabled()) + { + TreeMap<String, String> fcgi = new TreeMap<>(); + for (HttpField field : fastCGIHeaders) + fcgi.put(field.getName(), field.getValue()); + String eol = System.lineSeparator(); + _log.debug("FastCGI variables{}{}", eol, fcgi.entrySet().stream() + .map(entry -> String.format("%s: %s", entry.getKey(), entry.getValue())) + .collect(Collectors.joining(eol))); + } } } } |