Skip to content

Commit 27ba06e

Browse files
authored
Merge pull request php-curl-class#604 from zachborboa/602
Unify download implementation of MultiCurl::addDownload with Curl::download
2 parents 11dbef8 + 7b70bc2 commit 27ba06e

File tree

2 files changed

+24
-6
lines changed

2 files changed

+24
-6
lines changed

src/Curl/Curl.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class Curl
3939
public $errorCallback = null;
4040
public $completeCallback = null;
4141
public $fileHandle = null;
42-
private $downloadFileName = null;
42+
public $downloadFileName = null;
4343

4444
public $attempts = 0;
4545
public $retries = 0;

src/Curl/MultiCurl.php

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,15 +85,33 @@ public function addDownload($url, $mixed_filename)
8585

8686
// Use tmpfile() or php://temp to avoid "Too many open files" error.
8787
if (is_callable($mixed_filename)) {
88-
$callback = $mixed_filename;
89-
$curl->downloadCompleteCallback = $callback;
88+
$curl->downloadCompleteCallback = $mixed_filename;
89+
$curl->downloadFileName = null;
9090
$curl->fileHandle = tmpfile();
9191
} else {
9292
$filename = $mixed_filename;
93-
$curl->downloadCompleteCallback = function ($instance, $fh) use ($filename) {
94-
file_put_contents($filename, stream_get_contents($fh));
95-
};
93+
94+
// Use a temporary file when downloading. Not using a temporary file can cause an error when an existing
95+
// file has already fully completed downloading and a new download is started with the same destination save
96+
// path. The download request will include header "Range: bytes=$filesize-" which is syntactically valid,
97+
// but unsatisfiable.
98+
$download_filename = $filename . '.pccdownload';
99+
100+
$mode = 'wb';
101+
// Attempt to resume download only when a temporary download file exists and is not empty.
102+
if (is_file($download_filename) && $filesize = filesize($download_filename)) {
103+
$mode = 'ab';
104+
$first_byte_position = $filesize;
105+
$range = $first_byte_position . '-';
106+
$curl->setOpt(CURLOPT_RANGE, $range);
107+
}
108+
$curl->downloadFileName = $download_filename;
96109
$curl->fileHandle = fopen('php://temp', 'wb');
110+
111+
// Move the downloaded temporary file to the destination save path.
112+
$curl->downloadCompleteCallback = function ($instance, $fh) use ($download_filename) {
113+
file_put_contents($download_filename, stream_get_contents($fh));
114+
};
97115
}
98116

99117
$curl->setOpt(CURLOPT_FILE, $curl->fileHandle);

0 commit comments

Comments
 (0)