-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Open
Description
Environment
IOS
Current Behavior
Create a HTTPSClientSession, sendRequest and receiveResponse. Move app to background and move it back to foreground a few minutes later. Then the underlying socket will be invalid and read function fall into infinite loop.
Expect Behavior
read function return error when socket is invalid.
Reason
poco/NetSSL_OpenSSL/src/SecureSocketImpl.cpp
Lines 312 to 336 in de61f00
| int SecureSocketImpl::receiveBytes(void* buffer, int length, int flags) | |
| { | |
| poco_assert (_pSocket->initialized()); | |
| poco_check_ptr (_pSSL); | |
| int rc; | |
| if (_needHandshake) | |
| { | |
| rc = completeHandshake(); | |
| if (rc == 1) | |
| verifyPeerCertificate(); | |
| else | |
| return rc; | |
| } | |
| do | |
| { | |
| rc = SSL_read(_pSSL, buffer, length); | |
| } | |
| while (mustRetry(rc)); | |
| if (rc <= 0) | |
| { | |
| return handleError(rc); | |
| } | |
| return rc; | |
| } |
when socket is invalid, SSL_read return -1, but mustRetry always return true, so receiveBytes fall into infinite loop. This is because poll always return true when socket is invalid(platform specific).
poco/NetSSL_OpenSSL/src/SecureSocketImpl.cpp
Lines 437 to 445 in de61f00
| case SSL_ERROR_WANT_READ: | |
| if (_pSocket->getBlocking()) | |
| { | |
| if (_pSocket->poll(_pSocket->getReceiveTimeout(), Poco::Net::Socket::SELECT_READ)) | |
| return true; | |
| else | |
| throw Poco::TimeoutException(); | |
| } | |
| break; |
Possible Solution
SSL_MODE_AUTO_RETRY is set by poco:
poco/NetSSL_OpenSSL/src/Context.cpp
Line 181 in de61f00
| SSL_CTX_set_mode(_pSSLContext, SSL_MODE_AUTO_RETRY); |
and socket is blocking, there is no need to retry when SSL_read return error, reference: https://www.openssl.org/docs/man1.1.1/man3/SSL_read.html
revert f7ba58c can fix it.
Reactions are currently unavailable