Java Nio Socketchannel使用TLS1.2阅读Safari和iOS的EOS早期EOS



我有一个非常奇怪的问题,我最近几天正在工作。

我在我的服务器上写了一个代理应用程序。代理所做的就是管理来自不同应用程序的TLS/NONTLS请求和响应(WebApplications,iOSAPP,Android应用等),并代理服务器上应用程序的流量。

我遇到的问题是,当我通过Safari和通过HTTPS(TLSV1.2)访问使用我的代理的WebApplication时,我会随机从代理中得到任何响应。我进行了很多调试,这个问题是我的读取功能引起的。超时是非常随机的,我的测试我平均有10个请求中的8个超时。

这是代码:

public int read(ByteBuffer dst) throws IOException {
    if (!dst.hasRemaining()) {
        return 0;
    }
    if (peerAppData.hasRemaining()) {
        peerAppData.flip();
        return ByteBufferUtils.transferByteBuffer(peerAppData, dst);
    }
    peerNetData.compact();
    int bytesRead = socketChannel.read(peerNetData);
    if (bytesRead > 0) {
        peerNetData.flip();
        while (peerNetData.hasRemaining()) {
            peerAppData.compact();
            SSLEngineResult result = null;
            try {
                result = sslInfo.sslEngine.unwrap(peerNetData, peerAppData);
            } catch (SSLException e) {
                System.out.println(e.getMessage());
                e.printStackTrace();
                // throw e;
            }
            switch (result.getStatus()) {
            case OK:
                peerAppData.flip();
                return ByteBufferUtils.transferByteBuffer(peerAppData, dst);
            case BUFFER_UNDERFLOW:
                peerAppData.flip();
                return ByteBufferUtils.transferByteBuffer(peerAppData, dst);
            case BUFFER_OVERFLOW:
                peerAppData = enlargeApplicationBuffer(peerAppData);
                break;
            case CLOSED:
                closeConnection();
                dst.clear();
                return -1;
            default:
                System.out.println("Invalid SSL status: " + result.getStatus());
                throw new IllegalStateException("Invalid SSL status: " + result.getStatus());
            }
        }
    } else if (bytesRead < 0) {
        handleEndOfStream();
    }
    ByteBufferUtils.transferByteBuffer(peerAppData, dst);
    return bytesRead;
}

此代码适用于Chrome,Opera和Android。但是在Safari和iOS上,第二次读取了Socketchannel返回-1。这导致连接关闭。这就解释了为什么我会在Safari/ios方面获得超时。

我有一个工作代码,但我无法使用此代码,因为这不允许我像文件上传那样代理数据流。而且这无法正确处理SSLENGINERESULT。

public int read(ByteBuffer dst) throws IOException {
    int bytesRead = 1;
    int totalBytesRead = 0;
    peerNetData.clear();
    while (bytesRead > 0) {
        bytesRead = socketChannel.read(peerNetData);
        if (bytesRead > 0) {
            totalBytesRead = totalBytesRead + bytesRead;
        }
    }
    peerNetData.flip();
    if (totalBytesRead < 0) {
        return bytesRead;
    }
    while (peerNetData.hasRemaining()) {
        SSLEngineResult result = sslInfo.sslEngine.unwrap(peerNetData, dst);
        if (result.getStatus() != SSLEngineResult.Status.OK) {
            return -1;
        }
    }
    peerNetData.compact();
    return totalBytesRead;
}

我真的不知道为什么此代码仅根据Safari浏览器或任何iOS设备的要求失败。

你们中的任何人都遇到过同样的问题吗?

事先感谢,请告诉我是否错过了什么!

如果您的代理上游read()返回-1,上游对等方关闭了连接,并且您应该对下游的对等,而不是让它超时。

<</p>

相关内容

  • 没有找到相关文章

最新更新