Skip to content

Commit

Permalink
Merge pull request #19708 from stuartwdouglas/19621
Browse files Browse the repository at this point in the history
Fix "Response head already sent"
  • Loading branch information
stuartwdouglas authored Aug 31, 2021
2 parents db177ca + 9c55363 commit 4e009a2
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,40 +41,49 @@ public QuarkusErrorHandler(boolean showStack) {

@Override
public void handle(RoutingContext event) {
if (event.failure() == null) {
event.response().setStatusCode(event.statusCode());
event.response().end();
return;
}
//this can happen if there is no auth mechanisms
if (event.failure() instanceof UnauthorizedException) {
HttpAuthenticator authenticator = event.get(HttpAuthenticator.class.getName());
if (authenticator != null) {
authenticator.sendChallenge(event).subscribe().with(new Consumer<Boolean>() {
@Override
public void accept(Boolean aBoolean) {
event.response().end();
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) {
event.fail(throwable);
}
});
} else {
try {
if (event.failure() == null) {
event.response().setStatusCode(event.statusCode());
event.response().end();
return;
}
//this can happen if there is no auth mechanisms
if (event.failure() instanceof UnauthorizedException) {
HttpAuthenticator authenticator = event.get(HttpAuthenticator.class.getName());
if (authenticator != null) {
authenticator.sendChallenge(event).subscribe().with(new Consumer<Boolean>() {
@Override
public void accept(Boolean aBoolean) {
event.response().end();
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) {
event.fail(throwable);
}
});
} else {
event.response().setStatusCode(HttpResponseStatus.UNAUTHORIZED.code()).end();
}
return;
}
if (event.failure() instanceof ForbiddenException) {
event.response().setStatusCode(HttpResponseStatus.FORBIDDEN.code()).end();
return;
}
if (event.failure() instanceof AuthenticationFailedException) {
//generally this should be handled elsewhere
//but if we get to this point bad things have happened
//so it is better to send a response than to hang
event.response().setStatusCode(HttpResponseStatus.UNAUTHORIZED.code()).end();
return;
}
} catch (IllegalStateException e) {
//ignore this if the response is already started
if (!event.response().ended()) {
//could be that just the head is committed
event.response().end();
}
return;
}
if (event.failure() instanceof ForbiddenException) {
event.response().setStatusCode(HttpResponseStatus.FORBIDDEN.code()).end();
return;
}
if (event.failure() instanceof AuthenticationFailedException) {
//generally this should be handled elsewhere
//but if we get to this point bad things have happened
//so it is better to send a response than to hang
event.response().setStatusCode(HttpResponseStatus.UNAUTHORIZED.code()).end();
return;
}

Expand All @@ -100,6 +109,15 @@ public void accept(Throwable throwable) {
} else {
log.errorf(exception, "HTTP Request to %s failed, error id: %s", event.request().uri(), uuid);
}
//we have logged the error
//now lets see if we can actually send a response
//if not we just return
if (event.response().ended()) {
return;
} else if (event.response().headWritten()) {
event.response().end();
return;
}
String accept = event.request().getHeader("Accept");
if (accept != null && accept.contains("application/json")) {
event.response().headers().set(HttpHeaderNames.CONTENT_TYPE, "application/json; charset=utf-8");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public void testNdjsonMultiRoute() {
// We get the item followed by the exception
when().get("/hello-and-fail").then().statusCode(200)
.body(containsString("\"Hello\""))
.body(containsString("boom"));
.body(not(containsString("boom")));

when().get("/void").then().statusCode(204).body(hasLength(0));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public void testSSEMultiRoute() {
// We get the item followed by the exception
when().get("/hello-and-fail").then().statusCode(200)
.body(containsString("id: 0"))
.body(containsString("boom"));
.body(not(containsString("boom")));

when().get("/buffer").then().statusCode(200)
.body(is("data: Buffer\nid: 0\n\n"))
Expand Down

0 comments on commit 4e009a2

Please sign in to comment.