Last active
August 29, 2015 14:14
-
-
Save spaze/5b071ca79999c4b3fc70 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Check if the file is over given size. | |
* | |
* Use Content-Length header or partially download a file to see if it is bigger than specified size. | |
* Downloads up to the $limit bytes but not more. | |
* | |
* Enjoy. | |
*/ | |
class CheckLength | |
{ | |
private $downloaded; | |
private $expected; | |
private $limit = 1024; | |
private $allowedTypes = array(); | |
private $contentType; | |
private function handleProgress53($downloadExpected, $downloaded, $uploadExpected, $uploaded) | |
{ | |
return $this->handleDownloadProgress($downloadExpected, $downloaded); | |
} | |
private function handleProgress55($curl, $downloadExpected, $downloaded, $uploadExpected, $uploaded) | |
{ | |
return $this->handleDownloadProgress($downloadExpected, $downloaded); | |
} | |
private function handleDownloadProgress($downloadExpected, $downloaded) | |
{ | |
if (isset($this->contentType) && !in_array($this->contentType, $this->allowedTypes)) { | |
return 1; | |
} | |
$this->expected = $downloadExpected; | |
if ($downloadExpected) { | |
return 1; | |
} else { | |
$this->downloaded = $downloaded; | |
if ($this->downloaded > $this->limit) { | |
return 1; | |
} | |
} | |
} | |
private function handleHeader($curl, $header) | |
{ | |
$header = strtolower($header); | |
$line = explode(':', $header, 2); | |
if (isset($line[1])) { | |
if (trim($line[0]) === 'content-type') { | |
$type = explode(';', $line[1], 2); | |
$this->contentType = trim($type[0]); | |
} | |
} | |
return strlen($header); | |
} | |
public function check($url) | |
{ | |
$this->downloaded = 0; | |
$this->contentType = null; | |
$curl = curl_init(); | |
curl_setopt($curl, CURLOPT_URL, $url); | |
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); | |
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); | |
curl_setopt($curl, CURLOPT_NOPROGRESS, 0); | |
if (PHP_VERSION_ID >= 50500) { | |
curl_setopt($curl, CURLOPT_PROGRESSFUNCTION, [$this, 'handleProgress55']); | |
} elseif (PHP_VERSION_ID >= 50300) { | |
curl_setopt($curl, CURLOPT_PROGRESSFUNCTION, [$this, 'handleProgress53']); | |
} else { | |
throw new \Exception('No support for CURLOPT_PROGRESSFUNCTION'); | |
} | |
curl_setopt($curl, CURLOPT_HEADERFUNCTION, [$this, 'handleHeader']); | |
curl_exec($curl); | |
} | |
public function setLimit($limit) | |
{ | |
$this->limit = $limit; | |
} | |
public function setAllowedTypes($allowedTypes) | |
{ | |
$this->allowedTypes = $allowedTypes; | |
} | |
public function getExpected() | |
{ | |
return $this->expected; | |
} | |
public function getContentType() | |
{ | |
return $this->contentType; | |
} | |
public function getDownloaded() | |
{ | |
return $this->downloaded; | |
} | |
} | |
$urls = array( | |
'https://www.michalspacek.cz', // a web page | |
'http://cz1.php.net/get/php-5.6.5.tar.bz2/from/this/mirror', // 10+ MB file download with Content-Length | |
'http://test.localhost/test-10mb.php', // 10+ MB file download without Content-Length | |
); | |
$limit = 1024 * 1024; | |
$types = array( | |
'text/html', | |
'foo/bar', | |
); | |
$c = new CheckLength(); | |
$c->setLimit($limit); | |
$c->setAllowedTypes($types); | |
foreach ($urls as $url) { | |
$c->check($url); | |
$expected = $c->getExpected(); | |
$downloaded = $c->getDownloaded(); | |
$contentType = $c->getContentType(); | |
echo "URL: $url\n"; | |
echo "Content-Type: $contentType\n"; | |
if (!in_array($contentType, $types)) { | |
echo "File not with allowed content type\n"; | |
} | |
echo "File size: $expected\n"; | |
echo "Actually downloaded: $downloaded\n"; | |
if ($expected > $limit || $downloaded > $limit) { | |
echo "File is bigger than $limit bytes\n"; | |
} | |
echo "\n"; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment