[ https://issues.apache.org/jira/browse/HTTPCLIENT-2328?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17849830#comment-17849830 ]
Zoe Wang commented on HTTPCLIENT-2328: -------------------------------------- Hi Oleg, thank you for your response. I just tried enabling responseOutOfOrderStrategy and the request still got stuck. When I enabled SSL logs, it was able to receive close_notify, however, since per TLS 1.3 half-closed connection, the client side is not required to close the outbound connection upon receiving close_notify, the client side kept sending data and got stuck. {noformat} javax.net.ssl|DEBUG|01|main|2024-05-27 13:44:23.111 PDT|Alert.java:238|Received alert message ( "Alert": { "level" : "warning", "description": "close_notify" } )javax.net.ssl|DEBUG|01|main|2024-05-27 13:48:53.165 PDT|SSLSocketOutputRecord.java:334|WRITE: TLSv1.3 application_data, length = 8192 javax.net.ssl|DEBUG|01|main|2024-05-27 13:48:53.168 PDT|SSLCipher.java:2062|Plaintext before ENCRYPTION ( 0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ ... keep sending data, request hangs{noformat} For comparison, this is the SSL log if I use the workaround by enabling jdk.tls.acknowledgeCloseNotify. The request did not hang because the client side sends a close_notify alert back, which caused the connection to be duplex closed. {noformat} javax.net.ssl|DEBUG|01|main|2024-05-27 13:51:54.791 PDT|Alert.java:238|Received alert message ( "Alert": { "level" : "warning", "description": "close_notify" } ) javax.net.ssl|DEBUG|01|main|2024-05-27 13:51:54.791 PDT|SSLSocketOutputRecord.java:71|WRITE: TLSv1.3 alert(close_notify), length = 2 javax.net.ssl|DEBUG|01|main|2024-05-27 13:51:54.791 PDT|SSLCipher.java:2062|Plaintext before ENCRYPTION ( 0000: 01 00 15 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0010: 00 00 00 ... ) javax.net.ssl|DEBUG|01|main|2024-05-27 13:51:54.791 PDT|SSLSocketOutputRecord.java:85|Raw write ( 0000: 17 03 03 00 23 D5 FB 81 70 03 7A 4B AD DF D6 D1 ....#...p.zK.... 0010: BE 42 49 AB 09 44 82 A2 D8 47 A2 08 8D 34 86 3B .BI..D...G...4.; 0020: 10 56 CF FB 9F A3 8B 80 .V...... ) javax.net.ssl|DEBUG|01|main|2024-05-27 13:51:54.792 PDT|SSLSocketImpl.java:578|duplex close of SSLSocket javax.net.ssl|DEBUG|01|main|2024-05-27 13:51:54.792 PDT|SSLSocketImpl.java:1760|close the SSL connection (passive) Exception in thread "main" java.net.SocketException: Connection or outbound has closed at java.base/sun.security.ssl.SSLSocketImpl$AppOutputStream.write(SSLSocketImpl.java:1302) at org.apache.hc.core5.http.impl.io.DefaultBHttpClientConnection$1.write(DefaultBHttpClientConnection.java:231) at org.apache.hc.core5.http.impl.io.SessionOutputBufferImpl.flushBuffer(SessionOutputBufferImpl.java:117) at org.apache.hc.core5.http.impl.io.SessionOutputBufferImpl.write(SessionOutputBufferImpl.java:150) at org.apache.hc.core5.http.impl.io.ContentLengthOutputStream.write(ContentLengthOutputStream.java:112) at org.apache.hc.core5.http.io.entity.InputStreamEntity.writeTo(InputStreamEntity.java:106) at org.apache.hc.client5.http.impl.classic.RequestEntityProxy.writeTo(RequestEntityProxy.java:106) at org.apache.hc.core5.http.impl.io.DefaultBHttpClientConnection.sendRequestEntity(DefaultBHttpClientConnection.java:252) at org.apache.hc.core5.http.impl.io.HttpRequestExecutor.execute(HttpRequestExecutor.java:170) at org.apache.hc.core5.http.impl.io.HttpRequestExecutor.execute(HttpRequestExecutor.java:218) at org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager$InternalConnectionEndpoint.execute(PoolingHttpClientConnectionManager.java:594) at org.apache.hc.client5.http.impl.classic.InternalExecRuntime.execute(InternalExecRuntime.java:219) at org.apache.hc.client5.http.impl.classic.MainClientExec.execute(MainClientExec.java:107) at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51) at org.apache.hc.client5.http.impl.classic.ExecChainElement$1.proceed(ExecChainElement.java:57) at org.apache.hc.client5.http.impl.classic.ConnectExec.execute(ConnectExec.java:182) at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51) at org.apache.hc.client5.http.impl.classic.ExecChainElement$1.proceed(ExecChainElement.java:57) at org.apache.hc.client5.http.impl.classic.ProtocolExec.execute(ProtocolExec.java:165) at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51) at org.apache.hc.client5.http.impl.classic.ExecChainElement$1.proceed(ExecChainElement.java:57) at org.apache.hc.client5.http.impl.classic.ContentCompressionExec.execute(ContentCompressionExec.java:133) at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51) at org.apache.hc.client5.http.impl.classic.ExecChainElement$1.proceed(ExecChainElement.java:57) at org.apache.hc.client5.http.impl.classic.RedirectExec.execute(RedirectExec.java:115) at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51) at org.apache.hc.client5.http.impl.classic.InternalHttpClient.doExecute(InternalHttpClient.java:179) at org.apache.hc.client5.http.impl.classic.CloseableHttpClient.execute(CloseableHttpClient.java:75) at org.apache.hc.client5.http.impl.classic.CloseableHttpClient.execute(CloseableHttpClient.java:89) at software.amazon.awssdk.services.s3.internal.HalfCloseApache5Client.main(HalfCloseApache5Client.java:71) Suppressed: java.net.SocketException: Connection or outbound has closed at java.base/sun.security.ssl.SSLSocketImpl$AppOutputStream.write(SSLSocketImpl.java:1302) at org.apache.hc.core5.http.impl.io.DefaultBHttpClientConnection$1.write(DefaultBHttpClientConnection.java:231) at org.apache.hc.core5.http.impl.io.SessionOutputBufferImpl.flushBuffer(SessionOutputBufferImpl.java:117) at org.apache.hc.core5.http.impl.io.SessionOutputBufferImpl.flush(SessionOutputBufferImpl.java:126) at org.apache.hc.core5.http.impl.io.ContentLengthOutputStream.close(ContentLengthOutputStream.java:92) at org.apache.hc.core5.http.impl.io.DefaultBHttpClientConnection.sendRequestEntity(DefaultBHttpClientConnection.java:253) ... 22 more{noformat} > Request hangs if TLS 1.3 connection is half-closed > --------------------------------------------------- > > Key: HTTPCLIENT-2328 > URL: https://issues.apache.org/jira/browse/HTTPCLIENT-2328 > Project: HttpComponents HttpClient > Issue Type: Bug > Components: HttpClient (classic) > Affects Versions: 4.5.14, 5.3.1 > Reporter: Zoe Wang > Priority: Major > Attachments: HalfCloseApache5Client.Java, HalfCloseServer.java, > TlsHalfCloseApache4.java, keystore.jks > > > If a server with TLS 1.3 support closes the connection during the request, > more specifically, sending close_notify while the client is still writing to > socket, the request will hang indefinitely. It's not an issue with TLS 1.2 > because it uses duplex-close policy. With TLS 1.3's half-closed connection > policy, it seems Apache HTTP client is not able to detect connection closure > properly. We are able to reproduce the issue with both 4.x and 5.x. I should > note that HTTP URL connection does not have this issue. > The workaround it to set `jdk.tls.acknowledgeCloseNotify` to true (see > [https://bugs.openjdk.org/browse/JDK-8208526]), but that would require a lot > of users to make changes on their side. > > Steps to repro: > * Download the attached keystore file > * Update ksPath in the server code HalfCloseServer.java to where you > download the keystore > * Run the server, the server will begin listening on {{localhost:8081}} > * Create a random file of size 128MB and update client code "testFile" to > where the file is. > * Run the client, it should hang > ** If System.setProperty("jdk.tls.acknowledgeCloseNotify", "true") is > uncommented, it will not hang > ** It also won’t hang if we we force TLS1.2 > -- This message was sent by Atlassian Jira (v8.20.10#820010) --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@hc.apache.org For additional commands, e-mail: dev-h...@hc.apache.org