Repository: ambari
Updated Branches:
  refs/heads/branch-feature-AMBARI-18456 276d1244e -> 087de8b78


AMBARI-18871 HTTP responses needs to have the character encoding specified in 
the content type header (Anita Jebaraj via sangeetar)


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

Branch: refs/heads/branch-feature-AMBARI-18456
Commit: 2cc4c9ed7009be2e894fec7d24c3cb4f0dd9f24c
Parents: 85c9104
Author: Sangeeta Ravindran <sangee...@apache.org>
Authored: Tue Nov 29 13:57:50 2016 -0800
Committer: Sangeeta Ravindran <sangee...@apache.org>
Committed: Tue Nov 29 13:57:50 2016 -0800

----------------------------------------------------------------------
 ambari-server/conf/unix/ambari.properties       |  4 +-
 ambari-server/conf/windows/ambari.properties    |  2 +
 .../server/configuration/Configuration.java     | 46 ++++++++++++++++++++
 .../security/AbstractSecurityHeaderFilter.java  | 14 ++++++
 .../AmbariServerSecurityHeaderFilter.java       |  1 +
 .../AmbariViewsSecurityHeaderFilter.java        |  1 +
 .../AbstractSecurityHeaderFilterTest.java       | 29 ++++++++----
 7 files changed, 87 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/2cc4c9ed/ambari-server/conf/unix/ambari.properties
----------------------------------------------------------------------
diff --git a/ambari-server/conf/unix/ambari.properties 
b/ambari-server/conf/unix/ambari.properties
index 371653f..30a22d1 100644
--- a/ambari-server/conf/unix/ambari.properties
+++ b/ambari-server/conf/unix/ambari.properties
@@ -116,6 +116,7 @@ http.x-frame-options=DENY
 http.x-content-type-options=nosniff
 http.cache-control=no-store
 http.pragma=no-cache
+http.charset=utf-8
 
 # HTTP Header settings for Ambari Views
 views.http.strict-transport-security=max-age=31536000
@@ -124,6 +125,7 @@ views.http.x-frame-options=SAMEORIGIN
 views.http.x-content-type-options=nosniff
 views.http.cache-control=no-store
 views.http.pragma=no-cache
+views.http.charset=utf-8
 
 mpacks.staging.path=$ROOT/var/lib/ambari-server/resources/mpacks
 
@@ -132,4 +134,4 @@ 
security.server.disabled.ciphers=TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384|TLS_ECD
 
 server.python.log.name=ambari-server-command.log
 # server.pyton.log.level=(INFO/DEBUG)
-server.python.log.level=INFO
\ No newline at end of file
+server.python.log.level=INFO

http://git-wip-us.apache.org/repos/asf/ambari/blob/2cc4c9ed/ambari-server/conf/windows/ambari.properties
----------------------------------------------------------------------
diff --git a/ambari-server/conf/windows/ambari.properties 
b/ambari-server/conf/windows/ambari.properties
index e47319e..d84cf4b 100644
--- a/ambari-server/conf/windows/ambari.properties
+++ b/ambari-server/conf/windows/ambari.properties
@@ -97,6 +97,7 @@ http.x-frame-options=DENY
 http.x-content-type-options=nosniff
 http.cache-control=no-store
 http.pragma=no-cache
+http.charset=utf-8
 
 # HTTP Header settings for Ambari Views
 views.http.strict-transport-security=max-age=31536000
@@ -105,5 +106,6 @@ views.http.x-frame-options=SAMEORIGIN
 views.http.x-content-type-options=nosniff
 views.http.cache-control=no-store
 views.http.pragma=no-cache
+views.http.charset=utf-8
 
 mpacks.staging.path=resources\\mpacks

