@@ -4048,6 +4048,7 @@ - (void)doReadData
4048
4048
unsigned long estimatedBytesAvailable;
4049
4049
4050
4050
#if TARGET_OS_IPHONE
4051
+ {
4051
4052
if (flags & kSocketSecure )
4052
4053
{
4053
4054
// Relegated to using CFStream... :( Boo! Give us SecureTransport Apple!
@@ -4064,8 +4065,9 @@ - (void)doReadData
4064
4065
hasBytesAvailable = (estimatedBytesAvailable > 0 );
4065
4066
4066
4067
}
4068
+ }
4067
4069
#else
4068
-
4070
+ {
4069
4071
estimatedBytesAvailable = socketFDBytesAvailable;
4070
4072
4071
4073
if (flags & kSocketSecure )
@@ -4105,7 +4107,7 @@ - (void)doReadData
4105
4107
}
4106
4108
4107
4109
hasBytesAvailable = (estimatedBytesAvailable > 0 );
4108
-
4110
+ }
4109
4111
#endif
4110
4112
4111
4113
if ((hasBytesAvailable == NO ) && ([partialReadBuffer length ] == 0 ))
@@ -4133,12 +4135,12 @@ - (void)doReadData
4133
4135
if (flags & kStartingWriteTLS )
4134
4136
{
4135
4137
#if !TARGET_OS_IPHONE
4136
-
4138
+ {
4137
4139
// We are in the process of a SSL Handshake.
4138
4140
// We were waiting for incoming data which has just arrived.
4139
4141
4140
4142
[self continueSSLHandshake ];
4141
-
4143
+ }
4142
4144
#endif
4143
4145
}
4144
4146
else
@@ -4339,7 +4341,7 @@ - (void)doReadData
4339
4341
if (flags & kSocketSecure )
4340
4342
{
4341
4343
#if TARGET_OS_IPHONE
4342
-
4344
+ {
4343
4345
CFIndex result = CFReadStreamRead (readStream, buffer, (CFIndex)bytesToRead);
4344
4346
LogVerbose (@" CFReadStreamRead(): result = %i " , (int )result);
4345
4347
@@ -4367,11 +4369,31 @@ - (void)doReadData
4367
4369
// The actual number of bytes read was likely more due to the overhead of the encryption.
4368
4370
// So we reset our flag, and rely on the next callback to alert us of more data.
4369
4371
flags &= ~kSecureSocketHasBytesAvailable ;
4370
-
4372
+ }
4371
4373
#else
4374
+ {
4375
+ // The documentation from Apple states:
4376
+ //
4377
+ // "a read operation might return errSSLWouldBlock,
4378
+ // indicating that less data than requested was actually transferred"
4379
+ //
4380
+ // However, starting around 10.7, the function will sometimes return noErr,
4381
+ // even if it didn't read as much data as requested. So we need to watch out for that.
4382
+
4383
+ OSStatus result;
4384
+ do
4385
+ {
4386
+ void *loop_buffer = buffer + bytesRead;
4387
+ size_t loop_bytesToRead = (size_t )bytesToRead - bytesRead;
4388
+ size_t loop_bytesRead = 0 ;
4389
+
4390
+ result = SSLRead (sslContext, loop_buffer, loop_bytesToRead, &loop_bytesRead);
4391
+ LogVerbose (@" read from secure socket = %u " , (unsigned )bytesRead);
4392
+
4393
+ bytesRead += loop_bytesRead;
4394
+
4395
+ } while ((result == noErr) && (bytesRead < bytesToRead));
4372
4396
4373
- OSStatus result = SSLRead (sslContext, buffer, (size_t )bytesToRead, &bytesRead);
4374
- LogVerbose (@" read from secure socket = %u " , (unsigned )bytesRead);
4375
4397
4376
4398
if (result != noErr)
4377
4399
{
@@ -4395,7 +4417,7 @@ - (void)doReadData
4395
4417
4396
4418
// Do not modify socketFDBytesAvailable.
4397
4419
// It will be updated via the SSLReadFunction().
4398
-
4420
+ }
4399
4421
#endif
4400
4422
}
4401
4423
else
0 commit comments