939
940
resp.flushBuffer();
943
// Give the original thread a chance to exit the
944
// ErrorReportValve before we throw this exception
946
} catch (InterruptedException e) {
947
throw new ServletException(e);
941
949
throw new ServletException("Opps.");
1171
public void testBug51197() throws Exception {
1179
public void testBug51197a() throws Exception {
1180
doTestBug51197(false);
1184
public void testBug51197b() throws Exception {
1185
doTestBug51197(true);
1188
private void doTestBug51197(boolean threaded) throws Exception {
1172
1189
// Setup Tomcat instance
1173
1190
Tomcat tomcat = getTomcatInstance();
1178
1195
Context ctx = tomcat.addContext("", docBase.getAbsolutePath());
1180
1197
AsyncErrorServlet asyncErrorServlet =
1181
new AsyncErrorServlet(HttpServletResponse.SC_BAD_REQUEST);
1198
new AsyncErrorServlet(HttpServletResponse.SC_BAD_REQUEST, threaded);
1182
1199
Wrapper wrapper =
1183
1200
Tomcat.addServlet(ctx, "asyncErrorServlet", asyncErrorServlet);
1184
1201
wrapper.setAsyncSupported(true);
1194
1211
url.append(getPort());
1195
1212
url.append("/asyncErrorServlet");
1197
int rc = getUrl(url.toString(), new ByteChunk(), null);
1214
ByteChunk res = new ByteChunk();
1215
int rc = getUrl(url.toString(), res, null);
1199
1217
assertEquals(HttpServletResponse.SC_BAD_REQUEST, rc);
1219
// SRV 10.9.2 - Writing the response is entirely the application's
1220
// responsibility when an error occurs on an application thread.
1221
// The test servlet writes no content in this case.
1223
assertEquals(0, res.getLength());
1225
assertTrue(res.getLength() > 0);
1201
1228
// Without this test may complete before access log has a chance to log
1203
1230
Thread.sleep(REQUEST_TIME);
1205
1232
// Check the access log
1206
alv.validateAccessLog(1, HttpServletResponse.SC_BAD_REQUEST, TIMEOUT,
1207
TIMEOUT + TIMEOUT_MARGIN + REQUEST_TIME);
1233
alv.validateAccessLog(1, HttpServletResponse.SC_BAD_REQUEST, 0,
1211
1237
private static class AsyncErrorServlet extends HttpServlet {
1213
1239
private static final long serialVersionUID = 1L;
1215
private int status = 200;
1217
public AsyncErrorServlet(int status) {
1241
public static final String ERROR_MESSAGE = "It broke.";
1244
private boolean threaded;
1246
public AsyncErrorServlet(int status, boolean threaded) {
1218
1247
this.status = status;
1248
this.threaded = threaded;
1225
1255
final AsyncContext actxt = req.startAsync();
1226
1256
actxt.setTimeout(TIMEOUT);
1227
actxt.start(new Runnable() {
1231
((HttpServletResponse) actxt.getResponse()).sendError(
1233
} catch (IOException e) {
1258
actxt.start(new Runnable() {
1262
HttpServletResponse resp =
1263
(HttpServletResponse) actxt.getResponse();
1264
resp.sendError(status, ERROR_MESSAGE);
1265
// Complete so there is no delay waiting for the
1268
} catch (IOException e) {
1274
resp.sendError(status);