http://git-wip-us.apache.org/repos/asf/ambari/blob/2cc4c9ed/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
index 5676091..9be8751 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
@@ -2290,6 +2290,14 @@ public class Configuration {
   public static final ConfigurationProperty<String> HTTP_PRAGMA_HEADER_VALUE = 
new ConfigurationProperty<>(
       "http.pragma", "no-cache");
 
+   /**
+   * The value that will be used to set the {@code Charset} HTTP response 
header.
+   */
+  @Markdown(description = "The value that will be used to set the Character 
encoding to HTTP response header.")
+  public static final ConfigurationProperty<String> HTTP_CHARSET = new 
ConfigurationProperty<>(
+      "http.charset", "utf-8");
+
+
   /**
    * The value that will be used to set the {@code Strict-Transport-Security}
    * HTTP response header for Ambari View requests.
@@ -2339,6 +2347,14 @@ public class Configuration {
   public static final ConfigurationProperty<String> 
VIEWS_HTTP_PRAGMA_HEADER_VALUE = new ConfigurationProperty<>(
       "views.http.pragma", "no-cache");
 
+   /**
+   * The value that will be used to set the {@code CHARSET} to HTTP response 
header.
+   */
+  @Markdown(description = "The value that will be used to set the Character 
encoding to HTTP response header for Ambari View requests.")
+  public static final ConfigurationProperty<String> VIEWS_HTTP_CHARSET = new 
ConfigurationProperty<>(
+      "views.http.charset", "utf-8");
+
+
   /**
    * The time, in milliseconds, that requests to connect to a URL to retrieve
    * Version Definition Files (VDF) will wait before being terminated.
@@ -3536,6 +3552,21 @@ public class Configuration {
     return getProperty(HTTP_PRAGMA_HEADER_VALUE);
   }
 
+   /**
+   * Get the value that should be set for the <code>Charset</code> HTTP 
response header for Ambari Server UI.
+   * <p/>
+   * By default this will be <code>utf-8</code>. For example:
+   * <p/>
+   * <code>
+   * utf-8
+   * </code>
+   *
+   * @return the Charset value - null or "" indicates that the value is not set
+   */
+  public String getCharsetHTTPResponseHeader() {
+    return getProperty(HTTP_CHARSET);
+  }
+
   /**
    * Get the value that should be set for the 
<code>Strict-Transport-Security</code> HTTP response header for Ambari Views.
    * <p/>
@@ -3629,6 +3660,21 @@ public class Configuration {
   }
 
   /**
+   * Get the value that should be set for the <code>Charset</code> HTTP 
response header for Ambari Views.
+   * <p/>
+   * By default this will be <code>utf-8</code>. For example:
+   * <p/>
+   * <code>
+   * utf-8
+   * </code>
+   *
+   * @return the Charset value - null or "" indicates that the value is not set
+   */
+  public String getViewsCharsetHTTPResponseHeader() {
+    return getProperty(VIEWS_HTTP_CHARSET);
+  }
+
+  /**
    * Check to see if the hostname of the agent is to be validated as a proper 
hostname or not
    *
    * @return true if agent hostnames should be checked as a valid hostnames; 
otherwise false

http://git-wip-us.apache.org/repos/asf/ambari/blob/2cc4c9ed/ambari-server/src/main/java/org/apache/ambari/server/security/AbstractSecurityHeaderFilter.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/security/AbstractSecurityHeaderFilter.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/security/AbstractSecurityHeaderFilter.java
index 423a013..b8631f8 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/security/AbstractSecurityHeaderFilter.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/security/AbstractSecurityHeaderFilter.java
@@ -103,6 +103,11 @@ public abstract class AbstractSecurityHeaderFilter 
implements Filter {
    */
   private String pragmaHeader = 
Configuration.HTTP_PRAGMA_HEADER_VALUE.getDefaultValue();
 
+  /**
+   * The value for the Charset HTTP response header.
+   */
+  private String charset = Configuration.HTTP_CHARSET.getDefaultValue();
+
 
   @Override
   public void init(FilterConfig filterConfig) throws ServletException {
@@ -169,6 +174,10 @@ public abstract class AbstractSecurityHeaderFilter 
implements Filter {
     this.pragmaHeader = pragmaHeader;
   }
 
+  protected void setCharset(String charset) {
+    this.charset = charset;
+  }
+
   private void doFilterInternal(ServletRequest servletRequest, ServletResponse 
servletResponse) {
     if (servletResponse instanceof HttpServletResponse) {
       HttpServletResponse httpServletResponse = (HttpServletResponse) 
servletResponse;
@@ -202,6 +211,11 @@ public abstract class AbstractSecurityHeaderFilter 
implements Filter {
       if (!StringUtils.isEmpty(pragmaHeader)) {
         httpServletResponse.setHeader(PRAGMA_HEADER, pragmaHeader);
       }
+
+      // Conditionally set the Charset HTTP response header if a value is 
supplied
+      if (!StringUtils.isEmpty(charset)) {
+        httpServletResponse.setCharacterEncoding(charset);
+      }
     }
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/2cc4c9ed/ambari-server/src/main/java/org/apache/ambari/server/security/AmbariServerSecurityHeaderFilter.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/security/AmbariServerSecurityHeaderFilter.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/security/AmbariServerSecurityHeaderFilter.java
index aa00ac2..f9dc2aa 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/security/AmbariServerSecurityHeaderFilter.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/security/AmbariServerSecurityHeaderFilter.java
@@ -50,6 +50,7 @@ public class AmbariServerSecurityHeaderFilter extends 
AbstractSecurityHeaderFilt
     setXContentTypeHeader(configuration.getXContentTypeHTTPResponseHeader());
     setCacheControlHeader(configuration.getCacheControlHTTPResponseHeader());
     setPragmaHeader(configuration.getPragmaHTTPResponseHeader());
+    setCharset(configuration.getCharsetHTTPResponseHeader());
   }
 
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/2cc4c9ed/ambari-server/src/main/java/org/apache/ambari/server/security/AmbariViewsSecurityHeaderFilter.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/security/AmbariViewsSecurityHeaderFilter.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/security/AmbariViewsSecurityHeaderFilter.java
index d1be8cc..02fb4b3 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/security/AmbariViewsSecurityHeaderFilter.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/security/AmbariViewsSecurityHeaderFilter.java
@@ -46,5 +46,6 @@ public class AmbariViewsSecurityHeaderFilter extends 
AbstractSecurityHeaderFilte
     
setXContentTypeHeader(configuration.getViewsXContentTypeHTTPResponseHeader());
     
setCacheControlHeader(configuration.getViewsCacheControlHTTPResponseHeader());
     setPragmaHeader(configuration.getViewsPragmaHTTPResponseHeader());
+    setCharset(configuration.getViewsCharsetHTTPResponseHeader());
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/2cc4c9ed/ambari-server/src/test/java/org/apache/ambari/server/security/AbstractSecurityHeaderFilterTest.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/security/AbstractSecurityHeaderFilterTest.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/security/AbstractSecurityHeaderFilterTest.java
index d812ee6..dc97725 100644
--- 
a/ambari-server/src/test/java/org/apache/ambari/server/security/AbstractSecurityHeaderFilterTest.java
+++ 
b/ambari-server/src/test/java/org/apache/ambari/server/security/AbstractSecurityHeaderFilterTest.java
@@ -79,7 +79,7 @@ public abstract class AbstractSecurityHeaderFilterTest 
extends EasyMockSupport {
       protected void configure() {
         Properties properties = new Properties();
         properties.setProperty(Configuration.API_USE_SSL.getKey(), "false");
-
+        properties.setProperty(Configuration.HTTP_CHARSET.getKey(), 
Configuration.HTTP_CHARSET.getDefaultValue());
         bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
         bind(Configuration.class).toInstance(new Configuration(properties));
       }
@@ -101,7 +101,9 @@ public abstract class AbstractSecurityHeaderFilterTest 
extends EasyMockSupport {
     expectLastCall().once();        
     servletResponse.setHeader(AbstractSecurityHeaderFilter.PRAGMA_HEADER, 
defatulPropertyValueMap.get(AbstractSecurityHeaderFilter.PRAGMA_HEADER));
     expectLastCall().once();
-    
+    
servletResponse.setCharacterEncoding(Configuration.HTTP_CHARSET.getDefaultValue());
+    expectLastCall().once();
+
     FilterChain filterChain = createStrictMock(FilterChain.class);
     filterChain.doFilter(servletRequest, servletResponse);
     expectLastCall().once();
@@ -129,7 +131,7 @@ public abstract class AbstractSecurityHeaderFilterTest 
extends EasyMockSupport {
         properties.setProperty(Configuration.API_USE_SSL.getKey(), "true");
         
properties.setProperty(Configuration.CLIENT_API_SSL_KSTR_DIR_NAME.getKey(), 
httpPassFile.getParent());
         
properties.setProperty(Configuration.CLIENT_API_SSL_CRT_PASS_FILE_NAME.getKey(),
 httpPassFile.getName());
-
+        properties.setProperty(Configuration.HTTP_CHARSET.getKey(), 
Configuration.HTTP_CHARSET.getDefaultValue());
         bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
         bind(Configuration.class).toInstance(new Configuration(properties));
       }
@@ -153,7 +155,8 @@ public abstract class AbstractSecurityHeaderFilterTest 
extends EasyMockSupport {
     expectLastCall().once();
     servletResponse.setHeader(AbstractSecurityHeaderFilter.PRAGMA_HEADER, 
defatulPropertyValueMap.get(AbstractSecurityHeaderFilter.PRAGMA_HEADER));
     expectLastCall().once();
-
+    
servletResponse.setCharacterEncoding(Configuration.HTTP_CHARSET.getDefaultValue());
+    expectLastCall().once();
     FilterChain filterChain = createStrictMock(FilterChain.class);
     filterChain.doFilter(servletRequest, servletResponse);
     expectLastCall().once();
@@ -186,7 +189,8 @@ public abstract class AbstractSecurityHeaderFilterTest 
extends EasyMockSupport {
         
properties.setProperty(propertyNameMap.get(AbstractSecurityHeaderFilter.X_CONTENT_TYPE_HEADER),
 "custom4");
         
properties.setProperty(propertyNameMap.get(AbstractSecurityHeaderFilter.CACHE_CONTROL_HEADER),
 "custom5");
         
properties.setProperty(propertyNameMap.get(AbstractSecurityHeaderFilter.PRAGMA_HEADER),
 "custom6");
-
+        properties.setProperty(Configuration.HTTP_CHARSET.getKey(), "custom7");
+        properties.setProperty(Configuration.VIEWS_HTTP_CHARSET.getKey(), 
"custom7");
         bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
         bind(Configuration.class).toInstance(new Configuration(properties));
       }
@@ -208,7 +212,8 @@ public abstract class AbstractSecurityHeaderFilterTest 
extends EasyMockSupport {
     expectLastCall().once();
     servletResponse.setHeader(AbstractSecurityHeaderFilter.PRAGMA_HEADER, 
"custom6");
     expectLastCall().once();
-
+    servletResponse.setCharacterEncoding("custom7");
+    expectLastCall().once();
     FilterChain filterChain = createStrictMock(FilterChain.class);
     filterChain.doFilter(servletRequest, servletResponse);
     expectLastCall().once();
@@ -242,7 +247,8 @@ public abstract class AbstractSecurityHeaderFilterTest 
extends EasyMockSupport {
         
properties.setProperty(propertyNameMap.get(AbstractSecurityHeaderFilter.X_CONTENT_TYPE_HEADER),
 "custom4");
         
properties.setProperty(propertyNameMap.get(AbstractSecurityHeaderFilter.CACHE_CONTROL_HEADER),
 "custom5");
         
properties.setProperty(propertyNameMap.get(AbstractSecurityHeaderFilter.PRAGMA_HEADER),
 "custom6");
-
+        properties.setProperty(Configuration.HTTP_CHARSET.getKey(), "custom7");
+        properties.setProperty(Configuration.VIEWS_HTTP_CHARSET.getKey(), 
"custom7");
         bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
         bind(Configuration.class).toInstance(new Configuration(properties));
       }
@@ -266,7 +272,8 @@ public abstract class AbstractSecurityHeaderFilterTest 
extends EasyMockSupport {
     expectLastCall().once();
     servletResponse.setHeader(AbstractSecurityHeaderFilter.PRAGMA_HEADER, 
"custom6");
     expectLastCall().once();
-
+    servletResponse.setCharacterEncoding("custom7");
+    expectLastCall().once();
     FilterChain filterChain = createStrictMock(FilterChain.class);
     filterChain.doFilter(servletRequest, servletResponse);
     expectLastCall().once();
@@ -293,6 +300,8 @@ public abstract class AbstractSecurityHeaderFilterTest 
extends EasyMockSupport {
         Properties properties = new Properties();
         
properties.setProperty(Configuration.CLIENT_API_SSL_KSTR_DIR_NAME.getKey(), 
httpPassFile.getParent());
         
properties.setProperty(Configuration.CLIENT_API_SSL_CRT_PASS_FILE_NAME.getKey(),
 httpPassFile.getName());
+        properties.setProperty(Configuration.HTTP_CHARSET.getKey(), "");
+        properties.setProperty(Configuration.VIEWS_HTTP_CHARSET.getKey(), "");
         
properties.setProperty(propertyNameMap.get(AbstractSecurityHeaderFilter.STRICT_TRANSPORT_HEADER),
 "");
         
properties.setProperty(propertyNameMap.get(AbstractSecurityHeaderFilter.X_FRAME_OPTIONS_HEADER),
 "");
         
properties.setProperty(propertyNameMap.get(AbstractSecurityHeaderFilter.X_XSS_PROTECTION_HEADER),
 "");
@@ -339,6 +348,8 @@ public abstract class AbstractSecurityHeaderFilterTest 
extends EasyMockSupport {
         properties.setProperty(Configuration.API_USE_SSL.getKey(), "true");
         
properties.setProperty(Configuration.CLIENT_API_SSL_KSTR_DIR_NAME.getKey(), 
httpPassFile.getParent());
         
properties.setProperty(Configuration.CLIENT_API_SSL_CRT_PASS_FILE_NAME.getKey(),
 httpPassFile.getName());
+        properties.setProperty(Configuration.HTTP_CHARSET.getKey(), "");
+        properties.setProperty(Configuration.VIEWS_HTTP_CHARSET.getKey(), "");
         
properties.setProperty(propertyNameMap.get(AbstractSecurityHeaderFilter.STRICT_TRANSPORT_HEADER),
 "");
         
properties.setProperty(propertyNameMap.get(AbstractSecurityHeaderFilter.X_FRAME_OPTIONS_HEADER),
 "");
         
properties.setProperty(propertyNameMap.get(AbstractSecurityHeaderFilter.X_XSS_PROTECTION_HEADER),
 "");
@@ -373,4 +384,4 @@ public abstract class AbstractSecurityHeaderFilterTest 
extends EasyMockSupport {
     verifyAll();
   }
 
-}
\ No newline at end of file
+}

Reply via email to