Skip to content

Commit 8761c4e

Browse files
committed
Fix phpGH-20240: FTP with SSL: ftp_fput(): Connection timed out on successful writes
Looking at the strace, the timeout is only 1s which may be too low anyway for checking for a response, but some servers also don't end up replying finally anyway and close the connection already. `data_available` was originally used for non-blocking downloads/uploads and then reused for the shutdown sequence, but its error handling was never adjusted to be silent. Closes phpGH-20294.
1 parent 61b0d58 commit 8761c4e

File tree

2 files changed

+12
-3
lines changed

2 files changed

+12
-3
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ PHP NEWS
2121
. Fixed bug GH-19974 (fpm_status_export_to_zval segfault for parallel
2222
execution). (Jakub Zelenka, txuna)
2323

24+
- FTP:
25+
. Fixed bug GH-20240 (FTP with SSL: ftp_fput(): Connection timed out on
26+
successful writes). (nielsdos)
27+
2428
- GD:
2529
. Fixed bug GH-20070 (Return type violation in imagefilter when an invalid
2630
filter is provided). (Girgias)

ext/ftp/ftp.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1605,14 +1605,17 @@ my_recv(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t len)
16051605

16061606
/* {{{ data_available */
16071607
int
1608-
data_available(ftpbuf_t *ftp, php_socket_t s)
1608+
data_available(ftpbuf_t *ftp, php_socket_t s, bool silent)
16091609
{
16101610
int n;
16111611

16121612
n = my_poll(s, PHP_POLLREADABLE, 1000);
16131613
if (n < 1) {
16141614
char buf[256];
16151615
if (n == 0) {
1616+
if (silent) {
1617+
return 0;
1618+
}
16161619
#ifdef PHP_WIN32
16171620
_set_errno(ETIMEDOUT);
16181621
#else
@@ -1938,7 +1941,9 @@ static void ftp_ssl_shutdown(ftpbuf_t *ftp, php_socket_t fd, SSL *ssl_handle) {
19381941
done = 0;
19391942
}
19401943

1941-
while (!done && data_available(ftp, fd)) {
1944+
/* Don't report timeouts on the control channel if we're negotiating a shutdown already.
1945+
* Some servers don't put a final response. */
1946+
while (!done && data_available(ftp, fd, true)) {
19421947
ERR_clear_error();
19431948
nread = SSL_read(ssl_handle, buf, sizeof(buf));
19441949
if (nread <= 0) {
@@ -2198,7 +2203,7 @@ ftp_nb_continue_read(ftpbuf_t *ftp)
21982203
data = ftp->data;
21992204

22002205
/* check if there is already more data */
2201-
if (!data_available(ftp, data->fd)) {
2206+
if (!data_available(ftp, data->fd, false)) {
22022207
return PHP_FTP_MOREDATA;
22032208
}
22042209

0 commit comments

Comments
 (0)