Merged branch 'jetty-9.2.x' into 'master'.
This commit is contained in:
commit
1e33c32513
|
@ -85,14 +85,14 @@ public class ProxyServlet extends HttpServlet
|
||||||
private static final Set<String> HOP_HEADERS = new HashSet<>();
|
private static final Set<String> HOP_HEADERS = new HashSet<>();
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
HOP_HEADERS.add("proxy-connection");
|
|
||||||
HOP_HEADERS.add("connection");
|
HOP_HEADERS.add("connection");
|
||||||
HOP_HEADERS.add("keep-alive");
|
HOP_HEADERS.add("keep-alive");
|
||||||
|
HOP_HEADERS.add("proxy-authorization");
|
||||||
|
HOP_HEADERS.add("proxy-authenticate");
|
||||||
|
HOP_HEADERS.add("proxy-connection");
|
||||||
HOP_HEADERS.add("transfer-encoding");
|
HOP_HEADERS.add("transfer-encoding");
|
||||||
HOP_HEADERS.add("te");
|
HOP_HEADERS.add("te");
|
||||||
HOP_HEADERS.add("trailer");
|
HOP_HEADERS.add("trailer");
|
||||||
HOP_HEADERS.add("proxy-authorization");
|
|
||||||
HOP_HEADERS.add("proxy-authenticate");
|
|
||||||
HOP_HEADERS.add("upgrade");
|
HOP_HEADERS.add("upgrade");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,7 +406,25 @@ public class ProxyServlet extends HttpServlet
|
||||||
.method(request.getMethod())
|
.method(request.getMethod())
|
||||||
.version(HttpVersion.fromString(request.getProtocol()));
|
.version(HttpVersion.fromString(request.getProtocol()));
|
||||||
|
|
||||||
// Copy headers
|
// Copy headers.
|
||||||
|
|
||||||
|
// Any header listed by the Connection header must be removed:
|
||||||
|
// http://tools.ietf.org/html/rfc7230#section-6.1.
|
||||||
|
Set<String> hopHeaders = null;
|
||||||
|
Enumeration<String> connectionHeaders = request.getHeaders(HttpHeader.CONNECTION.asString());
|
||||||
|
while (connectionHeaders.hasMoreElements())
|
||||||
|
{
|
||||||
|
String value = connectionHeaders.nextElement();
|
||||||
|
String[] values = value.split(",");
|
||||||
|
for (String name : values)
|
||||||
|
{
|
||||||
|
name = name.trim().toLowerCase(Locale.ENGLISH);
|
||||||
|
if (hopHeaders == null)
|
||||||
|
hopHeaders = new HashSet<>();
|
||||||
|
hopHeaders.add(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
boolean hasContent = request.getContentLength() > 0 || request.getContentType() != null;
|
boolean hasContent = request.getContentLength() > 0 || request.getContentType() != null;
|
||||||
for (Enumeration<String> headerNames = request.getHeaderNames(); headerNames.hasMoreElements();)
|
for (Enumeration<String> headerNames = request.getHeaderNames(); headerNames.hasMoreElements();)
|
||||||
{
|
{
|
||||||
|
@ -419,9 +437,11 @@ public class ProxyServlet extends HttpServlet
|
||||||
if (_hostHeader != null && HttpHeader.HOST.is(headerName))
|
if (_hostHeader != null && HttpHeader.HOST.is(headerName))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Remove hop-by-hop headers
|
// Remove hop-by-hop headers.
|
||||||
if (HOP_HEADERS.contains(lowerHeaderName))
|
if (HOP_HEADERS.contains(lowerHeaderName))
|
||||||
continue;
|
continue;
|
||||||
|
if (hopHeaders != null && hopHeaders.contains(lowerHeaderName))
|
||||||
|
continue;
|
||||||
|
|
||||||
for (Enumeration<String> headerValues = request.getHeaders(headerName); headerValues.hasMoreElements();)
|
for (Enumeration<String> headerValues = request.getHeaders(headerName); headerValues.hasMoreElements();)
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,8 +32,10 @@ import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.StandardOpenOption;
|
import java.nio.file.StandardOpenOption;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
@ -69,6 +71,7 @@ import org.eclipse.jetty.client.http.HttpDestinationOverHTTP;
|
||||||
import org.eclipse.jetty.client.util.BufferingResponseListener;
|
import org.eclipse.jetty.client.util.BufferingResponseListener;
|
||||||
import org.eclipse.jetty.client.util.BytesContentProvider;
|
import org.eclipse.jetty.client.util.BytesContentProvider;
|
||||||
import org.eclipse.jetty.client.util.InputStreamResponseListener;
|
import org.eclipse.jetty.client.util.InputStreamResponseListener;
|
||||||
|
import org.eclipse.jetty.http.HttpHeader;
|
||||||
import org.eclipse.jetty.http.HttpMethod;
|
import org.eclipse.jetty.http.HttpMethod;
|
||||||
import org.eclipse.jetty.server.HttpConfiguration;
|
import org.eclipse.jetty.server.HttpConfiguration;
|
||||||
import org.eclipse.jetty.server.HttpConnectionFactory;
|
import org.eclipse.jetty.server.HttpConnectionFactory;
|
||||||
|
@ -1144,5 +1147,40 @@ public class ProxyServletTest
|
||||||
Assert.assertEquals(headerValue, response.getHeaders().get(headerName));
|
Assert.assertEquals(headerValue, response.getHeaders().get(headerName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHeadersListedByConnectionHeaderAreRemoved() throws Exception
|
||||||
|
{
|
||||||
|
prepareProxy();
|
||||||
|
|
||||||
|
final Map<String, String> hopHeaders = new LinkedHashMap<>();
|
||||||
|
hopHeaders.put(HttpHeader.TE.asString(), "gzip");
|
||||||
|
hopHeaders.put(HttpHeader.CONNECTION.asString(), "Keep-Alive, Foo, Bar");
|
||||||
|
hopHeaders.put("Foo", "abc");
|
||||||
|
hopHeaders.put("Foo", "def");
|
||||||
|
hopHeaders.put(HttpHeader.KEEP_ALIVE.asString(), "timeout=30");
|
||||||
|
|
||||||
|
prepareServer(new HttpServlet()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||||
|
{
|
||||||
|
List<String> names = Collections.list(request.getHeaderNames());
|
||||||
|
for (String name : names)
|
||||||
|
{
|
||||||
|
if (hopHeaders.containsKey(name))
|
||||||
|
throw new IOException("Hop header must not be proxied: " + name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
HttpClient client = prepareClient();
|
||||||
|
Request request = client.newRequest("localhost", serverConnector.getLocalPort());
|
||||||
|
for (Map.Entry<String, String> entry : hopHeaders.entrySet())
|
||||||
|
request.header(entry.getKey(), entry.getValue());
|
||||||
|
ContentResponse response = request.send();
|
||||||
|
|
||||||
|
Assert.assertEquals(200, response.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: test proxy authentication
|
// TODO: test proxy authentication
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,12 @@ public class ServletUpgradeResponse extends UpgradeResponse
|
||||||
|
|
||||||
public boolean isCommitted()
|
public boolean isCommitted()
|
||||||
{
|
{
|
||||||
return response.isCommitted();
|
if (response != null)
|
||||||
|
{
|
||||||
|
return response.isCommitted();
|
||||||
|
}
|
||||||
|
// True in all other cases
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isExtensionsNegotiated()
|
public boolean isExtensionsNegotiated()
|
||||||
|
|
Loading…
Reference in New Issue