@Override
    public HttpResponse encode(ServiceRequestContext ctx, WebSocket out) {
        final RequestHeaders requestHeaders = ctx.request().headers();
        final ResponseHeadersBuilder responseHeadersBuilder;
        if (ctx.sessionProtocol().isExplicitHttp1()) {
            final String webSocketKey = requestHeaders.get(HttpHeaderNames.SEC_WEBSOCKET_KEY, "");
            final String accept = generateSecWebSocketAccept(webSocketKey);
            responseHeadersBuilder =
                    ResponseHeaders.builder(HttpStatus.SWITCHING_PROTOCOLS)
                                   .add(HttpHeaderNames.UPGRADE, HttpHeaderValues.WEBSOCKET.toString())
                                   .add(HttpHeaderNames.CONNECTION, HttpHeaderValues.UPGRADE.toString())
                                   .add(HttpHeaderNames.SEC_WEBSOCKET_ACCEPT, accept);
        } else {
            // As described in https://datatracker.ietf.org/doc/html/rfc8441#section-5,
            // HTTP/2 does not use Sec-WebSocket-Key and Sec-WebSocket-Accept headers.
            responseHeadersBuilder = ResponseHeaders.builder(HttpStatus.OK);
        }
        maybeAddSubprotocol(requestHeaders, responseHeadersBuilder);

        final WebSocketServiceFrameDecoder decoder = ctx.attr(DECODER);
        assert decoder != null;
        decoder.setOutboundWebSocket(out);
        final StreamMessage<HttpData> data =
                out.recoverAndResume(cause -> {
                       if (cause instanceof ClosedStreamException) {
                           return StreamMessage.aborted(cause);
                       }
                       ctx.logBuilder().responseCause(cause);
                       return StreamMessage.of(newCloseWebSocketFrame(cause));
                   })
                   .map(frame -> HttpData.wrap(encoder.encode(ctx, frame)));
        return HttpResponse.of(responseHeadersBuilder.build(), data);
    }
Handles the HTTP/2 web socket handshake described in
<a href="https://datatracker.ietf.org/doc/html/rfc8441">Bootstrapping WebSockets with HTTP/2</a>.
These are examples of a request and the corresponding response:

<p>Request:
<pre>
HEADERS + END_HEADERS
:method = CONNECT
:protocol = websocket
:scheme = https
:path = /chat
:authority = server.example.com
sec-websocket-protocol = chat, superchat
sec-websocket-extensions = permessage-deflate
sec-websocket-version = 13
origin = http://www.example.com
</pre>

<p>Response:
<pre>
HEADERS + END_HEADERS
:status = 200
sec-websocket-protocol = chat
</pre>
core/src/main/java/com/linecorp/armeria/internal/server/websocket/DefaultWebSocketService.java