2015-03-21 23:06:08 +00:00
< ? php
2018-08-03 23:03:16 +00:00
use Zotlabs\Lib\Libzot ;
use Zotlabs\Lib\Zotfinger ;
2019-07-19 03:38:36 +00:00
use Zotlabs\Lib\Webfinger ;
2018-08-29 01:37:21 +00:00
use Zotlabs\Lib\ActivityStreams ;
use Zotlabs\Lib\Activity ;
2018-09-17 05:05:04 +00:00
use Zotlabs\Lib\ActivityPub ;
2018-11-12 01:44:01 +00:00
use Zotlabs\Lib\Queue ;
use Zotlabs\Lib\System ;
2018-12-14 20:46:03 +00:00
use Zotlabs\Lib\Keyutils ;
2020-11-17 05:39:49 +00:00
use Zotlabs\Lib\LDSignatures ;
use Zotlabs\Web\HTTPSig ;
2020-06-15 07:29:56 +00:00
use Zotlabs\Daemon\Run ;
2020-09-15 06:11:49 +00:00
2018-08-03 23:03:16 +00:00
2015-03-21 23:06:08 +00:00
/**
* @ file include / network . php
2017-09-04 22:23:42 +00:00
* @ brief Network related functions .
2015-03-21 23:06:08 +00:00
*/
2013-02-14 04:09:30 +00:00
2015-03-21 23:06:08 +00:00
/**
* @ brief Returns path to CA file .
*
* @ return string
*/
2013-02-14 04:09:30 +00:00
function get_capath () {
return appdirpath () . '/library/cacert.pem' ;
}
2013-03-28 02:02:01 +00:00
/**
2015-03-21 23:06:08 +00:00
* @ brief fetches an URL .
*
2013-03-28 02:02:01 +00:00
* @ param string $url
* URL to fetch
2015-03-21 23:06:08 +00:00
* @ param boolean $binary default false
2013-03-28 02:02:01 +00:00
* TRUE if asked to return binary results ( file download )
2015-03-21 23:06:08 +00:00
* @ param int $redirects default 0
2013-03-28 02:02:01 +00:00
* internal use , recursion counter
2016-06-16 04:25:26 +00:00
* @ param array $opts ( optional parameters ) associative array with :
2015-03-21 23:06:08 +00:00
* * \b timeout => int seconds , default system config value or 60 seconds
2017-03-01 00:31:35 +00:00
* * \b headers => array of additional header fields
2015-03-21 23:06:08 +00:00
* * \b http_auth => username : password
* * \b novalidate => do not validate SSL certs , default is to validate using our CA list
* * \b nobody => only return the header
2016-04-06 01:24:24 +00:00
* * \b filep => stream resource to write body to . header and body are not returned when using this option .
2016-06-16 04:25:26 +00:00
* * \b custom => custom request method : e . g . 'PUT' , 'DELETE'
2016-06-17 03:16:39 +00:00
* * \b cookiejar => cookie file ( write )
2016-10-01 22:41:25 +00:00
* * \b cookiefile => cookie file ( read )
2017-03-01 00:31:35 +00:00
* * \b session => boolean ; append session cookie * if * $url is our own site
2015-03-21 23:06:08 +00:00
*
2016-06-16 04:25:26 +00:00
* @ return array an associative array with :
2015-03-21 23:06:08 +00:00
* * \e int \b return_code => HTTP return code or 0 if timeout or failure
* * \e boolean \b success => boolean true ( if HTTP 2 xx result ) or false
2016-10-01 22:41:25 +00:00
* * \e string \b header => HTTP headers
2015-03-21 23:06:08 +00:00
* * \e string \b body => fetched content
2013-03-28 02:02:01 +00:00
*/
2021-03-15 05:10:44 +00:00
function z_fetch_url ( $url , $binary = false , $redirects = 0 , $opts = []) {
2012-08-10 03:31:06 +00:00
$ret = array ( 'return_code' => 0 , 'success' => false , 'header' => " " , 'body' => " " );
2020-08-13 06:10:03 +00:00
$passthru = false ;
2012-08-10 03:31:06 +00:00
$ch = @ curl_init ( $url );
2016-10-01 22:41:25 +00:00
if (( $redirects > 8 ) || ( ! $ch ))
2016-02-28 00:27:37 +00:00
return $ret ;
2012-08-10 03:31:06 +00:00
2018-10-11 00:58:51 +00:00
if ( ! array_key_exists ( 'request_target' , $opts )) {
$opts [ 'request_target' ] = 'get ' . get_request_string ( $url );
}
2012-08-10 03:31:06 +00:00
@ curl_setopt ( $ch , CURLOPT_HEADER , true );
2014-09-17 02:07:19 +00:00
@ curl_setopt ( $ch , CURLINFO_HEADER_OUT , true );
2013-02-14 04:09:30 +00:00
@ curl_setopt ( $ch , CURLOPT_CAINFO , get_capath ());
2013-02-15 01:39:16 +00:00
@ curl_setopt ( $ch , CURLOPT_SSL_VERIFYPEER , true );
@ curl_setopt ( $ch , CURLOPT_RETURNTRANSFER , true );
2020-05-03 23:52:44 +00:00
@ curl_setopt ( $ch , CURLOPT_ENCODING , '' );
2014-03-25 00:16:01 +00:00
$ciphers = @ get_config ( 'system' , 'curl_ssl_ciphers' );
2014-03-25 22:19:18 +00:00
if ( $ciphers )
@ curl_setopt ( $ch , CURLOPT_SSL_CIPHER_LIST , $ciphers );
2014-03-25 00:16:01 +00:00
2016-04-06 01:24:24 +00:00
if ( x ( $opts , 'filep' )) {
@ curl_setopt ( $ch , CURLOPT_FILE , $opts [ 'filep' ]);
2016-12-16 00:02:52 +00:00
@ curl_setopt ( $ch , CURLOPT_HEADER , false );
2020-08-13 06:10:03 +00:00
@ curl_setopt ( $ch , CURLOPT_FOLLOWLOCATION , true );
$passthru = true ;
2016-04-06 01:24:24 +00:00
}
2021-04-08 02:11:55 +00:00
if ( x ( $opts [ 'useragent' ])) {
@ curl_setopt ( $ch , CURLOPT_USERAGENT , $opts [ 'useragent' ]);
}
else {
@ curl_setopt ( $ch , CURLOPT_USERAGENT , " Mozilla/5.0 (compatible; zot) " );
}
2016-06-22 01:18:06 +00:00
if ( x ( $opts , 'upload' ))
@ curl_setopt ( $ch , CURLOPT_UPLOAD , $opts [ 'upload' ]);
2016-10-01 22:41:25 +00:00
2016-06-22 01:18:06 +00:00
if ( x ( $opts , 'infile' ))
@ curl_setopt ( $ch , CURLOPT_INFILE , $opts [ 'infile' ]);
2016-06-17 03:16:39 +00:00
2016-06-22 01:18:06 +00:00
if ( x ( $opts , 'infilesize' ))
@ curl_setopt ( $ch , CURLOPT_INFILESIZE , $opts [ 'infilesize' ]);
if ( x ( $opts , 'readfunc' ))
@ curl_setopt ( $ch , CURLOPT_READFUNCTION , $opts [ 'readfunc' ]);
2016-06-17 03:16:39 +00:00
2017-04-06 17:45:19 +00:00
// When using the session option and fetching from our own site,
2017-03-01 00:31:35 +00:00
// append the PHPSESSID cookie to any existing headers.
// Don't add to $opts['headers'] so that the cookie does not get
// sent to other sites via redirects
$instance_headers = (( array_key_exists ( 'headers' , $opts ) && is_array ( $opts [ 'headers' ])) ? $opts [ 'headers' ] : []);
if ( x ( $opts , 'session' )) {
if ( strpos ( $url , z_root ()) === 0 ) {
$instance_headers [] = 'Cookie: PHPSESSID=' . session_id ();
}
}
if ( $instance_headers )
@ curl_setopt ( $ch , CURLOPT_HTTPHEADER , $instance_headers );
2012-08-10 03:31:06 +00:00
2015-03-04 23:14:10 +00:00
if ( x ( $opts , 'nobody' ))
@ curl_setopt ( $ch , CURLOPT_NOBODY , $opts [ 'nobody' ]);
2016-06-16 04:25:26 +00:00
if ( x ( $opts , 'custom' ))
@ curl_setopt ( $ch , CURLOPT_CUSTOMREQUEST , $opts [ 'custom' ]);
2013-02-15 01:39:16 +00:00
if ( x ( $opts , 'timeout' ) && intval ( $opts [ 'timeout' ])) {
2017-01-25 03:44:24 +00:00
@ curl_setopt ( $ch , CURLOPT_TIMEOUT , intval ( $opts [ 'timeout' ]));
2012-08-10 03:31:06 +00:00
}
else {
2021-04-21 06:26:47 +00:00
$curl_time = intval ( get_config ( 'system' , 'curl_timeout' , 60 ));
2019-03-08 04:15:03 +00:00
@ curl_setopt ( $ch , CURLOPT_TIMEOUT , $curl_time );
2019-03-08 04:13:33 +00:00
}
if ( x ( $opts , 'connecttimeout' ) && intval ( $opts [ 'connecttimeout' ])) {
@ curl_setopt ( $ch , CURLOPT_CONNECTTIMEOUT , intval ( $opts [ 'connecttimeout' ]));
}
else {
2021-05-26 23:56:54 +00:00
$curl_contime = intval ( @ get_config ( 'system' , 'curl_connecttimeout' , 60 ));
2019-03-08 04:15:03 +00:00
@ curl_setopt ( $ch , CURLOPT_CONNECTTIMEOUT , $curl_contime );
2012-08-10 03:31:06 +00:00
}
2017-02-28 07:48:54 +00:00
2013-02-15 01:39:16 +00:00
if ( x ( $opts , 'http_auth' )) {
// "username" . ':' . "password"
@ curl_setopt ( $ch , CURLOPT_USERPWD , $opts [ 'http_auth' ]);
}
2012-08-10 03:31:06 +00:00
2016-06-17 03:16:39 +00:00
if ( x ( $opts , 'cookiejar' ))
@ curl_setopt ( $ch , CURLOPT_COOKIEJAR , $opts [ 'cookiejar' ]);
if ( x ( $opts , 'cookiefile' ))
@ curl_setopt ( $ch , CURLOPT_COOKIEFILE , $opts [ 'cookiefile' ]);
2016-06-28 05:25:37 +00:00
if ( x ( $opts , 'cookie' ))
@ curl_setopt ( $ch , CURLOPT_COOKIE , $opts [ 'cookie' ]);
2016-10-01 22:41:25 +00:00
@ curl_setopt ( $ch , CURLOPT_SSL_VERIFYPEER ,
2013-02-26 23:49:37 +00:00
(( x ( $opts , 'novalidate' ) && intval ( $opts [ 'novalidate' ])) ? false : true ));
2016-12-16 00:02:52 +00:00
$prx = @ get_config ( 'system' , 'proxy' );
2012-08-10 03:31:06 +00:00
if ( strlen ( $prx )) {
@ curl_setopt ( $ch , CURLOPT_HTTPPROXYTUNNEL , 1 );
@ curl_setopt ( $ch , CURLOPT_PROXY , $prx );
$prxusr = @ get_config ( 'system' , 'proxyuser' );
if ( strlen ( $prxusr ))
@ curl_setopt ( $ch , CURLOPT_PROXYUSERPWD , $prxusr );
}
if ( $binary )
@ curl_setopt ( $ch , CURLOPT_BINARYTRANSFER , 1 );
2014-01-30 10:04:20 +00:00
// don't let curl abort the entire application'
2012-08-10 03:31:06 +00:00
// if it throws any errors.
$s = @ curl_exec ( $ch );
$base = $s ;
$curl_info = @ curl_getinfo ( $ch );
$http_code = $curl_info [ 'http_code' ];
2014-01-30 10:04:20 +00:00
//logger('fetch_url:' . $http_code . ' data: ' . $s);
2012-08-10 03:31:06 +00:00
$header = '' ;
2020-08-13 06:10:03 +00:00
// For file redirects, set curl to follow location (indicated by $passthru).
// Then just return success or failure.
if ( $passthru ) {
if ( $http_code >= 200 && $http_code < 300 ) {
$ret [ 'success' ] = true ;
}
$ret [ 'return_code' ] = $http_code ;
@ curl_close ( $ch );
return $ret ;
}
2012-08-10 03:31:06 +00:00
// Pull out multiple headers, e.g. proxy and continuation headers
// allow for HTTP/2.x without fixing code
2019-12-27 21:55:50 +00:00
while ( preg_match ( '/^HTTP\/[1-3][\.0-9]* [1-5][0-9][0-9]/' , $base )) {
2012-08-10 03:31:06 +00:00
$chunk = substr ( $base , 0 , strpos ( $base , " \r \n \r \n " ) + 4 );
$header .= $chunk ;
$base = substr ( $base , strlen ( $chunk ));
}
2012-12-26 03:03:12 +00:00
if ( $http_code == 301 || $http_code == 302 || $http_code == 303 || $http_code == 307 || $http_code == 308 ) {
2021-03-15 05:10:44 +00:00
$matches = [];
2018-09-10 13:13:28 +00:00
preg_match ( '/(Location:|URI:)(.*?)\n/i' , $header , $matches );
2012-08-10 03:31:06 +00:00
$newurl = trim ( array_pop ( $matches ));
2020-08-13 06:58:09 +00:00
if ( strpos ( $newurl , '/' ) === 0 ) {
// We received a redirect to a relative path.
// Find the base component of the original url and re-assemble it with the new location
$base = @ parse_url ( $url );
if ( $base ) {
unset ( $base [ 'path' ]); unset ( $base [ 'query' ]); unset ( $base [ 'fragment' ]);
$newurl = unparse_url ( $base ) . $newurl ;
}
}
2020-08-13 06:10:03 +00:00
if ( $newurl ) {
@ curl_close ( $ch );
2015-02-23 13:53:10 +00:00
return z_fetch_url ( $newurl , $binary , ++ $redirects , $opts );
2012-08-10 03:31:06 +00:00
}
}
$rc = intval ( $http_code );
$ret [ 'return_code' ] = $rc ;
$ret [ 'success' ] = (( $rc >= 200 && $rc <= 299 ) ? true : false );
2013-09-11 00:09:10 +00:00
if ( ! $ret [ 'success' ]) {
2014-03-23 22:24:38 +00:00
$ret [ 'error' ] = curl_error ( $ch );
2013-09-11 00:09:10 +00:00
$ret [ 'debug' ] = $curl_info ;
2018-10-12 04:18:02 +00:00
$dbg = [
'url' => $ret [ 'debug' ][ 'url' ],
'content_type' => $ret [ 'debug' ][ 'content_type' ],
'error_code' => $ret [ 'debug' ][ 'error_code' ],
'request_header' => $ret [ 'debug' ][ 'request_header' ]
];
2014-05-28 04:21:38 +00:00
logger ( 'z_fetch_url: error: ' . $url . ': ' . $ret [ 'error' ], LOGGER_DEBUG );
2018-10-12 04:18:02 +00:00
logger ( 'z_fetch_url: debug: ' . print_r ( $dbg , true ), LOGGER_DATA );
2013-09-11 00:09:10 +00:00
}
2012-08-10 03:31:06 +00:00
$ret [ 'body' ] = substr ( $s , strlen ( $header ));
$ret [ 'header' ] = $header ;
2018-10-11 00:58:51 +00:00
$ret [ 'request_target' ] = $opts [ 'request_target' ];
2014-09-17 03:46:44 +00:00
if ( x ( $opts , 'debug' )) {
$ret [ 'debug' ] = $curl_info ;
}
2015-03-21 23:06:08 +00:00
2012-08-10 03:31:06 +00:00
@ curl_close ( $ch );
return ( $ret );
2013-02-26 23:49:37 +00:00
}
2012-08-01 00:55:27 +00:00
2014-09-09 09:42:07 +00:00
/**
2017-09-04 22:23:42 +00:00
* @ brief Does a curl post request .
2015-03-21 23:06:08 +00:00
*
2014-09-09 09:42:07 +00:00
* @ param string $url
2014-09-09 11:10:01 +00:00
* URL to post
2014-09-09 09:42:07 +00:00
* @ param mixed $params
2016-10-01 22:41:25 +00:00
* The full data to post in a HTTP " POST " operation . This parameter can
* either be passed as a urlencoded string like 'para1=val1¶2=val2&...'
* or as an array with the field name as key and field data as value . If value
* is an array , the Content - Type header will be set to multipart / form - data .
2014-09-09 09:42:07 +00:00
* @ param int $redirects = 0
* internal use , recursion counter
* @ param array $opts ( optional parameters )
* 'timeout' => int seconds , default system config value or 60 seconds
* 'http_auth' => username : password
* 'novalidate' => do not validate SSL certs , default is to validate using our CA list
2016-04-06 01:24:24 +00:00
* 'filep' => stream resource to write body to . header and body are not returned when using this option .
2016-06-16 04:25:26 +00:00
* 'custom' => custom request method : e . g . 'PUT' , 'DELETE'
*
* @ return array an associative array with :
2015-03-21 23:06:08 +00:00
* * \e int \b return_code => HTTP return code or 0 if timeout or failure
* * \e boolean \b success => boolean true ( if HTTP 2 xx result ) or false
* * \e string \b header => HTTP headers
* * \e string \b body => content
* * \e string \b debug => from curl_info ()
2014-09-09 09:42:07 +00:00
*/
2021-03-15 05:10:44 +00:00
function z_post_url ( $url , $params , $redirects = 0 , $opts = []) {
2015-03-21 23:06:08 +00:00
2016-06-20 01:57:56 +00:00
// logger('url: ' . $url);
// logger('params: ' . print_r($params,true));
// logger('opts: ' . print_r($opts,true));
2012-08-01 00:55:27 +00:00
$ret = array ( 'return_code' => 0 , 'success' => false , 'header' => " " , 'body' => " " );
$ch = curl_init ( $url );
2016-10-01 22:41:25 +00:00
if (( $redirects > 8 ) || ( ! $ch ))
2016-02-28 00:27:37 +00:00
return $ret ;
2012-08-01 00:55:27 +00:00
2018-10-11 00:58:51 +00:00
if ( ! array_key_exists ( 'request_target' , $opts )) {
$opts [ 'request_target' ] = 'post ' . get_request_string ( $url );
}
2014-03-25 00:16:01 +00:00
@ curl_setopt ( $ch , CURLOPT_HEADER , true );
2014-09-17 02:07:19 +00:00
@ curl_setopt ( $ch , CURLINFO_HEADER_OUT , true );
2013-02-14 04:09:30 +00:00
@ curl_setopt ( $ch , CURLOPT_CAINFO , get_capath ());
2014-03-25 00:16:01 +00:00
@ curl_setopt ( $ch , CURLOPT_RETURNTRANSFER , true );
@ curl_setopt ( $ch , CURLOPT_POST , 1 );
@ curl_setopt ( $ch , CURLOPT_POSTFIELDS , $params );
2020-05-03 23:52:44 +00:00
@ curl_setopt ( $ch , CURLOPT_ENCODING , '' );
2014-03-25 00:16:01 +00:00
$ciphers = @ get_config ( 'system' , 'curl_ssl_ciphers' );
2014-03-25 22:19:18 +00:00
if ( $ciphers )
@ curl_setopt ( $ch , CURLOPT_SSL_CIPHER_LIST , $ciphers );
2012-08-01 00:55:27 +00:00
2016-04-06 01:24:24 +00:00
if ( x ( $opts , 'filep' )) {
@ curl_setopt ( $ch , CURLOPT_FILE , $opts [ 'filep' ]);
2016-12-16 00:02:52 +00:00
@ curl_setopt ( $ch , CURLOPT_HEADER , false );
2016-04-06 01:24:24 +00:00
}
2021-04-08 02:11:55 +00:00
if ( x ( $opts [ 'useragent' ])) {
@ curl_setopt ( $ch , CURLOPT_USERAGENT , $opts [ 'useragent' ]);
}
else {
@ curl_setopt ( $ch , CURLOPT_USERAGENT , " Mozilla/5.0 (compatible; zot) " );
}
2017-03-01 00:31:35 +00:00
$instance_headers = (( array_key_exists ( 'headers' , $opts ) && is_array ( $opts [ 'headers' ])) ? $opts [ 'headers' ] : []);
if ( x ( $opts , 'session' )) {
if ( strpos ( $url , z_root ()) === 0 ) {
$instance_headers [] = 'Cookie: PHPSESSID=' . session_id ();
}
2016-03-22 04:31:28 +00:00
}
2017-03-01 00:31:35 +00:00
if ( $instance_headers )
@ curl_setopt ( $ch , CURLOPT_HTTPHEADER , $instance_headers );
2016-10-01 22:41:25 +00:00
2015-03-04 23:14:10 +00:00
if ( x ( $opts , 'nobody' ))
@ curl_setopt ( $ch , CURLOPT_NOBODY , $opts [ 'nobody' ]);
2016-06-20 01:57:56 +00:00
if ( x ( $opts , 'custom' )) {
2016-06-16 04:25:26 +00:00
@ curl_setopt ( $ch , CURLOPT_CUSTOMREQUEST , $opts [ 'custom' ]);
2016-06-20 01:57:56 +00:00
@ curl_setopt ( $ch , CURLOPT_POST , 0 );
}
2016-06-16 04:25:26 +00:00
2013-04-25 08:55:35 +00:00
if ( x ( $opts , 'timeout' ) && intval ( $opts [ 'timeout' ])) {
2019-03-08 04:13:33 +00:00
@ curl_setopt ( $ch , CURLOPT_TIMEOUT , intval ( $opts [ 'timeout' ]));
}
else {
$curl_time = intval ( @ get_config ( 'system' , 'curl_timeout' , 60 ));
2019-03-08 04:15:03 +00:00
@ curl_setopt ( $ch , CURLOPT_TIMEOUT , $curl_time );
2019-03-08 04:13:33 +00:00
}
if ( x ( $opts , 'connecttimeout' ) && intval ( $opts [ 'connecttimeout' ])) {
@ curl_setopt ( $ch , CURLOPT_CONNECTTIMEOUT , intval ( $opts [ 'connecttimeout' ]));
2012-08-01 00:55:27 +00:00
}
else {
2021-05-26 23:56:54 +00:00
$curl_contime = intval ( @ get_config ( 'system' , 'curl_connecttimeout' , 60 ));
2019-03-08 04:15:03 +00:00
@ curl_setopt ( $ch , CURLOPT_CONNECTTIMEOUT , $curl_contime );
2012-08-01 00:55:27 +00:00
}
2013-04-25 08:55:35 +00:00
if ( x ( $opts , 'http_auth' )) {
// "username" . ':' . "password"
@ curl_setopt ( $ch , CURLOPT_USERPWD , $opts [ 'http_auth' ]);
2012-08-01 00:55:27 +00:00
}
2012-11-13 22:58:58 +00:00
2016-06-17 03:16:39 +00:00
if ( x ( $opts , 'cookiejar' ))
@ curl_setopt ( $ch , CURLOPT_COOKIEJAR , $opts [ 'cookiejar' ]);
if ( x ( $opts , 'cookiefile' ))
@ curl_setopt ( $ch , CURLOPT_COOKIEFILE , $opts [ 'cookiefile' ]);
2016-06-28 05:25:37 +00:00
if ( x ( $opts , 'cookie' ))
@ curl_setopt ( $ch , CURLOPT_COOKIE , $opts [ 'cookie' ]);
2016-10-01 22:41:25 +00:00
@ curl_setopt ( $ch , CURLOPT_SSL_VERIFYPEER ,
2013-04-25 08:55:35 +00:00
(( x ( $opts , 'novalidate' ) && intval ( $opts [ 'novalidate' ])) ? false : true ));
2012-11-13 22:58:58 +00:00
2012-08-01 00:55:27 +00:00
$prx = get_config ( 'system' , 'proxy' );
if ( strlen ( $prx )) {
2014-03-25 00:16:01 +00:00
@ curl_setopt ( $ch , CURLOPT_HTTPPROXYTUNNEL , 1 );
@ curl_setopt ( $ch , CURLOPT_PROXY , $prx );
2012-08-01 00:55:27 +00:00
$prxusr = get_config ( 'system' , 'proxyuser' );
if ( strlen ( $prxusr ))
2014-03-25 00:16:01 +00:00
@ curl_setopt ( $ch , CURLOPT_PROXYUSERPWD , $prxusr );
2012-08-01 00:55:27 +00:00
}
// don't let curl abort the entire application
// if it throws any errors.
$s = @ curl_exec ( $ch );
$base = $s ;
2014-03-25 00:16:01 +00:00
$curl_info = @ curl_getinfo ( $ch );
2012-08-01 00:55:27 +00:00
$http_code = $curl_info [ 'http_code' ];
$header = '' ;
// Pull out multiple headers, e.g. proxy and continuation headers
// allow for HTTP/2.x without fixing code
2019-12-27 21:55:50 +00:00
while ( preg_match ( '/^HTTP\/[1-3][\.0-9]* [1-5][0-9][0-9]/' , $base )) {
2012-08-01 00:55:27 +00:00
$chunk = substr ( $base , 0 , strpos ( $base , " \r \n \r \n " ) + 4 );
$header .= $chunk ;
$base = substr ( $base , strlen ( $chunk ));
}
2016-03-22 04:31:28 +00:00
// would somebody take lighttpd and just shoot it?
if ( $http_code == 417 ) {
curl_close ( $ch );
if ( $opts ) {
if ( $opts [ 'headers' ])
$opts [ 'headers' ][] = 'Expect:' ;
else
$opts [ 'headers' ] = array ( 'Expect:' );
}
else
$opts = array ( 'headers' => array ( 'Expect:' ));
return z_post_url ( $url , $params , ++ $redirects , $opts );
}
2012-12-26 03:03:12 +00:00
if ( $http_code == 301 || $http_code == 302 || $http_code == 303 || $http_code == 307 || $http_code == 308 ) {
2021-03-15 05:10:44 +00:00
$matches = [];
2012-12-26 01:17:43 +00:00
preg_match ( '/(Location:|URI:)(.*?)\n/' , $header , $matches );
$newurl = trim ( array_pop ( $matches ));
2020-08-13 06:58:09 +00:00
if ( strpos ( $newurl , '/' ) === 0 ) {
// We received a redirect to a relative path.
// Find the base component of the original url and re-assemble it with the new location
$base = @ parse_url ( $url );
if ( $base ) {
unset ( $base [ 'path' ]); unset ( $base [ 'query' ]); unset ( $base [ 'fragment' ]);
$newurl = unparse_url ( $base ) . $newurl ;
}
}
if ( $newurl ) {
2012-08-01 00:55:27 +00:00
curl_close ( $ch );
2012-12-26 17:44:30 +00:00
if ( $http_code == 303 ) {
2017-05-08 09:00:00 +00:00
return z_fetch_url ( $newurl , false , ++ $redirects , $opts );
2020-08-13 06:58:09 +00:00
}
else {
2015-02-23 19:33:16 +00:00
return z_post_url ( $newurl , $params , ++ $redirects , $opts );
2012-12-26 15:08:21 +00:00
}
2012-12-26 01:17:43 +00:00
}
}
2012-08-01 00:55:27 +00:00
$rc = intval ( $http_code );
$ret [ 'return_code' ] = $rc ;
$ret [ 'success' ] = (( $rc >= 200 && $rc <= 299 ) ? true : false );
2013-09-11 00:09:10 +00:00
if ( ! $ret [ 'success' ]) {
2014-03-23 22:24:38 +00:00
$ret [ 'error' ] = curl_error ( $ch );
2013-09-11 00:09:10 +00:00
$ret [ 'debug' ] = $curl_info ;
2018-10-12 04:18:02 +00:00
$dbg = [
'url' => $ret [ 'debug' ][ 'url' ],
'content_type' => $ret [ 'debug' ][ 'content_type' ],
'error_code' => $ret [ 'debug' ][ 'error_code' ],
'request_header' => $ret [ 'debug' ][ 'request_header' ]
];
2014-05-28 04:21:38 +00:00
logger ( 'z_post_url: error: ' . $url . ': ' . $ret [ 'error' ], LOGGER_DEBUG );
2018-10-12 04:18:02 +00:00
logger ( 'z_post_url: debug: ' . print_r ( $dbg , true ), LOGGER_DATA );
2013-09-11 00:09:10 +00:00
}
2015-03-21 23:06:08 +00:00
$ret [ 'body' ] = substr ( $s , strlen ( $header ));
2012-08-01 00:55:27 +00:00
$ret [ 'header' ] = $header ;
2018-10-11 00:58:51 +00:00
$ret [ 'request_target' ] = $opts [ 'request_target' ];
2014-09-17 03:46:44 +00:00
if ( x ( $opts , 'debug' )) {
$ret [ 'debug' ] = $curl_info ;
}
2012-08-01 00:55:27 +00:00
curl_close ( $ch );
return ( $ret );
2013-02-26 23:49:37 +00:00
}
2012-08-01 00:55:27 +00:00
2020-11-14 19:57:28 +00:00
function json_return_and_die ( $x , $content_type = 'application/json' , $debug = false ) {
2016-02-19 08:06:10 +00:00
header ( " Content-type: $content_type " );
2020-11-14 19:57:28 +00:00
if ( $debug ) {
logger ( 'returned_json: ' . json_encode ( $x , JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES ), LOGGER_DATA );
}
2012-08-09 01:50:04 +00:00
echo json_encode ( $x );
killme ();
}
2020-11-17 05:39:49 +00:00
function as_return_and_die ( $obj , $channel ) {
$x = array_merge ([ '@context' => [
ACTIVITYSTREAMS_JSONLD_REV ,
'https://w3id.org/security/v1' ,
2021-01-23 00:59:56 +00:00
Activity :: ap_schema ()
2020-11-17 05:39:49 +00:00
]], $obj );
$headers = [];
$headers [ 'Content-Type' ] = 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' ;
$x [ 'signature' ] = LDSignatures :: sign ( $x , $channel );
$ret = json_encode ( $x , JSON_UNESCAPED_SLASHES );
logger ( 'data: ' . jindent ( $ret ), LOGGER_DATA );
$headers [ 'Date' ] = datetime_convert ( 'UTC' , 'UTC' , 'now' , 'D, d M Y H:i:s \\G\\M\\T' );
$headers [ 'Digest' ] = HTTPSig :: generate_digest_header ( $ret );
$headers [ '(request-target)' ] = strtolower ( $_SERVER [ 'REQUEST_METHOD' ]) . ' ' . $_SERVER [ 'REQUEST_URI' ];
$h = HTTPSig :: create_sig ( $headers , $channel [ 'channel_prvkey' ], channel_url ( $channel ));
HTTPSig :: set_headers ( $h );
echo $ret ;
killme ();
}
2013-03-28 02:02:01 +00:00
/**
2017-04-06 17:45:19 +00:00
* @ brief Send HTTP status header .
2015-03-21 23:06:08 +00:00
*
2013-03-28 02:02:01 +00:00
* @ param int $val
* integer HTTP status result value
2013-04-25 08:55:35 +00:00
* @ param string $msg
* optional message
2013-03-28 02:02:01 +00:00
*/
2015-11-21 02:56:41 +00:00
function http_status ( $val , $msg = '' ) {
2015-03-21 23:06:08 +00:00
if ( $val >= 400 )
2013-04-25 08:55:35 +00:00
$msg = (( $msg ) ? $msg : 'Error' );
2015-03-21 23:06:08 +00:00
if ( $val >= 200 && $val < 300 )
2013-04-25 08:55:35 +00:00
$msg = (( $msg ) ? $msg : 'OK' );
2011-08-10 01:55:46 +00:00
2017-09-13 03:24:57 +00:00
logger ( \App :: $query_string . ':' . $val . ' ' . $msg );
2013-04-25 08:55:35 +00:00
header ( $_SERVER [ 'SERVER_PROTOCOL' ] . ' ' . $val . ' ' . $msg );
2015-11-21 02:56:41 +00:00
}
/**
* @ brief Send HTTP status header and exit .
*
* @ param int $val
* integer HTTP status result value
* @ param string $msg
* optional message
2017-09-04 22:23:42 +00:00
* @ return void does not return , process is terminated
2015-11-21 02:56:41 +00:00
*/
function http_status_exit ( $val , $msg = '' ) {
http_status ( $val , $msg );
2011-08-10 01:55:46 +00:00
killme ();
2013-02-26 23:49:37 +00:00
}
2011-08-10 01:55:46 +00:00
2020-08-13 06:58:09 +00:00
/*
*
* Takes the output of parse_url and builds a URL from it
*
*/
function unparse_url ( $parsed_url ) {
$scheme = isset ( $parsed_url [ 'scheme' ]) ? $parsed_url [ 'scheme' ] . '://' : '' ;
$host = isset ( $parsed_url [ 'host' ]) ? $parsed_url [ 'host' ] : '' ;
2021-03-09 23:36:07 +00:00
$port = (( isset ( $parsed_url [ 'port' ]) && intval ( $parsed_url [ 'port' ])) ? ':' . intval ( $parsed_url [ 'port' ]) : '' );
2020-08-13 06:58:09 +00:00
$user = isset ( $parsed_url [ 'user' ]) ? $parsed_url [ 'user' ] : '' ;
$pass = isset ( $parsed_url [ 'pass' ]) ? ':' . $parsed_url [ 'pass' ] : '' ;
$pass = ( $user || $pass ) ? " $pass @ " : '' ;
$path = isset ( $parsed_url [ 'path' ]) ? $parsed_url [ 'path' ] : '' ;
$query = isset ( $parsed_url [ 'query' ]) ? '?' . $parsed_url [ 'query' ] : '' ;
$fragment = isset ( $parsed_url [ 'fragment' ]) ? '#' . $parsed_url [ 'fragment' ] : '' ;
return " $scheme $user $pass $host $port $path $query $fragment " ;
}
2017-04-06 17:45:19 +00:00
/**
2017-09-04 22:23:42 +00:00
* @ brief Convert an XML document to a normalised , case - corrected array used by webfinger .
2017-04-06 17:45:19 +00:00
*
* @ param string | array | SimpleXMLElement $xml_element
2017-09-04 22:23:42 +00:00
* @ param [ in , out ] int $recursion_depth
2017-04-06 17:45:19 +00:00
* @ return NULL | string | array
*/
2011-08-01 23:51:01 +00:00
function convert_xml_element_to_array ( $xml_element , & $recursion_depth = 0 ) {
2017-04-06 17:45:19 +00:00
// If we're getting too deep, bail out
if ( $recursion_depth > 512 ) {
return ( null );
}
2014-08-25 00:52:26 +00:00
2017-04-06 17:45:19 +00:00
if ( ! is_string ( $xml_element ) &&
! is_array ( $xml_element ) &&
( get_class ( $xml_element ) == 'SimpleXMLElement' )) {
$xml_element_copy = $xml_element ;
$xml_element = get_object_vars ( $xml_element );
}
2014-08-25 00:52:26 +00:00
2017-04-06 17:45:19 +00:00
if ( is_array ( $xml_element )) {
2021-03-15 05:10:44 +00:00
$result_array = [];
2017-04-06 17:45:19 +00:00
if ( count ( $xml_element ) <= 0 ) {
return ( trim ( strval ( $xml_element_copy )));
}
2014-08-25 00:52:26 +00:00
2017-04-06 17:45:19 +00:00
foreach ( $xml_element as $key => $value ) {
$recursion_depth ++ ;
$result_array [ strtolower ( $key )] =
2014-08-25 00:52:26 +00:00
convert_xml_element_to_array ( $value , $recursion_depth );
2017-04-06 17:45:19 +00:00
$recursion_depth -- ;
2014-08-25 00:52:26 +00:00
}
2017-04-06 17:45:19 +00:00
if ( $recursion_depth == 0 ) {
$temp_array = $result_array ;
$result_array = array (
strtolower ( $xml_element_copy -> getName ()) => $temp_array ,
);
}
return ( $result_array );
} else {
return ( trim ( strval ( $xml_element )));
}
2013-02-26 23:49:37 +00:00
}
2011-08-01 23:51:01 +00:00
2016-10-26 01:27:32 +00:00
function z_dns_check ( $h , $check_mx = 0 ) {
// dns_get_record() has issues on some platforms
// so allow somebody to ignore it completely
2016-10-26 06:32:24 +00:00
// Use config values from memory as this can be called during setup
// before a database or even any config structure exists.
2016-10-26 01:27:32 +00:00
2020-01-21 21:07:41 +00:00
if ( is_array ( App :: $config ) && array_path_exists ( 'system/do_not_check_dns' , App :: $config ) && App :: $config [ 'system' ][ 'do_not_check_dns' ])
2016-10-26 01:27:32 +00:00
return true ;
2018-05-24 23:32:21 +00:00
// This will match either Windows or Mac ('Darwin')
if ( stripos ( PHP_OS , 'win' ) !== false )
return true ;
// BSD variants have dns_get_record() but it only works reliably without any options
if ( stripos ( PHP_OS , 'bsd' ) !== false )
return (( @ dns_get_record ( $h ) || filter_var ( $h , FILTER_VALIDATE_IP )) ? true : false );
// Otherwise we will assume dns_get_record() works as documented
2020-01-21 21:07:41 +00:00
$opts = DNS_A + DNS_CNAME + DNS_AAAA ;
2018-05-24 23:32:21 +00:00
if ( $check_mx )
$opts += DNS_MX ;
2016-11-03 06:37:57 +00:00
2018-05-24 23:32:21 +00:00
return (( @ dns_get_record ( $h , $opts ) || filter_var ( $h , FILTER_VALIDATE_IP )) ? true : false );
2016-10-26 01:27:32 +00:00
}
2017-04-06 17:45:19 +00:00
/**
2017-09-04 22:23:42 +00:00
* @ brief Validates a given URL .
2017-04-06 17:45:19 +00:00
*
* Take a URL from the wild , prepend http :// if necessary and check DNS to see
* if it ' s real ( or check if is a valid IP address ) .
*
* @ see z_dns_check ()
*
2017-09-04 22:23:42 +00:00
* @ param [ in , out ] string $url URL to check
2017-04-06 17:45:19 +00:00
* @ return boolean Return true if it ' s OK , false if something is wrong with it
*/
2011-08-01 23:51:01 +00:00
function validate_url ( & $url ) {
2016-10-01 22:41:25 +00:00
2012-04-13 07:42:53 +00:00
// no naked subdomains (allow localhost for tests)
2017-04-06 17:45:19 +00:00
if ( strpos ( $url , '.' ) === false && strpos ( $url , '/localhost/' ) === false )
2012-02-12 22:18:32 +00:00
return false ;
2017-04-06 17:45:19 +00:00
if ( substr ( $url , 0 , 4 ) != 'http' )
2011-08-01 23:51:01 +00:00
$url = 'http://' . $url ;
2017-04-06 17:45:19 +00:00
2011-08-01 23:51:01 +00:00
$h = @ parse_url ( $url );
2016-10-01 22:41:25 +00:00
2016-10-26 01:27:32 +00:00
if (( $h ) && z_dns_check ( $h [ 'host' ])) {
2011-08-01 23:51:01 +00:00
return true ;
}
2017-04-06 17:45:19 +00:00
2011-08-01 23:51:01 +00:00
return false ;
2013-02-26 23:49:37 +00:00
}
2011-08-01 23:51:01 +00:00
2017-04-06 17:45:19 +00:00
/**
* @ brief Checks that email is an actual resolvable internet address .
*
* @ param string $addr
* @ return boolean
*/
2011-08-01 23:51:01 +00:00
function validate_email ( $addr ) {
2017-04-06 17:45:19 +00:00
if ( get_config ( 'system' , 'disable_email_validation' ))
2012-07-02 01:56:00 +00:00
return true ;
2017-04-06 17:45:19 +00:00
if ( ! strpos ( $addr , '@' ))
2011-08-01 23:51:01 +00:00
return false ;
2017-04-06 17:45:19 +00:00
$h = substr ( $addr , strpos ( $addr , '@' ) + 1 );
if (( $h ) && z_dns_check ( $h , true )) {
2011-08-01 23:51:01 +00:00
return true ;
}
2017-04-06 17:45:19 +00:00
2011-08-01 23:51:01 +00:00
return false ;
2013-02-26 23:49:37 +00:00
}
2011-08-01 23:51:01 +00:00
2017-04-06 17:45:19 +00:00
/**
* @ brief Check if email address is allowed to register here .
*
* Compare against our list ( wildcards allowed ) .
*
* @ param string $email
* @ return boolean Returns false if not allowed , true if allowed or if allowed list is
* not configured .
*/
2011-08-01 23:51:01 +00:00
function allowed_email ( $email ) {
2017-04-06 17:45:19 +00:00
$domain = strtolower ( substr ( $email , strpos ( $email , '@' ) + 1 ));
2011-08-01 23:51:01 +00:00
if ( ! $domain )
return false ;
2017-04-06 17:45:19 +00:00
$str_allowed = get_config ( 'system' , 'allowed_email' );
$str_not_allowed = get_config ( 'system' , 'not_allowed_email' );
2016-10-01 22:41:25 +00:00
2015-01-25 03:16:28 +00:00
if ( ! $str_allowed && ! $str_not_allowed )
2011-08-01 23:51:01 +00:00
return true ;
2015-01-25 03:16:28 +00:00
$return = false ;
2016-10-01 22:41:25 +00:00
$found_allowed = false ;
2015-01-25 03:16:28 +00:00
$found_not_allowed = false ;
2016-10-01 22:41:25 +00:00
2011-08-01 23:51:01 +00:00
$fnmatch = function_exists ( 'fnmatch' );
2015-01-25 03:16:28 +00:00
2017-04-06 17:45:19 +00:00
$allowed = explode ( ',' , $str_allowed );
2011-08-01 23:51:01 +00:00
if ( count ( $allowed )) {
foreach ( $allowed as $a ) {
$pat = strtolower ( trim ( $a ));
2015-01-25 03:16:28 +00:00
if (( $fnmatch && fnmatch ( $pat , $email )) || ( $pat == $domain )) {
2016-10-01 22:41:25 +00:00
$found_allowed = true ;
2011-08-01 23:51:01 +00:00
break ;
}
}
}
2015-01-25 03:16:28 +00:00
2017-04-06 17:45:19 +00:00
$not_allowed = explode ( ',' , $str_not_allowed );
2015-01-25 03:16:28 +00:00
if ( count ( $not_allowed )) {
foreach ( $not_allowed as $na ) {
$pat = strtolower ( trim ( $na ));
if (( $fnmatch && fnmatch ( $pat , $email )) || ( $pat == $domain )) {
2016-10-01 22:41:25 +00:00
$found_not_allowed = true ;
2015-01-25 03:16:28 +00:00
break ;
}
}
2016-10-01 22:41:25 +00:00
}
2015-01-25 03:16:28 +00:00
if ( $found_allowed ) {
2016-10-01 22:41:25 +00:00
$return = true ;
2015-01-25 03:16:28 +00:00
} elseif ( ! $str_allowed && ! $found_not_allowed ) {
2016-10-01 22:41:25 +00:00
$return = true ;
2015-01-25 03:16:28 +00:00
}
2017-04-06 17:45:19 +00:00
2015-01-25 03:16:28 +00:00
return $return ;
2013-02-26 23:49:37 +00:00
}
2011-08-01 23:51:01 +00:00
2017-09-04 22:23:42 +00:00
function parse_xml_string ( $s , $strict = true ) {
2011-08-01 23:51:01 +00:00
if ( $strict ) {
if ( ! strstr ( $s , '<?xml' ))
return false ;
2017-04-06 17:45:19 +00:00
2011-08-01 23:51:01 +00:00
$s2 = substr ( $s , strpos ( $s , '<?xml' ));
}
else
$s2 = $s ;
2017-04-06 17:45:19 +00:00
2011-08-01 23:51:01 +00:00
libxml_use_internal_errors ( true );
2018-04-30 06:05:38 +00:00
2011-08-01 23:51:01 +00:00
$x = @ simplexml_load_string ( $s2 );
2017-08-10 00:35:03 +00:00
if ( $x === false ) {
2011-08-01 23:51:01 +00:00
logger ( 'libxml: parse: error: ' . $s2 , LOGGER_DATA );
2017-08-10 00:35:03 +00:00
foreach ( libxml_get_errors () as $err ) {
logger ( 'libxml: parse: ' . $err -> code . ' at ' . $err -> line
. ':' . $err -> column . ' : ' . $err -> message , LOGGER_DATA );
}
2011-08-01 23:51:01 +00:00
libxml_clear_errors ();
}
2017-04-06 17:45:19 +00:00
2011-08-01 23:51:01 +00:00
return $x ;
2013-02-26 23:49:37 +00:00
}
2011-08-18 11:20:30 +00:00
2018-04-30 06:05:38 +00:00
function sxml2array ( $xmlObject , $out = array () )
{
foreach ( ( array ) $xmlObject as $index => $node )
$out [ $index ] = ( is_object ( $node ) ) ? sxml2array ( $node ) : $node ;
return $out ;
}
2012-05-17 04:29:57 +00:00
/**
2021-03-15 05:10:44 +00:00
* @ brief xml2 [] will convert the given XML text to an array in the XML structure .
2017-04-06 17:45:19 +00:00
*
2012-05-17 04:29:57 +00:00
* Link : http :// www . bin - co . com / php / scripts / xml2array /
2018-04-28 21:13:56 +00:00
* Portions significantly re - written by mike @ macgirvin . com
2017-04-06 17:45:19 +00:00
* ( namespaces , lowercase tags , get_attribute default changed , more ... )
*
2012-05-17 04:29:57 +00:00
* Examples : $array = xml2array ( file_get_contents ( 'feed.xml' ));
2017-04-06 17:45:19 +00:00
* $array = xml2array ( file_get_contents ( 'feed.xml' , true , 1 , 'attribute' ));
*
* @ param string $contents The XML text
* @ param boolean $namespaces true or false include namespace information in the returned array as array elements
* @ param int $get_attributes 1 or 0. If this is 1 the function will get the attributes as well as the tag values - this results in a different array structure in the return value .
* @ param string $priority Can be 'tag' or 'attribute' . This will change the way the resulting array sturcture . For 'tag' , the tags are given more importance .
*
* @ return array The parsed XML in an array form . Use print_r () to see the resulting array structure .
2016-10-01 22:41:25 +00:00
*/
2012-05-17 04:29:57 +00:00
function xml2array ( $contents , $namespaces = true , $get_attributes = 1 , $priority = 'attribute' ) {
2017-04-06 17:45:19 +00:00
if ( ! $contents )
2021-03-15 05:10:44 +00:00
return [];
2012-05-17 04:29:57 +00:00
2014-08-25 00:52:26 +00:00
if ( ! function_exists ( 'xml_parser_create' )) {
logger ( 'xml2array: parser function missing' );
2021-03-15 05:10:44 +00:00
return [];
2014-08-25 00:52:26 +00:00
}
2012-05-17 04:29:57 +00:00
libxml_use_internal_errors ( true );
libxml_clear_errors ();
if ( $namespaces )
2014-08-25 00:52:26 +00:00
$parser = @ xml_parser_create_ns ( " UTF-8 " , ':' );
2012-05-17 04:29:57 +00:00
else
2014-08-25 00:52:26 +00:00
$parser = @ xml_parser_create ();
2012-05-17 04:29:57 +00:00
if ( ! $parser ) {
logger ( 'xml2array: xml_parser_create: no resource' );
2021-03-15 05:10:44 +00:00
return [];
2012-05-17 04:29:57 +00:00
}
2016-10-01 22:41:25 +00:00
xml_parser_set_option ( $parser , XML_OPTION_TARGET_ENCODING , " UTF-8 " );
2012-05-17 04:29:57 +00:00
// http://minutillo.com/steve/weblog/2004/6/17/php-xml-and-character-encodings-a-tale-of-sadness-rage-and-data-loss
2014-08-25 00:52:26 +00:00
xml_parser_set_option ( $parser , XML_OPTION_CASE_FOLDING , 0 );
xml_parser_set_option ( $parser , XML_OPTION_SKIP_WHITE , 1 );
@ xml_parse_into_struct ( $parser , trim ( $contents ), $xml_values );
@ xml_parser_free ( $parser );
2012-05-17 04:29:57 +00:00
2014-08-25 00:52:26 +00:00
if ( ! $xml_values ) {
2012-05-17 04:29:57 +00:00
logger ( 'xml2array: libxml: parse error: ' . $contents , LOGGER_DATA );
foreach ( libxml_get_errors () as $err )
logger ( 'libxml: parse: ' . $err -> code . " at " . $err -> line . " : " . $err -> column . " : " . $err -> message , LOGGER_DATA );
libxml_clear_errors ();
2017-04-06 17:45:19 +00:00
2012-05-17 04:29:57 +00:00
return ;
}
2014-08-25 00:52:26 +00:00
//Initializations
2021-03-15 05:10:44 +00:00
$xml_array = [];
$parents = [];
$opened_tags = [];
$arr = [];
2014-08-25 00:52:26 +00:00
$current = & $xml_array ; // Reference
// Go through the tags.
2021-03-15 05:10:44 +00:00
$repeated_tag_index = []; // Multiple tags with same name will be turned into an array
2014-08-25 00:52:26 +00:00
foreach ( $xml_values as $data ) {
unset ( $attributes , $value ); // Remove existing values, or there will be trouble
// This command will extract these variables into the foreach scope
// tag(string), type(string), level(int), attributes(array).
extract ( $data ); // We could use the array by itself, but this cooler.
2021-03-15 05:10:44 +00:00
$result = [];
$attributes_data = [];
2016-10-01 22:41:25 +00:00
2014-08-25 00:52:26 +00:00
if ( isset ( $value )) {
if ( $priority == 'tag' ) $result = $value ;
else $result [ 'value' ] = $value ; // Put the value in a assoc array if we are in the 'Attribute' mode
}
//Set the attributes too.
if ( isset ( $attributes ) and $get_attributes ) {
foreach ( $attributes as $attr => $val ) {
if ( $priority == 'tag' ) $attributes_data [ $attr ] = $val ;
else $result [ '@attributes' ][ $attr ] = $val ; // Set all the attributes in a array called 'attr'
}
}
// See tag status and do the needed.
2012-05-17 04:29:57 +00:00
if ( $namespaces && strpos ( $tag , ':' )) {
2016-10-01 22:41:25 +00:00
$namespc = substr ( $tag , 0 , strrpos ( $tag , ':' ));
2012-05-17 04:29:57 +00:00
$tag = strtolower ( substr ( $tag , strlen ( $namespc ) + 1 ));
$result [ '@namespace' ] = $namespc ;
}
$tag = strtolower ( $tag );
if ( $type == " open " ) { // The starting of the tag '<tag>'
2014-08-25 00:52:26 +00:00
$parent [ $level - 1 ] = & $current ;
if ( ! is_array ( $current ) or ( ! in_array ( $tag , array_keys ( $current )))) { // Insert New tag
$current [ $tag ] = $result ;
if ( $attributes_data ) $current [ $tag . '_attr' ] = $attributes_data ;
$repeated_tag_index [ $tag . '_' . $level ] = 1 ;
$current = & $current [ $tag ];
} else { // There was another element with the same tag name
if ( isset ( $current [ $tag ][ 0 ])) { // If there is a 0th element it is already an array
$current [ $tag ][ $repeated_tag_index [ $tag . '_' . $level ]] = $result ;
$repeated_tag_index [ $tag . '_' . $level ] ++ ;
} else { // This section will make the value an array if multiple tags with the same name appear together
$current [ $tag ] = array ( $current [ $tag ], $result ); // This will combine the existing item and the new item together to make an array
$repeated_tag_index [ $tag . '_' . $level ] = 2 ;
2016-10-01 22:41:25 +00:00
2014-08-25 00:52:26 +00:00
if ( isset ( $current [ $tag . '_attr' ])) { // The attribute of the last(0th) tag must be moved as well
$current [ $tag ][ '0_attr' ] = $current [ $tag . '_attr' ];
unset ( $current [ $tag . '_attr' ]);
}
}
$last_item_index = $repeated_tag_index [ $tag . '_' . $level ] - 1 ;
$current = & $current [ $tag ][ $last_item_index ];
}
} elseif ( $type == " complete " ) { // Tags that ends in 1 line '<tag />'
//See if the key is already taken.
if ( ! isset ( $current [ $tag ])) { //New Key
$current [ $tag ] = $result ;
$repeated_tag_index [ $tag . '_' . $level ] = 1 ;
2017-04-06 17:45:19 +00:00
if ( $priority == 'tag' and $attributes_data )
$current [ $tag . '_attr' ] = $attributes_data ;
2014-08-25 00:52:26 +00:00
} else { // If taken, put all things inside a list(array)
if ( isset ( $current [ $tag ][ 0 ]) and is_array ( $current [ $tag ])) { // If it is already an array...
// ...push the new element into that array.
$current [ $tag ][ $repeated_tag_index [ $tag . '_' . $level ]] = $result ;
2016-10-01 22:41:25 +00:00
2014-08-25 00:52:26 +00:00
if ( $priority == 'tag' and $get_attributes and $attributes_data ) {
$current [ $tag ][ $repeated_tag_index [ $tag . '_' . $level ] . '_attr' ] = $attributes_data ;
}
$repeated_tag_index [ $tag . '_' . $level ] ++ ;
} else { // If it is not an array...
$current [ $tag ] = array ( $current [ $tag ], $result ); //...Make it an array using using the existing value and the new value
$repeated_tag_index [ $tag . '_' . $level ] = 1 ;
if ( $priority == 'tag' and $get_attributes ) {
if ( isset ( $current [ $tag . '_attr' ])) { // The attribute of the last(0th) tag must be moved as well
$current [ $tag ][ '0_attr' ] = $current [ $tag . '_attr' ];
unset ( $current [ $tag . '_attr' ]);
}
2016-10-01 22:41:25 +00:00
2014-08-25 00:52:26 +00:00
if ( $attributes_data ) {
$current [ $tag ][ $repeated_tag_index [ $tag . '_' . $level ] . '_attr' ] = $attributes_data ;
}
}
$repeated_tag_index [ $tag . '_' . $level ] ++ ; // 0 and 1 indexes are already taken
}
}
} elseif ( $type == 'close' ) { // End of tag '</tag>'
$current = & $parent [ $level - 1 ];
}
}
2016-10-01 22:41:25 +00:00
2014-08-25 00:52:26 +00:00
return ( $xml_array );
2016-10-01 22:41:25 +00:00
}
2012-08-09 23:26:44 +00:00
2012-10-23 02:46:18 +00:00
2019-03-16 20:46:05 +00:00
function email_header_encode ( $in_str , $charset = 'UTF-8' , $header = 'Subject' ) {
2014-08-25 00:52:26 +00:00
$out_str = $in_str ;
2012-10-23 02:46:18 +00:00
$need_to_convert = false ;
for ( $x = 0 ; $x < strlen ( $in_str ); $x ++ ) {
if (( ord ( $in_str [ $x ]) == 0 ) || (( ord ( $in_str [ $x ]) > 128 ))) {
$need_to_convert = true ;
2019-03-16 20:46:05 +00:00
break ;
2012-10-23 02:46:18 +00:00
}
}
if ( ! $need_to_convert )
return $in_str ;
2014-08-25 00:52:26 +00:00
if ( $out_str && $charset ) {
// define start delimimter, end delimiter and spacer
$end = " ?= " ;
$start = " =? " . $charset . " ?B? " ;
2019-03-17 23:32:21 +00:00
$spacer = $end . PHP_EOL . " " . $start ;
2014-08-25 00:52:26 +00:00
// determine length of encoded text within chunks
// and ensure length is even
2019-03-16 20:46:05 +00:00
$length = 75 - strlen ( $start ) - strlen ( $end ) - ( strlen ( $header ) + 2 );
2014-08-25 00:52:26 +00:00
/*
[ EDIT BY danbrown AT php DOT net : The following
is a bugfix provided by ( gardan AT gmx DOT de )
on 31 - MAR - 2005 with the following note :
" This means: $length should not be even,
but divisible by 4. The reason is that in
base64 - encoding 3 8 - bit - chars are represented
by 4 6 - bit - chars . These 4 chars must not be
split between two encoded words , according
to RFC - 2047.
*/
$length = $length - ( $length % 4 );
// encode the string and split it into chunks
// with spacers after each chunk
$out_str = base64_encode ( $out_str );
$out_str = chunk_split ( $out_str , $length , $spacer );
// remove trailing spacer and
// add start and end delimiters
$spacer = preg_quote ( $spacer , '/' );
$out_str = preg_replace ( " / " . $spacer . " $ / " , " " , $out_str );
$out_str = $start . $out_str . $end ;
}
return $out_str ;
2012-10-23 02:46:18 +00:00
}
2017-09-04 22:23:42 +00:00
/**
* @ brief
*
* @ param string $webbie
* @ param string $protocol ( optional ) default empty
2020-07-16 02:28:01 +00:00
* @ param boolean $verify ( optional ) default true , verify HTTP signatures on Zot discovery packets .
2017-09-04 22:23:42 +00:00
* @ return boolean
*/
2020-07-16 02:28:01 +00:00
function discover_by_webbie ( $webbie , $protocol = '' , $verify = true ) {
2014-08-20 02:38:42 +00:00
2017-03-09 19:51:21 +00:00
$result = [];
2016-03-23 02:58:59 +00:00
$network = null ;
2019-07-19 03:38:36 +00:00
$x = Webfinger :: exec ( $webbie );
2018-08-23 06:04:37 +00:00
$address = EMPTY_STR ;
if ( $x && array_key_exists ( 'subject' , $x ) && strpos ( $x [ 'subject' ], 'acct:' ) === 0 )
$address = str_replace ( 'acct:' , '' , $x [ 'subject' ]);
if ( $x && array_key_exists ( 'aliases' , $x ) && count ( $x [ 'aliases' ])) {
foreach ( $x [ 'aliases' ] as $a ) {
if ( strpos ( $a , 'acct:' ) === 0 ) {
$address = str_replace ( 'acct:' , '' , $a );
break ;
}
}
}
2020-07-22 23:40:58 +00:00
if ( $x && array_key_exists ( 'links' , $x ) && is_array ( $x [ 'links' ])) {
2014-08-20 02:38:42 +00:00
foreach ( $x [ 'links' ] as $link ) {
2016-03-17 01:00:13 +00:00
if ( array_key_exists ( 'rel' , $link )) {
2016-03-23 02:58:59 +00:00
2018-08-23 06:04:37 +00:00
$apurl = null ;
2016-03-23 02:58:59 +00:00
// If we discover zot - don't search further; grab the info and get out of
2016-10-01 22:41:25 +00:00
// here.
2016-03-23 02:58:59 +00:00
2018-08-03 23:03:16 +00:00
if ( $link [ 'rel' ] === PROTOCOL_ZOT6 && (( ! $protocol ) || ( strtolower ( $protocol ) === 'zot6' ))) {
logger ( 'zot6 found for ' . $webbie , LOGGER_DEBUG );
2020-08-07 21:57:59 +00:00
$record = Zotfinger :: exec ( $link [ 'href' ], null , $verify );
2018-08-03 23:03:16 +00:00
// Check the HTTP signature
2020-07-16 02:28:01 +00:00
if ( $verify ) {
2018-08-03 23:03:16 +00:00
2020-07-16 02:28:01 +00:00
$hsig = $record [ 'signature' ];
if ( $hsig && ( $hsig [ 'signer' ] === $url || $hsig [ 'signer' ] === $link [ 'href' ]) && $hsig [ 'header_valid' ] === true && $hsig [ 'content_valid' ] === true ) {
$hsig_valid = true ;
}
if ( ! $hsig_valid ) {
logger ( 'http signature not valid: ' . print_r ( $hsig , true ));
continue ;
}
}
2018-08-03 23:03:16 +00:00
$x = Libzot :: import_xchan ( $record [ 'data' ]);
if ( $x [ 'success' ]) {
2018-09-15 23:13:44 +00:00
return $x [ 'hash' ];
2016-03-17 01:00:13 +00:00
}
}
2018-08-29 01:37:21 +00:00
if ( $link [ 'rel' ] === 'self' && ( $link [ 'type' ] === 'application/activity+json' || strpos ( $link [ 'type' ], 'ld+json' ) !== false ) && (( ! $protocol ) || ( strtolower ( $protocol ) === 'activitypub' ))) {
2018-09-17 04:42:41 +00:00
$ap = ActivityPub :: discover ( $link [ 'href' ]);
if ( $ap ) {
return $ap ;
2018-08-23 06:04:37 +00:00
}
}
2014-08-20 02:38:42 +00:00
}
}
}
2018-09-17 05:05:04 +00:00
if ( strpos ( $webbie , 'http' ) === 0 ) {
$ap = ActivityPub :: discover ( $webbie );
2018-09-17 04:42:41 +00:00
if ( $ap ) {
return $ap ;
}
}
2016-03-23 02:58:59 +00:00
logger ( 'webfinger: ' . print_r ( $x , true ), LOGGER_DATA , LOG_INFO );
2016-03-17 01:00:13 +00:00
2017-09-04 22:23:42 +00:00
$arr = [
2018-04-19 02:41:09 +00:00
'address' => $webbie ,
'protocol' => $protocol ,
'success' => false ,
'xchan' => '' ,
2017-09-04 22:23:42 +00:00
'webfinger' => $x
];
/**
* @ hooks discover_channel_webfinger
* Called when performing a webfinger lookup .
* * \e string \b address - The webbie
* * \e string \b protocol
* * \e array \b webfinger - The result from webfinger_rfc7033 ()
* * \e boolean \b success - The return value , default false
*/
2016-03-17 01:00:13 +00:00
call_hooks ( 'discover_channel_webfinger' , $arr );
2015-08-03 23:52:51 +00:00
if ( $arr [ 'success' ])
2018-04-19 02:41:09 +00:00
return $arr [ 'xchan' ];
2015-08-03 23:52:51 +00:00
2016-03-23 02:58:59 +00:00
return false ;
2017-03-09 19:51:21 +00:00
}
2016-03-23 02:58:59 +00:00
2017-09-04 22:23:42 +00:00
/**
* @ brief Fetch and return a webfinger for a webbie .
2019-07-19 03:38:36 +00:00
* No longer used - see Zotlabs / Lib / Webfinger . php
2017-09-04 22:23:42 +00:00
*
2018-05-18 10:09:38 +00:00
* @ param string $webbie - The resource
2017-09-04 22:23:42 +00:00
* @ return boolean | string false or associative array from result JSON
*/
2018-05-18 10:09:38 +00:00
function webfinger_rfc7033 ( $webbie ) {
2014-08-20 02:38:42 +00:00
2016-03-15 01:12:35 +00:00
if ( strpos ( $webbie , '@' )) {
$lhs = substr ( $webbie , 0 , strpos ( $webbie , '@' ));
$rhs = substr ( $webbie , strpos ( $webbie , '@' ) + 1 );
2018-05-21 02:18:39 +00:00
$resource = urlencode ( 'acct:' . $webbie );
2016-03-15 01:12:35 +00:00
}
else {
$m = parse_url ( $webbie );
if ( $m ) {
if ( $m [ 'scheme' ] !== 'https' )
return false ;
2017-09-04 22:23:42 +00:00
2021-03-09 23:36:07 +00:00
$rhs = $m [ 'host' ] . (( isset ( $m [ 'port' ]) && intval ( $m [ 'port' ])) ? ':' . intval ( $m [ 'port' ]) : '' );
2016-03-15 01:12:35 +00:00
$resource = urlencode ( $webbie );
}
else
return false ;
}
2016-03-15 05:14:17 +00:00
logger ( 'fetching url from resource: ' . $rhs . ':' . $webbie );
2014-08-20 02:38:42 +00:00
2017-04-11 03:31:45 +00:00
$counter = 0 ;
2017-09-04 22:23:42 +00:00
$s = z_fetch_url ( 'https://' . $rhs . '/.well-known/webfinger?f=&resource=' . $resource . (( $zot ) ? '&zot=1' : '' ),
2018-05-21 02:18:39 +00:00
false , $counter , [ 'headers' => [ 'Accept: application/jrd+json, application/json, */*' ] ]);
2014-08-20 02:38:42 +00:00
2016-03-17 01:00:13 +00:00
if ( $s [ 'success' ]) {
2017-09-04 22:23:42 +00:00
$j = json_decode ( $s [ 'body' ], true );
2017-03-09 19:51:21 +00:00
return ( $j );
2016-03-17 01:00:13 +00:00
}
2017-03-09 19:51:21 +00:00
return false ;
2016-03-17 01:00:13 +00:00
}
2016-10-01 22:41:25 +00:00
2017-11-02 22:43:14 +00:00
function do_delivery ( $deliveries , $force = false ) {
// $force is set if a site that wasn't responding suddenly returns to life.
// Try and shove through everything going to that site while it's responding.
2015-06-29 23:56:18 +00:00
2015-10-16 01:52:04 +00:00
if ( ! ( is_array ( $deliveries ) && count ( $deliveries )))
return ;
2015-06-29 23:56:18 +00:00
2017-11-02 10:13:30 +00:00
$x = q ( " select count(outq_hash) as total from outq where outq_delivered = 0 " );
2018-07-03 05:43:41 +00:00
if ( intval ( $x [ 0 ][ 'total' ]) > intval ( get_config ( 'system' , 'force_queue_threshold' , 3000 )) && ( ! $force )) {
2017-11-02 10:13:30 +00:00
logger ( 'immediate delivery deferred.' , LOGGER_DEBUG , LOG_INFO );
foreach ( $deliveries as $d ) {
2018-11-12 01:44:01 +00:00
Queue :: update ( $d );
2017-11-02 10:13:30 +00:00
}
return ;
}
2016-10-01 22:41:25 +00:00
$interval = (( get_config ( 'system' , 'delivery_interval' ) !== false )
2015-10-16 01:52:04 +00:00
? intval ( get_config ( 'system' , 'delivery_interval' )) : 2 );
2015-06-29 23:56:18 +00:00
2015-10-16 01:52:04 +00:00
$deliveries_per_process = intval ( get_config ( 'system' , 'delivery_batch_count' ));
2015-06-29 23:56:18 +00:00
2015-10-16 01:52:04 +00:00
if ( $deliveries_per_process <= 0 )
$deliveries_per_process = 1 ;
2015-06-29 23:56:18 +00:00
2021-03-15 05:10:44 +00:00
$deliver = [];
2015-10-16 01:52:04 +00:00
foreach ( $deliveries as $d ) {
2015-06-29 23:56:18 +00:00
2016-05-20 03:48:40 +00:00
if ( ! $d )
continue ;
2015-10-16 01:52:04 +00:00
$deliver [] = $d ;
if ( count ( $deliver ) >= $deliveries_per_process ) {
2021-04-13 03:49:58 +00:00
Run :: Summon ( [ 'Deliver' , $deliver ] );
2021-03-15 05:10:44 +00:00
$deliver = [];
2015-10-16 01:52:04 +00:00
if ( $interval )
@ time_sleep_until ( microtime ( true ) + ( float ) $interval );
}
}
// catch any stragglers
2018-11-12 01:44:01 +00:00
if ( $deliver ) {
2021-04-13 03:49:58 +00:00
Run :: Summon ( [ 'Deliver' , $deliver ] );
2018-11-12 01:44:01 +00:00
}
2015-02-09 02:31:51 +00:00
}
2015-11-30 03:37:03 +00:00
function get_site_info () {
$register_policy = Array ( 'REGISTER_CLOSED' , 'REGISTER_APPROVE' , 'REGISTER_OPEN' );
2016-02-12 22:02:50 +00:00
$directory_mode = Array ( 'DIRECTORY_MODE_NORMAL' , 'DIRECTORY_MODE_PRIMARY' , 'DIRECTORY_MODE_SECONDARY' , 256 => 'DIRECTORY_MODE_STANDALONE' );
2016-10-01 22:41:25 +00:00
2015-11-30 03:37:03 +00:00
$sql_extra = '' ;
2018-08-02 08:56:34 +00:00
$r = q ( " select * from channel left join account on account_id = channel_account_id where ( account_roles & 4096 ) > 0 and account_default_channel = channel_id " );
2015-11-30 03:37:03 +00:00
if ( $r ) {
2021-03-15 05:10:44 +00:00
$admin = [];
2015-11-30 03:37:03 +00:00
foreach ( $r as $rr ) {
if ( $rr [ 'channel_pageflags' ] & PAGE_HUBADMIN )
2016-09-21 22:28:37 +00:00
$admin [] = array ( 'name' => $rr [ 'channel_name' ], 'address' => channel_reddress ( $rr ), 'channel' => z_root () . '/channel/' . $rr [ 'channel_address' ]);
2015-11-30 03:37:03 +00:00
}
if ( ! $admin ) {
foreach ( $r as $rr ) {
2016-09-21 22:28:37 +00:00
$admin [] = array ( 'name' => $rr [ 'channel_name' ], 'address' => channel_reddress ( $rr ), 'channel' => z_root () . '/channel/' . $rr [ 'channel_address' ]);
2015-11-30 03:37:03 +00:00
}
}
}
else {
$admin = false ;
}
$def_service_class = get_config ( 'system' , 'default_service_class' );
if ( $def_service_class )
$service_class = get_config ( 'service_class' , $def_service_class );
else
$service_class = false ;
2016-06-21 03:34:19 +00:00
$visible_plugins = visible_plugin_list ();
2015-11-30 03:37:03 +00:00
if ( @ is_dir ( '.git' ) && function_exists ( 'shell_exec' ))
$commit = trim ( @ shell_exec ( 'git log -1 --format="%h"' ));
if ( ! isset ( $commit ) || strlen ( $commit ) > 16 )
$commit = '' ;
$site_info = get_config ( 'system' , 'info' );
$site_name = get_config ( 'system' , 'sitename' );
if ( ! get_config ( 'system' , 'hidden_version_siteinfo' )) {
2018-11-12 01:44:01 +00:00
$version = System :: get_project_version ();
2015-12-04 01:09:05 +00:00
2015-11-30 03:37:03 +00:00
if ( @ is_dir ( '.git' ) && function_exists ( 'shell_exec' )) {
$commit = trim ( @ shell_exec ( 'git log -1 --format="%h"' ));
}
2016-01-18 00:29:32 +00:00
2015-11-30 03:37:03 +00:00
if ( ! isset ( $commit ) || strlen ( $commit ) > 16 )
$commit = '' ;
}
else {
2017-04-06 17:45:19 +00:00
$version = $commit = '' ;
2015-11-30 03:37:03 +00:00
}
2016-10-01 22:41:25 +00:00
2015-11-30 03:37:03 +00:00
//Statistics
2018-08-02 08:56:34 +00:00
// $channels_total_stat = intval(get_config('system','channels_total_stat'));
// $channels_active_halfyear_stat = intval(get_config('system','channels_active_halfyear_stat'));
// $channels_active_monthly_stat = intval(get_config('system','channels_active_monthly_stat'));
// $local_posts_stat = intval(get_config('system','local_posts_stat'));
// $local_comments_stat = intval(get_config('system','local_comments_stat'));
// $hide_in_statistics = intval(get_config('system','hide_in_statistics'));
2015-11-30 03:37:03 +00:00
$site_expire = intval ( get_config ( 'system' , 'default_expire_days' ));
2016-01-10 07:39:53 +00:00
load_config ( 'feature_lock' );
2021-03-15 05:10:44 +00:00
$locked_features = [];
2016-03-31 23:06:03 +00:00
if ( is_array ( App :: $config [ 'feature_lock' ]) && count ( App :: $config [ 'feature_lock' ])) {
foreach ( App :: $config [ 'feature_lock' ] as $k => $v ) {
2016-01-10 07:39:53 +00:00
if ( $k === 'config_loaded' )
continue ;
2017-04-06 17:45:19 +00:00
2016-01-10 07:39:53 +00:00
$locked_features [ $k ] = intval ( $v );
}
}
2019-10-05 21:42:38 +00:00
$protocols = [ 'zot' ];
2020-11-27 00:17:07 +00:00
if ( get_config ( 'system' , 'activitypub' , ACTIVITYPUB_ENABLED )) {
2019-10-05 21:42:38 +00:00
$protocols [] = 'activitypub' ;
}
2016-01-10 07:39:53 +00:00
2017-03-13 03:54:48 +00:00
$data = [
'url' => z_root (),
2018-11-12 01:44:01 +00:00
'platform' => System :: get_platform_name (),
2017-03-13 03:54:48 +00:00
'site_name' => (( $site_name ) ? $site_name : '' ),
'version' => $version ,
2020-12-22 23:30:52 +00:00
// 'version_tag' => $tag,
2019-08-16 06:53:02 +00:00
'addon_version' => defined ( 'ADDON_VERSION' ) ? ADDON_VERSION : 'unknown' ,
2017-03-13 03:54:48 +00:00
'commit' => $commit ,
2019-10-05 21:42:38 +00:00
'protocols' => $protocols ,
2017-03-13 03:54:48 +00:00
'plugins' => $visible_plugins ,
'register_policy' => $register_policy [ get_config ( 'system' , 'register_policy' )],
2021-06-02 09:00:44 +00:00
'invitation_only' => ( bool ) ( defined ( 'INVITE_WORKING' ) && intval ( get_config ( 'system' , 'invitation_only' ))),
2017-03-13 03:54:48 +00:00
'directory_mode' => $directory_mode [ get_config ( 'system' , 'directory_mode' )],
2020-12-22 23:30:52 +00:00
// 'directory_server' => get_config('system','directory_server'),
2017-03-13 03:54:48 +00:00
'language' => get_config ( 'system' , 'language' ),
2019-11-19 03:08:46 +00:00
// 'rss_connections' => (bool) intval(get_config('system','feed_contacts')),
2017-03-13 03:54:48 +00:00
'expiration' => $site_expire ,
2015-11-30 03:37:03 +00:00
'default_service_restrictions' => $service_class ,
2017-03-13 03:54:48 +00:00
'locked_features' => $locked_features ,
'admin' => $admin ,
2018-01-23 04:07:08 +00:00
'dbdriver' => DBA :: $dba -> getdriver () . ' ' . (( ACTIVE_DBTYPE == DBTYPE_POSTGRES ) ? 'postgres' : 'mysql' ),
2017-03-13 03:54:48 +00:00
'lastpoll' => get_config ( 'system' , 'lastpoll' ),
2018-12-13 22:28:38 +00:00
'ebs' => System :: ebs (),
2018-08-02 08:56:34 +00:00
'info' => (( $site_info ) ? $site_info : '' )
2017-03-13 03:54:48 +00:00
];
2017-04-06 17:45:19 +00:00
2018-02-24 22:38:28 +00:00
2015-11-30 03:37:03 +00:00
return $data ;
2015-11-30 04:26:00 +00:00
}
2017-04-06 17:45:19 +00:00
/**
* @ brief
*
* @ param string $url
* @ return boolean
*/
2015-11-30 04:26:00 +00:00
function check_siteallowed ( $url ) {
$retvalue = true ;
2019-09-11 02:31:08 +00:00
$arr = [ 'url' => $url ];
2017-09-04 22:23:42 +00:00
/**
* @ hooks check_siteallowed
* Used to over - ride or bypass the site black / white block lists .
* * \e string \b url
* * \e boolean \b allowed - optional return value set in hook
*/
call_hooks ( 'check_siteallowed' , $arr );
2015-12-07 04:45:21 +00:00
2019-09-11 02:31:08 +00:00
if ( array_key_exists ( 'allowed' , $arr )) {
2015-12-07 04:45:21 +00:00
return $arr [ 'allowed' ];
2019-09-11 02:31:08 +00:00
}
2015-12-07 04:45:21 +00:00
2021-04-15 00:33:21 +00:00
// your own site is always allowed
if ( strpos ( $url , z_root ()) !== false ) {
return $retvalue ;
}
2020-06-14 11:58:27 +00:00
$bl1 = get_config ( 'system' , 'allowed_sites' );
2021-04-14 20:40:56 +00:00
$bl2 = get_config ( 'system' , 'denied_sites' );
2019-09-11 02:31:08 +00:00
if ( is_array ( $bl1 ) && $bl1 ) {
2021-04-14 20:40:56 +00:00
if ( ! ( is_array ( $bl2 ) && $bl2 )) {
$retvalue = false ;
}
2019-09-11 02:31:08 +00:00
foreach ( $bl1 as $bl ) {
if ( $bl === '*' ) {
2015-11-30 04:26:00 +00:00
$retvalue = true ;
2019-09-11 02:31:08 +00:00
}
2021-04-15 04:23:01 +00:00
if ( $bl && ( strpos ( $url , $bl ) !== false || wildmat ( $bl , $url ))) {
2015-11-30 04:26:00 +00:00
return true ;
2021-04-15 04:23:01 +00:00
}
2015-11-30 04:26:00 +00:00
}
}
2021-04-14 20:40:56 +00:00
if ( is_array ( $bl2 ) && $bl2 ) {
foreach ( $bl2 as $bl ) {
2019-09-11 02:31:08 +00:00
if ( $bl === '*' ) {
2015-11-30 04:26:00 +00:00
$retvalue = false ;
2019-09-11 02:31:08 +00:00
}
2021-04-15 04:23:01 +00:00
if ( $bl && ( strpos ( $url , $bl ) !== false || wildmat ( $bl , $url ))) {
2015-11-30 04:26:00 +00:00
return false ;
}
}
}
2017-04-06 17:45:19 +00:00
2015-11-30 04:26:00 +00:00
return $retvalue ;
}
2019-01-05 22:47:21 +00:00
/**
* @ brief
*
* @ param string $url
* @ return boolean
*/
function check_pubstream_siteallowed ( $url ) {
$retvalue = true ;
$arr = array ( 'url' => $url );
/**
* @ hooks check_siteallowed
* Used to over - ride or bypass the site black / white block lists .
* * \e string \b url
* * \e boolean \b allowed - optional return value set in hook
*/
call_hooks ( 'pubstream_check_siteallowed' , $arr );
2021-04-15 04:23:01 +00:00
if ( array_key_exists ( 'allowed' , $arr )) {
2019-01-05 22:47:21 +00:00
return $arr [ 'allowed' ];
2021-04-15 04:23:01 +00:00
}
2019-01-05 22:47:21 +00:00
2021-04-15 00:33:21 +00:00
// your own site is always allowed
if ( strpos ( $url , z_root ()) !== false ) {
return $retvalue ;
}
2020-06-14 11:58:27 +00:00
$bl1 = get_config ( 'system' , 'pubstream_allowed_sites' );
2021-04-14 20:40:56 +00:00
$bl2 = get_config ( 'system' , 'pubstream_denied_sites' );
2021-04-15 04:23:01 +00:00
if ( is_array ( $bl1 ) && $bl1 ) {
2021-04-14 20:40:56 +00:00
if ( ! ( is_array ( $bl2 ) && $bl2 )) {
$retvalue = false ;
}
2021-04-15 04:23:01 +00:00
foreach ( $bl1 as $bl ) {
if ( $bl === '*' ) {
2019-01-05 22:47:21 +00:00
$retvalue = true ;
2021-04-15 04:23:01 +00:00
}
if ( $bl && ( strpos ( $url , $bl ) !== false || wildmat ( $bl , $url ))) {
2019-01-05 22:47:21 +00:00
return true ;
2021-04-15 04:23:01 +00:00
}
2019-01-05 22:47:21 +00:00
}
}
2021-04-15 04:23:01 +00:00
if ( is_array ( $bl2 ) && $bl2 ) {
foreach ( $bl2 as $bl ) {
if ( $bl === '*' ) {
2019-01-05 22:47:21 +00:00
$retvalue = false ;
2021-04-15 04:23:01 +00:00
}
if ( $bl && ( strpos ( $url , $bl ) !== false || wildmat ( $bl , $url ))) {
2019-01-05 22:47:21 +00:00
return false ;
}
}
}
return $retvalue ;
}
2017-04-06 17:45:19 +00:00
/**
* @ brief
*
* @ param string $hash
* @ return boolean
*/
2015-11-30 04:26:00 +00:00
function check_channelallowed ( $hash ) {
$retvalue = true ;
2019-09-11 02:31:08 +00:00
$arr = [ 'hash' => $hash ];
2017-09-04 22:23:42 +00:00
/**
* @ hooks check_channelallowed
* Used to over - ride or bypass the channel black / white block lists .
* * \e string \b hash
* * \e boolean \b allowed - optional return value set in hook
*/
call_hooks ( 'check_channelallowed' , $arr );
2015-12-07 04:45:21 +00:00
2019-09-11 02:31:08 +00:00
if ( array_key_exists ( 'allowed' , $arr )) {
2015-12-07 04:45:21 +00:00
return $arr [ 'allowed' ];
2019-09-11 02:31:08 +00:00
}
2015-12-07 04:45:21 +00:00
2020-06-14 11:58:27 +00:00
$bl1 = get_config ( 'system' , 'allowed_channels' );
2021-04-14 20:40:56 +00:00
$bl2 = get_config ( 'system' , 'denied_channels' );
2019-09-11 02:31:08 +00:00
if ( is_array ( $bl1 ) && $bl1 ) {
2021-04-14 20:40:56 +00:00
if ( ! ( is_array ( $bl2 ) && $bl2 )) {
$retvalue = false ;
}
2019-09-11 02:31:08 +00:00
foreach ( $bl1 as $bl ) {
if ( $bl === '*' ) {
2015-11-30 04:26:00 +00:00
$retvalue = true ;
2019-09-11 02:31:08 +00:00
}
2021-04-15 04:23:01 +00:00
if ( $bl && ( strpos ( $url , $bl ) !== false || wildmat ( $bl , $url ))) {
2015-11-30 04:26:00 +00:00
return true ;
2019-09-11 02:31:08 +00:00
}
2015-11-30 04:26:00 +00:00
}
}
2021-04-14 20:40:56 +00:00
if ( is_array ( $bl2 ) && $bl2 ) {
foreach ( $bl2 as $bl ) {
2019-09-11 02:31:08 +00:00
if ( $bl === '*' ) {
2015-11-30 04:26:00 +00:00
$retvalue = false ;
2019-09-11 02:31:08 +00:00
}
2021-04-15 04:23:01 +00:00
if ( $bl && ( strpos ( $url , $bl ) !== false || wildmat ( $bl , $url ))) {
2015-11-30 04:26:00 +00:00
return false ;
}
}
}
2017-04-06 17:45:19 +00:00
2015-11-30 04:26:00 +00:00
return $retvalue ;
}
2019-01-05 22:47:21 +00:00
/**
* @ brief
*
* @ param string $hash
* @ return boolean
*/
function check_pubstream_channelallowed ( $hash ) {
$retvalue = true ;
$arr = array ( 'hash' => $hash );
/**
* @ hooks check_channelallowed
* Used to over - ride or bypass the channel black / white block lists .
* * \e string \b hash
* * \e boolean \b allowed - optional return value set in hook
*/
call_hooks ( 'check_pubstream_channelallowed' , $arr );
2021-04-15 04:23:01 +00:00
if ( array_key_exists ( 'allowed' , $arr )) {
2019-01-05 22:47:21 +00:00
return $arr [ 'allowed' ];
2021-04-15 04:23:01 +00:00
}
2019-01-05 22:47:21 +00:00
2020-06-14 11:58:27 +00:00
$bl1 = get_config ( 'system' , 'pubstream_allowed_channels' );
2021-04-14 20:40:56 +00:00
$bl2 = get_config ( 'system' , 'pubstream_denied_channels' );
2021-04-15 04:23:01 +00:00
if ( is_array ( $bl1 ) && $bl1 ) {
2021-04-14 20:40:56 +00:00
if ( ! ( is_array ( $bl2 ) && $bl2 )) {
$retvalue = false ;
}
2021-04-15 04:23:01 +00:00
foreach ( $bl1 as $bl ) {
if ( $bl === '*' ) {
2019-01-05 22:47:21 +00:00
$retvalue = true ;
2021-04-15 04:23:01 +00:00
}
if ( $bl && ( strpos ( $url , $bl ) !== false || wildmat ( $bl , $url ))) {
2019-01-05 22:47:21 +00:00
return true ;
2021-04-15 04:23:01 +00:00
}
2019-01-05 22:47:21 +00:00
}
}
2021-04-15 04:23:01 +00:00
if ( is_array ( $bl2 ) && $bl2 ) {
foreach ( $bl2 as $bl ) {
if ( $bl === '*' ) {
2019-01-05 22:47:21 +00:00
$retvalue = false ;
2021-04-15 04:23:01 +00:00
}
if ( $bl && ( strpos ( $url , $bl ) !== false || wildmat ( $bl , $url ))) {
2019-01-05 22:47:21 +00:00
return false ;
}
}
}
return $retvalue ;
}
2016-04-26 23:12:31 +00:00
function deliverable_singleton ( $channel_id , $xchan ) {
2017-08-11 04:43:36 +00:00
if ( array_key_exists ( 'xchan_hash' , $xchan ))
$xchan_hash = $xchan [ 'xchan_hash' ];
elseif ( array_key_exists ( 'hubloc_hash' , $xchan ))
$xchan_hash = $xchan [ 'hubloc_hash' ];
else
return true ;
2016-04-26 23:12:31 +00:00
$r = q ( " select abook_instance from abook where abook_channel = %d and abook_xchan = '%s' limit 1 " ,
intval ( $channel_id ),
2017-08-11 04:43:36 +00:00
dbesc ( $xchan_hash )
2015-12-10 02:30:30 +00:00
);
if ( $r ) {
if ( ! $r [ 0 ][ 'abook_instance' ])
return true ;
if ( strpos ( $r [ 0 ][ 'abook_instance' ], z_root ()) !== false )
return true ;
}
return false ;
}
2016-05-11 04:46:04 +00:00
2020-06-16 03:54:54 +00:00
function get_repository_version ( $branch = 'release' ) {
2016-05-11 04:46:04 +00:00
2020-10-16 10:42:55 +00:00
$path = " https://codeberg.org/zot/ " . (( PLATFORM_NAME === 'mistpark' ) ? 'misty' : PLATFORM_NAME ) . " /raw/ $branch /boot.php " ;
2016-10-01 22:41:25 +00:00
2016-05-11 04:46:04 +00:00
$x = z_fetch_url ( $path );
if ( $x [ 'success' ]) {
$y = preg_match ( '/define(.*?)STD_VERSION(.*?)([0-9.].*)\'/' , $x [ 'body' ], $matches );
if ( $y )
return $matches [ 3 ];
}
return '?.?' ;
2016-10-01 22:41:25 +00:00
}
2016-05-21 05:13:20 +00:00
2017-04-06 17:45:19 +00:00
/**
* @ brief Get translated network name .
*
* @ param string $s Network string , see boot . php
* @ return string Translated name of the network
*/
2016-05-21 05:13:20 +00:00
function network_to_name ( $s ) {
$nets = array (
2017-07-31 04:55:28 +00:00
NETWORK_DFRN => t ( 'Friendica' ),
NETWORK_FRND => t ( 'Friendica' ),
NETWORK_OSTATUS => t ( 'OStatus' ),
NETWORK_GNUSOCIAL => t ( 'GNU-Social' ),
NETWORK_FEED => t ( 'RSS/Atom' ),
NETWORK_ACTIVITYPUB => t ( 'ActivityPub' ),
NETWORK_MAIL => t ( 'Email' ),
NETWORK_DIASPORA => t ( 'Diaspora' ),
NETWORK_FACEBOOK => t ( 'Facebook' ),
2021-05-02 23:41:18 +00:00
NETWORK_ZOT6 => t ( 'Nomad' ),
2017-07-31 04:55:28 +00:00
NETWORK_ZOT => t ( 'Zot' ),
NETWORK_LINKEDIN => t ( 'LinkedIn' ),
NETWORK_XMPP => t ( 'XMPP/IM' ),
NETWORK_MYSPACE => t ( 'MySpace' ),
2016-05-21 05:13:20 +00:00
);
2017-09-04 22:23:42 +00:00
/**
* @ hooks network_to_name
* @ deprecated
*/
2016-05-21 05:13:20 +00:00
call_hooks ( 'network_to_name' , $nets );
$search = array_keys ( $nets );
$replace = array_values ( $nets );
2017-04-06 17:45:19 +00:00
return str_replace ( $search , $replace , $s );
2016-05-21 05:13:20 +00:00
}
2016-10-01 10:06:01 +00:00
2017-04-06 17:45:19 +00:00
/**
* @ brief Send a text email message .
*
2017-09-04 22:23:42 +00:00
* @ param array $params an associative array with :
2017-04-06 17:45:19 +00:00
* * \e string \b fromName name of the sender
* * \e string \b fromEmail email of the sender
* * \e string \b replyTo replyTo address to direct responses
* * \e string \b toEmail destination email address
* * \e string \b messageSubject subject of the message
* * \e string \b htmlVersion html version of the message
* * \e string \b textVersion text only version of the message
* * \e string \b additionalMailHeader additions to the smtp mail header
*/
2016-10-01 10:06:01 +00:00
function z_mail ( $params ) {
if ( ! $params [ 'fromEmail' ]) {
$params [ 'fromEmail' ] = get_config ( 'system' , 'from_email' );
if ( ! $params [ 'fromEmail' ])
$params [ 'fromEmail' ] = 'Administrator' . '@' . App :: get_hostname ();
}
if ( ! $params [ 'fromName' ]) {
$params [ 'fromName' ] = get_config ( 'system' , 'from_email_name' );
if ( ! $params [ 'fromName' ])
2018-11-12 01:44:01 +00:00
$params [ 'fromName' ] = System :: get_site_name ();
2016-10-01 10:06:01 +00:00
}
if ( ! $params [ 'replyTo' ]) {
$params [ 'replyTo' ] = get_config ( 'system' , 'reply_address' );
if ( ! $params [ 'replyTo' ])
$params [ 'replyTo' ] = 'noreply' . '@' . App :: get_hostname ();
}
$params [ 'sent' ] = false ;
$params [ 'result' ] = false ;
2017-09-04 22:23:42 +00:00
/**
* @ hooks email_send
* * \e params @ see z_mail ()
*/
2016-10-01 22:15:14 +00:00
call_hooks ( 'email_send' , $params );
2016-10-01 10:06:01 +00:00
if ( $params [ 'sent' ]) {
2016-10-13 23:47:45 +00:00
logger ( 'notification: z_mail returns ' . (( $params [ 'result' ]) ? 'success' : 'failure' ), LOGGER_DEBUG );
2016-10-01 10:06:01 +00:00
return $params [ 'result' ];
}
2016-10-01 22:41:25 +00:00
$fromName = email_header_encode ( html_entity_decode ( $params [ 'fromName' ], ENT_QUOTES , 'UTF-8' ), 'UTF-8' );
2016-10-01 10:06:01 +00:00
$messageSubject = email_header_encode ( html_entity_decode ( $params [ 'messageSubject' ], ENT_QUOTES , 'UTF-8' ), 'UTF-8' );
$messageHeader =
$params [ 'additionalMailHeader' ] .
2019-03-17 23:34:54 +00:00
2019-03-17 23:32:21 +00:00
" From: $fromName < { $params [ 'fromEmail' ] } > " . PHP_EOL .
" Reply-To: $fromName < { $params [ 'replyTo' ] } > " . PHP_EOL .
2018-04-16 23:12:57 +00:00
" Content-Type: text/plain; charset=UTF-8 " ;
2016-10-01 10:06:01 +00:00
// send the message
$res = mail (
$params [ 'toEmail' ], // send to address
$messageSubject , // subject
$params [ 'textVersion' ],
$messageHeader // message headers
);
2016-10-13 23:47:45 +00:00
logger ( 'notification: z_mail returns ' . (( $res ) ? 'success' : 'failure' ), LOGGER_DEBUG );
2016-10-01 10:06:01 +00:00
return $res ;
}
2016-10-12 03:53:13 +00:00
2017-04-06 17:45:19 +00:00
/**
* @ brief Discover the best API path available for redmatrix / hubzilla servers .
*
* @ param string $host
* @ return string
*/
2016-10-12 03:53:13 +00:00
function probe_api_path ( $host ) {
$schemes = [ 'https' , 'http' ];
$paths = [ '/api/z/1.0/version' , '/api/red/version' ];
foreach ( $schemes as $scheme ) {
foreach ( $paths as $path ) {
$curpath = $scheme . '://' . $host . $path ;
$x = z_fetch_url ( $curpath );
2018-03-31 20:22:12 +00:00
if ( $x [ 'success' ] && ! strpos ( $x [ 'body' ], 'not implemented' ))
2017-04-06 17:45:19 +00:00
return str_replace ( 'version' , '' , $curpath );
2016-10-12 03:53:13 +00:00
}
}
return '' ;
2016-10-27 00:41:32 +00:00
}
2017-05-03 03:17:47 +00:00
2017-05-05 04:55:56 +00:00
function service_plink ( $contact , $guid ) {
$plink = '' ;
$m = parse_url ( $contact [ 'xchan_url' ]);
if ( $m ) {
2021-03-09 23:36:07 +00:00
$url = $m [ 'scheme' ] . '://' . $m [ 'host' ] . (( isset ( $m [ 'port' ]) && intval ( $m [ 'port' ])) ? ':' . intval ( $m [ 'port' ]) : '' );
2017-05-05 04:55:56 +00:00
}
else {
$url = 'https://' . substr ( $contact [ 'xchan_addr' ], strpos ( $contact [ 'xchan_addr' ], '@' ) + 1 );
}
$handle = substr ( $contact [ 'xchan_addr' ], 0 , strpos ( $contact [ 'xchan_addr' ], '@' ));
$plink = $url . '/channel/' . $handle . '?f=&mid=' . $guid ;
2017-07-05 10:32:46 +00:00
$x = [ 'xchan' => $contact , 'guid' => $guid , 'url' => $url , 'plink' => $plink ];
2017-09-04 22:23:42 +00:00
/**
* @ hooks service_plink
* * \e array \b xchan
* * \e string \b guid
* * \e string \b url
* * \e string \b plink will get returned
*/
2017-05-05 04:55:56 +00:00
call_hooks ( 'service_plink' , $x );
return $x [ 'plink' ];
}
2017-09-04 22:23:42 +00:00
/**
* @ brief
*
* @ param array $mimeTypes
* @ param string $acceptedTypes by default false will use $_SERVER [ 'HTTP_ACCEPT' ]
* @ return array | NULL
*/
2017-07-18 02:53:03 +00:00
function getBestSupportedMimeType ( $mimeTypes = null , $acceptedTypes = false ) {
2017-09-04 22:23:42 +00:00
// Values will be stored in this array
$AcceptTypes = [];
2017-07-18 02:53:03 +00:00
2021-03-12 01:17:40 +00:00
if ( $acceptedTypes === false ) {
$acceptedTypes = (( isset ( $_SERVER [ 'HTTP_ACCEPT' ]) && $_SERVER [ 'HTTP_ACCEPT' ]) ? $_SERVER [ 'HTTP_ACCEPT' ] : EMPTY_STR );
}
2017-07-18 02:53:03 +00:00
2017-09-04 22:23:42 +00:00
// Accept header is case insensitive, and whitespace isn’ t important
$accept = strtolower ( str_replace ( ' ' , '' , $acceptedTypes ));
// divide it into parts in the place of a ","
$accept = explode ( ',' , $accept );
foreach ( $accept as $a ) {
// the default quality is 1.
$q = 1 ;
// check if there is a different quality
if ( strpos ( $a , ';q=' )) {
// divide "mime/type;q=X" into two parts: "mime/type" i "X"
list ( $a , $q ) = explode ( ';q=' , $a );
}
// mime-type $a is accepted with the quality $q
// WARNING: $q == 0 means, that mime-type isn’ t supported!
$AcceptTypes [ $a ] = $q ;
}
arsort ( $AcceptTypes );
2017-09-20 02:15:15 +00:00
2017-09-04 22:23:42 +00:00
// if no parameter was passed, just return parsed data
if ( ! $mimeTypes ) return $AcceptTypes ;
2017-09-20 02:15:15 +00:00
2017-09-04 22:23:42 +00:00
$mimeTypes = array_map ( 'strtolower' , ( array ) $mimeTypes );
2017-09-20 02:15:15 +00:00
2017-09-04 22:23:42 +00:00
// let’ s check our supported types:
foreach ( $AcceptTypes as $mime => $q ) {
if ( $q && in_array ( $mime , $mimeTypes )) return $mime ;
}
// no mime-type found
return null ;
}
/**
* @ brief Perform caching for jsonld normaliser .
*
* @ param string $url
* @ return mixed | boolean | array
*/
function jsonld_document_loader ( $url ) {
2017-09-20 02:15:15 +00:00
require_once ( 'library/jsonld/jsonld.php' );
2018-08-11 23:16:54 +00:00
$recursion = 0 ;
$x = debug_backtrace ();
if ( $x ) {
foreach ( $x as $n ) {
if ( $n [ 'function' ] === __FUNCTION__ ) {
$recursion ++ ;
}
}
}
if ( $recursion > 5 ) {
logger ( 'jsonld bomb detected at: ' . $url );
killme ();
}
2020-03-04 02:24:26 +00:00
$cachepath = 'cache/ldcache' ;
2017-09-20 02:15:15 +00:00
if ( ! is_dir ( $cachepath ))
2017-09-04 22:23:42 +00:00
os_mkdir ( $cachepath , STORAGE_DEFAULT_PERMISSIONS , true );
2017-09-20 02:15:15 +00:00
$filename = $cachepath . '/' . urlencode ( $url );
if ( file_exists ( $filename ) && filemtime ( $filename ) > time () - ( 12 * 60 * 60 )) {
return json_decode ( file_get_contents ( $filename ));
}
$r = jsonld_default_document_loader ( $url );
if ( $r ) {
2017-09-04 22:23:42 +00:00
file_put_contents ( $filename , json_encode ( $r ));
2017-09-20 02:15:15 +00:00
return $r ;
}
logger ( 'not found' );
if ( file_exists ( $filename )) {
return json_decode ( file_get_contents ( $filename ));
}
return [];
2018-04-23 02:49:26 +00:00
}
2018-05-23 06:20:29 +00:00
function is_https_request () {
2021-04-11 23:27:44 +00:00
2018-05-23 06:20:29 +00:00
$https = false ;
2021-04-11 23:27:44 +00:00
if ( array_key_exists ( 'HTTPS' , $_SERVER ) && $_SERVER [ 'HTTPS' ]) {
2018-05-23 06:20:29 +00:00
$https = true ;
2021-04-11 23:27:44 +00:00
}
elseif ( array_key_exists ( 'SERVER_PORT' , $_SERVER ) && intval ( $_SERVER [ 'SERVER_PORT' ]) === 443 ) {
2018-05-23 06:20:29 +00:00
$https = true ;
2021-04-11 23:27:44 +00:00
}
elseif ( array_key_exists ( 'HTTP_X_FORWARDED_PROTO' , $_SERVER ) && $_SERVER [ 'HTTP_X_FORWARDED_PROTO' ] === 'https' ) {
$https = true ; // technically this is not true, but pretending it is will allow reverse proxies to work
}
2018-05-23 06:20:29 +00:00
return $https ;
}
2018-10-11 00:58:51 +00:00
/**
* @ brief Given a URL , return everything after the host portion .
* example https :// foobar . com / gravy ? g = 5 & y = 6
* returns / gravy ? g = 5 & y = 6
* result always returns the leading slash
*/
function get_request_string ( $url ) {
$a = explode ( '/' , $url , 4 );
return '/' . (( count ( $a ) > 3 ) ? $a [ 3 ] : EMPTY_STR );
}
2020-09-03 06:02:32 +00:00