Fixes #312 (REQUEST_URI should retain original query string in case of rewrites)
Added init-param "originalQueryAttribute" to FastCGIProxyServlet to retrieve the original query in case of rewrites.
This commit is contained in:
parent
1c5a1fc6a2
commit
3c0b654141
|
@ -58,14 +58,17 @@ public class HttpChannelOverFCGI extends HttpChannel
|
|||
|
||||
protected void header(HttpField field)
|
||||
{
|
||||
if (FCGI.Headers.REQUEST_METHOD.equalsIgnoreCase(field.getName()))
|
||||
method = field.getValue();
|
||||
else if (FCGI.Headers.DOCUMENT_URI.equalsIgnoreCase(field.getName()))
|
||||
path = field.getValue();
|
||||
else if (FCGI.Headers.QUERY_STRING.equalsIgnoreCase(field.getName()))
|
||||
query = field.getValue();
|
||||
else if (FCGI.Headers.SERVER_PROTOCOL.equalsIgnoreCase(field.getName()))
|
||||
version = field.getValue();
|
||||
String name = field.getName();
|
||||
String value = field.getValue();
|
||||
getRequest().setAttribute(name, value);
|
||||
if (FCGI.Headers.REQUEST_METHOD.equalsIgnoreCase(name))
|
||||
method = value;
|
||||
else if (FCGI.Headers.DOCUMENT_URI.equalsIgnoreCase(name))
|
||||
path = value;
|
||||
else if (FCGI.Headers.QUERY_STRING.equalsIgnoreCase(name))
|
||||
query = value;
|
||||
else if (FCGI.Headers.SERVER_PROTOCOL.equalsIgnoreCase(name))
|
||||
version = value;
|
||||
else
|
||||
processField(field);
|
||||
}
|
||||
|
@ -107,10 +110,11 @@ public class HttpChannelOverFCGI extends HttpChannel
|
|||
httpName.append(part.substring(1).toLowerCase(Locale.ENGLISH));
|
||||
}
|
||||
String headerName = httpName.toString();
|
||||
String value = field.getValue();
|
||||
if (HttpHeader.HOST.is(headerName))
|
||||
return new HostPortHttpField(field.getValue());
|
||||
return new HostPortHttpField(value);
|
||||
else
|
||||
return new HttpField(httpName.toString(), field.getValue());
|
||||
return new HttpField(headerName, value);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -71,6 +71,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 ORIGINAL_QUERY_ATTRIBUTE_INIT_PARAM = "originalQueryAttribute";
|
||||
public static final String FASTCGI_HTTPS_INIT_PARAM = "fastCGI.HTTPS";
|
||||
|
||||
private static final String REMOTE_ADDR_ATTRIBUTE = FastCGIProxyServlet.class.getName() + ".remoteAddr";
|
||||
|
@ -80,9 +81,11 @@ public class FastCGIProxyServlet extends AsyncProxyServlet.Transparent
|
|||
private static final String SERVER_PORT_ATTRIBUTE = FastCGIProxyServlet.class.getName() + ".serverPort";
|
||||
private static final String SCHEME_ATTRIBUTE = FastCGIProxyServlet.class.getName() + ".scheme";
|
||||
private static final String REQUEST_URI_ATTRIBUTE = FastCGIProxyServlet.class.getName() + ".requestURI";
|
||||
private static final String REQUEST_QUERY_ATTRIBUTE = FastCGIProxyServlet.class.getName() + ".requestQuery";
|
||||
|
||||
private Pattern scriptPattern;
|
||||
private String originalURIAttribute;
|
||||
private String originalQueryAttribute;
|
||||
private boolean fcgiHTTPS;
|
||||
|
||||
@Override
|
||||
|
@ -96,6 +99,7 @@ public class FastCGIProxyServlet extends AsyncProxyServlet.Transparent
|
|||
scriptPattern = Pattern.compile(value);
|
||||
|
||||
originalURIAttribute = getInitParameter(ORIGINAL_URI_ATTRIBUTE_INIT_PARAM);
|
||||
originalQueryAttribute = getInitParameter(ORIGINAL_QUERY_ATTRIBUTE_INIT_PARAM);
|
||||
|
||||
fcgiHTTPS = Boolean.parseBoolean(getInitParameter(FASTCGI_HTTPS_INIT_PARAM));
|
||||
}
|
||||
|
@ -122,14 +126,21 @@ public class FastCGIProxyServlet extends AsyncProxyServlet.Transparent
|
|||
|
||||
// Has the original URI been rewritten ?
|
||||
String originalURI = null;
|
||||
String originalQuery = null;
|
||||
if (originalURIAttribute != null)
|
||||
originalURI = (String)request.getAttribute(originalURIAttribute);
|
||||
if (originalURI != null && originalQueryAttribute != null)
|
||||
{
|
||||
originalQuery = (String)request.getAttribute(originalQueryAttribute);
|
||||
if (originalQuery != null)
|
||||
originalURI += "?" + originalQuery;
|
||||
}
|
||||
|
||||
if (originalURI == null)
|
||||
{
|
||||
// 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);
|
||||
originalQuery = (String)request.getAttribute(RequestDispatcher.FORWARD_QUERY_STRING);
|
||||
if (originalPath == null)
|
||||
{
|
||||
originalPath = (String)request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI);
|
||||
|
@ -145,6 +156,8 @@ public class FastCGIProxyServlet extends AsyncProxyServlet.Transparent
|
|||
|
||||
if (originalURI != null)
|
||||
proxyRequest.attribute(REQUEST_URI_ATTRIBUTE, originalURI);
|
||||
if (originalQuery != null)
|
||||
proxyRequest.attribute(REQUEST_QUERY_ATTRIBUTE, originalQuery);
|
||||
|
||||
// If the Host header is missing, add it.
|
||||
if (!proxyRequest.getHeaders().containsKey(HttpHeader.HOST.asString()))
|
||||
|
@ -200,6 +213,10 @@ public class FastCGIProxyServlet extends AsyncProxyServlet.Transparent
|
|||
}
|
||||
fastCGIHeaders.put(FCGI.Headers.REQUEST_URI, requestURI);
|
||||
|
||||
String requestQuery = (String)proxyRequest.getAttributes().get(REQUEST_QUERY_ATTRIBUTE);
|
||||
if (requestQuery != null)
|
||||
fastCGIHeaders.put(FCGI.Headers.QUERY_STRING, requestQuery);
|
||||
|
||||
String scriptName = rawPath;
|
||||
Matcher matcher = scriptPattern.matcher(rawPath);
|
||||
if (matcher.matches())
|
||||
|
|
|
@ -31,13 +31,17 @@ import org.eclipse.jetty.client.HttpClient;
|
|||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.util.FutureResponseListener;
|
||||
import org.eclipse.jetty.fcgi.FCGI;
|
||||
import org.eclipse.jetty.fcgi.server.ServerFCGIConnectionFactory;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.server.HttpConfiguration;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.server.handler.HandlerWrapper;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
@ -57,6 +61,7 @@ public class FastCGIProxyServletTest
|
|||
private Server server;
|
||||
private ServerConnector httpConnector;
|
||||
private ServerConnector fcgiConnector;
|
||||
private ServletContextHandler context;
|
||||
private HttpClient client;
|
||||
|
||||
public FastCGIProxyServletTest(boolean sendStatus200)
|
||||
|
@ -76,7 +81,7 @@ public class FastCGIProxyServletTest
|
|||
server.addConnector(fcgiConnector);
|
||||
|
||||
final String contextPath = "/";
|
||||
ServletContextHandler context = new ServletContextHandler(server, contextPath);
|
||||
context = new ServletContextHandler(server, contextPath);
|
||||
|
||||
final String servletPath = "/script";
|
||||
FastCGIProxyServlet fcgiServlet = new FastCGIProxyServlet()
|
||||
|
@ -138,11 +143,11 @@ public class FastCGIProxyServletTest
|
|||
prepare(new HttpServlet()
|
||||
{
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
Assert.assertTrue(req.getRequestURI().endsWith(path));
|
||||
resp.setContentLength(data.length);
|
||||
resp.getOutputStream().write(data);
|
||||
Assert.assertTrue(request.getRequestURI().endsWith(path));
|
||||
response.setContentLength(data.length);
|
||||
response.getOutputStream().write(data);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -169,4 +174,48 @@ public class FastCGIProxyServletTest
|
|||
Assert.assertEquals(200, response.getStatus());
|
||||
Assert.assertArrayEquals(data, response.getContent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testURIRewrite() throws Exception
|
||||
{
|
||||
String originalPath = "/original/index.php";
|
||||
String originalQuery = "foo=bar";
|
||||
String remotePath = "/remote/index.php";
|
||||
prepare(new HttpServlet()
|
||||
{
|
||||
@Override
|
||||
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
Assert.assertThat((String)request.getAttribute(FCGI.Headers.REQUEST_URI), Matchers.startsWith(originalPath));
|
||||
Assert.assertEquals(originalQuery, request.getAttribute(FCGI.Headers.QUERY_STRING));
|
||||
Assert.assertThat(request.getRequestURI(), Matchers.endsWith(remotePath));
|
||||
}
|
||||
});
|
||||
context.stop();
|
||||
String pathAttribute = "_path_attribute";
|
||||
String queryAttribute = "_query_attribute";
|
||||
ServletHolder fcgi = context.getServletHandler().getServlet("fcgi");
|
||||
fcgi.setInitParameter(FastCGIProxyServlet.ORIGINAL_URI_ATTRIBUTE_INIT_PARAM, pathAttribute);
|
||||
fcgi.setInitParameter(FastCGIProxyServlet.ORIGINAL_QUERY_ATTRIBUTE_INIT_PARAM, queryAttribute);
|
||||
context.insertHandler(new HandlerWrapper()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
if (target.startsWith("/remote/"))
|
||||
{
|
||||
request.setAttribute(pathAttribute, originalPath);
|
||||
request.setAttribute(queryAttribute, originalQuery);
|
||||
}
|
||||
super.handle(target, baseRequest, request, response);
|
||||
}
|
||||
});
|
||||
context.start();
|
||||
|
||||
ContentResponse response = client.newRequest("localhost", httpConnector.getLocalPort())
|
||||
.path(remotePath)
|
||||
.send();
|
||||
|
||||
Assert.assertEquals(HttpStatus.OK_200, response.getStatus());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue