tez-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From s...@apache.org
Subject tez git commit: TEZ-3575. RM have started forwarding origin. Use that in AMWebController for CORS support (sree)
Date Wed, 25 Jan 2017 16:15:13 GMT
Repository: tez
Updated Branches:
  refs/heads/master abab52694 -> d227b99a4


TEZ-3575. RM have started forwarding origin. Use that in AMWebController for CORS support
(sree)


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/d227b99a
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/d227b99a
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/d227b99a

Branch: refs/heads/master
Commit: d227b99a493f7dc48f73bafb4b409f735dc65ced
Parents: abab526
Author: Sreenath Somarajapuram <sree@apache.org>
Authored: Wed Jan 25 21:45:27 2017 +0530
Committer: Sreenath Somarajapuram <sree@apache.org>
Committed: Wed Jan 25 21:45:27 2017 +0530

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../apache/tez/dag/app/web/AMWebController.java | 32 +++++++++++++----
 .../tez/dag/app/web/TestAMWebController.java    | 38 ++++++++++++++++++++
 3 files changed, 64 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/d227b99a/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 8170d10..4d43bca 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -176,6 +176,7 @@ ALL CHANGES:
   TEZ-2712. Tez UI: Display the vertex description in the tooltip of vertex in DAG view UI
   TEZ-3583. Tez UI: UTs are flaky because of a dependency issue
   TEZ-3580. Tez UI: Pagination broken on queries page
+  TEZ-3575. RM have started forwarding origin. Use that in AMWebController for CORS support
 
 Release 0.8.5: Unreleased
 

http://git-wip-us.apache.org/repos/asf/tez/blob/d227b99a/tez-dag/src/main/java/org/apache/tez/dag/app/web/AMWebController.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/main/java/org/apache/tez/dag/app/web/AMWebController.java b/tez-dag/src/main/java/org/apache/tez/dag/app/web/AMWebController.java
index 54706ec..2115dac 100644
--- a/tez-dag/src/main/java/org/apache/tez/dag/app/web/AMWebController.java
+++ b/tez-dag/src/main/java/org/apache/tez/dag/app/web/AMWebController.java
@@ -41,6 +41,7 @@ import com.google.common.collect.Sets;
 import com.google.inject.Inject;
 import com.google.inject.name.Named;
 
+import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.tez.common.counters.CounterGroup;
 import org.apache.tez.common.counters.LimitExceededException;
 import org.apache.tez.common.counters.TezCounter;
@@ -67,6 +68,9 @@ public class AMWebController extends Controller {
 
   private final static Logger LOG = LoggerFactory.getLogger(AMWebController.class);
 
+  // HTTP CORS Request Headers
+  static final String ORIGIN = "Origin";
+
   // HTTP CORS Response Headers
   static final String ACCESS_CONTROL_ALLOW_ORIGIN = "Access-Control-Allow-Origin";
   static final String ACCESS_CONTROL_ALLOW_CREDENTIALS = "Access-Control-Allow-Credentials";
@@ -114,6 +118,17 @@ public class AMWebController extends Controller {
     renderJSON("Tez AM UI WebServices");
   }
 
+  static String encodeHeader(final String header) {
+    if (header == null) {
+      return null;
+    }
+    // Protect against HTTP response splitting vulnerability
+    // since value is written as part of the response header
+    // Ensure this header only has one header by removing
+    // CRs and LFs
+    return header.split("\n|\r")[0].trim();
+  }
+
   @VisibleForTesting
   public void setCorsHeaders() {
     final HttpServletResponse res = response();
@@ -123,17 +138,20 @@ public class AMWebController extends Controller {
      * if it matches the allowed origins. however rm does not forward these headers.
      */
     String historyUrlBase = appContext.getAMConf().get(TezConfiguration.TEZ_HISTORY_URL_BASE,
"");
-    String origin = null;
-    try {
-      URL url = new URL(historyUrlBase);
-      origin = url.getProtocol() + "://" + url.getAuthority();
-    } catch (MalformedURLException e) {
-      if (LOG.isDebugEnabled()) {
-        LOG.debug("Invalid url set for tez history url base: " + historyUrlBase, e);
+    String origin = request().getHeader(ORIGIN);
+    if(origin == null) {
+      try {
+        URL url = new URL(historyUrlBase);
+        origin = url.getProtocol() + "://" + url.getAuthority();
+      } catch (MalformedURLException e) {
+        if (LOG.isDebugEnabled()) {
+          LOG.debug("Invalid url set for tez history url base: " + historyUrlBase, e);
+        }
       }
     }
 
     if (origin != null) {
+      origin = encodeHeader(origin);
       res.setHeader(ACCESS_CONTROL_ALLOW_ORIGIN, origin);
     }
     res.setHeader(ACCESS_CONTROL_ALLOW_METHODS, ALLOWED_METHODS);

http://git-wip-us.apache.org/repos/asf/tez/blob/d227b99a/tez-dag/src/test/java/org/apache/tez/dag/app/web/TestAMWebController.java
----------------------------------------------------------------------
diff --git a/tez-dag/src/test/java/org/apache/tez/dag/app/web/TestAMWebController.java b/tez-dag/src/test/java/org/apache/tez/dag/app/web/TestAMWebController.java
index 8561c8c..16b391b 100644
--- a/tez-dag/src/test/java/org/apache/tez/dag/app/web/TestAMWebController.java
+++ b/tez-dag/src/test/java/org/apache/tez/dag/app/web/TestAMWebController.java
@@ -92,11 +92,49 @@ public class TestAMWebController {
     mockRequest = mock(HttpServletRequest.class);
   }
 
+  @Test
+  public void testEncodeHeaders() {
+    String validOrigin = "http://localhost:12345";
+    String encodedValidOrigin = AMWebController.encodeHeader(validOrigin);
+    Assert.assertEquals("Valid origin encoding should match exactly",
+        validOrigin, encodedValidOrigin);
+
+    String httpResponseSplitOrigin = validOrigin + " \nSecondHeader: value";
+    String encodedResponseSplitOrigin =
+        AMWebController.encodeHeader(httpResponseSplitOrigin);
+    Assert.assertEquals("Http response split origin should be protected against",
+        validOrigin, encodedResponseSplitOrigin);
+
+    // Test Origin List
+    String validOriginList = "http://foo.example.com:12345 http://bar.example.com:12345";
+    String encodedValidOriginList = AMWebController
+        .encodeHeader(validOriginList);
+    Assert.assertEquals("Valid origin list encoding should match exactly",
+        validOriginList, encodedValidOriginList);
+  }
+
+  @Test(timeout = 5000)
+  public void testCorsHeadersWithOrigin() {
+    AMWebController amWebController = new AMWebController(mockRequestContext, mockAppContext,
+        "TEST_HISTORY_URL");
+    AMWebController spy = spy(amWebController);
+    String originURL = "http://origin.com:8080";
+
+    doReturn(mockResponse).when(spy).response();
+
+    doReturn(mockRequest).when(spy).request();
+    doReturn(originURL).when(mockRequest).getHeader(AMWebController.ORIGIN);
+
+    spy.setCorsHeaders();
+    verify(mockResponse).setHeader("Access-Control-Allow-Origin", originURL);
+  }
+
   @Test(timeout = 5000)
   public void testCorsHeadersAreSet() {
     AMWebController amWebController = new AMWebController(mockRequestContext, mockAppContext,
         "TEST_HISTORY_URL");
     AMWebController spy = spy(amWebController);
+    doReturn(mockRequest).when(spy).request();
     doReturn(mockResponse).when(spy).response();
     spy.setCorsHeaders();
 


Mime
View raw message