Skip to content

Commit 99f39d1

Browse files
committed
Merge pull request php-curl-class#101 from zachborboa/master
Fix php-curl-class#98: Implement download() method
2 parents 7c2245f + 2fb88ff commit 99f39d1

File tree

3 files changed

+90
-0
lines changed

3 files changed

+90
-0
lines changed

src/Curl/Curl.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,27 @@ public function options($url, $data = array())
182182
return $this->exec();
183183
}
184184

185+
public function download($url, $filename)
186+
{
187+
$fh = fopen($filename, 'wb');
188+
$this->setOpt(CURLOPT_FILE, $fh);
189+
$this->get($url);
190+
fclose($fh);
191+
192+
// Reset CURLOPT_FILE with STDOUT to avoid: "curl_exec(): CURLOPT_FILE
193+
// resource has gone away, resetting to default". Using null causes
194+
// "curl_setopt(): supplied argument is not a valid File-Handle
195+
// resource".
196+
$this->setOpt(CURLOPT_FILE, STDOUT);
197+
198+
// Reset CURLOPT_RETURNTRANSFER to tell cURL to return subsequent
199+
// responses as the return value of curl_exec(). Without this,
200+
// curl_exec() will revert to returning boolean values.
201+
$this->setOpt(CURLOPT_RETURNTRANSFER, true);
202+
203+
return ! $this->error;
204+
}
205+
185206
public function setBasicAuthentication($username, $password = '')
186207
{
187208
$this->setOpt(CURLOPT_HTTPAUTH, CURLAUTH_BASIC);

tests/PHPCurlClass/PHPCurlClassTest.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,50 @@ public function testOptionsRequestMethod()
330330
$this->assertEquals('OPTIONS', $test->curl->response_headers['X-REQUEST-METHOD']);
331331
}
332332

333+
public function testDownload()
334+
{
335+
// Upload a file.
336+
$upload_file_path = Helper\get_png();
337+
$upload_test = new Test();
338+
$upload_test->server('upload_response', 'POST', array(
339+
'image' => '@' . $upload_file_path,
340+
));
341+
$uploaded_file_path = $upload_test->curl->response->file_path;
342+
$this->assertNotEquals($upload_file_path, $uploaded_file_path);
343+
$this->assertEquals(md5_file($upload_file_path), $upload_test->curl->response_headers['ETag']);
344+
345+
// Download the file.
346+
$downloaded_file_path = tempnam('/tmp', 'php-curl-class.');
347+
$download_test = new Test();
348+
$download_test->curl->setHeader('X-DEBUG-TEST', 'download_response');
349+
$this->assertTrue($download_test->curl->download(Test::TEST_URL . '?' . http_build_query(array(
350+
'file_path' => $uploaded_file_path,
351+
)), $downloaded_file_path));
352+
$this->assertNotEquals($uploaded_file_path, $downloaded_file_path);
353+
354+
$this->assertEquals(filesize($upload_file_path), filesize($downloaded_file_path));
355+
$this->assertEquals(md5_file($upload_file_path), md5_file($downloaded_file_path));
356+
$this->assertEquals(md5_file($upload_file_path), $download_test->curl->response_headers['ETag']);
357+
358+
// Ensure successive requests set the appropriate values.
359+
$this->assertEquals('GET', $download_test->server('server', 'GET', array(
360+
'key' => 'REQUEST_METHOD',
361+
)));
362+
$this->assertFalse(is_bool($download_test->curl->response));
363+
$this->assertFalse(is_bool($download_test->curl->raw_response));
364+
365+
// Remove server file.
366+
$this->assertEquals('true', $download_test->server('upload_cleanup', 'POST', array(
367+
'file_path' => $uploaded_file_path,
368+
)));
369+
370+
unlink($upload_file_path);
371+
unlink($downloaded_file_path);
372+
$this->assertFalse(file_exists($upload_file_path));
373+
$this->assertFalse(file_exists($uploaded_file_path));
374+
$this->assertFalse(file_exists($downloaded_file_path));
375+
}
376+
333377
public function testBasicHttpAuth401Unauthorized()
334378
{
335379
$test = new Test();

tests/PHPCurlClass/server.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
<?php
2+
require 'Helper.php';
3+
4+
use \Helper\Test;
5+
26
$http_raw_post_data = file_get_contents('php://input');
37
$_PUT = array();
48
$_PATCH = array();
@@ -117,6 +121,27 @@
117121
$rss->appendChild($channel);
118122
echo $doc->saveXML();
119123
exit;
124+
} elseif ($test === 'upload_response') {
125+
$tmp_filename = tempnam('/tmp', 'php-curl-class.');
126+
move_uploaded_file($_FILES['image']['tmp_name'], $tmp_filename);
127+
header('Content-Type: application/json');
128+
header('ETag: ' . md5_file($tmp_filename));
129+
echo json_encode(array(
130+
'file_path' => $tmp_filename,
131+
));
132+
exit;
133+
} elseif ($test === 'upload_cleanup') {
134+
$unsafe_file_path = $_POST['file_path'];
135+
echo var_export(unlink($unsafe_file_path), true);
136+
exit;
137+
} elseif ($test === 'download_response') {
138+
$unsafe_file_path = $_GET['file_path'];
139+
header('Content-Type: image/png');
140+
header('Content-Disposition: attachment; filename="image.png"');
141+
header('Content-Length: ' . filesize($unsafe_file_path));
142+
header('ETag: ' . md5_file($unsafe_file_path));
143+
readfile($unsafe_file_path);
144+
exit;
120145
} elseif ($test === 'error_message') {
121146
if (function_exists('http_response_code')) {
122147
http_response_code(401);

0 commit comments

Comments
 (0)