diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/qjournal/server/JournalNodeHttpServer.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/qjournal/server/JournalNodeHttpServer.java index 1d29c1beb3..4f51fe8b50 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/qjournal/server/JournalNodeHttpServer.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/qjournal/server/JournalNodeHttpServer.java @@ -78,6 +78,16 @@ void start() throws IOException { DFSConfigKeys.DFS_JOURNALNODE_KERBEROS_INTERNAL_SPNEGO_PRINCIPAL_KEY, DFSConfigKeys.DFS_JOURNALNODE_KEYTAB_FILE_KEY); + final boolean xFrameEnabled = conf.getBoolean( + DFSConfigKeys.DFS_XFRAME_OPTION_ENABLED, + DFSConfigKeys.DFS_XFRAME_OPTION_ENABLED_DEFAULT); + + final String xFrameOptionValue = conf.getTrimmed( + DFSConfigKeys.DFS_XFRAME_OPTION_VALUE, + DFSConfigKeys.DFS_XFRAME_OPTION_VALUE_DEFAULT); + + builder.configureXFrame(xFrameEnabled).setXFrameOption(xFrameOptionValue); + httpServer = builder.build(); httpServer.setAttribute(JN_ATTRIBUTE_KEY, localJournalNode); httpServer.setAttribute(JspHelper.CURRENT_CONF, conf); diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/qjournal/server/TestJournalNodeHttpServerXFrame.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/qjournal/server/TestJournalNodeHttpServerXFrame.java new file mode 100644 index 0000000000..c870fcceef --- /dev/null +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/qjournal/server/TestJournalNodeHttpServerXFrame.java @@ -0,0 +1,86 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *
+ * http://www.apache.org/licenses/LICENSE-2.0 + *
+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package org.apache.hadoop.hdfs.qjournal.server; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Test; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hdfs.DFSConfigKeys; +import org.apache.hadoop.hdfs.qjournal.MiniJournalCluster; +import org.apache.hadoop.http.HttpServer2; + +/** + * Test that X-Frame-Options works correctly with JournalNodeHttpServer. + */ +public class TestJournalNodeHttpServerXFrame { + + private static final int NUM_JN = 1; + + private MiniJournalCluster cluster; + + @Test + public void testJournalNodeXFrameOptionsEnabled() throws Exception { + boolean xFrameEnabled = true; + cluster = createCluster(xFrameEnabled); + HttpURLConnection conn = getConn(cluster); + String xfoHeader = conn.getHeaderField("X-FRAME-OPTIONS"); + Assert.assertTrue("X-FRAME-OPTIONS is absent in the header", xfoHeader != null); + Assert.assertTrue(xfoHeader.endsWith(HttpServer2.XFrameOption.SAMEORIGIN.toString())); + } + + @Test + public void testJournalNodeXFrameOptionsDisabled() throws Exception { + boolean xFrameEnabled = false; + cluster = createCluster(xFrameEnabled); + HttpURLConnection conn = getConn(cluster); + String xfoHeader = conn.getHeaderField("X-FRAME-OPTIONS"); + System.out.println(xfoHeader); + Assert.assertTrue("unexpected X-FRAME-OPTION in header", xfoHeader == null); + } + + @After + public void cleanup() throws IOException { + if (cluster != null) { + cluster.shutdown(); + cluster = null; + } + } + + private static MiniJournalCluster createCluster(boolean enabled) throws IOException { + Configuration conf = new Configuration(); + conf.setBoolean(DFSConfigKeys.DFS_XFRAME_OPTION_ENABLED, enabled); + MiniJournalCluster jCluster = + new MiniJournalCluster.Builder(conf).format(true).numJournalNodes(NUM_JN).build(); + jCluster.waitActive(); + return jCluster; + } + + private static HttpURLConnection getConn(MiniJournalCluster journalCluster) throws IOException { + JournalNode journalNode = journalCluster.getJournalNode(0); + URL newURL = new URL(journalNode.getHttpServerURI()); + HttpURLConnection conn = (HttpURLConnection) newURL.openConnection(); + conn.connect(); + return conn; + } +} \ No newline at end of file