diff --git a/hadoop-client-modules/hadoop-client-minicluster/pom.xml b/hadoop-client-modules/hadoop-client-minicluster/pom.xml
index 2a36f02373c..91f21c211bf 100644
--- a/hadoop-client-modules/hadoop-client-minicluster/pom.xml
+++ b/hadoop-client-modules/hadoop-client-minicluster/pom.xml
@@ -782,6 +782,18 @@
*/**
+
+ org.eclipse.jetty:jetty-util-ajax
+
+ */**
+
+
+
+ org.eclipse.jetty:jetty-server
+
+ jetty-dir.css
+
+
diff --git a/hadoop-common-project/hadoop-auth/pom.xml b/hadoop-common-project/hadoop-auth/pom.xml
index f510da5c8f4..ae73e7c7d0b 100644
--- a/hadoop-common-project/hadoop-auth/pom.xml
+++ b/hadoop-common-project/hadoop-auth/pom.xml
@@ -188,7 +188,7 @@
guava
compile
-
+
diff --git a/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/server/AuthenticationFilter.java b/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/server/AuthenticationFilter.java
index 94d11f48cf2..b339a5d5a24 100644
--- a/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/server/AuthenticationFilter.java
+++ b/hadoop-common-project/hadoop-auth/src/main/java/org/apache/hadoop/security/authentication/server/AuthenticationFilter.java
@@ -619,11 +619,17 @@ && getMaxInactiveInterval() > 0) {
KerberosAuthenticator.WWW_AUTHENTICATE))) {
errCode = HttpServletResponse.SC_FORBIDDEN;
}
+ // After Jetty 9.4.21, sendError() no longer allows a custom message.
+ // use setStatus() to set a custom message.
+ String reason;
if (authenticationEx == null) {
- httpResponse.sendError(errCode, "Authentication required");
+ reason = "Authentication required";
} else {
- httpResponse.sendError(errCode, authenticationEx.getMessage());
+ reason = authenticationEx.getMessage();
}
+
+ httpResponse.setStatus(errCode, reason);
+ httpResponse.sendError(errCode, reason);
}
}
}
diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/http/RestCsrfPreventionFilter.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/http/RestCsrfPreventionFilter.java
index 59cb0d65995..b81ed8e9015 100644
--- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/http/RestCsrfPreventionFilter.java
+++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/http/RestCsrfPreventionFilter.java
@@ -37,6 +37,7 @@
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.conf.Configuration;
+import org.eclipse.jetty.server.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -271,6 +272,10 @@ public void proceed() throws IOException, ServletException {
@Override
public void sendError(int code, String message) throws IOException {
+ if (httpResponse instanceof Response) {
+ ((Response)httpResponse).setStatusWithReason(code, message);
+ }
+
httpResponse.sendError(code, message);
}
}
diff --git a/hadoop-common-project/hadoop-kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSAuthenticationFilter.java b/hadoop-common-project/hadoop-kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSAuthenticationFilter.java
index da542ffb191..7f114db9ef2 100644
--- a/hadoop-common-project/hadoop-kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSAuthenticationFilter.java
+++ b/hadoop-common-project/hadoop-kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSAuthenticationFilter.java
@@ -28,6 +28,7 @@
import org.apache.hadoop.security.token.delegation.web.DelegationTokenAuthenticationHandler;
import org.apache.hadoop.security.token.delegation.web.KerberosDelegationTokenAuthenticationHandler;
import org.apache.hadoop.security.token.delegation.web.PseudoDelegationTokenAuthenticationHandler;
+import org.eclipse.jetty.server.Response;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
@@ -113,6 +114,18 @@ public void setStatus(int sc) {
public void sendError(int sc, String msg) throws IOException {
statusCode = sc;
this.msg = msg;
+
+ ServletResponse response = getResponse();
+
+ // After Jetty 9.4.21, sendError() no longer allows a custom message.
+ // use setStatusWithReason() to set a custom message.
+ if (response instanceof Response) {
+ ((Response) response).setStatusWithReason(sc, msg);
+ } else {
+ KMS.LOG.warn("The wrapped response object is instance of {}" +
+ ", not org.eclipse.jetty.server.Response. Can't set custom error " +
+ "message", response.getClass());
+ }
super.sendError(sc, HtmlQuoting.quoteHtmlChars(msg));
}
diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/ImageServlet.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/ImageServlet.java
index d58af1e3536..f2a15f0325c 100644
--- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/ImageServlet.java
+++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/ImageServlet.java
@@ -43,6 +43,7 @@
import org.apache.hadoop.security.SecurityUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.eclipse.jetty.server.Response;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hdfs.DFSUtil;
@@ -118,7 +119,7 @@ private FSImage getAndValidateFSImage(ServletContext context,
if (nnImage == null) {
String errorMsg = "NameNode initialization not yet complete. "
+ "FSImage has not been set in the NameNode.";
- response.sendError(HttpServletResponse.SC_FORBIDDEN, errorMsg);
+ sendError(response, HttpServletResponse.SC_FORBIDDEN, errorMsg);
throw new IOException(errorMsg);
}
return nnImage;
@@ -207,7 +208,7 @@ private void serveFile(File file) throws IOException {
} catch (Throwable t) {
String errMsg = "GetImage failed. " + StringUtils.stringifyException(t);
- response.sendError(HttpServletResponse.SC_GONE, errMsg);
+ sendError(response, HttpServletResponse.SC_GONE, errMsg);
throw new IOException(errMsg);
} finally {
response.getOutputStream().close();
@@ -223,7 +224,7 @@ private void validateRequest(ServletContext context, Configuration conf,
conf)) {
String errorMsg = "Only Namenode, Secondary Namenode, and administrators may access "
+ "this servlet";
- response.sendError(HttpServletResponse.SC_FORBIDDEN, errorMsg);
+ sendError(response, HttpServletResponse.SC_FORBIDDEN, errorMsg);
LOG.warn("Received non-NN/SNN/administrator request for image or edits from "
+ request.getUserPrincipal().getName()
+ " at "
@@ -236,7 +237,7 @@ private void validateRequest(ServletContext context, Configuration conf,
&& !myStorageInfoString.equals(theirStorageInfoString)) {
String errorMsg = "This namenode has storage info " + myStorageInfoString
+ " but the secondary expected " + theirStorageInfoString;
- response.sendError(HttpServletResponse.SC_FORBIDDEN, errorMsg);
+ sendError(response, HttpServletResponse.SC_FORBIDDEN, errorMsg);
LOG.warn("Received an invalid request file transfer request "
+ "from a secondary with storage info " + theirStorageInfoString);
throw new IOException(errorMsg);
@@ -552,7 +553,7 @@ public Void run() throws Exception {
// we need a different response type here so the client can differentiate this
// from the failure to upload due to (1) security, or (2) other checkpoints already
// present
- response.sendError(HttpServletResponse.SC_EXPECTATION_FAILED,
+ sendError(response, HttpServletResponse.SC_EXPECTATION_FAILED,
"Nameode "+request.getLocalAddr()+" is currently not in a state which can "
+ "accept uploads of new fsimages. State: "+state);
return null;
@@ -567,7 +568,7 @@ public Void run() throws Exception {
// if the node is attempting to upload an older transaction, we ignore it
SortedSet larger = currentlyDownloadingCheckpoints.tailSet(imageRequest);
if (larger.size() > 0) {
- response.sendError(HttpServletResponse.SC_CONFLICT,
+ sendError(response, HttpServletResponse.SC_CONFLICT,
"Another checkpointer is already in the process of uploading a" +
" checkpoint made up to transaction ID " + larger.last());
return null;
@@ -575,7 +576,7 @@ public Void run() throws Exception {
//make sure no one else has started uploading one
if (!currentlyDownloadingCheckpoints.add(imageRequest)) {
- response.sendError(HttpServletResponse.SC_CONFLICT,
+ sendError(response, HttpServletResponse.SC_CONFLICT,
"Either current namenode is checkpointing or another"
+ " checkpointer is already in the process of "
+ "uploading a checkpoint made at transaction ID "
@@ -622,7 +623,7 @@ public Void run() throws Exception {
(txid - lastCheckpointTxid) + " expecting at least "
+ checkpointTxnCount;
LOG.info(message);
- response.sendError(HttpServletResponse.SC_CONFLICT, message);
+ sendError(response, HttpServletResponse.SC_CONFLICT, message);
return null;
}
@@ -632,7 +633,7 @@ public Void run() throws Exception {
+ "another checkpointer already uploaded an "
+ "checkpoint for txid " + txid;
LOG.info(message);
- response.sendError(HttpServletResponse.SC_CONFLICT, message);
+ sendError(response, HttpServletResponse.SC_CONFLICT, message);
return null;
}
@@ -669,11 +670,20 @@ public Void run() throws Exception {
});
} catch (Throwable t) {
String errMsg = "PutImage failed. " + StringUtils.stringifyException(t);
- response.sendError(HttpServletResponse.SC_GONE, errMsg);
+ sendError(response, HttpServletResponse.SC_GONE, errMsg);
throw new IOException(errMsg);
}
}
+ private void sendError(HttpServletResponse response, int code, String message)
+ throws IOException {
+ if (response instanceof Response) {
+ ((Response)response).setStatusWithReason(code, message);
+ }
+
+ response.sendError(code, message);
+ }
+
/*
* Params required to handle put image request
*/
diff --git a/hadoop-project/pom.xml b/hadoop-project/pom.xml
index d83626f2d14..235e3115437 100644
--- a/hadoop-project/pom.xml
+++ b/hadoop-project/pom.xml
@@ -35,7 +35,7 @@
false
true
- 9.4.20.v20190813
+ 9.4.39.v20210325
_
_