Version 4.1.19
This commit is contained in:
1 parent
28bd025b35
commit
2bd5025018
2674 files changed
+233518
-77766
No files matched your search
+159
-29
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief HTTP Request Class
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @since 18 Feb 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
@@ -41,8 +41,16 @@ class _Request extends \IPS\Patterns\Singleton
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->parseIncomingRecursively( $_GET );
|
||||
$this->parseIncomingRecursively( $_POST );
|
||||
if ( isset( $_SERVER['REQUEST_METHOD'] ) AND $_SERVER['REQUEST_METHOD'] == 'PUT' )
|
||||
{
|
||||
parse_str( file_get_contents('php://input'), $params );
|
||||
$this->parseIncomingRecursively( $params );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->parseIncomingRecursively( $_GET );
|
||||
$this->parseIncomingRecursively( $_POST );
|
||||
}
|
||||
|
||||
array_walk_recursive( $_COOKIE, array( $this, 'clean' ) );
|
||||
|
||||
@@ -164,7 +172,7 @@ class _Request extends \IPS\Patterns\Singleton
|
||||
*/
|
||||
public function isSecure()
|
||||
{
|
||||
if( !empty( $_SERVER['HTTPS'] ) AND mb_strtolower( $_SERVER['HTTPS'] ) == 'on' )
|
||||
if( !empty( $_SERVER['HTTPS'] ) AND ( mb_strtolower( $_SERVER['HTTPS'] ) == 'on' or $_SERVER['HTTPS'] === '1' ) )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@@ -172,6 +180,10 @@ class _Request extends \IPS\Patterns\Singleton
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else if( !empty( $_SERVER['HTTP_CLOUDFRONT_FORWARDED_PROTO'] ) AND mb_strtolower( $_SERVER['HTTP_CLOUDFRONT_FORWARDED_PROTO'] ) == 'https' )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else if ( !empty( $_SERVER['HTTP_X_FORWARDED_HTTPS'] ) AND mb_strtolower( $_SERVER['HTTP_X_FORWARDED_HTTPS'] ) == 'https' )
|
||||
{
|
||||
return TRUE;
|
||||
@@ -202,13 +214,34 @@ class _Request extends \IPS\Patterns\Singleton
|
||||
public function url()
|
||||
{
|
||||
if( $this->_url === NULL )
|
||||
{
|
||||
/* Work out the query string. We need to urldecode the friendly url slug because browsers will send the value percent-encoded, which we don't want as it turns, for example, à into a percent-encoded character
|
||||
but we don't want to urlencode the query string, because that will already be urlencoded */
|
||||
$path = urldecode( ( $_SERVER['QUERY_STRING'] AND mb_strpos( $_SERVER['REQUEST_URI'], $_SERVER['QUERY_STRING'] ) !== FALSE ) ? mb_substr( $_SERVER['REQUEST_URI'], 0, -mb_strlen( $_SERVER['QUERY_STRING'] ) ) : $_SERVER['REQUEST_URI'] ) . $_SERVER['QUERY_STRING'];
|
||||
{
|
||||
$url = $this->isSecure() ? 'https' : 'http';
|
||||
$url .= '://';
|
||||
|
||||
/* Return */
|
||||
$this->_url = new \IPS\Http\Url( ( ( $this->isSecure() ) ? 'https://' : 'http://' ) . ( !empty( $_SERVER['HTTP_HOST'] ) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME'] ) . $path, TRUE );
|
||||
if ( !empty( $_SERVER['HTTP_X_FORWARDED_HOST'] ) )
|
||||
{
|
||||
$url .= $_SERVER['HTTP_X_FORWARDED_HOST'];
|
||||
}
|
||||
elseif ( !empty( $_SERVER['HTTP_HOST'] ) )
|
||||
{
|
||||
$url .= $_SERVER['HTTP_HOST'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$url .= $_SERVER['SERVER_NAME'];
|
||||
}
|
||||
|
||||
if ( $_SERVER['QUERY_STRING'] AND mb_strpos( $_SERVER['REQUEST_URI'], $_SERVER['QUERY_STRING'] ) !== FALSE )
|
||||
{
|
||||
$url .= mb_substr( $_SERVER['REQUEST_URI'], 0, -mb_strlen( $_SERVER['QUERY_STRING'] ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$url .= $_SERVER['REQUEST_URI'];
|
||||
}
|
||||
$url .= $_SERVER['QUERY_STRING'];
|
||||
|
||||
return $this->_url = \IPS\Http\Url::createFromString( $url, TRUE, TRUE );
|
||||
}
|
||||
|
||||
return $this->_url;
|
||||
@@ -238,6 +271,11 @@ class _Request extends \IPS\Patterns\Singleton
|
||||
{
|
||||
$addrs[] = $_SERVER['HTTP_CLIENT_IP'];
|
||||
}
|
||||
|
||||
if ( isset( $_SERVER['HTTP_X_CLIENT_IP'] ) )
|
||||
{
|
||||
$addrs[] = $_SERVER['HTTP_X_CLIENT_IP'];
|
||||
}
|
||||
|
||||
if( isset( $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'] ) )
|
||||
{
|
||||
@@ -292,6 +330,24 @@ class _Request extends \IPS\Patterns\Singleton
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cookie path
|
||||
*
|
||||
* @return string|void
|
||||
*/
|
||||
public static function getCookiePath()
|
||||
{
|
||||
if( \IPS\COOKIE_PATH !== NULL )
|
||||
{
|
||||
return \IPS\COOKIE_PATH;
|
||||
}
|
||||
|
||||
$path = mb_substr( \IPS\Settings::i()->base_url, mb_strpos( \IPS\Settings::i()->base_url, ( !empty( $_SERVER['SERVER_NAME'] ) ) ? $_SERVER['SERVER_NAME'] : $_SERVER['HTTP_HOST'] ) + mb_strlen( ( !empty( $_SERVER['SERVER_NAME'] ) ) ? $_SERVER['SERVER_NAME'] : $_SERVER['HTTP_HOST'] ) );
|
||||
$path = mb_substr( $path, mb_strpos( $path, '/' ) );
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a cookie
|
||||
@@ -308,22 +364,11 @@ class _Request extends \IPS\Patterns\Singleton
|
||||
{
|
||||
/* Work out the path and if cookies should be SSL only */
|
||||
$sslOnly = FALSE;
|
||||
|
||||
if( \IPS\COOKIE_PATH !== NULL AND $path === NULL )
|
||||
{
|
||||
$path = \IPS\COOKIE_PATH;
|
||||
}
|
||||
|
||||
if ( $path === NULL )
|
||||
{
|
||||
$path = mb_substr( \IPS\Settings::i()->base_url, mb_strpos( \IPS\Settings::i()->base_url, ( !empty( $_SERVER['SERVER_NAME'] ) ) ? $_SERVER['SERVER_NAME'] : $_SERVER['HTTP_HOST'] ) + mb_strlen( ( !empty( $_SERVER['SERVER_NAME'] ) ) ? $_SERVER['SERVER_NAME'] : $_SERVER['HTTP_HOST'] ) );
|
||||
$path = mb_substr( $path, mb_strpos( $path, '/' ) );
|
||||
}
|
||||
|
||||
if( mb_substr( \IPS\Settings::i()->base_url, 0, 5 ) == 'https' AND !\IPS\COOKIE_BYPASS_SSLONLY )
|
||||
if( mb_substr( \IPS\Settings::i()->base_url, 0, 5 ) == 'https' AND \IPS\COOKIE_BYPASS_SSLONLY !== TRUE )
|
||||
{
|
||||
$sslOnly = TRUE;
|
||||
}
|
||||
$path = $path ?: static::getCookiePath();
|
||||
|
||||
/* Are we forcing a cookie domain? */
|
||||
if( \IPS\COOKIE_DOMAIN !== NULL AND $domain === NULL )
|
||||
@@ -349,6 +394,23 @@ class _Request extends \IPS\Patterns\Singleton
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Editor autosave keys to be cleared
|
||||
*/
|
||||
protected $clearAutoSaveCookie = array();
|
||||
|
||||
/**
|
||||
* Set cookie to clear autosave content from editor
|
||||
*
|
||||
* @param $autoSaveKey string The editor's autosave key
|
||||
* @return void
|
||||
*/
|
||||
public function setClearAutosaveCookie( $autoSaveKey )
|
||||
{
|
||||
$this->clearAutoSaveCookie[] = $autoSaveKey;
|
||||
\IPS\Request::i()->setCookie( 'clearAutosave', implode( ',', $this->clearAutoSaveCookie ), NULL, FALSE );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request method
|
||||
*
|
||||
@@ -366,18 +428,86 @@ class _Request extends \IPS\Patterns\Singleton
|
||||
*/
|
||||
public static function floodCheck()
|
||||
{
|
||||
/* Flood control */
|
||||
if( \IPS\Member::loggedIn()->group['g_search_flood'] )
|
||||
$groupFloodSeconds = \IPS\Member::loggedIn()->group['g_search_flood'];
|
||||
|
||||
if ( \IPS\Session::i()->userAgent->spider )
|
||||
{
|
||||
if( isset( $_SESSION['lastSearch'] ) and ( time() - $_SESSION['lastSearch'] ) < \IPS\Member::loggedIn()->group['g_search_flood'] )
|
||||
/* Force a 30 second flood control so if guests have it switched off, or set very low, you do not get flooded by known bots */
|
||||
$groupFloodSeconds = \IPS\BOT_SEARCH_FLOOD_SECONDS;
|
||||
}
|
||||
|
||||
/* Flood control */
|
||||
if( $groupFloodSeconds )
|
||||
{
|
||||
$time = ( isset( \IPS\Request::i()->cookie['lastSearch'] ) ) ? \IPS\Request::i()->cookie['lastSearch'] : 0;
|
||||
if ( isset( $_SESSION['lastSearch'] ) and $_SESSION['lastSearch'] > $time )
|
||||
{
|
||||
$secondsToWait = \IPS\Member::loggedIn()->group['g_search_flood'] - ( time() - $_SESSION['lastSearch'] );
|
||||
\IPS\Output::i()->error( \IPS\Member::loggedIn()->language()->addToStack( 'search_flood_error', FALSE, array( 'sprintf' => array( $secondsToWait ) ) ), '1C205/3', 429, \IPS\Member::loggedIn()->language()->addToStack( 'search_flood_error_admin', FALSE, array( 'sprintf' => array( $secondsToWait ) ) ), array( 'Retry-After' => \IPS\DateTime::create()->add( new \DateInterval( 'PT' . $secondsToWait . 'S' ) )->format('r') ) );
|
||||
$time = $_SESSION['lastSearch'];
|
||||
}
|
||||
|
||||
if( $time and ( time() - $time ) < $groupFloodSeconds )
|
||||
{
|
||||
$secondsToWait = $groupFloodSeconds - ( time() - $time );
|
||||
\IPS\Output::i()->error( \IPS\Member::loggedIn()->language()->addToStack( 'search_flood_error', FALSE, array( 'pluralize' => array( $secondsToWait ) ) ), '1C205/3', 429, \IPS\Member::loggedIn()->language()->addToStack( 'search_flood_error_admin', FALSE, array( 'pluralize' => array( $secondsToWait ) ) ), array( 'Retry-After' => \IPS\DateTime::create()->add( new \DateInterval( 'PT' . $secondsToWait . 'S' ) )->format('r') ) );
|
||||
}
|
||||
|
||||
$_SESSION['lastSearch'] = time();
|
||||
$expire = new \IPS\DateTime;
|
||||
\IPS\Request::i()->setCookie( 'lastSearch', time(), $expire->add( new \DateInterval( 'PT' . intval( $groupFloodSeconds ) . 'S' ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is PHP running as CGI?
|
||||
*
|
||||
* @note Possible values: cgi, cgi-fcgi, fpm-fcgi
|
||||
* @return boolean
|
||||
*/
|
||||
public function isCgi()
|
||||
{
|
||||
if ( \substr( PHP_SAPI, 0, 3 ) == 'cgi' OR \substr( PHP_SAPI, -3 ) == 'cgi' )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirmation check
|
||||
*
|
||||
* @param string $title Lang string key for title
|
||||
* @param string $message Lang string key for confirm message
|
||||
* @param string $submit Lang string key for submit button
|
||||
* @return void
|
||||
*/
|
||||
public function confirmedDelete( $title = 'delete_confirm', $message = 'delete_confirm_detail', $submit = 'delete' )
|
||||
{
|
||||
/* The confirmation dialogs will send form_submitted=1, as will displaying a form, so we check for this.
|
||||
If the admin (or user) simply visited a delete URL directly, this would not be included in the request. */
|
||||
if ( ! isset( \IPS\Request::i()->wasConfirmed ) )
|
||||
{
|
||||
$form = new \IPS\Helpers\Form( 'form', $submit );
|
||||
$form->hiddenValues['wasConfirmed'] = 1;
|
||||
$form->addMessage( $message, 'ipsMessage ipsMessage_warning' );
|
||||
|
||||
/* We call sendOutput() to show the form now */
|
||||
\IPS\Output::i()->output = $form;
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( $title );
|
||||
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core', 'front' )->genericBlock( $form, \IPS\Output::i()->title ), 200, 'text/html', \IPS\Output::i()->httpHeaders );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->globalTemplate( \IPS\Output::i()->title, \IPS\Output::i()->output, array( 'app' => \IPS\Dispatcher::i()->application->directory, 'module' => \IPS\Dispatcher::i()->module->key, 'controller' => \IPS\Dispatcher::i()->controller ) ), 200, 'text/html', \IPS\Output::i()->httpHeaders );
|
||||
}
|
||||
}
|
||||
|
||||
/* If we are here, we're all good! */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Old IPB escape-on-input routine
|
||||
|
||||
Reference in new issue
Block a user