@Override
    protected void intercept(@NonNull final HttpRequestChain chain, @NonNull ByteBuffer buffer,
                             int index) throws IOException {
        if (!chain.request().isHttps()) {
            chain.process(buffer);
        } else if (mEngineFactory == null) {
            // Skip all interceptors
            chain.processFinal(buffer);
            mLog.w("JSK not installed, skip all interceptors!");
        } else {
            if (!mClientAlpnResolved) {
                buffer = mergeRequestBuffer(buffer);
                int verifyResult = SSLUtils.verifyPacket(buffer);
                if (verifyResult == SSLUtils.PACKET_NOT_ENCRYPTED) {
                    throw new IOException("SSL packet is not encrypt.");
                }
                if (verifyResult == SSLUtils.PACKET_NOT_ENOUGH) {
                    pendRequestBuffer(buffer);
                    return;
                }

                mRequestCodec.setRequest(chain.request());
                // Start handshake with remote server
                mResponseCodec.setRequest(chain.request());

                // Parse the ALPN protocol of client.
                HttpProtocol[] protocols = SSLUtils.parseClientHelloAlpn(buffer);
                mClientAlpnResolved = true;

                if (protocols == null || protocols.length == 0) {
                    mRequestCodec.setSelectedAlpnResolved();
                    mResponseCodec.setSelectedAlpnResolved();
                    mResponseCodec.prepareHandshake();
                } else {
                    // Detect remote server's ALPN and then continue request.
                    mResponseCodec.prepareHandshake(protocols, new HttpSSLResponseCodec.AlpnResolvedCallback() {
                        @Override
                        public void onResult(String selectedAlpnProtocol) throws IOException {
                            if (selectedAlpnProtocol != null) {
                                HttpProtocol protocol = HttpProtocol.parse(selectedAlpnProtocol);
                                // Only accept Http1.1 and Http2.0
                                if (protocol == HttpProtocol.HTTP_1_1 || protocol == HttpProtocol.HTTP_2) {
                                    mRequestCodec.setSelectedAlpnProtocol(protocol);
                                    chain.request().session().protocol = protocol;
                                    mLog.i("Server selected ALPN protocol: " + protocol.toString());
                                } else {
                                    mLog.w("Unexpected server ALPN protocol: " + protocol.toString());
                                }
                            }
                            mRequestCodec.setSelectedAlpnResolved();
                            // Continue request.
                            decodeRequest(chain, ByteBuffer.allocate(0));
                        }
                    });
                }
            }
            // Hold the request buffer until the server ALPN configuration resolved.
            if (!mRequestCodec.selectedAlpnResolved()) {
                pendRequestBuffer(buffer);
                return;
            }

            decodeRequest(chain, buffer);
        }
    }
An interceptor decodes SSL encrypt packets to plaintext packets.

@author Megatron King
@since 2018-11-15 15:39
netbare-core/src/main/java/com/github/megatronking/netbare/http/HttpSSLCodecInterceptor.java