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<>();
|
||||
static
|
||||
{
|
||||
HOP_HEADERS.add("proxy-connection");
|
||||
HOP_HEADERS.add("connection");
|
||||
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("te");
|
||||
HOP_HEADERS.add("trailer");
|
||||
HOP_HEADERS.add("proxy-authorization");
|
||||
HOP_HEADERS.add("proxy-authenticate");
|
||||
HOP_HEADERS.add("upgrade");
|
||||
}
|
||||
|
||||
|
@ -406,7 +406,25 @@ public class ProxyServlet extends HttpServlet
|
|||
.method(request.getMethod())
|
||||
.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;
|
||||
for (Enumeration<String> headerNames = request.getHeaderNames(); headerNames.hasMoreElements();)
|
||||
{
|
||||
|
@ -419,9 +437,11 @@ public class ProxyServlet extends HttpServlet
|
|||
if (_hostHeader != null && HttpHeader.HOST.is(headerName))
|
||||
continue;
|
||||
|
||||
// Remove hop-by-hop headers
|
||||
// Remove hop-by-hop headers.
|
||||
if (HOP_HEADERS.contains(lowerHeaderName))
|
||||
continue;
|
||||
if (hopHeaders != null && hopHeaders.contains(lowerHeaderName))
|
||||
continue;
|
||||
|
||||
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.StandardOpenOption;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
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.BytesContentProvider;
|
||||
import org.eclipse.jetty.client.util.InputStreamResponseListener;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.server.HttpConfiguration;
|
||||
import org.eclipse.jetty.server.HttpConnectionFactory;
|
||||
|
@ -1144,5 +1147,40 @@ public class ProxyServletTest
|
|||
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
|
||||
}
|
||||
|
|
|
@ -59,7 +59,12 @@ public class ServletUpgradeResponse extends UpgradeResponse
|
|||
|
||||
public boolean isCommitted()
|
||||
{
|
||||
return response.isCommitted();
|
||||
if (response != null)
|
||||
{
|
||||
return response.isCommitted();
|
||||
}
|
||||
// True in all other cases
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isExtensionsNegotiated()
|
||||
|
|
Loading…
Reference in New Issue