mirror of
https://github.com/getgrav/grav.git
synced 2025-12-08 08:49:57 +01:00
Merge branch 'develop' into feature/introduce-testing
This commit is contained in:
47
CHANGELOG.md
47
CHANGELOG.md
@@ -1,10 +1,43 @@
|
|||||||
|
# v1.0.7
|
||||||
|
## 01/XX/2016
|
||||||
|
|
||||||
|
1. [](#new)
|
||||||
|
* Added `composer create-project` as an additional installation method #585
|
||||||
|
* New optional system config setting to strip home from page routs and urls #561
|
||||||
|
* Added Greek, Finnish, Norwegian, Polish, Portuguese, and Romanian languages
|
||||||
|
* Added new `Page->topParent()` method to return top most parent of a page
|
||||||
|
* Added plugins configuration tab to debugger
|
||||||
|
* Added support for APCu and PHP7.0 via new Doctrine Cache release
|
||||||
|
* Added global setting for `twig_first` processing (false by default)
|
||||||
|
* New configuration options for Session settings #553
|
||||||
|
1. [](#improved)
|
||||||
|
* Use `URI->host()` for session domain
|
||||||
|
* Add support for `open_basedir` when installing packages via GPM
|
||||||
|
* Improved `Utils::generateNonceString()` method to handle reverse proxies
|
||||||
|
* Optimized core thumbnails saving 38% in file size
|
||||||
|
* Added new `bin/gpm index --installed-only` option
|
||||||
|
* Improved GPM errors to provider more helpful diagnostic of issues
|
||||||
|
* Removed old hardcoded PHP version references
|
||||||
|
* Moved `onPageContentProcessed()` event so it's fired more reliably
|
||||||
|
* Maintain md5 keys during sorting of Assets #566
|
||||||
|
* Update to Caddyfile for Caddy web server
|
||||||
|
1. [](#bugfix)
|
||||||
|
* Fixed an issue with cache/config checksum not being set on cache load
|
||||||
|
* Fix for page blueprint and theme inheritance issue #534
|
||||||
|
* Set `ZipBackup` timeout to 10 minutes if possible
|
||||||
|
* Fix case where we only have inline data for CSS or JS #565
|
||||||
|
* Fix `bin/grav sandbox` command to work with new `webserver-config` folder
|
||||||
|
* Fix for markdown attributes on external URLs
|
||||||
|
* Fixed issue where `data:` page header was acting as `publish_date:`
|
||||||
|
* Fix for special characters in URL parameters (e.g. /tag:c++) #541
|
||||||
|
|
||||||
# v1.0.6
|
# v1.0.6
|
||||||
## 12/22/2015
|
## 12/22/2015
|
||||||
|
|
||||||
1. [](#new)
|
1. [](#new)
|
||||||
* Set minimum requirements to [PHP 5.5.9](http://bit.ly/1Jt9OXO)
|
* Set minimum requirements to [PHP 5.5.9](http://bit.ly/1Jt9OXO)
|
||||||
* Added `saveConfig` to Themes
|
* Added `saveConfig` to Themes
|
||||||
1. [](#improved)
|
1. [](#improved)
|
||||||
* Updated Whoops to new 2.0 version (PHP 7.0 compatible)
|
* Updated Whoops to new 2.0 version (PHP 7.0 compatible)
|
||||||
* Moved sample web server configs into dedicated directory
|
* Moved sample web server configs into dedicated directory
|
||||||
* FastCGI will use Apache's `mod_deflate` if gzip turned off
|
* FastCGI will use Apache's `mod_deflate` if gzip turned off
|
||||||
@@ -14,7 +47,7 @@
|
|||||||
* Fix lang prefix in url twig variables #523
|
* Fix lang prefix in url twig variables #523
|
||||||
* Fix case insensitive HTTPS check #535
|
* Fix case insensitive HTTPS check #535
|
||||||
* Field field validation handles case `multiple` missing
|
* Field field validation handles case `multiple` missing
|
||||||
|
|
||||||
# v1.0.5
|
# v1.0.5
|
||||||
## 12/18/2015
|
## 12/18/2015
|
||||||
|
|
||||||
@@ -25,7 +58,7 @@
|
|||||||
* Use Grav's fork of Parsedown until PR is merged
|
* Use Grav's fork of Parsedown until PR is merged
|
||||||
* New function to persist plugin configuration to disk
|
* New function to persist plugin configuration to disk
|
||||||
* GPM `selfupgrade` will now check PHP version requirements
|
* GPM `selfupgrade` will now check PHP version requirements
|
||||||
1. [](#improved)
|
1. [](#improved)
|
||||||
* If the field allows multiple files, return array
|
* If the field allows multiple files, return array
|
||||||
* Handle non-array values in file validation
|
* Handle non-array values in file validation
|
||||||
1. [](#bugfix)
|
1. [](#bugfix)
|
||||||
@@ -54,7 +87,7 @@
|
|||||||
# v1.0.1
|
# v1.0.1
|
||||||
## 12/11/2015
|
## 12/11/2015
|
||||||
|
|
||||||
1. [](#improved)
|
1. [](#improved)
|
||||||
* Reduced package sizes by removing extra vendor dev bits
|
* Reduced package sizes by removing extra vendor dev bits
|
||||||
1. [](#bugfix)
|
1. [](#bugfix)
|
||||||
* Fix issue when you enable debugger from admin plugin
|
* Fix issue when you enable debugger from admin plugin
|
||||||
@@ -67,7 +100,7 @@
|
|||||||
* Added setters to set state of CSS/JS pipelining
|
* Added setters to set state of CSS/JS pipelining
|
||||||
* Added `user/accounts` to `.gitignore`
|
* Added `user/accounts` to `.gitignore`
|
||||||
* Added configurable permissions option for Image cache
|
* Added configurable permissions option for Image cache
|
||||||
1. [](#improved)
|
1. [](#improved)
|
||||||
* Hungarian translation updated
|
* Hungarian translation updated
|
||||||
* Refactored Theme initialization for improved flexibility
|
* Refactored Theme initialization for improved flexibility
|
||||||
* Wrapped security section of account blueprints in an 'super user' authorize check
|
* Wrapped security section of account blueprints in an 'super user' authorize check
|
||||||
@@ -101,7 +134,7 @@
|
|||||||
* Automatically create unique security salt for each configuration
|
* Automatically create unique security salt for each configuration
|
||||||
* Added Hungarian translation
|
* Added Hungarian translation
|
||||||
* Added support for User groups
|
* Added support for User groups
|
||||||
1. [](#improved)
|
1. [](#improved)
|
||||||
* Improved robots.txt to disallow crawling of non-user folders
|
* Improved robots.txt to disallow crawling of non-user folders
|
||||||
* Nonces only generated once per action and process
|
* Nonces only generated once per action and process
|
||||||
* Added IP into Nonce string calculation
|
* Added IP into Nonce string calculation
|
||||||
|
|||||||
10
README.md
10
README.md
@@ -23,12 +23,20 @@ The underlying architecture of Grav is designed to use well-established and _bes
|
|||||||
|
|
||||||
# QuickStart
|
# QuickStart
|
||||||
|
|
||||||
You have two options to get Grav:
|
These are the options to get Grav:
|
||||||
|
|
||||||
### Downloading a Grav Package
|
### Downloading a Grav Package
|
||||||
|
|
||||||
You can download a **ready-built** package from the [Downloads page on http://getgrav.org](http://getgrav.org/downloads)
|
You can download a **ready-built** package from the [Downloads page on http://getgrav.org](http://getgrav.org/downloads)
|
||||||
|
|
||||||
|
### With composer
|
||||||
|
|
||||||
|
You can create a new project with the latest **stable** Grav release with the following command:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ composer create-project getgrav/grav ~/webroot/grav
|
||||||
|
```
|
||||||
|
|
||||||
### From GitHub
|
### From GitHub
|
||||||
|
|
||||||
1. Clone the Grav repository from [https://github.com/getgrav/grav]() to a folder in the webroot of your server, e.g. `~/webroot/grav`. Launch a **terminal** or **console** and navigate to the webroot folder:
|
1. Clone the Grav repository from [https://github.com/getgrav/grav]() to a folder in the webroot of your server, e.g. `~/webroot/grav`. Launch a **terminal** or **console** and navigate to the webroot folder:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "getgrav/grav",
|
"name": "getgrav/grav",
|
||||||
"type": "library",
|
"type": "project",
|
||||||
"description": "Modern, Crazy Fast, Ridiculously Easy and Amazingly Powerful Flat-File CMS",
|
"description": "Modern, Crazy Fast, Ridiculously Easy and Amazingly Powerful Flat-File CMS",
|
||||||
"keywords": ["cms","flat-file cms","flat cms","flatfile cms","php"],
|
"keywords": ["cms","flat-file cms","flat cms","flatfile cms","php"],
|
||||||
"homepage": "http://getgrav.org",
|
"homepage": "http://getgrav.org",
|
||||||
@@ -8,7 +8,6 @@
|
|||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.5.9",
|
"php": ">=5.5.9",
|
||||||
"twig/twig": "~1.23",
|
"twig/twig": "~1.23",
|
||||||
"erusev/parsedown": "dev-master as 1.6.0",
|
|
||||||
"erusev/parsedown-extra": "~0.7",
|
"erusev/parsedown-extra": "~0.7",
|
||||||
"symfony/yaml": "~2.8",
|
"symfony/yaml": "~2.8",
|
||||||
"symfony/console": "~2.8",
|
"symfony/console": "~2.8",
|
||||||
@@ -44,5 +43,13 @@
|
|||||||
},
|
},
|
||||||
"archive": {
|
"archive": {
|
||||||
"exclude": ["VERSION"]
|
"exclude": ["VERSION"]
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"post-create-project-cmd": "bin/grav install"
|
||||||
|
},
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-develop": "1.x-dev"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ class Cache extends Getters
|
|||||||
|
|
||||||
protected $driver_name;
|
protected $driver_name;
|
||||||
|
|
||||||
|
protected $driver_setting;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
@@ -108,13 +110,15 @@ class Cache extends Getters
|
|||||||
// Cache key allows us to invalidate all cache on configuration changes.
|
// Cache key allows us to invalidate all cache on configuration changes.
|
||||||
$this->key = ($prefix ? $prefix : 'g') . '-' . substr(md5($uri->rootUrl(true) . $this->config->key() . GRAV_VERSION), 2, 8);
|
$this->key = ($prefix ? $prefix : 'g') . '-' . substr(md5($uri->rootUrl(true) . $this->config->key() . GRAV_VERSION), 2, 8);
|
||||||
|
|
||||||
|
$this->driver_setting = $this->config->get('system.cache.driver');
|
||||||
|
|
||||||
$this->driver = $this->getCacheDriver();
|
$this->driver = $this->getCacheDriver();
|
||||||
|
|
||||||
// Set the cache namespace to our unique key
|
// Set the cache namespace to our unique key
|
||||||
$this->driver->setNamespace($this->key);
|
$this->driver->setNamespace($this->key);
|
||||||
|
|
||||||
// Dump Cache state
|
// Dump Cache state
|
||||||
$grav['debugger']->addMessage('Cache: [' . ($this->enabled ? 'true' : 'false') . '] Driver: [' . $this->driver_name . ']');
|
$grav['debugger']->addMessage('Cache: [' . ($this->enabled ? 'true' : 'false') . '] Setting: [' . $this->driver_setting . '] Driver: [' . $this->driver_name . ']');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,7 +131,7 @@ class Cache extends Getters
|
|||||||
*/
|
*/
|
||||||
public function getCacheDriver()
|
public function getCacheDriver()
|
||||||
{
|
{
|
||||||
$setting = $this->config->get('system.cache.driver');
|
$setting = $this->driver_setting;
|
||||||
$driver_name = 'file';
|
$driver_name = 'file';
|
||||||
|
|
||||||
if (!$setting || $setting == 'auto') {
|
if (!$setting || $setting == 'auto') {
|
||||||
|
|||||||
@@ -7,23 +7,26 @@ class Response
|
|||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The callback for the progress
|
* The callback for the progress
|
||||||
|
*
|
||||||
* @var callable Either a function or callback in array notation
|
* @var callable Either a function or callback in array notation
|
||||||
*/
|
*/
|
||||||
public static $callback = null;
|
public static $callback = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Which method to use for HTTP calls, can be 'curl', 'fopen' or 'auto'. Auto is default and fopen is the preferred method
|
* Which method to use for HTTP calls, can be 'curl', 'fopen' or 'auto'. Auto is default and fopen is the preferred method
|
||||||
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
private static $method = 'auto';
|
private static $method = 'auto';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default parameters for `curl` and `fopen`
|
* Default parameters for `curl` and `fopen`
|
||||||
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private static $defaults = [
|
private static $defaults = [
|
||||||
|
|
||||||
'curl' => [
|
'curl' => [
|
||||||
CURLOPT_REFERER => 'Grav GPM',
|
CURLOPT_REFERER => 'Grav GPM',
|
||||||
CURLOPT_USERAGENT => 'Grav GPM',
|
CURLOPT_USERAGENT => 'Grav GPM',
|
||||||
CURLOPT_RETURNTRANSFER => true,
|
CURLOPT_RETURNTRANSFER => true,
|
||||||
@@ -51,7 +54,9 @@ class Response
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the preferred method to use for making HTTP calls.
|
* Sets the preferred method to use for making HTTP calls.
|
||||||
|
*
|
||||||
* @param string $method Default is `auto`
|
* @param string $method Default is `auto`
|
||||||
|
*
|
||||||
* @return Response
|
* @return Response
|
||||||
*/
|
*/
|
||||||
public static function setMethod($method = 'auto')
|
public static function setMethod($method = 'auto')
|
||||||
@@ -67,9 +72,11 @@ class Response
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes a request to the URL by using the preferred method
|
* Makes a request to the URL by using the preferred method
|
||||||
* @param string $uri URL to call
|
*
|
||||||
* @param array $options An array of parameters for both `curl` and `fopen`
|
* @param string $uri URL to call
|
||||||
|
* @param array $options An array of parameters for both `curl` and `fopen`
|
||||||
* @param callable $callback Either a function or callback in array notation
|
* @param callable $callback Either a function or callback in array notation
|
||||||
|
*
|
||||||
* @return string The response of the request
|
* @return string The response of the request
|
||||||
*/
|
*/
|
||||||
public static function get($uri = '', $options = [], $callback = null)
|
public static function get($uri = '', $options = [], $callback = null)
|
||||||
@@ -83,7 +90,8 @@ class Response
|
|||||||
if (!Utils::isFunctionDisabled('set_time_limit') && !ini_get('safe_mode') && function_exists('set_time_limit')) {
|
if (!Utils::isFunctionDisabled('set_time_limit') && !ini_get('safe_mode') && function_exists('set_time_limit')) {
|
||||||
set_time_limit(0);
|
set_time_limit(0);
|
||||||
}
|
}
|
||||||
} catch (\Exception $e) {}
|
} catch (\Exception $e) {
|
||||||
|
}
|
||||||
|
|
||||||
$options = array_replace_recursive(self::$defaults, $options);
|
$options = array_replace_recursive(self::$defaults, $options);
|
||||||
$method = 'get' . ucfirst(strtolower(self::$method));
|
$method = 'get' . ucfirst(strtolower(self::$method));
|
||||||
@@ -92,9 +100,31 @@ class Response
|
|||||||
return static::$method($uri, $options, $callback);
|
return static::$method($uri, $options, $callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if cURL is available
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public static function isCurlAvailable()
|
||||||
|
{
|
||||||
|
return function_exists('curl_version');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the remote fopen request is enabled in PHP
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public static function isFopenAvailable()
|
||||||
|
{
|
||||||
|
return preg_match('/1|yes|on|true/i', ini_get('allow_url_fopen'));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Progress normalized for cURL and Fopen
|
* Progress normalized for cURL and Fopen
|
||||||
|
*
|
||||||
* @param args Variable length of arguments passed in by stream method
|
* @param args Variable length of arguments passed in by stream method
|
||||||
|
*
|
||||||
* @return array Normalized array with useful data.
|
* @return array Normalized array with useful data.
|
||||||
* Format: ['code' => int|false, 'filesize' => bytes, 'transferred' => bytes, 'percent' => int]
|
* Format: ['code' => int|false, 'filesize' => bytes, 'transferred' => bytes, 'percent' => int]
|
||||||
*/
|
*/
|
||||||
@@ -115,7 +145,7 @@ class Response
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($bytes_transferred > 0) {
|
if ($bytes_transferred > 0) {
|
||||||
if ($notification_code == STREAM_NOTIFY_PROGRESS|STREAM_NOTIFY_COMPLETED || $isCurlResource) {
|
if ($notification_code == STREAM_NOTIFY_PROGRESS | STREAM_NOTIFY_COMPLETED || $isCurlResource) {
|
||||||
|
|
||||||
$progress = [
|
$progress = [
|
||||||
'code' => $notification_code,
|
'code' => $notification_code,
|
||||||
@@ -131,31 +161,14 @@ class Response
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if cURL is available
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public static function isCurlAvailable()
|
|
||||||
{
|
|
||||||
return function_exists('curl_version');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the remote fopen request is enabled in PHP
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public static function isFopenAvailable()
|
|
||||||
{
|
|
||||||
return preg_match('/1|yes|on|true/i', ini_get('allow_url_fopen'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Automatically picks the preferred method
|
* Automatically picks the preferred method
|
||||||
|
*
|
||||||
* @return string The response of the request
|
* @return string The response of the request
|
||||||
*/
|
*/
|
||||||
private static function getAuto()
|
private static function getAuto()
|
||||||
{
|
{
|
||||||
if (self::isFopenAvailable()) {
|
if (!ini_get('open_basedir') && self::isFopenAvailable()) {
|
||||||
return self::getFopen(func_get_args());
|
return self::getFopen(func_get_args());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,46 +177,9 @@ class Response
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts a HTTP request via cURL
|
|
||||||
* @return string The response of the request
|
|
||||||
*/
|
|
||||||
private static function getCurl()
|
|
||||||
{
|
|
||||||
$args = func_get_args();
|
|
||||||
$args = count($args) > 1 ? $args : array_shift($args);
|
|
||||||
|
|
||||||
$uri = $args[0];
|
|
||||||
$options = $args[1];
|
|
||||||
$callback = $args[2];
|
|
||||||
|
|
||||||
$ch = curl_init($uri);
|
|
||||||
curl_setopt_array($ch, $options['curl']);
|
|
||||||
|
|
||||||
if ($callback) {
|
|
||||||
curl_setopt_array(
|
|
||||||
$ch,
|
|
||||||
[
|
|
||||||
CURLOPT_NOPROGRESS => false,
|
|
||||||
CURLOPT_PROGRESSFUNCTION => ['self', 'progress']
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$response = curl_exec($ch);
|
|
||||||
|
|
||||||
if ($errno = curl_errno($ch)) {
|
|
||||||
$error_message = curl_strerror($errno);
|
|
||||||
throw new \RuntimeException("cURL error ({$errno}):\n {$error_message}");
|
|
||||||
}
|
|
||||||
|
|
||||||
curl_close($ch);
|
|
||||||
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts a HTTP request via fopen
|
* Starts a HTTP request via fopen
|
||||||
|
*
|
||||||
* @return string The response of the request
|
* @return string The response of the request
|
||||||
*/
|
*/
|
||||||
private static function getFopen()
|
private static function getFopen()
|
||||||
@@ -229,4 +205,99 @@ class Response
|
|||||||
|
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts a HTTP request via cURL
|
||||||
|
*
|
||||||
|
* @return string The response of the request
|
||||||
|
*/
|
||||||
|
private static function getCurl()
|
||||||
|
{
|
||||||
|
$args = func_get_args();
|
||||||
|
$args = count($args) > 1 ? $args : array_shift($args);
|
||||||
|
|
||||||
|
$uri = $args[0];
|
||||||
|
$options = $args[1];
|
||||||
|
$callback = $args[2];
|
||||||
|
|
||||||
|
$ch = curl_init($uri);
|
||||||
|
|
||||||
|
$response = static::_curl_exec_follow($ch, $options, $callback);
|
||||||
|
|
||||||
|
if ($errno = curl_errno($ch)) {
|
||||||
|
$error_message = curl_strerror($errno);
|
||||||
|
throw new \RuntimeException("cURL error ({$errno}):\n {$error_message}");
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function _curl_exec_follow($ch, $options, $callback)
|
||||||
|
{
|
||||||
|
if ($callback) {
|
||||||
|
curl_setopt_array(
|
||||||
|
$ch,
|
||||||
|
[
|
||||||
|
CURLOPT_NOPROGRESS => false,
|
||||||
|
CURLOPT_PROGRESSFUNCTION => ['self', 'progress']
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// no open_basedir set, we can proceed normally
|
||||||
|
if (!ini_get('open_basedir')) {
|
||||||
|
curl_setopt_array($ch, $options['curl']);
|
||||||
|
return curl_exec($ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
$max_redirects = isset($options['curl'][CURLOPT_MAXREDIRS]) ? $options['curl'][CURLOPT_MAXREDIRS] : 3;
|
||||||
|
$options['curl'][CURLOPT_FOLLOWLOCATION] = false;
|
||||||
|
|
||||||
|
// open_basedir set but no redirects to follow, we can disable followlocation and proceed normally
|
||||||
|
curl_setopt_array($ch, $options['curl']);
|
||||||
|
if ($max_redirects <= 0) {
|
||||||
|
return curl_exec($ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
$uri = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
|
||||||
|
$rch = curl_copy_handle($ch);
|
||||||
|
|
||||||
|
curl_setopt($rch, CURLOPT_HEADER, true);
|
||||||
|
curl_setopt($rch, CURLOPT_NOBODY, true);
|
||||||
|
curl_setopt($rch, CURLOPT_FORBID_REUSE, false);
|
||||||
|
curl_setopt($rch, CURLOPT_RETURNTRANSFER, true);
|
||||||
|
|
||||||
|
do {
|
||||||
|
curl_setopt($rch, CURLOPT_URL, $uri);
|
||||||
|
$header = curl_exec($rch);
|
||||||
|
|
||||||
|
if (curl_errno($rch)) {
|
||||||
|
$code = 0;
|
||||||
|
} else {
|
||||||
|
$code = curl_getinfo($rch, CURLINFO_HTTP_CODE);
|
||||||
|
if ($code == 301 || $code == 302) {
|
||||||
|
preg_match('/Location:(.*?)\n/', $header, $matches);
|
||||||
|
$uri = trim(array_pop($matches));
|
||||||
|
} else {
|
||||||
|
$code = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while ($code && --$max_redirects);
|
||||||
|
|
||||||
|
curl_close($rch);
|
||||||
|
|
||||||
|
if (!$max_redirects) {
|
||||||
|
if ($max_redirects === null) {
|
||||||
|
trigger_error('Too many redirects. When following redirects, libcurl hit the maximum amount.', E_USER_WARNING);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_setopt($ch, CURLOPT_URL, $uri);
|
||||||
|
|
||||||
|
return curl_exec($ch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -209,9 +209,9 @@ trait ParsedownGravTrait
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if there is a media file that matches the path referenced..
|
// if there is a media file that matches the path referenced..
|
||||||
if ($media && isset($media->all()[$url['path']])) {
|
if ($media && isset($media->all()[$path_parts['basename']])) {
|
||||||
// get the medium object
|
// get the medium object
|
||||||
$medium = $media->all()[$url['path']];
|
$medium = $media->all()[$path_parts['basename']];
|
||||||
|
|
||||||
// if there is a query, then parse it and build action calls
|
// if there is a query, then parse it and build action calls
|
||||||
if (isset($url['query'])) {
|
if (isset($url['query'])) {
|
||||||
|
|||||||
@@ -453,6 +453,36 @@ abstract class Utils
|
|||||||
* @return string the nonce string
|
* @return string the nonce string
|
||||||
*/
|
*/
|
||||||
private static function generateNonceString($action, $plusOneTick = false)
|
private static function generateNonceString($action, $plusOneTick = false)
|
||||||
|
{
|
||||||
|
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
|
||||||
|
$ip = $_SERVER['HTTP_CLIENT_IP'];
|
||||||
|
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
|
||||||
|
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
|
||||||
|
} else {
|
||||||
|
$ip = $_SERVER['REMOTE_ADDR'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$username = '';
|
||||||
|
if (isset(self::getGrav()['user'])) {
|
||||||
|
$user = self::getGrav()['user'];
|
||||||
|
$username = $user->username;
|
||||||
|
}
|
||||||
|
|
||||||
|
$username .= $ip;
|
||||||
|
|
||||||
|
$token = session_id();
|
||||||
|
$i = self::nonceTick();
|
||||||
|
|
||||||
|
if ($plusOneTick) {
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( $i . '|' . $action . '|' . $username . '|' . $token . '|' . self::getGrav()['config']->get('security.salt'));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Added in version 1.0.8 to ensure that existing nonces are not broken.
|
||||||
|
//TODO: to be removed
|
||||||
|
private static function generateNonceStringOldStyle($action, $plusOneTick = false)
|
||||||
{
|
{
|
||||||
if (isset(self::getGrav()['user'])) {
|
if (isset(self::getGrav()['user'])) {
|
||||||
$user = self::getGrav()['user'];
|
$user = self::getGrav()['user'];
|
||||||
@@ -463,14 +493,11 @@ abstract class Utils
|
|||||||
} else {
|
} else {
|
||||||
$username = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '';
|
$username = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$token = session_id();
|
$token = session_id();
|
||||||
$i = self::nonceTick();
|
$i = self::nonceTick();
|
||||||
|
|
||||||
if ($plusOneTick) {
|
if ($plusOneTick) {
|
||||||
$i++;
|
$i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ( $i . '|' . $action . '|' . $username . '|' . $token . '|' . self::getGrav()['config']->get('security.salt'));
|
return ( $i . '|' . $action . '|' . $username . '|' . $token . '|' . self::getGrav()['config']->get('security.salt'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -509,6 +536,20 @@ abstract class Utils
|
|||||||
return static::$nonces[$action];
|
return static::$nonces[$action];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Added in version 1.0.8 to ensure that existing nonces are not broken.
|
||||||
|
//TODO: to be removed
|
||||||
|
public static function getNonceOldStyle($action, $plusOneTick = false)
|
||||||
|
{
|
||||||
|
// Don't regenerate this again if not needed
|
||||||
|
if (isset(static::$nonces[$action])) {
|
||||||
|
return static::$nonces[$action];
|
||||||
|
}
|
||||||
|
$nonce = md5(self::generateNonceStringOldStyle($action, $plusOneTick));
|
||||||
|
static::$nonces[$action] = $nonce;
|
||||||
|
|
||||||
|
return static::$nonces[$action];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify the passed nonce for the give action
|
* Verify the passed nonce for the give action
|
||||||
*
|
*
|
||||||
@@ -530,6 +571,21 @@ abstract class Utils
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Added in version 1.0.8 to ensure that existing nonces are not broken.
|
||||||
|
//TODO: to be removed
|
||||||
|
//Nonce generated 0-12 hours ago
|
||||||
|
if ($nonce == self::getNonceOldStyle($action)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Nonce generated 12-24 hours ago
|
||||||
|
$plusOneTick = true;
|
||||||
|
if ($nonce == self::getNonceOldStyle($action, $plusOneTick)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//End TODO: to be removed
|
||||||
|
|
||||||
//Invalid nonce
|
//Invalid nonce
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user