Skip to content

Instantly share code, notes, and snippets.

@spaze
Last active August 29, 2015 14:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save spaze/5b071ca79999c4b3fc70 to your computer and use it in GitHub Desktop.
Save spaze/5b071ca79999c4b3fc70 to your computer and use it in GitHub Desktop.
<?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