HADOOP-7729. Send back valid HTTP response if user hits IPC port with HTTP GET. Contributed by Todd Lipcon.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1183512 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Todd Lipcon 2011-10-14 21:44:35 +00:00
parent 4cb7a4854d
commit a11f67fb78
3 changed files with 45 additions and 2 deletions

View File

@ -50,6 +50,9 @@ Trunk (unreleased changes)
HADOOP-7743. Add Maven profile to create a full source tarball. (tucu)
HADOOP-7729. Send back valid HTTP response if user hits IPC port with
HTTP GET. (todd)
BUGS
HADOOP-7606. Upgrade Jackson to version 1.7.1 to match the version required

View File

@ -102,6 +102,23 @@ public abstract class Server {
*/
public static final ByteBuffer HEADER = ByteBuffer.wrap("hrpc".getBytes());
/**
* If the user accidentally sends an HTTP GET to an IPC port, we detect this
* and send back a nicer response.
*/
private static final ByteBuffer HTTP_GET_BYTES = ByteBuffer.wrap(
"GET ".getBytes());
/**
* An HTTP response to send back if we detect an HTTP request to our IPC
* port.
*/
static final String RECEIVED_HTTP_REQ_RESPONSE =
"HTTP/1.1 404 Not Found\r\n" +
"Content-type: text/plain\r\n\r\n" +
"It looks like you are making an HTTP request to a Hadoop IPC port. " +
"This is not the correct port for the web interface on this daemon.\r\n";
// 1 : Introduce ping and server does not throw away RPCs
// 3 : Introduce the protocol into the RPC connection header
// 4 : Introduced SASL security layer
@ -910,6 +927,7 @@ public class Connection {
private ByteArrayOutputStream authFailedResponse = new ByteArrayOutputStream();
// Fake 'call' for SASL context setup
private static final int SASL_CALLID = -33;
private final Call saslCall = new Call(SASL_CALLID, null, this);
private final ByteArrayOutputStream saslResponse = new ByteArrayOutputStream();
@ -1142,7 +1160,7 @@ public int readAndProcess() throws IOException, InterruptedException {
if (count < 0 || dataLengthBuffer.remaining() > 0)
return count;
}
if (!rpcHeaderRead) {
//Every connection is expected to send the header.
if (rpcHeaderBuffer == null) {
@ -1156,7 +1174,16 @@ public int readAndProcess() throws IOException, InterruptedException {
byte[] method = new byte[] {rpcHeaderBuffer.get(1)};
authMethod = AuthMethod.read(new DataInputStream(
new ByteArrayInputStream(method)));
dataLengthBuffer.flip();
dataLengthBuffer.flip();
// Check if it looks like the user is hitting an IPC port
// with an HTTP GET - this is a common error, so we can
// send back a simple string indicating as much.
if (HTTP_GET_BYTES.equals(dataLengthBuffer)) {
setupHttpRequestOnIpcPortResponse();
return -1;
}
if (!HEADER.equals(dataLengthBuffer) || version != CURRENT_VERSION) {
//Warning is ok since this is not supposed to happen.
LOG.warn("Incorrect header or version mismatch from " +
@ -1275,6 +1302,13 @@ private void setupBadVersionResponse(int clientVersion) throws IOException {
responder.doRespond(fakeCall);
}
}
private void setupHttpRequestOnIpcPortResponse() throws IOException {
Call fakeCall = new Call(0, null, this);
fakeCall.setResponse(ByteBuffer.wrap(
RECEIVED_HTTP_REQ_RESPONSE.getBytes()));
responder.doRespond(fakeCall);
}
/// Reads the connection header following version
private void processHeader(byte[] buf) throws IOException {

View File

@ -583,6 +583,12 @@ public void testIpcFromHadoop0_21_0() throws Exception {
NetworkTraces.RESPONSE_TO_HADOOP_0_21_0_RPC);
}
@Test
public void testHttpGetResponse() throws Exception {
doIpcVersionTest("GET / HTTP/1.0\r\n\r\n".getBytes(),
Server.RECEIVED_HTTP_REQ_RESPONSE.getBytes());
}
private void doIpcVersionTest(
byte[] requestData,
byte[] expectedResponse) throws Exception {