|
@@ -1,4 +1,4 @@
|
|
-/**
|
|
|
|
|
|
+/*
|
|
* Licensed to the Apache Software Foundation (ASF) under one
|
|
* Licensed to the Apache Software Foundation (ASF) under one
|
|
* or more contributor license agreements. See the NOTICE file
|
|
* or more contributor license agreements. See the NOTICE file
|
|
* distributed with this work for additional information
|
|
* distributed with this work for additional information
|
|
@@ -17,18 +17,10 @@
|
|
*/
|
|
*/
|
|
package org.apache.hadoop.hdfs.server.datanode.web;
|
|
package org.apache.hadoop.hdfs.server.datanode.web;
|
|
|
|
|
|
-import static org.apache.hadoop.hdfs.client.HdfsClientConfigKeys.DFS_WEBHDFS_REST_CSRF_ENABLED_DEFAULT;
|
|
|
|
-import static org.apache.hadoop.hdfs.client.HdfsClientConfigKeys.DFS_WEBHDFS_REST_CSRF_ENABLED_KEY;
|
|
|
|
-
|
|
|
|
-import java.util.Enumeration;
|
|
|
|
-import java.util.Map;
|
|
|
|
-import javax.servlet.FilterConfig;
|
|
|
|
-import javax.servlet.ServletContext;
|
|
|
|
-import javax.servlet.ServletException;
|
|
|
|
-
|
|
|
|
import io.netty.bootstrap.ChannelFactory;
|
|
import io.netty.bootstrap.ChannelFactory;
|
|
import io.netty.bootstrap.ServerBootstrap;
|
|
import io.netty.bootstrap.ServerBootstrap;
|
|
import io.netty.channel.ChannelFuture;
|
|
import io.netty.channel.ChannelFuture;
|
|
|
|
+import io.netty.channel.ChannelHandler;
|
|
import io.netty.channel.ChannelInitializer;
|
|
import io.netty.channel.ChannelInitializer;
|
|
import io.netty.channel.ChannelOption;
|
|
import io.netty.channel.ChannelOption;
|
|
import io.netty.channel.ChannelPipeline;
|
|
import io.netty.channel.ChannelPipeline;
|
|
@@ -40,9 +32,6 @@ import io.netty.handler.codec.http.HttpRequestDecoder;
|
|
import io.netty.handler.codec.http.HttpResponseEncoder;
|
|
import io.netty.handler.codec.http.HttpResponseEncoder;
|
|
import io.netty.handler.ssl.SslHandler;
|
|
import io.netty.handler.ssl.SslHandler;
|
|
import io.netty.handler.stream.ChunkedWriteHandler;
|
|
import io.netty.handler.stream.ChunkedWriteHandler;
|
|
-
|
|
|
|
-import org.slf4j.Logger;
|
|
|
|
-import org.slf4j.LoggerFactory;
|
|
|
|
import org.apache.hadoop.conf.Configuration;
|
|
import org.apache.hadoop.conf.Configuration;
|
|
import org.apache.hadoop.fs.permission.FsPermission;
|
|
import org.apache.hadoop.fs.permission.FsPermission;
|
|
import org.apache.hadoop.hdfs.DFSConfigKeys;
|
|
import org.apache.hadoop.hdfs.DFSConfigKeys;
|
|
@@ -55,11 +44,17 @@ import org.apache.hadoop.http.HttpConfig;
|
|
import org.apache.hadoop.http.HttpServer2;
|
|
import org.apache.hadoop.http.HttpServer2;
|
|
import org.apache.hadoop.net.NetUtils;
|
|
import org.apache.hadoop.net.NetUtils;
|
|
import org.apache.hadoop.security.authorize.AccessControlList;
|
|
import org.apache.hadoop.security.authorize.AccessControlList;
|
|
-import org.apache.hadoop.security.http.RestCsrfPreventionFilter;
|
|
|
|
import org.apache.hadoop.security.ssl.SSLFactory;
|
|
import org.apache.hadoop.security.ssl.SSLFactory;
|
|
|
|
+import org.slf4j.Logger;
|
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
|
|
|
|
|
+import javax.servlet.FilterConfig;
|
|
|
|
+import javax.servlet.ServletContext;
|
|
import java.io.Closeable;
|
|
import java.io.Closeable;
|
|
import java.io.IOException;
|
|
import java.io.IOException;
|
|
|
|
+import java.lang.reflect.Constructor;
|
|
|
|
+import java.lang.reflect.InvocationTargetException;
|
|
|
|
+import java.lang.reflect.Method;
|
|
import java.net.BindException;
|
|
import java.net.BindException;
|
|
import java.net.InetSocketAddress;
|
|
import java.net.InetSocketAddress;
|
|
import java.net.SocketAddress;
|
|
import java.net.SocketAddress;
|
|
@@ -67,6 +62,9 @@ import java.net.SocketException;
|
|
import java.net.URI;
|
|
import java.net.URI;
|
|
import java.nio.channels.ServerSocketChannel;
|
|
import java.nio.channels.ServerSocketChannel;
|
|
import java.security.GeneralSecurityException;
|
|
import java.security.GeneralSecurityException;
|
|
|
|
+import java.util.Enumeration;
|
|
|
|
+import java.util.Map;
|
|
|
|
+import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
|
|
import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_ADMIN;
|
|
import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_ADMIN;
|
|
import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_DATANODE_HTTPS_ADDRESS_DEFAULT;
|
|
import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_DATANODE_HTTPS_ADDRESS_DEFAULT;
|
|
@@ -74,7 +72,19 @@ import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_DATANODE_HTTPS_ADDRESS_KE
|
|
import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_DATANODE_HTTP_ADDRESS_KEY;
|
|
import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_DATANODE_HTTP_ADDRESS_KEY;
|
|
import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_DATANODE_HTTP_INTERNAL_PROXY_PORT;
|
|
import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_DATANODE_HTTP_INTERNAL_PROXY_PORT;
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * Data node HTTP Server Class.
|
|
|
|
+ */
|
|
public class DatanodeHttpServer implements Closeable {
|
|
public class DatanodeHttpServer implements Closeable {
|
|
|
|
+ static final Logger LOG = LoggerFactory.getLogger(DatanodeHttpServer.class);
|
|
|
|
+ private static final ConcurrentHashMap<Class<?>, Object> HANDLER_STATE
|
|
|
|
+ = new ConcurrentHashMap<Class<?>, Object>() {};
|
|
|
|
+ // HttpServer threads are only used for the web UI and basic servlets, so
|
|
|
|
+ // set them to the minimum possible
|
|
|
|
+ private static final int HTTP_SELECTOR_THREADS = 1;
|
|
|
|
+ private static final int HTTP_ACCEPTOR_THREADS = 1;
|
|
|
|
+ private static final int HTTP_MAX_THREADS =
|
|
|
|
+ HTTP_SELECTOR_THREADS + HTTP_ACCEPTOR_THREADS + 1;
|
|
private final HttpServer2 infoServer;
|
|
private final HttpServer2 infoServer;
|
|
private final EventLoopGroup bossGroup;
|
|
private final EventLoopGroup bossGroup;
|
|
private final EventLoopGroup workerGroup;
|
|
private final EventLoopGroup workerGroup;
|
|
@@ -84,23 +94,13 @@ public class DatanodeHttpServer implements Closeable {
|
|
private final ServerBootstrap httpsServer;
|
|
private final ServerBootstrap httpsServer;
|
|
private final Configuration conf;
|
|
private final Configuration conf;
|
|
private final Configuration confForCreate;
|
|
private final Configuration confForCreate;
|
|
- private final RestCsrfPreventionFilter restCsrfPreventionFilter;
|
|
|
|
private InetSocketAddress httpAddress;
|
|
private InetSocketAddress httpAddress;
|
|
private InetSocketAddress httpsAddress;
|
|
private InetSocketAddress httpsAddress;
|
|
- static final Logger LOG = LoggerFactory.getLogger(DatanodeHttpServer.class);
|
|
|
|
-
|
|
|
|
- // HttpServer threads are only used for the web UI and basic servlets, so
|
|
|
|
- // set them to the minimum possible
|
|
|
|
- private static final int HTTP_SELECTOR_THREADS = 1;
|
|
|
|
- private static final int HTTP_ACCEPTOR_THREADS = 1;
|
|
|
|
- private static final int HTTP_MAX_THREADS =
|
|
|
|
- HTTP_SELECTOR_THREADS + HTTP_ACCEPTOR_THREADS + 1;
|
|
|
|
|
|
|
|
public DatanodeHttpServer(final Configuration conf,
|
|
public DatanodeHttpServer(final Configuration conf,
|
|
- final DataNode datanode,
|
|
|
|
- final ServerSocketChannel externalHttpChannel)
|
|
|
|
- throws IOException {
|
|
|
|
- this.restCsrfPreventionFilter = createRestCsrfPreventionFilter(conf);
|
|
|
|
|
|
+ final DataNode datanode,
|
|
|
|
+ final ServerSocketChannel externalHttpChannel)
|
|
|
|
+ throws IOException {
|
|
this.conf = conf;
|
|
this.conf = conf;
|
|
|
|
|
|
Configuration confForInfoServer = new Configuration(conf);
|
|
Configuration confForInfoServer = new Configuration(conf);
|
|
@@ -136,7 +136,7 @@ public class DatanodeHttpServer implements Closeable {
|
|
this.infoServer.setAttribute("datanode", datanode);
|
|
this.infoServer.setAttribute("datanode", datanode);
|
|
this.infoServer.setAttribute(JspHelper.CURRENT_CONF, conf);
|
|
this.infoServer.setAttribute(JspHelper.CURRENT_CONF, conf);
|
|
this.infoServer.addServlet(null, "/blockScannerReport",
|
|
this.infoServer.addServlet(null, "/blockScannerReport",
|
|
- BlockScanner.Servlet.class);
|
|
|
|
|
|
+ BlockScanner.Servlet.class);
|
|
DataNodeUGIProvider.init(conf);
|
|
DataNodeUGIProvider.init(conf);
|
|
this.infoServer.start();
|
|
this.infoServer.start();
|
|
final InetSocketAddress jettyAddr = infoServer.getConnectorAddress(0);
|
|
final InetSocketAddress jettyAddr = infoServer.getConnectorAddress(0);
|
|
@@ -148,24 +148,26 @@ public class DatanodeHttpServer implements Closeable {
|
|
this.workerGroup = new NioEventLoopGroup();
|
|
this.workerGroup = new NioEventLoopGroup();
|
|
this.externalHttpChannel = externalHttpChannel;
|
|
this.externalHttpChannel = externalHttpChannel;
|
|
HttpConfig.Policy policy = DFSUtil.getHttpPolicy(conf);
|
|
HttpConfig.Policy policy = DFSUtil.getHttpPolicy(conf);
|
|
|
|
+ final ChannelHandler[] handlers = getFilterHandlers(conf);
|
|
|
|
|
|
if (policy.isHttpEnabled()) {
|
|
if (policy.isHttpEnabled()) {
|
|
this.httpServer = new ServerBootstrap().group(bossGroup, workerGroup)
|
|
this.httpServer = new ServerBootstrap().group(bossGroup, workerGroup)
|
|
- .childHandler(new ChannelInitializer<SocketChannel>() {
|
|
|
|
- @Override
|
|
|
|
- protected void initChannel(SocketChannel ch) throws Exception {
|
|
|
|
- ChannelPipeline p = ch.pipeline();
|
|
|
|
- p.addLast(new HttpRequestDecoder(),
|
|
|
|
- new HttpResponseEncoder());
|
|
|
|
- if (restCsrfPreventionFilter != null) {
|
|
|
|
- p.addLast(new RestCsrfPreventionFilterHandler(
|
|
|
|
- restCsrfPreventionFilter));
|
|
|
|
- }
|
|
|
|
- p.addLast(
|
|
|
|
- new ChunkedWriteHandler(),
|
|
|
|
- new URLDispatcher(jettyAddr, conf, confForCreate));
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
|
|
+ .childHandler(new ChannelInitializer<SocketChannel>() {
|
|
|
|
+ @Override
|
|
|
|
+ protected void initChannel(SocketChannel ch) throws Exception {
|
|
|
|
+ ChannelPipeline p = ch.pipeline();
|
|
|
|
+ p.addLast(new HttpRequestDecoder(),
|
|
|
|
+ new HttpResponseEncoder());
|
|
|
|
+ if (handlers != null) {
|
|
|
|
+ for (ChannelHandler c : handlers) {
|
|
|
|
+ p.addLast(c);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ p.addLast(
|
|
|
|
+ new ChunkedWriteHandler(),
|
|
|
|
+ new URLDispatcher(jettyAddr, conf, confForCreate));
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
|
|
this.httpServer.childOption(
|
|
this.httpServer.childOption(
|
|
ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK,
|
|
ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK,
|
|
@@ -188,7 +190,9 @@ public class DatanodeHttpServer implements Closeable {
|
|
// The channel has been bounded externally via JSVC,
|
|
// The channel has been bounded externally via JSVC,
|
|
// thus bind() becomes a no-op.
|
|
// thus bind() becomes a no-op.
|
|
@Override
|
|
@Override
|
|
- protected void doBind(SocketAddress localAddress) throws Exception {}
|
|
|
|
|
|
+ protected void doBind(SocketAddress localAddress)
|
|
|
|
+ throws Exception {
|
|
|
|
+ }
|
|
};
|
|
};
|
|
}
|
|
}
|
|
});
|
|
});
|
|
@@ -205,30 +209,92 @@ public class DatanodeHttpServer implements Closeable {
|
|
throw new IOException(e);
|
|
throw new IOException(e);
|
|
}
|
|
}
|
|
this.httpsServer = new ServerBootstrap().group(bossGroup, workerGroup)
|
|
this.httpsServer = new ServerBootstrap().group(bossGroup, workerGroup)
|
|
- .channel(NioServerSocketChannel.class)
|
|
|
|
- .childHandler(new ChannelInitializer<SocketChannel>() {
|
|
|
|
- @Override
|
|
|
|
- protected void initChannel(SocketChannel ch) throws Exception {
|
|
|
|
- ChannelPipeline p = ch.pipeline();
|
|
|
|
- p.addLast(
|
|
|
|
- new SslHandler(sslFactory.createSSLEngine()),
|
|
|
|
- new HttpRequestDecoder(),
|
|
|
|
- new HttpResponseEncoder());
|
|
|
|
- if (restCsrfPreventionFilter != null) {
|
|
|
|
- p.addLast(new RestCsrfPreventionFilterHandler(
|
|
|
|
- restCsrfPreventionFilter));
|
|
|
|
|
|
+ .channel(NioServerSocketChannel.class)
|
|
|
|
+ .childHandler(new ChannelInitializer<SocketChannel>() {
|
|
|
|
+ @Override
|
|
|
|
+ protected void initChannel(SocketChannel ch) throws Exception {
|
|
|
|
+ ChannelPipeline p = ch.pipeline();
|
|
|
|
+ p.addLast(
|
|
|
|
+ new SslHandler(sslFactory.createSSLEngine()),
|
|
|
|
+ new HttpRequestDecoder(),
|
|
|
|
+ new HttpResponseEncoder());
|
|
|
|
+ if (handlers != null) {
|
|
|
|
+ for (ChannelHandler c : handlers) {
|
|
|
|
+ p.addLast(c);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ p.addLast(
|
|
|
|
+ new ChunkedWriteHandler(),
|
|
|
|
+ new URLDispatcher(jettyAddr, conf, confForCreate));
|
|
}
|
|
}
|
|
- p.addLast(
|
|
|
|
- new ChunkedWriteHandler(),
|
|
|
|
- new URLDispatcher(jettyAddr, conf, confForCreate));
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
|
|
+ });
|
|
} else {
|
|
} else {
|
|
this.httpsServer = null;
|
|
this.httpsServer = null;
|
|
this.sslFactory = null;
|
|
this.sslFactory = null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ private static String getHostnameForSpnegoPrincipal(Configuration conf) {
|
|
|
|
+ String addr = conf.getTrimmed(DFS_DATANODE_HTTP_ADDRESS_KEY, null);
|
|
|
|
+ if (addr == null) {
|
|
|
|
+ addr = conf.getTrimmed(DFS_DATANODE_HTTPS_ADDRESS_KEY,
|
|
|
|
+ DFS_DATANODE_HTTPS_ADDRESS_DEFAULT);
|
|
|
|
+ }
|
|
|
|
+ InetSocketAddress inetSocker = NetUtils.createSocketAddr(addr);
|
|
|
|
+ return inetSocker.getHostString();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Get an array of ChannelHandlers specified in the conf
|
|
|
|
+ * @param conf configuration to read and pass
|
|
|
|
+ * @return array of ChannelHandlers ready to be used
|
|
|
|
+ * @throws NoSuchMethodException if the handler does not implement a method
|
|
|
|
+ * initializeState(conf)
|
|
|
|
+ * @throws InvocationTargetException if the handler's initalizeState method
|
|
|
|
+ * raises an exception
|
|
|
|
+ */
|
|
|
|
+ private ChannelHandler[] getFilterHandlers(Configuration configuration) {
|
|
|
|
+ if (configuration == null) {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ // If the hdfs-site.xml has the proper configs for filter classes, use them.
|
|
|
|
+ Class<?>[] classes =
|
|
|
|
+ configuration.getClasses(
|
|
|
|
+ DFSConfigKeys.DFS_DATANODE_HTTPSERVER_FILTER_HANDLERS);
|
|
|
|
+
|
|
|
|
+ // else use the hard coded class from the default configuration.
|
|
|
|
+ if (classes == null) {
|
|
|
|
+ classes =
|
|
|
|
+ configuration.getClasses(
|
|
|
|
+ DFSConfigKeys.DFS_DATANODE_HTTPSERVER_FILTER_HANDLERS_DEFAULT);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // if we are not able to find any handlers, let us fail since running
|
|
|
|
+ // with Csrf will is a security hole. Let us abort the startup.
|
|
|
|
+ if(classes == null) {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ChannelHandler[] handlers = new ChannelHandler[classes.length];
|
|
|
|
+ for (int i = 0; i < classes.length; i++) {
|
|
|
|
+ LOG.debug("Loading filter handler {}", classes[i].getName());
|
|
|
|
+ try {
|
|
|
|
+ Method initializeState = classes[i].getDeclaredMethod("initializeState",
|
|
|
|
+ Configuration.class);
|
|
|
|
+ Constructor constructor =
|
|
|
|
+ classes[i].getDeclaredConstructor(initializeState.getReturnType());
|
|
|
|
+ handlers[i] = (ChannelHandler) constructor.newInstance(
|
|
|
|
+ HANDLER_STATE.getOrDefault(classes[i],
|
|
|
|
+ initializeState.invoke(null, configuration)));
|
|
|
|
+ } catch (NoSuchMethodException | InvocationTargetException
|
|
|
|
+ | IllegalAccessException | InstantiationException
|
|
|
|
+ | IllegalArgumentException e) {
|
|
|
|
+ LOG.error("Failed to initialize handler {}", classes[i].toString());
|
|
|
|
+ throw new RuntimeException(e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return (handlers);
|
|
|
|
+ }
|
|
|
|
+
|
|
public InetSocketAddress getHttpAddress() {
|
|
public InetSocketAddress getHttpAddress() {
|
|
return httpAddress;
|
|
return httpAddress;
|
|
}
|
|
}
|
|
@@ -294,55 +360,21 @@ public class DatanodeHttpServer implements Closeable {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- private static String getHostnameForSpnegoPrincipal(Configuration conf) {
|
|
|
|
- String addr = conf.getTrimmed(DFS_DATANODE_HTTP_ADDRESS_KEY, null);
|
|
|
|
- if (addr == null) {
|
|
|
|
- addr = conf.getTrimmed(DFS_DATANODE_HTTPS_ADDRESS_KEY,
|
|
|
|
- DFS_DATANODE_HTTPS_ADDRESS_DEFAULT);
|
|
|
|
- }
|
|
|
|
- InetSocketAddress inetSocker = NetUtils.createSocketAddr(addr);
|
|
|
|
- return inetSocker.getHostString();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Creates the {@link RestCsrfPreventionFilter} for the DataNode. Since the
|
|
|
|
- * DataNode HTTP server is not implemented in terms of the servlet API, it
|
|
|
|
- * takes some extra effort to obtain an instance of the filter. This method
|
|
|
|
- * takes care of configuration and implementing just enough of the servlet API
|
|
|
|
- * and related interfaces so that the DataNode can get a fully initialized
|
|
|
|
- * instance of the filter.
|
|
|
|
- *
|
|
|
|
- * @param conf configuration to read
|
|
|
|
- * @return initialized filter, or null if CSRF protection not enabled
|
|
|
|
- */
|
|
|
|
- private static RestCsrfPreventionFilter createRestCsrfPreventionFilter(
|
|
|
|
- Configuration conf) {
|
|
|
|
- if (!conf.getBoolean(DFS_WEBHDFS_REST_CSRF_ENABLED_KEY,
|
|
|
|
- DFS_WEBHDFS_REST_CSRF_ENABLED_DEFAULT)) {
|
|
|
|
- return null;
|
|
|
|
- }
|
|
|
|
- String restCsrfClassName = RestCsrfPreventionFilter.class.getName();
|
|
|
|
- Map<String, String> restCsrfParams = RestCsrfPreventionFilter
|
|
|
|
- .getFilterParams(conf, "dfs.webhdfs.rest-csrf.");
|
|
|
|
- RestCsrfPreventionFilter filter = new RestCsrfPreventionFilter();
|
|
|
|
- try {
|
|
|
|
- filter.init(new MapBasedFilterConfig(restCsrfClassName, restCsrfParams));
|
|
|
|
- } catch (ServletException e) {
|
|
|
|
- throw new IllegalStateException(
|
|
|
|
- "Failed to initialize RestCsrfPreventionFilter.", e);
|
|
|
|
- }
|
|
|
|
- return filter;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
- * A minimal {@link FilterConfig} implementation backed by a {@link Map}.
|
|
|
|
|
|
+ * Since the DataNode HTTP server is not implemented in terms of the
|
|
|
|
+ * servlet API, it
|
|
|
|
+ * takes some extra effort to obtain an instance of the filter. This
|
|
|
|
+ * method provides
|
|
|
|
+ * a minimal {@link FilterConfig} implementation backed by a {@link Map}.
|
|
|
|
+ * Call this from
|
|
|
|
+ * your filter handler to initialize a servlet filter.
|
|
*/
|
|
*/
|
|
- private static final class MapBasedFilterConfig implements FilterConfig {
|
|
|
|
|
|
+ public static final class MapBasedFilterConfig implements FilterConfig {
|
|
|
|
|
|
private final String filterName;
|
|
private final String filterName;
|
|
private final Map<String, String> parameters;
|
|
private final Map<String, String> parameters;
|
|
|
|
|
|
- /**
|
|
|
|
|
|
+ /*
|
|
* Creates a new MapBasedFilterConfig.
|
|
* Creates a new MapBasedFilterConfig.
|
|
*
|
|
*
|
|
* @param filterName filter name
|
|
* @param filterName filter name
|
|
@@ -374,10 +406,10 @@ public class DatanodeHttpServer implements Closeable {
|
|
throw this.notImplemented();
|
|
throw this.notImplemented();
|
|
}
|
|
}
|
|
|
|
|
|
- /**
|
|
|
|
|
|
+ /*
|
|
* Creates an exception indicating that an interface method is not
|
|
* Creates an exception indicating that an interface method is not
|
|
- * implemented. These should never be seen in practice, because it is only
|
|
|
|
- * used for methods that are not called by {@link RestCsrfPreventionFilter}.
|
|
|
|
|
|
+ * implemented. If you are building a handler it is possible you will
|
|
|
|
+ * need to make this interface more extensive.
|
|
*
|
|
*
|
|
* @return exception indicating method not implemented
|
|
* @return exception indicating method not implemented
|
|
*/
|
|
*/
|