jetty.project
jetty.project copied to clipboard
Read response body on failed WebSocket upgrade attempt
Jetty Version
12.0.19
Jetty Environment
ee10
Java Version
21
Question
When making a WebSocket connection I am able to catch the UpgradeException with message Failed to upgrade to websocket: Unexpected HTTP Response Status Code.
In this case I can see the response status code and response headers by capturing the handshake response.
try {
AtomicReference<Response> responseRef = new AtomicReference<>();
client.connect(backendListener, uri, clientUpgrade, new JettyUpgradeListener() {
@Override
public void onHandshakeResponse(Request request, Response response) {
log.debug("Received HTTP {} response from WebSocket backend", response);
responseRef.set(response);
}
}).get();
} catch (UpgradeException e) {
if (e.getCause().getMessage().startsWith("Failed to upgrade to websocket: Unexpected HTTP Response Status Code")) {
Response response = responseRef.get();
log.info("Status: {}", response.getStatus());
log.info("Headers: {}", response.getHeaders());
// InputStream responseBody = response.getBody() ??
}
}
Is there any way to read the response body stream from the handshake as well? As far as I can tell the Response does not have any methods that support reading?
Use-Case
When connecting to a WebSocket endpoint, the server may reject the upgrade request with a HTTP 4XX or 5XX error. For example the request headers could be invalid. When this happens I would like to be able to read the response body to learn more about the error cause.
As per the WebSocket spec
If the status code received from the server is not 101, the
client handles the response per HTTP [[RFC2616](https://datatracker.ietf.org/doc/html/rfc2616)] procedures. In
particular, the client might perform authentication if it
receives a 401 status code; the server might redirect the client
using a 3xx status code (but clients are not required to follow
them), etc. Otherwise, proceed as follows.
Currently, the response body is discarded, so there is no way to retrieve it. Also, browsers don't expose failed WebSocket upgrades (just an error).
This is the first time we got this specific request.
Can you control the body generation on the server?
Since this is a WebSocket Client the HTTP response body isn't relevant anyway.
If this was an HTTP Client that could also do WebSocket then the HTTP response body would have relevance to the HTTP Client.
@joakime it is the HTTP response of the HTTP request for the WebSocket upgrade.
JettyUpgradeListener's Request and Response parameters are those of jetty-client.
So it can be done, just we do not currently do it since typically the headers are enough.