我已经基于套接字创建了web server。它可以通过HTTPS或HTTP提供文件。
我遇到的问题是在使用Firefox和Chromium通过HTTPS向服务器请求文件(例如图像)时发生的。
当Firefox向https://localhost:8443/ada.jpg
处的服务器请求图像时,Firefox会报告
SSL_ERROR_RX_RECORD_TOO_LONG
类似地,Chromium错误与
ERR_SSL_PROTOCOL_ERROR
以下方法可以正常工作:
curl -Ok "https://localhost:8443/ada.jpg"
https://localhost:8443/
http://localhost:8443/ada.jpg
我用Wireshark在浏览器获取图像时查看帧:Firefox和Chromium都在服务器仍在传输图像的同时向服务器发送[FIN, ACK]
帧。服务器继续发送图像的一部分,然后浏览器发送[RST]
帧。
以下是Firefox和服务器之间交换的最后几帧:
25 1.873102771 ::1 ::1 TCP 86 55444 → 8443 [ACK] Seq=937 Ack=18043 Win=56704 Len=0 TSval=3976879013 TSecr=3976879013
26 1.873237965 ::1 ::1 TLSv1.3 110 Application Data
27 1.873247272 ::1 ::1 TCP 86 8443 → 55444 [ACK] Seq=18043 Ack=961 Win=65536 Len=0 TSval=3976879013 TSecr=3976879013
28 1.873346910 ::1 ::1 TCP 86 55444 → 8443 [FIN, ACK] Seq=961 Ack=18043 Win=65536 Len=0 TSval=3976879013 TSecr=3976879013
29 1.876736432 ::1 ::1 TLSv1.3 16508 Application Data
30 1.876769660 ::1 ::1 TCP 74 55444 → 8443 [RST] Seq=962 Win=0 Len=0
Here是cURL和Firefox的Wireshark捕获。
要重现错误,请执行
git clone git@gitlab.com:bullbytes/simple_socket_based_server.git
cd simple_socket_based_server
./gradlew run
这将启动启用了TLS的服务器。然后,在浏览器中打开以下URL(第一次,您必须为自签名证书添加例外):
https://localhost:8443/ada.jpg
为使自己确信禁用TLS后,传输映像成功,请按以下方式启动服务器:
./gradlew run --args="--use-tls=no"
从协议中删除s
后,图片应显示在浏览器中:
http://localhost:8443/ada.jpg
服务器的请求处理循环为here。
如何进一步调试并修复?
我在使用OpenJDK 12.0.2 + 10的Arch Linux 5.2.9。
答案 0 :(得分:5)
它在JDK 13中已修复¹。
原始错误报告为here,标题为
TLSv1.3可能会生成超过2 ^ 14 + 1个字节的TLSInnerPlainText
与问题中的观察结果一致:记录比violates TLSv1.3协议更长。
This bug report指出,Java的TLS实现已通过this commit在JDK 11.0.5 b01和13中修复。
通常,JDK 13 reimplemented Socket
和ServerSocket
²使它们在project Loom中引入的光纤中能很好地发挥作用。
我为JDK 12提交的错误是here。
如果在您的情况下无法升级JDK,则可以暂时使用ServerSocketChannel
而不是ServerSocket
。 Jetty做到了。
¹ Arch Linux上的OpenJDK build 13 + 33不会发生该错误:该图像在Firefox中显示正常
用于重现错误的² The server建立在ServerSocket
上。