@@ -1798,13 +1798,59 @@ static size_t php_openssl_sockop_write(php_stream *stream, const char *buf, size
1798
1798
}
1799
1799
/* }}} */
1800
1800
1801
+ static void php_openssl_stream_wait_for_data (php_netstream_data_t * sock TSRMLS_DC )
1802
+ {
1803
+ int retval ;
1804
+ struct timeval * ptimeout ;
1805
+
1806
+ if (sock -> socket == -1 ) {
1807
+ return ;
1808
+ }
1809
+
1810
+ sock -> timeout_event = 0 ;
1811
+
1812
+ if (sock -> timeout .tv_sec == -1 )
1813
+ ptimeout = NULL ;
1814
+ else
1815
+ ptimeout = & sock -> timeout ;
1816
+
1817
+ while (1 ) {
1818
+ retval = php_pollfd_for (sock -> socket , PHP_POLLREADABLE , ptimeout );
1819
+
1820
+ if (retval == 0 )
1821
+ sock -> timeout_event = 1 ;
1822
+
1823
+ if (retval >= 0 )
1824
+ break ;
1825
+
1826
+ if (php_socket_errno () != EINTR )
1827
+ break ;
1828
+ }
1829
+ }
1830
+
1801
1831
static size_t php_openssl_sockop_read (php_stream * stream , char * buf , size_t count TSRMLS_DC ) /* {{{ */
1802
1832
{
1803
1833
php_openssl_netstream_data_t * sslsock = (php_openssl_netstream_data_t * )stream -> abstract ;
1834
+ php_netstream_data_t * sock ;
1804
1835
int nr_bytes = 0 ;
1805
1836
1806
1837
if (sslsock -> ssl_active ) {
1807
1838
int retry = 1 ;
1839
+ sock = (php_netstream_data_t * )stream -> abstract ;
1840
+
1841
+ /* The SSL_read() function will block indefinitely waiting for data on a blocking
1842
+ socket. If we don't poll for readability first this operation has the potential
1843
+ to hang forever. To avoid this scenario we poll with a timeout before performing
1844
+ the actual read. If it times out we're finished.
1845
+ */
1846
+ if (sock -> is_blocked ) {
1847
+ php_openssl_stream_wait_for_data (sock );
1848
+ if (sock -> timeout_event ) {
1849
+ stream -> eof = 1 ;
1850
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "SSL read operation timed out" );
1851
+ return nr_bytes ;
1852
+ }
1853
+ }
1808
1854
1809
1855
do {
1810
1856
nr_bytes = SSL_read (sslsock -> ssl_handle , buf , count );
0 commit comments