提交 4a014639 编写于 作者: J Jeff Thompson

Adopt Daniel's suggestion for tying Stapler change to Jenkins.

And remove duplication in tests.
上级 13d4a37a
......@@ -39,7 +39,7 @@ THE SOFTWARE.
<properties>
<staplerFork>true</staplerFork>
<stapler.version>1.259-rc1394.3f695d5ed2a7</stapler.version>
<stapler.version>1.259-rc1395.948a5cffe7c0</stapler.version>
<spring.version>2.5.6.SEC03</spring.version>
<groovy.version>2.4.12</groovy.version>
</properties>
......
......@@ -3,13 +3,23 @@ package hudson.init.impl;
import hudson.init.Initializer;
import jenkins.model.Jenkins;
import jenkins.telemetry.impl.java11.MissingClassTelemetry;
import org.kohsuke.MetaInfServices;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.kohsuke.stapler.HttpResponses;
import org.kohsuke.stapler.Stapler;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.WebApp;
import org.kohsuke.stapler.compression.CompressionFilter;
import javax.annotation.CheckForNull;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.EOFException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
......@@ -24,25 +34,7 @@ public class InstallUncaughtExceptionHandler {
@Initializer
public static void init(final Jenkins j) throws IOException {
CompressionFilter.setUncaughtExceptionHandler(j.servletContext, (e, context, req, rsp) -> {
if (rsp.isCommitted()) {
LOGGER.log(isEOFException(e) ? Level.FINE : Level.WARNING, null, e);
return;
}
String id = UUID.randomUUID().toString();
LOGGER.log(isEOFException(e) ? Level.FINE : Level.WARNING, "Caught unhandled exception with ID " + id, e);
req.setAttribute("jenkins.exception.id", id);
req.setAttribute("javax.servlet.error.exception",e);
try {
// If we have an exception, let's see if it's related with missing classes on Java 11. We reach
// here with a ClassNotFoundException in an action, for example. Setting the report here is the only
// way to catch the missing classes when the plugin uses Thread.currentThread().getContextClassLoader().loadClass
MissingClassTelemetry.reportExceptionInside(e);
WebApp.get(j.servletContext).getSomeStapler().invoke(req, rsp, j, "/oops");
} catch (ServletException | IOException x) {
if (!Stapler.isSocketException(x)) {
throw x;
}
}
handleException(j, e, req, rsp);
});
try {
Thread.setDefaultUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler());
......@@ -58,6 +50,42 @@ public class InstallUncaughtExceptionHandler {
}
}
private static void handleException(Jenkins j, Throwable e, HttpServletRequest req, HttpServletResponse rsp) throws IOException, ServletException {
if (rsp.isCommitted()) {
LOGGER.log(isEOFException(e) ? Level.FINE : Level.WARNING, null, e);
return;
}
String id = UUID.randomUUID().toString();
LOGGER.log(isEOFException(e) ? Level.FINE : Level.WARNING, "Caught unhandled exception with ID " + id, e);
req.setAttribute("jenkins.exception.id", id);
req.setAttribute("javax.servlet.error.exception",e);
try {
// If we have an exception, let's see if it's related with missing classes on Java 11. We reach
// here with a ClassNotFoundException in an action, for example. Setting the report here is the only
// way to catch the missing classes when the plugin uses Thread.currentThread().getContextClassLoader().loadClass
MissingClassTelemetry.reportExceptionInside(e);
WebApp.get(j.servletContext).getSomeStapler().invoke(req, rsp, j, "/oops");
} catch (ServletException | IOException x) {
if (!Stapler.isSocketException(x)) {
throw x;
}
}
}
@Restricted(NoExternalUse.class)
@MetaInfServices
public static class ErrorCustomizer implements HttpResponses.ErrorCustomizer {
@CheckForNull
@Override
public HttpResponses.HttpResponseException handleError(int i, Throwable throwable) {
return new HttpResponses.HttpResponseException(throwable) {
public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException {
handleException(Jenkins.get(), throwable, req, rsp);
}
};
}
}
private static boolean isEOFException(Throwable e) {
if (e == null) {
return false;
......
......@@ -23,7 +23,6 @@
*/
package jenkins.security;
import com.gargoylesoftware.htmlunit.Page;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import hudson.model.FreeStyleProject;
import hudson.model.ItemGroup;
......@@ -36,7 +35,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.MockAuthorizationStrategy;
import org.kohsuke.stapler.HttpResponses;
import org.xml.sax.SAXException;
import java.io.IOException;
......@@ -61,7 +60,6 @@ public class StackTraceSuppressionTest {
private void clearProperties() {
System.clearProperty("jenkins.model.Jenkins.SHOW_STACK_TRACE");
System.clearProperty("org.kohsuke.stapler.HttpResponses.SHOW_STACK_TRACE");
}
@Test
......@@ -85,14 +83,10 @@ public class StackTraceSuppressionTest {
/* This test belongs in Stapler but it's easy to put it together here.
This test is based upon Stapler throwing an exception for this broken request.
If Stapler is improved to better handle this error, this test may erroneously fail. */
JenkinsRule.WebClient wc = j.createWebClient();
wc.setThrowExceptionOnFailingStatusCode(false);
HtmlPage page = wc.goTo("adjuncts/40331c1bldu3i%3b//'%3b//\"%3b//%25>%3f>uezm3<script>alert(1)</script>foo/org/kohsuke/stapler/jquery/jquery.full.js");
String content = page.getWebResponse().getContentAsString();
assertThat(content, containsString("No such adjunct found"));
assertThat(content, not(containsString("AdjunctManager.doDynamic")));
String relativePath = "adjuncts/40331c1bldu3i%3b//'%3b//\"%3b//%25>%3f>uezm3<script>alert(1)</script>foo/org/kohsuke/stapler/jquery/jquery.full.js";
String detailString = "AdjunctManager.doDynamic";
checkSuppressedStack(relativePath, detailString);
}
@Test
......@@ -100,15 +94,9 @@ public class StackTraceSuppressionTest {
/* This test belongs in Stapler but it's easy to put it together here.
This test is based upon Stapler throwing an exception for this broken request.
If Stapler is improved to better handle this error, this test may erroneously fail. */
JenkinsRule.WebClient wc = j.createWebClient();
System.setProperty("org.kohsuke.stapler.HttpResponses.SHOW_STACK_TRACE", "true");
wc.setThrowExceptionOnFailingStatusCode(false);
Page page = wc.goTo("adjuncts/40331c1bldu3i%3b//'%3b//\"%3b//%25>%3f>uezm3<script>alert(1)</script>foo/org/kohsuke/stapler/jquery/jquery.full.js", "text/plain");
String content = page.getWebResponse().getContentAsString();
assertThat(content, containsString("No such adjunct found"));
assertThat(content, containsString("AdjunctManager.doDynamic"));
String relativePath = "adjuncts/40331c1bldu3i%3b//'%3b//\"%3b//%25>%3f>uezm3<script>alert(1)</script>foo/org/kohsuke/stapler/jquery/jquery.full.js";
String detailString = "AdjunctManager.doDynamic";
checkDisplayedStackTrace(relativePath, detailString);
}
@Test
......@@ -118,15 +106,9 @@ public class StackTraceSuppressionTest {
If Jenkins is improved to better handle this error, this test may erroneously fail. */
FreeStyleProject projectError = createBrokenProject();
JenkinsRule.WebClient wc = j.createWebClient();
wc.setThrowExceptionOnFailingStatusCode(false);
HtmlPage page = wc.goTo("job/" + projectError.getName() + "/configure");
String content = page.getWebResponse().getContentAsString();
assertThat(content, containsString("A problem occurred while processing the request."));
assertThat(content, containsString("Logging ID="));
assertThat(content, containsString("Oops!"));
assertThat(content, not(containsString("JellyTagException")));
String relativePath = "job/" + projectError.getName() + "/configure";
String detailString = "JellyTagException";
checkSuppressedStack(relativePath, detailString);
}
@Test
......@@ -136,49 +118,27 @@ public class StackTraceSuppressionTest {
If Jenkins is improved to better handle this error, this test may erroneously fail. */
FreeStyleProject projectError = createBrokenProject();
System.setProperty("jenkins.model.Jenkins.SHOW_STACK_TRACE", "true");
JenkinsRule.WebClient wc = j.createWebClient();
wc.setThrowExceptionOnFailingStatusCode(false);
HtmlPage page = wc.goTo("job/" + projectError.getName() + "/configure");
String content = page.getWebResponse().getContentAsString();
assertThat(content, containsString("A problem occurred while processing the request."));
assertThat(content, containsString("Logging ID="));
assertThat(content, containsString("Oops!"));
assertThat(content, containsString("Stack trace"));
assertThat(content, containsString("JellyTagException"));
String relativePath = "job/" + projectError.getName() + "/configure";
String detailString = "JellyTagException";
checkDisplayedStackTrace(relativePath, detailString);
}
@Test
public void exceptionEndpoint() throws Exception {
/* This test is based upon a testing endpoint that really shouldn't exist in production code.
If Jenkins is improved to eliminate this endpoint, this test may erroneously fail. */
JenkinsRule.WebClient wc = j.createWebClient();
wc.setThrowExceptionOnFailingStatusCode(false);
HtmlPage page = wc.goTo("exception");
String content = page.getWebResponse().getContentAsString();
assertThat(content, containsString("A problem occurred while processing the request."));
assertThat(content, containsString("Logging ID="));
assertThat(content, containsString("Oops!"));
assertThat(content, not(containsString("Jenkins.doException")));
String relativePath = "exception";
String detailString = "Jenkins.doException";
checkSuppressedStack(relativePath, detailString);
}
@Test
public void exceptionEndpointShowsTrace() throws Exception {
/* This test is based upon a testing endpoint that really shouldn't exist in production code.
If Jenkins is improved to eliminate this endpoint, this test may erroneously fail. */
System.setProperty("jenkins.model.Jenkins.SHOW_STACK_TRACE", "true");
JenkinsRule.WebClient wc = j.createWebClient();
wc.setThrowExceptionOnFailingStatusCode(false);
HtmlPage page = wc.goTo("exception");
String content = page.getWebResponse().getContentAsString();
assertThat(content, containsString("A problem occurred while processing the request."));
assertThat(content, containsString("Logging ID="));
assertThat(content, containsString("Oops!"));
assertThat(content, containsString("Stack trace"));
assertThat(content, containsString("Jenkins.doException"));
String relativePath = "exception";
String detailString = "Jenkins.doException";
checkDisplayedStackTrace(relativePath, detailString);
}
private FreeStyleProject createBrokenProject() throws IOException {
......@@ -196,4 +156,32 @@ public class StackTraceSuppressionTest {
return (FreeStyleProject) j.jenkins.createProject(descriptor, "throw-error");
}
private void checBaseResponseContent(String content) {
assertThat(content, containsString("A problem occurred while processing the request."));
assertThat(content, containsString("Logging ID="));
assertThat(content, containsString("Oops!"));
}
private void checkSuppressedStack(String relativePath, String detailString) throws IOException, SAXException {
JenkinsRule.WebClient wc = j.createWebClient();
wc.setThrowExceptionOnFailingStatusCode(false);
HtmlPage page = wc.goTo(relativePath);
String content = page.getWebResponse().getContentAsString();
checBaseResponseContent(content);
assertThat(content, not(containsString(detailString)));
}
private void checkDisplayedStackTrace(String relativePath, String detailString) throws IOException, SAXException {
System.setProperty("jenkins.model.Jenkins.SHOW_STACK_TRACE", "true");
JenkinsRule.WebClient wc = j.createWebClient();
wc.setThrowExceptionOnFailingStatusCode(false);
HtmlPage page = wc.goTo(relativePath);
String content = page.getWebResponse().getContentAsString();
checBaseResponseContent(content);
assertThat(content, containsString("Stack trace"));
assertThat(content, containsString(detailString));
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册