From d667cd871b423743f77caf29a612d6a9b7c903c8 Mon Sep 17 00:00:00 2001 From: Suresh Srinivas Date: Wed, 7 Mar 2012 20:08:52 +0000 Subject: [PATCH] HADOOP-7729. Merge r1183512 from trunk to 0.23 git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-0.23@1298085 13f79535-47bb-0310-9956-ffa450edef68 --- .../hadoop-common/CHANGES.txt | 3 ++ .../java/org/apache/hadoop/ipc/Server.java | 38 ++++++++++++++++++- .../java/org/apache/hadoop/ipc/TestIPC.java | 6 +++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/hadoop-common-project/hadoop-common/CHANGES.txt b/hadoop-common-project/hadoop-common/CHANGES.txt index 7c27b965846..42272ab1692 100644 --- a/hadoop-common-project/hadoop-common/CHANGES.txt +++ b/hadoop-common-project/hadoop-common/CHANGES.txt @@ -288,6 +288,9 @@ Release 0.23.1 - 2012-02-17 HADOOP-7470. Move up to Jackson 1.8.8. (Enis Soztutar via szetszwo) + HADOOP-7729. Send back valid HTTP response if user hits IPC port with + HTTP GET. (todd) + HADOOP-8027. Visiting /jmx on the daemon web interfaces may print unnecessary error in logs. (atm) diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Server.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Server.java index 80672602896..9ec09cf990e 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Server.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Server.java @@ -110,6 +110,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 @@ -990,6 +1007,7 @@ public abstract class Server { 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(); @@ -1222,7 +1240,7 @@ public abstract class Server { if (count < 0 || dataLengthBuffer.remaining() > 0) return count; } - + if (!rpcHeaderRead) { //Every connection is expected to send the header. if (rpcHeaderBuffer == null) { @@ -1236,7 +1254,16 @@ public abstract class Server { 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 " + @@ -1355,6 +1382,13 @@ public abstract class Server { 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 { diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestIPC.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestIPC.java index e50d6449316..1f3e67a4f9a 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestIPC.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/ipc/TestIPC.java @@ -584,6 +584,12 @@ public class TestIPC { 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 {