5959import org .apache .hadoop .security .authentication .util .RandomSignerSecretProvider ;
6060import org .apache .hadoop .security .authentication .util .SignerSecretProvider ;
6161import org .apache .hadoop .security .authentication .util .ZKSignerSecretProvider ;
62+ import org .apache .hadoop .security .ssl .SSLFactory ;
6263import org .apache .hadoop .security .ssl .SslSelectChannelConnectorSecure ;
6364import org .apache .hadoop .jmx .JMXJsonServlet ;
6465import org .apache .hadoop .log .LogLevel ;
114115public final class HttpServer2 implements FilterContainer {
115116 public static final Log LOG = LogFactory .getLog (HttpServer2 .class );
116117
118+ public static final String HTTP_SCHEME = "http" ;
119+ public static final String HTTPS_SCHEME = "https" ;
120+
117121 static final String FILTER_INITIALIZER_PROPERTY
118122 = "hadoop.http.filter.initializers" ;
119123 public static final String HTTP_MAX_THREADS = "hadoop.http.max.threads" ;
@@ -149,6 +153,7 @@ public static class Builder {
149153 private ArrayList <URI > endpoints = Lists .newArrayList ();
150154 private String name ;
151155 private Configuration conf ;
156+ private Configuration sslConf ;
152157 private String [] pathSpecs ;
153158 private AccessControlList adminsAcl ;
154159 private boolean securityEnabled = false ;
@@ -241,6 +246,15 @@ public Builder setConf(Configuration conf) {
241246 return this ;
242247 }
243248
249+ /**
250+ * Specify the SSL configuration to load. This API provides an alternative
251+ * to keyStore/keyPassword/trustStore.
252+ */
253+ public Builder setSSLConf (Configuration sslCnf ) {
254+ this .sslConf = sslCnf ;
255+ return this ;
256+ }
257+
244258 public Builder setPathSpec (String [] pathSpec ) {
245259 this .pathSpecs = pathSpec ;
246260 return this ;
@@ -281,6 +295,56 @@ public Builder excludeCiphers(String pExcludeCiphers) {
281295 return this ;
282296 }
283297
298+ /**
299+ * A wrapper of {@link Configuration#getPassword(String)}. It returns
300+ * <code>String</code> instead of <code>char[]</code>.
301+ *
302+ * @param conf the configuration
303+ * @param name the property name
304+ * @return the password string or null
305+ */
306+ private static String getPasswordString (Configuration conf , String name )
307+ throws IOException {
308+ char [] passchars = conf .getPassword (name );
309+ if (passchars == null ) {
310+ return null ;
311+ }
312+ return new String (passchars );
313+ }
314+
315+ /**
316+ * Load SSL properties from the SSL configuration.
317+ */
318+ private void loadSSLConfiguration () throws IOException {
319+ if (sslConf == null ) {
320+ return ;
321+ }
322+ needsClientAuth = sslConf .getBoolean (
323+ SSLFactory .SSL_SERVER_NEED_CLIENT_AUTH ,
324+ SSLFactory .SSL_SERVER_NEED_CLIENT_AUTH_DEFAULT );
325+ keyStore = sslConf .getTrimmed (SSLFactory .SSL_SERVER_KEYSTORE_LOCATION );
326+ if (keyStore == null || keyStore .isEmpty ()) {
327+ throw new IOException (String .format ("Property %s not specified" ,
328+ SSLFactory .SSL_SERVER_KEYSTORE_LOCATION ));
329+ }
330+ keyStorePassword = getPasswordString (sslConf ,
331+ SSLFactory .SSL_SERVER_KEYSTORE_PASSWORD );
332+ if (keyStorePassword == null ) {
333+ throw new IOException (String .format ("Property %s not specified" ,
334+ SSLFactory .SSL_SERVER_KEYSTORE_PASSWORD ));
335+ }
336+ keyStoreType = sslConf .get (SSLFactory .SSL_SERVER_KEYSTORE_TYPE ,
337+ SSLFactory .SSL_SERVER_KEYSTORE_TYPE_DEFAULT );
338+ keyPassword = getPasswordString (sslConf ,
339+ SSLFactory .SSL_SERVER_KEYSTORE_KEYPASSWORD );
340+ trustStore = sslConf .get (SSLFactory .SSL_SERVER_TRUSTSTORE_LOCATION );
341+ trustStorePassword = getPasswordString (sslConf ,
342+ SSLFactory .SSL_SERVER_TRUSTSTORE_PASSWORD );
343+ trustStoreType = sslConf .get (SSLFactory .SSL_SERVER_TRUSTSTORE_TYPE ,
344+ SSLFactory .SSL_SERVER_TRUSTSTORE_TYPE_DEFAULT );
345+ excludeCiphers = sslConf .get (SSLFactory .SSL_SERVER_EXCLUDE_CIPHER_LIST );
346+ }
347+
284348 public HttpServer2 build () throws IOException {
285349 Preconditions .checkNotNull (name , "name is not set" );
286350 Preconditions .checkState (!endpoints .isEmpty (), "No endpoints specified" );
@@ -305,6 +369,7 @@ public HttpServer2 build() throws IOException {
305369 if ("http" .equals (scheme )) {
306370 listener = HttpServer2 .createDefaultChannelConnector ();
307371 } else if ("https" .equals (scheme )) {
372+ loadSSLConfiguration ();
308373 listener = createHttpsChannelConnector ();
309374
310375 } else {
0 commit comments