0

From the docs,

immediately after sending the 101 (Switching Protocols) response, the server is expected to continue responding to the original request as if it had received its equivalent within the new protocol (i.e., the server still has an outstanding request to satisfy after the protocol has been changed, and is expected to do so without requiring the request to be repeated).

If the Upgrade header field is received in a GET request and the server decides to switch protocols, it first responds with a 101 (Switching Protocols) message in HTTP/1.1 and then immediately follows that with the new protocol's equivalent of a response to a GET on the target resource. This allows a connection to be upgraded to protocols with the same semantics as HTTP without the latency cost of an additional round trip.

I have made my interceptors(Using OkHttp) as follows

public class H2cUpgradeRequestInterceptor implements Interceptor {
private static final Log logger = LogFactory.getLog(H2cUpgradeRequestInterceptor.class);

@Override
public Response intercept(Chain chain) throws IOException {
    Request request = chain.request();
    Request upgradeRequest = request.newBuilder().addHeader("Connection", "Upgrade, HTTP2-Settings")
            .addHeader("Upgrade", "h2c").addHeader("HTTP2-Settings", "AAMAAABkAARAAAAAAAIAAAAA").build();
    Response upgradeResponse = chain.proceed(upgradeRequest);
    if (upgradeResponse != null && upgradeResponse.code() == HttpStatus.SC_SWITCHING_PROTOCOLS) {
        logger.debug("Switching Protocols success"); // Success. Got 101 in reply.
    }
    upgradeResponse.body(); // returns null
    // I am clueless on how to read the response hereafter.
    // As per the docs, the 101 status code reply will be followed by a data stream. How can I access this?
    return upgradeResponse;

}

}

So basically, for a single request. I will receive 101 as response first if the upgrade is successful, then followed by another response as per the upgraded protocol(if my understanding is right?). Is there anyway to achieve this with OkHttp? Or, Any other client also would be helpful.

Thanks!

Community
  • 1
  • 1
Mohamed Anees A
  • 4,119
  • 1
  • 22
  • 35
  • Same response, but it starts with an HTTP1.1 101 header message, and then the _rest_ of the response is as per the upgraded protocol. So just one response, but the very first part of it will be a line of HTTP1.1 that says the server has indeed upgraded the request. Everything after that is in the new protocol (http2, websocket, what have you) – Mike 'Pomax' Kamermans Sep 30 '19 at 17:37
  • @Mike'Pomax'Kamermans But the `upgradeResponse.body()` is `null`. Which is why I am not sure how to proceed. Ideally, I am expecting it to produce a JSON since I am sending a `GET` request. – Mohamed Anees A Sep 30 '19 at 17:42
  • Don't consume the body _while you're sending it_, that destroys it. From [the docs](https://square.github.io/okhttp/4.x/okhttp/okhttp3/-response/): "Returns a non-null value if this response was passed to Callback.onResponse or returned from Call.execute. Response bodies must be closed and may be consumed only once." Try using [peekBody](https://square.github.io/okhttp/4.x/okhttp/okhttp3/-response/peek-body/) instead. – Mike 'Pomax' Kamermans Sep 30 '19 at 17:54
  • I am using `upgradeResponse.body()` after the `proceed()` call. I have edited the question to show where exactly I am using it – Mohamed Anees A Sep 30 '19 at 18:02
  • right, but `.body()` _destructively reads the body_ so you even if you did get something out, you've effectively just destroyed the response itself. That can't be what you want to do. – Mike 'Pomax' Kamermans Sep 30 '19 at 18:04
  • If that is the case, then something like this would happen https://stackoverflow.com/questions/27922703/accessing-body-string-of-an-okhttp-response-twice-results-in-illegalstateexcepti/27922818#27922818 – Mohamed Anees A Sep 30 '19 at 18:10
  • OkHttp does not support HTTP upgrades. – Jesse Wilson Oct 01 '19 at 01:35
  • @JesseWilson Its [main readme](https://github.com/square/okhttp) suggests it supports http/2, which is hard to do on the current web without honouring http1.2 upgrade requests. Do you have a link to where it's made clear the actual upgrade call itself is not supported? – Mike 'Pomax' Kamermans Oct 01 '19 at 15:13
  • @JesseWilson Maybe it needs to be mentioned on the docs. Something like HttpClient which mentions this explicitly in their release news. – Mohamed Anees A Oct 01 '19 at 18:11
  • Does Chrome support HTTP/2? – Jesse Wilson Oct 02 '19 at 18:15

0 Answers0