@@ -204,13 +204,59 @@ static size_t php_openssl_sockop_write(php_stream *stream, const char *buf, size
204
204
return didwrite ;
205
205
}
206
206
207
+ static void php_openssl_stream_wait_for_data (php_netstream_data_t * sock TSRMLS_DC )
208
+ {
209
+ int retval ;
210
+ struct timeval * ptimeout ;
211
+
212
+ if (sock -> socket == -1 ) {
213
+ return ;
214
+ }
215
+
216
+ sock -> timeout_event = 0 ;
217
+
218
+ if (sock -> timeout .tv_sec == -1 )
219
+ ptimeout = NULL ;
220
+ else
221
+ ptimeout = & sock -> timeout ;
222
+
223
+ while (1 ) {
224
+ retval = php_pollfd_for (sock -> socket , PHP_POLLREADABLE , ptimeout );
225
+
226
+ if (retval == 0 )
227
+ sock -> timeout_event = 1 ;
228
+
229
+ if (retval >= 0 )
230
+ break ;
231
+
232
+ if (php_socket_errno () != EINTR )
233
+ break ;
234
+ }
235
+ }
236
+
207
237
static size_t php_openssl_sockop_read (php_stream * stream , char * buf , size_t count TSRMLS_DC )
208
238
{
209
239
php_openssl_netstream_data_t * sslsock = (php_openssl_netstream_data_t * )stream -> abstract ;
240
+ php_netstream_data_t * sock ;
210
241
int nr_bytes = 0 ;
211
242
212
243
if (sslsock -> ssl_active ) {
213
244
int retry = 1 ;
245
+ sock = (php_netstream_data_t * )stream -> abstract ;
246
+
247
+ /* The SSL_read() function will block indefinitely waiting for data on a blocking
248
+ socket. If we don't poll for readability first this operation has the potential
249
+ to hang forever. To avoid this scenario we poll with a timeout before performing
250
+ the actual read. If it times out we're finished.
251
+ */
252
+ if (sock -> is_blocked ) {
253
+ php_openssl_stream_wait_for_data (sock );
254
+ if (sock -> timeout_event ) {
255
+ stream -> eof = 1 ;
256
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "SSL read operation timed out" );
257
+ return nr_bytes ;
258
+ }
259
+ }
214
260
215
261
do {
216
262
nr_bytes = SSL_read (sslsock -> ssl_handle , buf , count );
0 commit comments