HADOOP-11350. The size of header buffer of HttpServer is too small when HTTPS is enabled. Contributed by Benoy Antony.
This commit is contained in:
parent
6f792fc198
commit
2e4df87104
|
@ -355,6 +355,9 @@ Release 2.7.0 - UNRELEASED
|
||||||
HADOOP-11462. TestSocketIOWithTimeout needs change for PowerPC platform.
|
HADOOP-11462. TestSocketIOWithTimeout needs change for PowerPC platform.
|
||||||
(Ayappan via cnauroth)
|
(Ayappan via cnauroth)
|
||||||
|
|
||||||
|
HADOOP-11350. The size of header buffer of HttpServer is too small when
|
||||||
|
HTTPS is enabled. (Benoy Antony via wheat9)
|
||||||
|
|
||||||
Release 2.6.0 - 2014-11-18
|
Release 2.6.0 - 2014-11-18
|
||||||
|
|
||||||
INCOMPATIBLE CHANGES
|
INCOMPATIBLE CHANGES
|
||||||
|
|
|
@ -279,6 +279,7 @@ public final class HttpServer2 implements FilterContainer {
|
||||||
listener = HttpServer2.createDefaultChannelConnector();
|
listener = HttpServer2.createDefaultChannelConnector();
|
||||||
} else if ("https".equals(scheme)) {
|
} else if ("https".equals(scheme)) {
|
||||||
SslSocketConnector c = new SslSocketConnectorSecure();
|
SslSocketConnector c = new SslSocketConnectorSecure();
|
||||||
|
c.setHeaderBufferSize(1024*64);
|
||||||
c.setNeedClientAuth(needsClientAuth);
|
c.setNeedClientAuth(needsClientAuth);
|
||||||
c.setKeyPassword(keyPassword);
|
c.setKeyPassword(keyPassword);
|
||||||
|
|
||||||
|
|
|
@ -28,15 +28,32 @@ import org.apache.hadoop.http.HttpServer2.Builder;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a base class for functional tests of the {@link HttpServer2}.
|
* This is a base class for functional tests of the {@link HttpServer2}.
|
||||||
* The methods are static for other classes to import statically.
|
* The methods are static for other classes to import statically.
|
||||||
*/
|
*/
|
||||||
public class HttpServerFunctionalTest extends Assert {
|
public class HttpServerFunctionalTest extends Assert {
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public static class LongHeaderServlet extends HttpServlet {
|
||||||
|
@Override
|
||||||
|
public void doGet(HttpServletRequest request,
|
||||||
|
HttpServletResponse response
|
||||||
|
) throws ServletException, IOException {
|
||||||
|
Assert.assertEquals(63 * 1024, request.getHeader("longheader").length());
|
||||||
|
response.setStatus(HttpServletResponse.SC_OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** JVM property for the webapp test dir : {@value} */
|
/** JVM property for the webapp test dir : {@value} */
|
||||||
public static final String TEST_BUILD_WEBAPPS = "test.build.webapps";
|
public static final String TEST_BUILD_WEBAPPS = "test.build.webapps";
|
||||||
/** expected location of the test.build.webapps dir: {@value} */
|
/** expected location of the test.build.webapps dir: {@value} */
|
||||||
|
@ -44,6 +61,7 @@ public class HttpServerFunctionalTest extends Assert {
|
||||||
|
|
||||||
/** name of the test webapp: {@value} */
|
/** name of the test webapp: {@value} */
|
||||||
private static final String TEST = "test";
|
private static final String TEST = "test";
|
||||||
|
protected static URL baseUrl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create but do not start the test webapp server. The test webapp dir is
|
* Create but do not start the test webapp server. The test webapp dir is
|
||||||
|
@ -227,4 +245,18 @@ public class HttpServerFunctionalTest extends Assert {
|
||||||
}
|
}
|
||||||
return out.toString();
|
return out.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that verifies headers can be up to 64K long.
|
||||||
|
* The test adds a 63K header leaving 1K for other headers.
|
||||||
|
* This is because the header buffer setting is for ALL headers,
|
||||||
|
* names and values included. */
|
||||||
|
protected void testLongHeader(HttpURLConnection conn) throws IOException {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 0 ; i < 63 * 1024; i++) {
|
||||||
|
sb.append("a");
|
||||||
|
}
|
||||||
|
conn.setRequestProperty("longheader", sb.toString());
|
||||||
|
assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,6 @@ import java.util.concurrent.Executors;
|
||||||
public class TestHttpServer extends HttpServerFunctionalTest {
|
public class TestHttpServer extends HttpServerFunctionalTest {
|
||||||
static final Log LOG = LogFactory.getLog(TestHttpServer.class);
|
static final Log LOG = LogFactory.getLog(TestHttpServer.class);
|
||||||
private static HttpServer2 server;
|
private static HttpServer2 server;
|
||||||
private static URL baseUrl;
|
|
||||||
private static final int MAX_THREADS = 10;
|
private static final int MAX_THREADS = 10;
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
|
@ -120,17 +119,6 @@ public class TestHttpServer extends HttpServerFunctionalTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
|
||||||
public static class LongHeaderServlet extends HttpServlet {
|
|
||||||
@Override
|
|
||||||
public void doGet(HttpServletRequest request,
|
|
||||||
HttpServletResponse response
|
|
||||||
) throws ServletException, IOException {
|
|
||||||
Assert.assertEquals(63 * 1024, request.getHeader("longheader").length());
|
|
||||||
response.setStatus(HttpServletResponse.SC_OK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public static class HtmlContentServlet extends HttpServlet {
|
public static class HtmlContentServlet extends HttpServlet {
|
||||||
@Override
|
@Override
|
||||||
|
@ -210,20 +198,10 @@ public class TestHttpServer extends HttpServerFunctionalTest {
|
||||||
readOutput(new URL(baseUrl, "/echomap?a=b&c<=d&a=>")));
|
readOutput(new URL(baseUrl, "/echomap?a=b&c<=d&a=>")));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test that verifies headers can be up to 64K long.
|
|
||||||
* The test adds a 63K header leaving 1K for other headers.
|
|
||||||
* This is because the header buffer setting is for ALL headers,
|
|
||||||
* names and values included. */
|
|
||||||
@Test public void testLongHeader() throws Exception {
|
@Test public void testLongHeader() throws Exception {
|
||||||
URL url = new URL(baseUrl, "/longheader");
|
URL url = new URL(baseUrl, "/longheader");
|
||||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||||
StringBuilder sb = new StringBuilder();
|
testLongHeader(conn);
|
||||||
for (int i = 0 ; i < 63 * 1024; i++) {
|
|
||||||
sb.append("a");
|
|
||||||
}
|
|
||||||
conn.setRequestProperty("longheader", sb.toString());
|
|
||||||
assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void testContentTypes() throws Exception {
|
@Test public void testContentTypes() throws Exception {
|
||||||
|
|
|
@ -49,7 +49,6 @@ public class TestSSLHttpServer extends HttpServerFunctionalTest {
|
||||||
private static final Log LOG = LogFactory.getLog(TestSSLHttpServer.class);
|
private static final Log LOG = LogFactory.getLog(TestSSLHttpServer.class);
|
||||||
private static Configuration conf;
|
private static Configuration conf;
|
||||||
private static HttpServer2 server;
|
private static HttpServer2 server;
|
||||||
private static URL baseUrl;
|
|
||||||
private static String keystoresDir;
|
private static String keystoresDir;
|
||||||
private static String sslConfDir;
|
private static String sslConfDir;
|
||||||
private static SSLFactory clientSslFactory;
|
private static SSLFactory clientSslFactory;
|
||||||
|
@ -85,6 +84,7 @@ public class TestSSLHttpServer extends HttpServerFunctionalTest {
|
||||||
sslConf.get("ssl.server.truststore.password"),
|
sslConf.get("ssl.server.truststore.password"),
|
||||||
sslConf.get("ssl.server.truststore.type", "jks")).build();
|
sslConf.get("ssl.server.truststore.type", "jks")).build();
|
||||||
server.addServlet("echo", "/echo", TestHttpServer.EchoServlet.class);
|
server.addServlet("echo", "/echo", TestHttpServer.EchoServlet.class);
|
||||||
|
server.addServlet("longheader", "/longheader", LongHeaderServlet.class);
|
||||||
server.start();
|
server.start();
|
||||||
baseUrl = new URL("https://"
|
baseUrl = new URL("https://"
|
||||||
+ NetUtils.getHostPortString(server.getConnectorAddress(0)));
|
+ NetUtils.getHostPortString(server.getConnectorAddress(0)));
|
||||||
|
@ -106,6 +106,19 @@ public class TestSSLHttpServer extends HttpServerFunctionalTest {
|
||||||
"/echo?a=b&c<=d&e=>")));
|
"/echo?a=b&c<=d&e=>")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that verifies headers can be up to 64K long.
|
||||||
|
* The test adds a 63K header leaving 1K for other headers.
|
||||||
|
* This is because the header buffer setting is for ALL headers,
|
||||||
|
* names and values included. */
|
||||||
|
@Test
|
||||||
|
public void testLongHeader() throws Exception {
|
||||||
|
URL url = new URL(baseUrl, "/longheader");
|
||||||
|
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
|
||||||
|
conn.setSSLSocketFactory(clientSslFactory.createSSLSocketFactory());
|
||||||
|
testLongHeader(conn);
|
||||||
|
}
|
||||||
|
|
||||||
private static String readOut(URL url) throws Exception {
|
private static String readOut(URL url) throws Exception {
|
||||||
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
|
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
|
||||||
conn.setSSLSocketFactory(clientSslFactory.createSSLSocketFactory());
|
conn.setSSLSocketFactory(clientSslFactory.createSSLSocketFactory());
|
||||||
|
|
Loading…
Reference in New Issue