HADOOP-17371. Bump Jetty to the latest version 9.4.34. Contributed by Wei-Chiu Chuang. (#2453)

(cherry picked from commit 66ee0a6df0)
This commit is contained in:
Wei-Chiu Chuang 2021-01-04 09:43:58 -08:00
parent cfcd17ffe7
commit 6340ac857b
7 changed files with 67 additions and 13 deletions

View File

@ -840,6 +840,18 @@
<exclude>*/**</exclude> <exclude>*/**</exclude>
</excludes> </excludes>
</filter> </filter>
<filter>
<artifact>org.eclipse.jetty:jetty-util-ajax</artifact>
<excludes>
<exclude>*/**</exclude>
</excludes>
</filter>
<filter>
<artifact>org.eclipse.jetty:jetty-server</artifact>
<excludes>
<exclude>jetty-dir.css</exclude>
</excludes>
</filter>
</filters> </filters>
<!-- relocate classes from mssql-jdbc --> <!-- relocate classes from mssql-jdbc -->

View File

@ -193,6 +193,10 @@
<artifactId>guava</artifactId> <artifactId>guava</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -19,6 +19,7 @@
import org.apache.hadoop.security.authentication.client.AuthenticationException; import org.apache.hadoop.security.authentication.client.AuthenticationException;
import org.apache.hadoop.security.authentication.client.KerberosAuthenticator; import org.apache.hadoop.security.authentication.client.KerberosAuthenticator;
import org.apache.hadoop.security.authentication.util.*; import org.apache.hadoop.security.authentication.util.*;
import org.eclipse.jetty.server.Response;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -619,11 +620,20 @@ && getMaxInactiveInterval() > 0) {
KerberosAuthenticator.WWW_AUTHENTICATE))) { KerberosAuthenticator.WWW_AUTHENTICATE))) {
errCode = HttpServletResponse.SC_FORBIDDEN; errCode = HttpServletResponse.SC_FORBIDDEN;
} }
// After Jetty 9.4.21, sendError() no longer allows a custom message.
// use setStatusWithReason() to set a custom message.
String reason;
if (authenticationEx == null) { if (authenticationEx == null) {
httpResponse.sendError(errCode, "Authentication required"); reason = "Authentication required";
} else { } else {
httpResponse.sendError(errCode, authenticationEx.getMessage()); reason = authenticationEx.getMessage();
} }
if (httpResponse instanceof Response) {
((Response)httpResponse).setStatusWithReason(errCode, reason);
}
httpResponse.sendError(errCode, reason);
} }
} }
} }

View File

@ -37,6 +37,7 @@
import org.apache.hadoop.classification.InterfaceStability; import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.eclipse.jetty.server.Response;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -271,6 +272,10 @@ public void proceed() throws IOException, ServletException {
@Override @Override
public void sendError(int code, String message) throws IOException { public void sendError(int code, String message) throws IOException {
if (httpResponse instanceof Response) {
((Response)httpResponse).setStatusWithReason(code, message);
}
httpResponse.sendError(code, message); httpResponse.sendError(code, message);
} }
} }

View File

@ -28,6 +28,7 @@
import org.apache.hadoop.security.token.delegation.web.DelegationTokenAuthenticationHandler; 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.KerberosDelegationTokenAuthenticationHandler;
import org.apache.hadoop.security.token.delegation.web.PseudoDelegationTokenAuthenticationHandler; import org.apache.hadoop.security.token.delegation.web.PseudoDelegationTokenAuthenticationHandler;
import org.eclipse.jetty.server.Response;
import javax.servlet.FilterChain; import javax.servlet.FilterChain;
import javax.servlet.FilterConfig; import javax.servlet.FilterConfig;
@ -113,6 +114,18 @@ public void setStatus(int sc) {
public void sendError(int sc, String msg) throws IOException { public void sendError(int sc, String msg) throws IOException {
statusCode = sc; statusCode = sc;
this.msg = msg; 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)); super.sendError(sc, HtmlQuoting.quoteHtmlChars(msg));
} }

View File

@ -42,6 +42,7 @@
import org.apache.hadoop.hdfs.DFSConfigKeys; import org.apache.hadoop.hdfs.DFSConfigKeys;
import org.apache.hadoop.hdfs.DFSUtilClient; import org.apache.hadoop.hdfs.DFSUtilClient;
import org.apache.hadoop.security.SecurityUtil; import org.apache.hadoop.security.SecurityUtil;
import org.eclipse.jetty.server.Response;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.classification.InterfaceAudience;
@ -119,7 +120,7 @@ private FSImage getAndValidateFSImage(ServletContext context,
if (nnImage == null) { if (nnImage == null) {
String errorMsg = "NameNode initialization not yet complete. " String errorMsg = "NameNode initialization not yet complete. "
+ "FSImage has not been set in the NameNode."; + "FSImage has not been set in the NameNode.";
response.sendError(HttpServletResponse.SC_FORBIDDEN, errorMsg); sendError(response, HttpServletResponse.SC_FORBIDDEN, errorMsg);
throw new IOException(errorMsg); throw new IOException(errorMsg);
} }
return nnImage; return nnImage;
@ -218,7 +219,7 @@ private void serveFile(File file) throws IOException {
} catch (Throwable t) { } catch (Throwable t) {
String errMsg = "GetImage failed. " + StringUtils.stringifyException(t); String errMsg = "GetImage failed. " + StringUtils.stringifyException(t);
response.sendError(HttpServletResponse.SC_GONE, errMsg); sendError(response, HttpServletResponse.SC_GONE, errMsg);
throw new IOException(errMsg); throw new IOException(errMsg);
} finally { } finally {
response.getOutputStream().close(); response.getOutputStream().close();
@ -234,7 +235,7 @@ private void validateRequest(ServletContext context, Configuration conf,
conf)) { conf)) {
String errorMsg = "Only Namenode, Secondary Namenode, and administrators may access " String errorMsg = "Only Namenode, Secondary Namenode, and administrators may access "
+ "this servlet"; + "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 " LOG.warn("Received non-NN/SNN/administrator request for image or edits from "
+ request.getUserPrincipal().getName() + request.getUserPrincipal().getName()
+ " at " + " at "
@ -247,7 +248,7 @@ private void validateRequest(ServletContext context, Configuration conf,
&& !myStorageInfoString.equals(theirStorageInfoString)) { && !myStorageInfoString.equals(theirStorageInfoString)) {
String errorMsg = "This namenode has storage info " + myStorageInfoString String errorMsg = "This namenode has storage info " + myStorageInfoString
+ " but the secondary expected " + theirStorageInfoString; + " 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 " LOG.warn("Received an invalid request file transfer request "
+ "from a secondary with storage info " + theirStorageInfoString); + "from a secondary with storage info " + theirStorageInfoString);
throw new IOException(errorMsg); throw new IOException(errorMsg);
@ -578,7 +579,7 @@ public Void run() throws Exception {
// we need a different response type here so the client can differentiate this // 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 // from the failure to upload due to (1) security, or (2) other checkpoints already
// present // present
response.sendError(HttpServletResponse.SC_EXPECTATION_FAILED, sendError(response, HttpServletResponse.SC_EXPECTATION_FAILED,
"Nameode "+request.getLocalAddr()+" is currently not in a state which can " "Nameode "+request.getLocalAddr()+" is currently not in a state which can "
+ "accept uploads of new fsimages. State: "+state); + "accept uploads of new fsimages. State: "+state);
return null; return null;
@ -593,7 +594,7 @@ public Void run() throws Exception {
// if the node is attempting to upload an older transaction, we ignore it // if the node is attempting to upload an older transaction, we ignore it
SortedSet<ImageUploadRequest> larger = currentlyDownloadingCheckpoints.tailSet(imageRequest); SortedSet<ImageUploadRequest> larger = currentlyDownloadingCheckpoints.tailSet(imageRequest);
if (larger.size() > 0) { if (larger.size() > 0) {
response.sendError(HttpServletResponse.SC_CONFLICT, sendError(response, HttpServletResponse.SC_CONFLICT,
"Another checkpointer is already in the process of uploading a" + "Another checkpointer is already in the process of uploading a" +
" checkpoint made up to transaction ID " + larger.last()); " checkpoint made up to transaction ID " + larger.last());
return null; return null;
@ -601,7 +602,7 @@ public Void run() throws Exception {
//make sure no one else has started uploading one //make sure no one else has started uploading one
if (!currentlyDownloadingCheckpoints.add(imageRequest)) { if (!currentlyDownloadingCheckpoints.add(imageRequest)) {
response.sendError(HttpServletResponse.SC_CONFLICT, sendError(response, HttpServletResponse.SC_CONFLICT,
"Either current namenode is checkpointing or another" "Either current namenode is checkpointing or another"
+ " checkpointer is already in the process of " + " checkpointer is already in the process of "
+ "uploading a checkpoint made at transaction ID " + "uploading a checkpoint made at transaction ID "
@ -648,7 +649,7 @@ public Void run() throws Exception {
(txid - lastCheckpointTxid) + " expecting at least " (txid - lastCheckpointTxid) + " expecting at least "
+ checkpointTxnCount; + checkpointTxnCount;
LOG.info(message); LOG.info(message);
response.sendError(HttpServletResponse.SC_CONFLICT, message); sendError(response, HttpServletResponse.SC_CONFLICT, message);
return null; return null;
} }
@ -658,7 +659,7 @@ public Void run() throws Exception {
+ "another checkpointer already uploaded an " + "another checkpointer already uploaded an "
+ "checkpoint for txid " + txid; + "checkpoint for txid " + txid;
LOG.info(message); LOG.info(message);
response.sendError(HttpServletResponse.SC_CONFLICT, message); sendError(response, HttpServletResponse.SC_CONFLICT, message);
return null; return null;
} }
@ -695,11 +696,20 @@ public Void run() throws Exception {
}); });
} catch (Throwable t) { } catch (Throwable t) {
String errMsg = "PutImage failed. " + StringUtils.stringifyException(t); String errMsg = "PutImage failed. " + StringUtils.stringifyException(t);
response.sendError(HttpServletResponse.SC_GONE, errMsg); sendError(response, HttpServletResponse.SC_GONE, errMsg);
throw new IOException(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 * Params required to handle put image request
*/ */

View File

@ -37,7 +37,7 @@
<!--Whether to proceed to next module if any test failures exist--> <!--Whether to proceed to next module if any test failures exist-->
<ignoreTestFailure>true</ignoreTestFailure> <ignoreTestFailure>true</ignoreTestFailure>
<maven.test.redirectTestOutputToFile>true</maven.test.redirectTestOutputToFile> <maven.test.redirectTestOutputToFile>true</maven.test.redirectTestOutputToFile>
<jetty.version>9.4.20.v20190813</jetty.version> <jetty.version>9.4.35.v20201120</jetty.version>
<test.exclude>_</test.exclude> <test.exclude>_</test.exclude>
<test.exclude.pattern>_</test.exclude.pattern> <test.exclude.pattern>_</test.exclude.pattern>