use Friendica\Protocol\Diaspora;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Network;
+use Friendica\Util\Proxy as ProxyUtils;
use Friendica\Util\XML;
require_once 'include/conversation.php';
require_once 'mod/item.php';
require_once 'include/security.php';
require_once 'mod/wall_upload.php';
-require_once 'mod/proxy.php';
define('API_METHOD_ANY', '*');
define('API_METHOD_GET', 'GET');
preg_match_all("/\[img](.*?)\[\/img\]/ism", $bbcode, $images);
foreach ($images[1] as $image) {
- $replace = proxy_url($image);
+ $replace = ProxyUtils::proxifyUrl($image);
$text = str_replace($image, $replace, $text);
}
return [];
// If image cache is activated, then use the following sizes:
// thumb (150), small (340), medium (600) and large (1024)
if (!Config::get("system", "proxy_disabled")) {
- $media_url = proxy_url($url);
+ $media_url = ProxyUtils::proxifyUrl($url);
$sizes = [];
$scale = Image::getScalingDimensions($image[0], $image[1], 150);
use Friendica\Object\Post;
use Friendica\Object\Thread;
use Friendica\Util\DateTimeFormat;
+use Friendica\Util\Proxy as ProxyUtils;
use Friendica\Util\Temporal;
use Friendica\Util\XML;
*
*/
function conversation(App $a, array $items, $mode, $update, $preview = false, $order = 'commented', $uid = 0) {
- require_once 'mod/proxy.php';
$ssl_state = ((local_user()) ? true : false);
if (local_user()) {
$str_blocked = PConfig::get(local_user(), 'system', 'blocked');
+
if ($str_blocked) {
$arr_blocked = explode(',', $str_blocked);
+
for ($x = 0; $x < count($arr_blocked); $x ++) {
$arr_blocked[$x] = trim($arr_blocked[$x]);
}
}
} elseif ($mode === 'notes') {
$profile_owner = local_user();
+
if (!$update) {
$live_update_div = '<div id="live-notes"></div>' . "\r\n"
. "<script> var profile_uid = " . local_user()
}
} elseif ($mode === 'display') {
$profile_owner = $a->profile['uid'];
+
if (!$update) {
$live_update_div = '<div id="live-display"></div>' . "\r\n"
. "<script> var profile_uid = " . defaults($_SESSION, 'uid', 0) . ";"
} elseif ($mode === 'community') {
$items = conversation_add_children($items, true, $order, $uid);
$profile_owner = 0;
+
if (!$update) {
$live_update_div = '<div id="live-community"></div>' . "\r\n"
. "<script> var profile_uid = -1; var netargs = '" . substr($a->cmd, 10)
$page_template = get_markup_template("conversation.tpl");
- if ($items && count($items)) {
+ if (!empty($items)) {
if ($mode === 'community') {
$writable = true;
} else {
'name' => $profile_name_e,
'sparkle' => $sparkle,
'lock' => $lock,
- 'thumb' => System::removedBaseUrl(proxy_url($item['author-avatar'], false, PROXY_SIZE_THUMB)),
+ 'thumb' => System::removedBaseUrl(ProxyUtils::proxifyUrl($item['author-avatar'], false, ProxyUtils::SIZE_THUMB)),
'title' => $title_e,
'body' => $body_e,
'tags' => $tags_e,
'indent' => '',
'owner_name' => $owner_name_e,
'owner_url' => $owner_url,
- 'owner_photo' => System::removedBaseUrl(proxy_url($item['owner-avatar'], false, PROXY_SIZE_THUMB)),
+ 'owner_photo' => System::removedBaseUrl(ProxyUtils::proxifyUrl($item['owner-avatar'], false, ProxyUtils::SIZE_THUMB)),
'plink' => get_plink($item),
'edpost' => false,
'isstarred' => $isstarred,
*
* @param $args Query parameters (1 to N parameters of different types)
* @return array|bool Query array
+ * @deprecated
*/
function q($sql) {
$args = func_get_args();
use Friendica\Render\FriendicaSmarty;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Map;
+use Friendica\Util\Proxy as ProxyUtils;
-require_once "mod/proxy.php";
require_once "include/conversation.php";
/**
'$click' => defaults($contact, 'click', ''),
'$class' => $class,
'$url' => $url,
- '$photo' => proxy_url($contact['thumb'], false, PROXY_SIZE_THUMB),
+ '$photo' => ProxyUtils::proxifyUrl($contact['thumb'], false, ProxyUtils::SIZE_THUMB),
'$name' => $contact['name'],
'title' => $contact['name'] . ' [' . $contact['addr'] . ']',
'$parkle' => $sparkle,
use Friendica\Database\DBA;
use Friendica\Model\Contact;
use Friendica\Model\Item;
+use Friendica\Util\Proxy as ProxyUtils;
require_once 'include/dba.php';
-require_once 'mod/proxy.php';
function acl_content(App $a)
{
$contacts = [];
foreach ($r as $g) {
$contacts[] = [
- 'photo' => proxy_url($g['photo'], false, PROXY_SIZE_MICRO),
+ 'photo' => ProxyUtils::proxifyUrl($g['photo'], false, ProxyUtils::SIZE_MICRO),
'name' => $g['name'],
'nick' => defaults($g, 'addr', $g['url']),
'network' => $g['network'],
foreach ($r as $g) {
$entry = [
'type' => 'c',
- 'photo' => proxy_url($g['micro'], false, PROXY_SIZE_MICRO),
+ 'photo' => ProxyUtils::proxifyUrl($g['micro'], false, ProxyUtils::SIZE_MICRO),
'name' => htmlentities($g['name']),
'id' => intval($g['id']),
'network' => $g['network'],
if (count($contact) > 0) {
$unknown_contacts[] = [
'type' => 'c',
- 'photo' => proxy_url($contact['micro'], false, PROXY_SIZE_MICRO),
+ 'photo' => ProxyUtils::proxifyUrl($contact['micro'], false, ProxyUtils::SIZE_MICRO),
'name' => htmlentities($contact['name']),
'id' => intval($contact['cid']),
'network' => $contact['network'],
use Friendica\Model\Contact;
use Friendica\Model\GContact;
use Friendica\Model\Profile;
+use Friendica\Util\Proxy as ProxyUtils;
require_once 'include/dba.php';
require_once 'mod/contacts.php';
'url' => $rr['url'],
'itemurl' => defaults($contact_details, 'addr', $rr['url']),
'name' => htmlentities($contact_details['name']),
- 'thumb' => proxy_url($contact_details['thumb'], false, PROXY_SIZE_THUMB),
+ 'thumb' => ProxyUtils::proxifyUrl($contact_details['thumb'], false, ProxyUtils::SIZE_THUMB),
'img_hover' => htmlentities($contact_details['name']),
'details' => $contact_details['location'],
'tags' => $contact_details['keywords'],
use Friendica\Model\Contact;
use Friendica\Model\GContact;
use Friendica\Model\Profile;
+use Friendica\Util\Proxy as ProxyUtils;
require_once 'include/dba.php';
require_once 'mod/contacts.php';
'url' => $rr['url'],
'itemurl' => defaults($contact_details, 'addr', $rr['url']),
'name' => $contact_details['name'],
- 'thumb' => proxy_url($contact_details['thumb'], false, PROXY_SIZE_THUMB),
+ 'thumb' => ProxyUtils::proxifyUrl($contact_details['thumb'], false, ProxyUtils::SIZE_THUMB),
'img_hover' => htmlentities($contact_details['name']),
'details' => $contact_details['location'],
'tags' => $contact_details['keywords'],
use Friendica\Model\Profile;
use Friendica\Network\Probe;
use Friendica\Util\DateTimeFormat;
-
-require_once 'mod/proxy.php';
+use Friendica\Util\Proxy as ProxyUtils;
function contacts_init(App $a)
{
'id' => $rr['id'],
'alt_text' => $alt_text,
'dir_icon' => $dir_icon,
- 'thumb' => proxy_url($rr['thumb'], false, PROXY_SIZE_THUMB),
+ 'thumb' => ProxyUtils::proxifyUrl($rr['thumb'], false, ProxyUtils::SIZE_THUMB),
'name' => htmlentities($rr['name']),
'username' => htmlentities($rr['name']),
'account_type' => Contact::getAccountType($rr),
use Friendica\Database\DBA;
use Friendica\Model\Contact;
use Friendica\Model\Profile;
+use Friendica\Util\Proxy as ProxyUtils;
function directory_init(App $a)
{
function directory_content(App $a)
{
- require_once("mod/proxy.php");
-
if ((Config::get('system', 'block_public') && !local_user() && !remote_user())
|| (Config::get('system', 'block_local_dir') && !local_user() && !remote_user())
) {
'id' => $rr['id'],
'url' => $profile_link,
'itemurl' => $itemurl,
- 'thumb' => proxy_url($rr[$photo], false, PROXY_SIZE_THUMB),
+ 'thumb' => ProxyUtils::proxifyUrl($rr[$photo], false, ProxyUtils::SIZE_THUMB),
'img_hover' => $rr['name'],
'name' => $rr['name'],
'details' => $details,
use Friendica\Network\Probe;
use Friendica\Protocol\PortableContact;
use Friendica\Util\Network;
+use Friendica\Util\Proxy as ProxyUtils;
require_once 'mod/contacts.php';
'url' => Contact::magicLink($jj->url),
'itemurl' => $itemurl,
'name' => htmlentities($jj->name),
- 'thumb' => proxy_url($jj->photo, false, PROXY_SIZE_THUMB),
+ 'thumb' => ProxyUtils::proxifyUrl($jj->photo, false, ProxyUtils::SIZE_THUMB),
'img_hover' => $jj->tags,
'conntxt' => $conntxt,
'connlnk' => $connlnk,
use Friendica\Model\Profile;
use Friendica\Network\Probe;
use Friendica\Database\DBA;
+use Friendica\Util\Proxy as ProxyUtils;
function follow_post(App $a)
{
$o = replace_macros($tpl, [
'$header' => htmlentities($header),
- //'$photo' => proxy_url($ret['photo'], false, PROXY_SIZE_SMALL),
+ //'$photo' => ProxyUtils::proxifyUrl($ret['photo'], false, ProxyUtils::SIZE_SMALL),
'$desc' => '',
'$pls_answer' => L10n::t('Please answer the following:'),
'$does_know_you' => ['knowyou', L10n::t('Does %s know you?', $ret['name']), false, '', [L10n::t('No'), L10n::t('Yes')]],
use Friendica\Database\DBA;
use Friendica\Model\Contact;
use Friendica\Model\GContact;
+use Friendica\Util\Proxy as ProxyUtils;
function hovercard_init(App $a)
{
'name' => $contact['name'],
'nick' => $contact['nick'],
'addr' => defaults($contact, 'addr', $contact['url']),
- 'thumb' => proxy_url($contact['thumb'], false, PROXY_SIZE_THUMB),
+ 'thumb' => ProxyUtils::proxifyUrl($contact['thumb'], false, ProxyUtils::SIZE_THUMB),
'url' => Contact::magicLink($contact['url']),
'nurl' => $contact['nurl'], // We additionally store the nurl as identifier
'location' => $contact['location'],
use Friendica\Database\DBA;
use Friendica\Model\Contact;
use Friendica\Util\Network;
+use Friendica\Util\Proxy as ProxyUtils;
require_once 'include/text.php';
-require_once 'mod/proxy.php';
/**
* @brief Controller for /match.
'tags' => $contact_details['keywords'],
'about' => $contact_details['about'],
'account_type' => Contact::getAccountType($contact_details),
- 'thumb' => proxy_url($jj->photo, false, PROXY_SIZE_THUMB),
+ 'thumb' => ProxyUtils::proxifyUrl($jj->photo, false, ProxyUtils::SIZE_THUMB),
'inttxt' => ' ' . L10n::t('is interested in:'),
'conntxt' => L10n::t('Connect'),
'connlnk' => $connlnk,
use Friendica\Model\Contact;
use Friendica\Model\Mail;
use Friendica\Util\DateTimeFormat;
+use Friendica\Util\Proxy as ProxyUtils;
use Friendica\Util\Temporal;
require_once 'include/conversation.php';
'from_url' => $from_url,
'from_addr' => $contact['addr'],
'sparkle' => $sparkle,
- 'from_photo' => proxy_url($from_photo, false, PROXY_SIZE_THUMB),
+ 'from_photo' => ProxyUtils::proxifyUrl($from_photo, false, ProxyUtils::SIZE_THUMB),
'subject' => $subject_e,
'body' => $body_e,
'delete' => L10n::t('Delete message'),
'$from_url' => Contact::magicLink($rr['url']),
'$from_addr' => $contact['addr'],
'$sparkle' => ' sparkle',
- '$from_photo' => proxy_url($from_photo, false, PROXY_SIZE_THUMB),
+ '$from_photo' => ProxyUtils::proxifyUrl($from_photo, false, ProxyUtils::SIZE_THUMB),
'$subject' => $subject_e,
'$delete' => L10n::t('Delete conversation'),
'$body' => $body_e,
use Friendica\Model\Profile;
use Friendica\Module\Login;
use Friendica\Util\DateTimeFormat;
+use Friendica\Util\Proxy as ProxyUtils;
require_once 'include/conversation.php';
require_once 'include/items.php';
'id' => 'network',
'name' => htmlentities($contact['name']),
'itemurl' => defaults($contact, 'addr', $contact['nurl']),
- 'thumb' => proxy_url($contact['thumb'], false, PROXY_SIZE_THUMB),
+ 'thumb' => ProxyUtils::proxifyUrl($contact['thumb'], false, ProxyUtils::SIZE_THUMB),
'details' => $contact['location'],
];
use Friendica\Model\Item;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Temporal;
+use Friendica\Util\Proxy as ProxyUtils;
use Friendica\Util\XML;
-require_once 'mod/proxy.php';
require_once 'include/enotify.php';
/**
$contact = Contact::getDetailsByURL($notif['url']);
if (isset($contact['micro'])) {
- $notif['photo'] = proxy_url($contact['micro'], false, PROXY_SIZE_MICRO);
+ $notif['photo'] = ProxyUtils::proxifyUrl($contact['micro'], false, ProxyUtils::SIZE_MICRO);
} else {
- $notif['photo'] = proxy_url($notif['photo'], false, PROXY_SIZE_MICRO);
+ $notif['photo'] = ProxyUtils::proxifyUrl($notif['photo'], false, ProxyUtils::SIZE_MICRO);
}
$local_time = DateTimeFormat::local($notif['date']);
+++ /dev/null
-<?php
-/**
- * @file mod/proxy.php
- * @brief Based upon "Privacy Image Cache" by Tobias Hößl <https://github.com/CatoTH/>
- */
-
-use Friendica\App;
-use Friendica\Core\Config;
-use Friendica\Core\System;
-use Friendica\Database\DBA;
-use Friendica\Model\Photo;
-use Friendica\Object\Image;
-use Friendica\Util\DateTimeFormat;
-use Friendica\Util\Network;
-
-define('PROXY_DEFAULT_TIME', 86400); // 1 Day
-
-define('PROXY_SIZE_MICRO', 'micro');
-define('PROXY_SIZE_THUMB', 'thumb');
-define('PROXY_SIZE_SMALL', 'small');
-define('PROXY_SIZE_MEDIUM', 'medium');
-define('PROXY_SIZE_LARGE', 'large');
-
-require_once 'include/security.php';
-
-function proxy_init(App $a) {
- // Pictures are stored in one of the following ways:
- // 1. If a folder "proxy" exists and is writeable, then use this for caching
- // 2. If a cache path is defined, use this
- // 3. If everything else failed, cache into the database
- //
- // Question: Do we really need these three methods?
-
- if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
- header('HTTP/1.1 304 Not Modified');
- header('Last-Modified: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT');
- header('Etag: ' . $_SERVER['HTTP_IF_NONE_MATCH']);
- header('Expires: ' . gmdate('D, d M Y H:i:s', time() + (31536000)) . ' GMT');
- header('Cache-Control: max-age=31536000');
-
- if (function_exists('header_remove')) {
- header_remove('Last-Modified');
- header_remove('Expires');
- header_remove('Cache-Control');
- }
- exit;
- }
-
- if (function_exists('header_remove')) {
- header_remove('Pragma');
- header_remove('pragma');
- }
-
- $thumb = false;
- $size = 1024;
- $sizetype = '';
- $basepath = $a->get_basepath();
-
- // If the cache path isn't there, try to create it
- if (!is_dir($basepath . '/proxy') && is_writable($basepath)) {
- mkdir($basepath . '/proxy');
- }
-
- // Checking if caching into a folder in the webroot is activated and working
- $direct_cache = (is_dir($basepath . '/proxy') && is_writable($basepath . '/proxy'));
-
- // Look for filename in the arguments
- if ((isset($a->argv[1]) || isset($a->argv[2]) || isset($a->argv[3])) && !isset($_REQUEST['url'])) {
- if (isset($a->argv[3])) {
- $url = $a->argv[3];
- } elseif (isset($a->argv[2])) {
- $url = $a->argv[2];
- } else {
- $url = $a->argv[1];
- }
-
- if (isset($a->argv[3]) && ($a->argv[3] == 'thumb')) {
- $size = 200;
- }
-
- // thumb, small, medium and large.
- if (substr($url, -6) == ':micro') {
- $size = 48;
- $sizetype = ':micro';
- $url = substr($url, 0, -6);
- } elseif (substr($url, -6) == ':thumb') {
- $size = 80;
- $sizetype = ':thumb';
- $url = substr($url, 0, -6);
- } elseif (substr($url, -6) == ':small') {
- $size = 175;
- $url = substr($url, 0, -6);
- $sizetype = ':small';
- } elseif (substr($url, -7) == ':medium') {
- $size = 600;
- $url = substr($url, 0, -7);
- $sizetype = ':medium';
- } elseif (substr($url, -6) == ':large') {
- $size = 1024;
- $url = substr($url, 0, -6);
- $sizetype = ':large';
- }
-
- $pos = strrpos($url, '=.');
- if ($pos) {
- $url = substr($url, 0, $pos + 1);
- }
-
- $url = str_replace(['.jpg', '.jpeg', '.gif', '.png'], ['','','',''], $url);
-
- $url = base64_decode(strtr($url, '-_', '+/'), true);
-
- if ($url) {
- $_REQUEST['url'] = $url;
- }
- } else {
- $direct_cache = false;
- }
-
- if (!$direct_cache) {
- $urlhash = 'pic:' . sha1($_REQUEST['url']);
-
- $cachefile = get_cachefile(hash('md5', $_REQUEST['url']));
- if ($cachefile != '' && file_exists($cachefile)) {
- $img_str = file_get_contents($cachefile);
- $mime = image_type_to_mime_type(exif_imagetype($cachefile));
-
- header('Content-type: ' . $mime);
- header('Last-Modified: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT');
- header('Etag: "' . md5($img_str) . '"');
- header('Expires: ' . gmdate('D, d M Y H:i:s', time() + (31536000)) . ' GMT');
- header('Cache-Control: max-age=31536000');
-
- // reduce quality - if it isn't a GIF
- if ($mime != 'image/gif') {
- $Image = new Image($img_str, $mime);
- if ($Image->isValid()) {
- $img_str = $Image->asString();
- }
- }
-
- echo $img_str;
- killme();
- }
- } else {
- $cachefile = '';
- }
-
- $valid = true;
- $photo = null;
- if (!$direct_cache && ($cachefile == '')) {
- $photo = DBA::selectFirst('photo', ['data', 'desc'], ['resource-id' => $urlhash]);
- if (DBA::isResult($photo)) {
- $img_str = $photo['data'];
- $mime = $photo['desc'];
- if ($mime == '') {
- $mime = 'image/jpeg';
- }
- }
- }
-
- if (!DBA::isResult($photo)) {
- // It shouldn't happen but it does - spaces in URL
- $_REQUEST['url'] = str_replace(' ', '+', $_REQUEST['url']);
- $redirects = 0;
- $img_str = Network::fetchUrl($_REQUEST['url'], true, $redirects, 10);
-
- $tempfile = tempnam(get_temppath(), 'cache');
- file_put_contents($tempfile, $img_str);
- $mime = image_type_to_mime_type(exif_imagetype($tempfile));
- unlink($tempfile);
-
- // If there is an error then return a blank image
- if ((substr($a->get_curl_code(), 0, 1) == '4') || (!$img_str)) {
- $img_str = file_get_contents('images/blank.png');
- $mime = 'image/png';
- $cachefile = ''; // Clear the cachefile so that the dummy isn't stored
- $valid = false;
- $Image = new Image($img_str, 'image/png');
- if ($Image->isValid()) {
- $Image->scaleDown(10);
- $img_str = $Image->asString();
- }
- } elseif ($mime != 'image/jpeg' && !$direct_cache && $cachefile == '') {
- $image = @imagecreatefromstring($img_str);
-
- if ($image === FALSE) {
- die();
- }
-
- $fields = ['uid' => 0, 'contact-id' => 0, 'guid' => System::createGUID(), 'resource-id' => $urlhash, 'created' => DateTimeFormat::utcNow(), 'edited' => DateTimeFormat::utcNow(),
- 'filename' => basename($_REQUEST['url']), 'type' => '', 'album' => '', 'height' => imagesy($image), 'width' => imagesx($image),
- 'datasize' => 0, 'data' => $img_str, 'scale' => 100, 'profile' => 0,
- 'allow_cid' => '', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '', 'desc' => $mime];
- DBA::insert('photo', $fields);
- } else {
- $Image = new Image($img_str, $mime);
- if ($Image->isValid() && !$direct_cache && ($cachefile == '')) {
- Photo::store($Image, 0, 0, $urlhash, $_REQUEST['url'], '', 100);
- }
- }
- }
-
- $img_str_orig = $img_str;
-
- // reduce quality - if it isn't a GIF
- if ($mime != 'image/gif') {
- $Image = new Image($img_str, $mime);
- if ($Image->isValid()) {
- $Image->scaleDown($size);
- $img_str = $Image->asString();
- }
- }
-
- // If there is a real existing directory then put the cache file there
- // advantage: real file access is really fast
- // Otherwise write in cachefile
- if ($valid && $direct_cache) {
- file_put_contents($basepath . '/proxy/' . proxy_url($_REQUEST['url'], true), $img_str_orig);
- if ($sizetype != '') {
- file_put_contents($basepath . '/proxy/' . proxy_url($_REQUEST['url'], true) . $sizetype, $img_str);
- }
- } elseif ($cachefile != '') {
- file_put_contents($cachefile, $img_str_orig);
- }
-
- header('Content-type: ' . $mime);
-
- // Only output the cache headers when the file is valid
- if ($valid) {
- header('Last-Modified: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT');
- header('Etag: "' . md5($img_str) . '"');
- header('Expires: ' . gmdate('D, d M Y H:i:s', time() + (31536000)) . ' GMT');
- header('Cache-Control: max-age=31536000');
- }
-
- echo $img_str;
-
- killme();
-}
-
-/**
- * @brief Transform a remote URL into a local one
- *
- * This function only performs the URL replacement on http URL and if the
- * provided URL isn't local, "the isn't deactivated" (sic) and if the config
- * system.proxy_disabled is set to false.
- *
- * @param string $url The URL to proxyfy
- * @param bool $writemode Returns a local path the remote URL should be saved to
- * @param string $size One of the PROXY_SIZE_* constants
- *
- * @return string The proxyfied URL or relative path
- */
-function proxy_url($url, $writemode = false, $size = '') {
- $a = get_app();
-
- if (substr($url, 0, strlen('http')) !== 'http') {
- return $url;
- }
-
- // Only continue if it isn't a local image and the isn't deactivated
- if (proxy_is_local_image($url)) {
- $url = str_replace(normalise_link(System::baseUrl()) . '/', System::baseUrl() . '/', $url);
- return $url;
- }
-
- if (Config::get('system', 'proxy_disabled')) {
- return $url;
- }
-
- // Image URL may have encoded ampersands for display which aren't desirable for proxy
- $url = html_entity_decode($url, ENT_NOQUOTES, 'utf-8');
-
- // Creating a sub directory to reduce the amount of files in the cache directory
- $basepath = $a->get_basepath() . '/proxy';
-
- $shortpath = hash('md5', $url);
- $longpath = substr($shortpath, 0, 2);
-
- if (is_dir($basepath) && $writemode && !is_dir($basepath . '/' . $longpath)) {
- mkdir($basepath . '/' . $longpath);
- chmod($basepath . '/' . $longpath, 0777);
- }
-
- $longpath .= '/' . strtr(base64_encode($url), '+/', '-_');
-
- // Extract the URL extension
- $extension = pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_EXTENSION);
-
- $extensions = ['jpg', 'jpeg', 'gif', 'png'];
- if (in_array($extension, $extensions)) {
- $shortpath .= '.' . $extension;
- $longpath .= '.' . $extension;
- }
-
- $proxypath = System::baseUrl() . '/proxy/' . $longpath;
-
- if ($size != '') {
- $size = ':' . $size;
- }
-
- // Too long files aren't supported by Apache
- // Writemode in combination with long files shouldn't be possible
- if ((strlen($proxypath) > 250) && $writemode) {
- return $shortpath;
- } elseif (strlen($proxypath) > 250) {
- return System::baseUrl() . '/proxy/' . $shortpath . '?url=' . urlencode($url);
- } elseif ($writemode) {
- return $longpath;
- } else {
- return $proxypath . $size;
- }
-}
-
-/**
- * @param $url string
- * @return boolean
- */
-function proxy_is_local_image($url) {
- if ($url[0] == '/') {
- return true;
- }
-
- if (strtolower(substr($url, 0, 5)) == 'data:') {
- return true;
- }
-
- // links normalised - bug #431
- $baseurl = normalise_link(System::baseUrl());
- $url = normalise_link($url);
- return (substr($url, 0, strlen($baseurl)) == $baseurl);
-}
-
-/**
- * @brief Return the array of query string parameters from a URL
- *
- * @param string $url
- * @return array Associative array of query string parameters
- */
-function proxy_parse_query($url) {
- $query = parse_url($url, PHP_URL_QUERY);
- $query = html_entity_decode($query);
- $query_list = explode('&', $query);
- $arr = [];
-
- foreach ($query_list as $key_value) {
- $key_value_list = explode('=', $key_value);
- $arr[$key_value_list[0]] = $key_value_list[1];
- }
-
- unset($url, $query_list, $url);
- return $arr;
-}
-
-function proxy_img_cb($matches) {
- // if the picture seems to be from another picture cache then take the original source
- $queryvar = proxy_parse_query($matches[2]);
- if (($queryvar['url'] != '') && (substr($queryvar['url'], 0, 4) == 'http')) {
- $matches[2] = urldecode($queryvar['url']);
- }
-
- // following line changed per bug #431
- if (proxy_is_local_image($matches[2])) {
- return $matches[1] . $matches[2] . $matches[3];
- }
-
- return $matches[1] . proxy_url(htmlspecialchars_decode($matches[2])) . $matches[3];
-}
-
-function proxy_parse_html($html) {
- $html = str_replace(normalise_link(System::baseUrl()) . '/', System::baseUrl() . '/', $html);
-
- return preg_replace_callback('/(<img [^>]*src *= *["\'])([^"\']+)(["\'][^>]*>)/siU', 'proxy_img_cb', $html);
-}
use Friendica\Database\DBA;
use Friendica\Model\Contact;
use Friendica\Model\GContact;
+use Friendica\Util\Proxy as ProxyUtils;
function suggest_init(App $a) {
if (! local_user()) {
}
-function suggest_content(App $a) {
-
- require_once("mod/proxy.php");
-
+function suggest_content(App $a)
+{
$o = '';
+
if (! local_user()) {
notice(L10n::t('Permission denied.') . EOL);
return;
'itemurl' => (($contact_details['addr'] != "") ? $contact_details['addr'] : $rr['url']),
'img_hover' => $rr['url'],
'name' => $contact_details['name'],
- 'thumb' => proxy_url($contact_details['thumb'], false, PROXY_SIZE_THUMB),
+ 'thumb' => ProxyUtils::proxifyUrl($contact_details['thumb'], false, ProxyUtils::SIZE_THUMB),
'details' => $contact_details['location'],
'tags' => $contact_details['keywords'],
'about' => $contact_details['about'],
use Friendica\Database\DBA;
use Friendica\Model\Contact;
use Friendica\Model\Profile;
+use Friendica\Util\Proxy as ProxyUtils;
function viewcontacts_init(App $a)
{
function viewcontacts_content(App $a)
{
- require_once("mod/proxy.php");
-
if ((Config::get('system', 'block_public')) && (! local_user()) && (! remote_user())) {
notice(L10n::t('Public access denied.') . EOL);
return;
'id' => $rr['id'],
'img_hover' => L10n::t('Visit %s\'s profile [%s]', $contact_details['name'], $rr['url']),
'photo_menu' => Contact::photoMenu($rr),
- 'thumb' => proxy_url($contact_details['thumb'], false, PROXY_SIZE_THUMB),
+ 'thumb' => ProxyUtils::proxifyUrl($contact_details['thumb'], false, ProxyUtils::SIZE_THUMB),
'name' => htmlentities(substr($contact_details['name'], 0, 20)),
'username' => htmlentities($contact_details['name']),
'details' => $contact_details['location'],
use Friendica\Core\System;
use Friendica\Database\DBA;
use Friendica\Model\Contact;
+use Friendica\Util\Proxy as ProxyUtils;
require_once 'include/dba.php';
'name' => $contact['name'],
'cid' => $contact['id'],
'selected' => $selected,
- 'micro' => System::removedBaseUrl(proxy_url($contact['micro'], false, PROXY_SIZE_MICRO)),
+ 'micro' => System::removedBaseUrl(ProxyUtils::proxifyUrl($contact['micro'], false, ProxyUtils::SIZE_MICRO)),
'id' => ++$id,
];
$entries[] = $entry;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Network;
use Friendica\Util\ParseUrl;
+use Friendica\Util\Proxy as ProxyUtils;
require_once 'include/dba.php';
-require_once 'mod/proxy.php';
/**
* Handles all OEmbed content fetching and replacement
$ret = $oembed->html;
}
break;
+
case "photo":
- $ret .= '<img width="' . $oembed->width . '" src="' . proxy_url($oembed->url) . '">';
+ $ret .= '<img width="' . $oembed->width . '" src="' . ProxyUtils::proxifyUrl($oembed->url) . '">';
break;
+
case "link":
break;
+
case "rich":
- $ret .= proxy_parse_html($oembed->html);
+ $ret .= ProxyUtils::proxifyHtml($oembed->html);
break;
}
use Friendica\Util\Map;
use Friendica\Util\Network;
use Friendica\Util\ParseUrl;
+use Friendica\Util\Proxy as ProxyUtils;
use League\HTMLToMarkdown\HtmlConverter;
-require_once "mod/proxy.php";
-
class BBCode extends BaseObject
{
/**
{
// Only send proxied pictures to API and for internal display
if (in_array($simplehtml, [false, 2])) {
- return proxy_url($image);
+ return ProxyUtils::proxifyUrl($image);
} else {
return $image;
}
} else {
$text = trim($share[1]) . "\n";
- $avatar = proxy_url($avatar, false, PROXY_SIZE_THUMB);
+ $avatar = ProxyUtils::proxifyUrl($avatar, false, ProxyUtils::SIZE_THUMB);
$tpl = get_markup_template('shared_content.tpl');
$text .= replace_macros($tpl, [
use Friendica\Model\Contact;
use Friendica\Model\Item;
use Friendica\Util\DateTimeFormat;
+use Friendica\Util\Proxy as ProxyUtils;
use Friendica\Util\Temporal;
use Friendica\Util\XML;
case 'system':
$default_item_label = 'notify';
$default_item_link = System::baseUrl(true) . '/notify/view/' . $it['id'];
- $default_item_image = proxy_url($it['photo'], false, PROXY_SIZE_MICRO);
+ $default_item_image = ProxyUtils::proxifyUrl($it['photo'], false, ProxyUtils::SIZE_MICRO);
$default_item_url = $it['url'];
$default_item_text = strip_tags(BBCode::convert($it['msg']));
$default_item_when = DateTimeFormat::local($it['date'], 'r');
case 'home':
$default_item_label = 'comment';
$default_item_link = System::baseUrl(true) . '/display/' . $it['parent-guid'];
- $default_item_image = proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO);
+ $default_item_image = ProxyUtils::proxifyUrl($it['author-avatar'], false, ProxyUtils::SIZE_MICRO);
$default_item_url = $it['author-link'];
$default_item_text = L10n::t("%s commented on %s's post", $it['author-name'], $it['parent-author-name']);
$default_item_when = DateTimeFormat::local($it['created'], 'r');
default:
$default_item_label = (($it['id'] == $it['parent']) ? 'post' : 'comment');
$default_item_link = System::baseUrl(true) . '/display/' . $it['parent-guid'];
- $default_item_image = proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO);
+ $default_item_image = ProxyUtils::proxifyUrl($it['author-avatar'], false, ProxyUtils::SIZE_MICRO);
$default_item_url = $it['author-link'];
$default_item_text = (($it['id'] == $it['parent'])
? L10n::t("%s created a new post", $it['author-name'])
$notif = [
'label' => 'like',
'link' => System::baseUrl(true) . '/display/' . $it['parent-guid'],
- 'image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
+ 'image' => ProxyUtils::proxifyUrl($it['author-avatar'], false, ProxyUtils::SIZE_MICRO),
'url' => $it['author-link'],
'text' => L10n::t("%s liked %s's post", $it['author-name'], $it['parent-author-name']),
'when' => $default_item_when,
$notif = [
'label' => 'dislike',
'link' => System::baseUrl(true) . '/display/' . $it['parent-guid'],
- 'image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
+ 'image' => ProxyUtils::proxifyUrl($it['author-avatar'], false, ProxyUtils::SIZE_MICRO),
'url' => $it['author-link'],
'text' => L10n::t("%s disliked %s's post", $it['author-name'], $it['parent-author-name']),
'when' => $default_item_when,
$notif = [
'label' => 'attend',
'link' => System::baseUrl(true) . '/display/' . $it['parent-guid'],
- 'image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
+ 'image' => ProxyUtils::proxifyUrl($it['author-avatar'], false, ProxyUtils::SIZE_MICRO),
'url' => $it['author-link'],
'text' => L10n::t("%s is attending %s's event", $it['author-name'], $it['parent-author-name']),
'when' => $default_item_when,
$notif = [
'label' => 'attendno',
'link' => System::baseUrl(true) . '/display/' . $it['parent-guid'],
- 'image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
+ 'image' => ProxyUtils::proxifyUrl($it['author-avatar'], false, ProxyUtils::SIZE_MICRO),
'url' => $it['author-link'],
'text' => L10n::t("%s is not attending %s's event", $it['author-name'], $it['parent-author-name']),
'when' => $default_item_when,
$notif = [
'label' => 'attendmaybe',
'link' => System::baseUrl(true) . '/display/' . $it['parent-guid'],
- 'image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
+ 'image' => ProxyUtils::proxifyUrl($it['author-avatar'], false, ProxyUtils::SIZE_MICRO),
'url' => $it['author-link'],
'text' => L10n::t("%s may attend %s's event", $it['author-name'], $it['parent-author-name']),
'when' => $default_item_when,
$notif = [
'label' => 'friend',
'link' => System::baseUrl(true) . '/display/' . $it['parent-guid'],
- 'image' => proxy_url($it['author-avatar'], false, PROXY_SIZE_MICRO),
+ 'image' => ProxyUtils::proxifyUrl($it['author-avatar'], false, ProxyUtils::SIZE_MICRO),
'url' => $it['author-link'],
'text' => L10n::t("%s is now friends with %s", $it['author-name'], $it['fname']),
'when' => $default_item_when,
'madeby_zrl' => Contact::magicLink($it['url']),
'madeby_addr' => $it['addr'],
'contact_id' => $it['contact-id'],
- 'photo' => ((x($it, 'fphoto')) ? proxy_url($it['fphoto'], false, PROXY_SIZE_SMALL) : "images/person-175.jpg"),
+ 'photo' => ((x($it, 'fphoto')) ? ProxyUtils::proxifyUrl($it['fphoto'], false, ProxyUtils::SIZE_SMALL) : "images/person-175.jpg"),
'name' => $it['fname'],
'url' => $it['furl'],
'zrl' => Contact::magicLink($it['furl']),
'uid' => $_SESSION['uid'],
'intro_id' => $it['intro_id'],
'contact_id' => $it['contact-id'],
- 'photo' => ((x($it, 'photo')) ? proxy_url($it['photo'], false, PROXY_SIZE_SMALL) : "images/person-175.jpg"),
+ 'photo' => ((x($it, 'photo')) ? ProxyUtils::proxifyUrl($it['photo'], false, ProxyUtils::SIZE_SMALL) : "images/person-175.jpg"),
'name' => $it['name'],
'location' => BBCode::convert($it['glocation'], false),
'about' => BBCode::convert($it['gabout'], false),
use Friendica\Protocol\Diaspora;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Network;
+use Friendica\Util\Proxy as ProxyUtils;
use Friendica\Util\Temporal;
require_once 'include/dba.php';
-require_once 'mod/proxy.php';
class Profile
{
}
if (isset($p['photo'])) {
- $p['photo'] = proxy_url($p['photo'], false, PROXY_SIZE_SMALL);
+ $p['photo'] = ProxyUtils::proxifyUrl($p['photo'], false, ProxyUtils::SIZE_SMALL);
}
$p['url'] = Contact::magicLink(defaults($p, 'url', $profile_url));
--- /dev/null
+<?php
+/**
+ * @file src/Module/Proxy.php
+ * @brief Based upon "Privacy Image Cache" by Tobias Hößl <https://github.com/CatoTH/>
+ */
+namespace Friendica\Module;
+
+use Friendica\App;
+use Friendica\BaseModule;
+use Friendica\Core\Config;
+use Friendica\Core\System;
+use Friendica\Database\DBA;
+use Friendica\Model\Photo;
+use Friendica\Object\Image;
+use Friendica\Util\DateTimeFormat;
+use Friendica\Util\Network;
+use Friendica\Util\Proxy as ProxyUtils;
+
+require_once 'include/security.php';
+
+/**
+ * @brief Module Proxy
+ */
+class Proxy extends BaseModule
+{
+
+ /**
+ * @brief Initializer method for this class.
+ *
+ * Sets application instance and checks if /proxy/ path is writable.
+ *
+ * @param \Friendica\App $app Application instance
+ */
+ public static function init()
+ {
+ // Set application instance here
+ $a = self::getApp();
+
+ /*
+ * Pictures are stored in one of the following ways:
+ *
+ * 1. If a folder "proxy" exists and is writeable, then use this for caching
+ * 2. If a cache path is defined, use this
+ * 3. If everything else failed, cache into the database
+ *
+ * Question: Do we really need these three methods?
+ */
+ if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
+ header('HTTP/1.1 304 Not Modified');
+ header('Last-Modified: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT');
+ header('Etag: ' . $_SERVER['HTTP_IF_NONE_MATCH']);
+ header('Expires: ' . gmdate('D, d M Y H:i:s', time() + (31536000)) . ' GMT');
+ header('Cache-Control: max-age=31536000');
+
+ if (function_exists('header_remove')) {
+ header_remove('Last-Modified');
+ header_remove('Expires');
+ header_remove('Cache-Control');
+ }
+
+ /// @TODO Stop here?
+ exit();
+ }
+
+ if (function_exists('header_remove')) {
+ header_remove('Pragma');
+ header_remove('pragma');
+ }
+
+ $thumb = false;
+ $size = 1024;
+ $sizetype = '';
+ $basepath = $a->get_basepath();
+
+ // If the cache path isn't there, try to create it
+ if (!is_dir($basepath . '/proxy') && is_writable($basepath)) {
+ mkdir($basepath . '/proxy');
+ }
+
+ // Checking if caching into a folder in the webroot is activated and working
+ $direct_cache = (is_dir($basepath . '/proxy') && is_writable($basepath . '/proxy'));
+
+ // Look for filename in the arguments
+ if ((isset($a->argv[1]) || isset($a->argv[2]) || isset($a->argv[3])) && !isset($_REQUEST['url'])) {
+ if (isset($a->argv[3])) {
+ $url = $a->argv[3];
+ } elseif (isset($a->argv[2])) {
+ $url = $a->argv[2];
+ } else {
+ $url = $a->argv[1];
+ }
+
+ if (isset($a->argv[3]) && ($a->argv[3] == 'thumb')) {
+ $size = 200;
+ }
+
+ // thumb, small, medium and large.
+ if (substr($url, -6) == ':micro') {
+ $size = 48;
+ $sizetype = ':micro';
+ $url = substr($url, 0, -6);
+ } elseif (substr($url, -6) == ':thumb') {
+ $size = 80;
+ $sizetype = ':thumb';
+ $url = substr($url, 0, -6);
+ } elseif (substr($url, -6) == ':small') {
+ $size = 175;
+ $url = substr($url, 0, -6);
+ $sizetype = ':small';
+ } elseif (substr($url, -7) == ':medium') {
+ $size = 600;
+ $url = substr($url, 0, -7);
+ $sizetype = ':medium';
+ } elseif (substr($url, -6) == ':large') {
+ $size = 1024;
+ $url = substr($url, 0, -6);
+ $sizetype = ':large';
+ }
+
+ $pos = strrpos($url, '=.');
+ if ($pos) {
+ $url = substr($url, 0, $pos + 1);
+ }
+
+ $url = str_replace(['.jpg', '.jpeg', '.gif', '.png'], ['','','',''], $url);
+
+ $url = base64_decode(strtr($url, '-_', '+/'), true);
+
+ if ($url) {
+ $_REQUEST['url'] = $url;
+ }
+ } else {
+ $direct_cache = false;
+ }
+
+ if (!$direct_cache) {
+ $urlhash = 'pic:' . sha1($_REQUEST['url']);
+
+ $cachefile = get_cachefile(hash('md5', $_REQUEST['url']));
+ if ($cachefile != '' && file_exists($cachefile)) {
+ $img_str = file_get_contents($cachefile);
+ $mime = image_type_to_mime_type(exif_imagetype($cachefile));
+
+ header('Content-type: ' . $mime);
+ header('Last-Modified: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT');
+ header('Etag: "' . md5($img_str) . '"');
+ header('Expires: ' . gmdate('D, d M Y H:i:s', time() + (31536000)) . ' GMT');
+ header('Cache-Control: max-age=31536000');
+
+ // reduce quality - if it isn't a GIF
+ if ($mime != 'image/gif') {
+ $image = new Image($img_str, $mime);
+
+ if ($image->isValid()) {
+ $img_str = $image->asString();
+ }
+ }
+
+ echo $img_str;
+ exit();
+ }
+ } else {
+ $cachefile = '';
+ }
+
+ $valid = true;
+ $photo = null;
+
+ if (!$direct_cache && ($cachefile == '')) {
+ $photo = DBA::selectFirst('photo', ['data', 'desc'], ['resource-id' => $urlhash]);
+
+ if (DBA::isResult($photo)) {
+ $img_str = $photo['data'];
+ $mime = $photo['desc'];
+
+ if ($mime == '') {
+ $mime = 'image/jpeg';
+ }
+ }
+ }
+
+ if (!DBA::isResult($photo)) {
+ // It shouldn't happen but it does - spaces in URL
+ $_REQUEST['url'] = str_replace(' ', '+', $_REQUEST['url']);
+ $redirects = 0;
+ $img_str = Network::fetchUrl($_REQUEST['url'], true, $redirects, 10);
+
+ $tempfile = tempnam(get_temppath(), 'cache');
+ file_put_contents($tempfile, $img_str);
+ $mime = image_type_to_mime_type(exif_imagetype($tempfile));
+ unlink($tempfile);
+
+ // If there is an error then return a blank image
+ if ((substr($a->get_curl_code(), 0, 1) == '4') || (!$img_str)) {
+ $img_str = file_get_contents('images/blank.png');
+ $mime = 'image/png';
+ $cachefile = ''; // Clear the cachefile so that the dummy isn't stored
+ $valid = false;
+ $image = new Image($img_str, 'image/png');
+
+ if ($image->isValid()) {
+ $image->scaleDown(10);
+ $img_str = $image->asString();
+ }
+ } elseif ($mime != 'image/jpeg' && !$direct_cache && $cachefile == '') {
+ $image = @imagecreatefromstring($img_str);
+
+ if ($image === FALSE) {
+ die();
+ }
+
+ $fields = ['uid' => 0, 'contact-id' => 0, 'guid' => System::createGUID(), 'resource-id' => $urlhash, 'created' => DateTimeFormat::utcNow(), 'edited' => DateTimeFormat::utcNow(),
+ 'filename' => basename($_REQUEST['url']), 'type' => '', 'album' => '', 'height' => imagesy($image), 'width' => imagesx($image),
+ 'datasize' => 0, 'data' => $img_str, 'scale' => 100, 'profile' => 0,
+ 'allow_cid' => '', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '', 'desc' => $mime];
+ DBA::insert('photo', $fields);
+ } else {
+ $image = new Image($img_str, $mime);
+
+ if ($image->isValid() && !$direct_cache && ($cachefile == '')) {
+ Photo::store($image, 0, 0, $urlhash, $_REQUEST['url'], '', 100);
+ }
+ }
+ }
+
+ $img_str_orig = $img_str;
+
+ // reduce quality - if it isn't a GIF
+ if ($mime != 'image/gif') {
+ $image = new Image($img_str, $mime);
+
+ if ($image->isValid()) {
+ $image->scaleDown($size);
+ $img_str = $image->asString();
+ }
+ }
+
+ /*
+ * If there is a real existing directory then put the cache file there
+ * advantage: real file access is really fast
+ * Otherwise write in cachefile
+ */
+ if ($valid && $direct_cache) {
+ file_put_contents($basepath . '/proxy/' . ProxyUtils::proxifyUrl($_REQUEST['url'], true), $img_str_orig);
+
+ if ($sizetype != '') {
+ file_put_contents($basepath . '/proxy/' . ProxyUtils::proxifyUrl($_REQUEST['url'], true) . $sizetype, $img_str);
+ }
+ } elseif ($cachefile != '') {
+ file_put_contents($cachefile, $img_str_orig);
+ }
+
+ header('Content-type: ' . $mime);
+
+ // Only output the cache headers when the file is valid
+ if ($valid) {
+ header('Last-Modified: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT');
+ header('Etag: "' . md5($img_str) . '"');
+ header('Expires: ' . gmdate('D, d M Y H:i:s', time() + (31536000)) . ' GMT');
+ header('Cache-Control: max-age=31536000');
+ }
+
+ echo $img_str;
+
+ exit();
+ }
+
+}
use Friendica\Model\Item;
use Friendica\Model\Term;
use Friendica\Util\DateTimeFormat;
+use Friendica\Util\Proxy as ProxyUtils;
use Friendica\Util\Temporal;
require_once 'include/dba.php';
*/
public function getTemplateData($conv_responses, $thread_level = 1)
{
- require_once "mod/proxy.php";
-
$result = [];
$a = self::getApp();
|| strlen($item['deny_cid']) || strlen($item['deny_gid']))))
? L10n::t('Private Message')
: false);
+
$shareable = in_array($conv->getProfileOwner(), [0, local_user()]) && $item['private'] != 1;
if (local_user() && link_compare($a->contact['url'], $item['author-link'])) {
'profile_url' => $profile_link,
'item_photo_menu' => item_photo_menu($item),
'name' => $name_e,
- 'thumb' => $a->remove_baseurl(proxy_url($item['author-avatar'], false, PROXY_SIZE_THUMB)),
+ 'thumb' => $a->remove_baseurl(ProxyUtils::proxifyUrl($item['author-avatar'], false, ProxyUtils::SIZE_THUMB)),
'osparkle' => $osparkle,
'sparkle' => $sparkle,
'title' => $title_e,
'indent' => $indent,
'shiny' => $shiny,
'owner_url' => $this->getOwnerUrl(),
- 'owner_photo' => $a->remove_baseurl(proxy_url($item['owner-avatar'], false, PROXY_SIZE_THUMB)),
+ 'owner_photo' => $a->remove_baseurl(ProxyUtils::proxifyUrl($item['owner-avatar'], false, ProxyUtils::SIZE_THUMB)),
'owner_name' => htmlentities($owner_name_e),
'plink' => get_plink($item),
'edpost' => Feature::isEnabled($conv->getProfileOwner(), 'edit_posts') ? $edpost : '',
use Friendica\Object\Image;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Network;
+use Friendica\Util\Proxy as ProxyUtils;
use Friendica\Util\XML;
require_once 'include/dba.php';
require_once 'mod/share.php';
require_once 'include/enotify.php';
require_once 'include/api.php';
-require_once 'mod/proxy.php';
/**
* @brief This class contain functions for the OStatus protocol
}
// Is it a remote picture? Then make a smaller preview here
- $preview = proxy_url($preview, false, PROXY_SIZE_SMALL);
+ $preview = ProxyUtils::proxifyUrl($preview, false, ProxyUtils::SIZE_SMALL);
// Is it a local picture? Then make it smaller here
$preview = str_replace(["-0.jpg", "-0.png"], ["-2.jpg", "-2.png"], $preview);
--- /dev/null
+<?php
+
+namespace Friendica\Util;
+
+use Friendica\BaseModule;
+use Friendica\BaseObject;
+use Friendica\Core\Config;
+use Friendica\Core\System;
+
+require_once 'include/security.php';
+
+/**
+ * @brief Proxy utilities class
+ */
+class Proxy
+{
+
+ /**
+ * Default time to keep images in proxy storage
+ */
+ const DEFAULT_TIME = 86400; // 1 Day
+
+ /**
+ * Sizes constants
+ */
+ const SIZE_MICRO = 'micro';
+ const SIZE_THUMB = 'thumb';
+ const SIZE_SMALL = 'small';
+ const SIZE_MEDIUM = 'medium';
+ const SIZE_LARGE = 'large';
+
+ /**
+ * Accepted extensions
+ *
+ * @var array
+ * @todo Make this configurable?
+ */
+ private static $extensions = [
+ 'jpg',
+ 'jpeg',
+ 'gif',
+ 'png',
+ ];
+
+ /**
+ * @brief Private constructor
+ */
+ private function __construct () {
+ // No instances from utilities classes
+ }
+
+ /**
+ * @brief Transform a remote URL into a local one.
+ *
+ * This function only performs the URL replacement on http URL and if the
+ * provided URL isn't local, "the isn't deactivated" (sic) and if the config
+ * system.proxy_disabled is set to false.
+ *
+ * @param string $url The URL to proxyfy
+ * @param bool $writemode Returns a local path the remote URL should be saved to
+ * @param string $size One of the ProxyUtils::SIZE_* constants
+ *
+ * @return string The proxyfied URL or relative path
+ */
+ public static function proxifyUrl($url, $writemode = false, $size = '')
+ {
+ // Get application instance
+ $a = BaseObject::getApp();
+
+ // Trim URL first
+ $url = trim($url);
+
+ // Is no http in front of it?
+ /// @TODO To weak test for being a valid URL
+ if (substr($url, 0, 4) !== 'http') {
+ return $url;
+ }
+
+ // Only continue if it isn't a local image and the isn't deactivated
+ if (self::isLocalImage($url)) {
+ $url = str_replace(normalise_link(System::baseUrl()) . '/', System::baseUrl() . '/', $url);
+ return $url;
+ }
+
+ // Is the proxy disabled?
+ if (Config::get('system', 'proxy_disabled')) {
+ return $url;
+ }
+
+ // Image URL may have encoded ampersands for display which aren't desirable for proxy
+ $url = html_entity_decode($url, ENT_NOQUOTES, 'utf-8');
+
+ // Creating a sub directory to reduce the amount of files in the cache directory
+ $basepath = $a->get_basepath() . '/proxy';
+
+ $shortpath = hash('md5', $url);
+ $longpath = substr($shortpath, 0, 2);
+
+ if (is_dir($basepath) && $writemode && !is_dir($basepath . '/' . $longpath)) {
+ mkdir($basepath . '/' . $longpath);
+ chmod($basepath . '/' . $longpath, 0777);
+ }
+
+ $longpath .= '/' . strtr(base64_encode($url), '+/', '-_');
+
+ // Extract the URL extension
+ $extension = pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_EXTENSION);
+
+ if (in_array($extension, self::$extensions)) {
+ $shortpath .= '.' . $extension;
+ $longpath .= '.' . $extension;
+ }
+
+ $proxypath = System::baseUrl() . '/proxy/' . $longpath;
+
+ if ($size != '') {
+ $size = ':' . $size;
+ }
+
+ // Too long files aren't supported by Apache
+ // Writemode in combination with long files shouldn't be possible
+ if ((strlen($proxypath) > 250) && $writemode) {
+ return $shortpath;
+ } elseif (strlen($proxypath) > 250) {
+ return System::baseUrl() . '/proxy/' . $shortpath . '?url=' . urlencode($url);
+ } elseif ($writemode) {
+ return $longpath;
+ } else {
+ return $proxypath . $size;
+ }
+ }
+
+ /**
+ * @brief "Proxifies" HTML code's image tags
+ *
+ * "Proxifies", means replaces image URLs in given HTML code with those from
+ * proxy storage directory.
+ *
+ * @param string $html Un-proxified HTML code
+ *
+ * @return string Proxified HTML code
+ */
+ public static function proxifyHtml($html)
+ {
+ $html = str_replace(normalise_link(System::baseUrl()) . '/', System::baseUrl() . '/', $html);
+
+ return preg_replace_callback('/(<img [^>]*src *= *["\'])([^"\']+)(["\'][^>]*>)/siU', 'self::replaceUrl', $html);
+ }
+
+ /**
+ * @brief Checks if the URL is a local URL.
+ *
+ * @param string $url
+ * @return boolean
+ */
+ private static function isLocalImage($url)
+ {
+ if (substr($url, 0, 1) == '/') {
+ return true;
+ }
+
+ if (strtolower(substr($url, 0, 5)) == 'data:') {
+ return true;
+ }
+
+ // links normalised - bug #431
+ $baseurl = normalise_link(System::baseUrl());
+ $url = normalise_link($url);
+
+ return (substr($url, 0, strlen($baseurl)) == $baseurl);
+ }
+
+ /**
+ * @brief Return the array of query string parameters from a URL
+ *
+ * @param string $url URL to parse
+ * @return array Associative array of query string parameters
+ */
+ private static function parseQuery($url)
+ {
+ $query = parse_url($url, PHP_URL_QUERY);
+ $query = html_entity_decode($query);
+ $query_list = explode('&', $query);
+
+ $arr = [];
+
+ foreach ($query_list as $key_value) {
+ $key_value_list = explode('=', $key_value);
+ $arr[$key_value_list[0]] = $key_value_list[1];
+ }
+
+ unset($url, $query_list, $url);
+
+ return $arr;
+ }
+
+ /**
+ * @brief Call-back method to replace the UR
+ *
+ * @param array $matches Matches from preg_replace_callback()
+ * @return string Proxified HTML image tag
+ */
+ private static function replaceUrl(array $matches)
+ {
+ // if the picture seems to be from another picture cache then take the original source
+ $queryvar = self::parseQuery($matches[2]);
+
+ if (!empty($queryvar['url']) && substr($queryvar['url'], 0, 4) == 'http') {
+ $matches[2] = urldecode($queryvar['url']);
+ }
+
+ // Following line changed per bug #431
+ if (self::isLocalImage($matches[2])) {
+ return $matches[1] . $matches[2] . $matches[3];
+ }
+
+ // Return proxified HTML
+ return $matches[1] . self::proxifyUrl(htmlspecialchars_decode($matches[2])) . $matches[3];
+ }
+
+}
use Friendica\Core\Cache;
use Friendica\Core\Config;
use Friendica\Database\DBA;
+use Friendica\Database\PostUpdate;
use Friendica\Model\Contact;
use Friendica\Model\GContact;
use Friendica\Model\Photo;
use Friendica\Model\User;
use Friendica\Network\Probe;
use Friendica\Protocol\PortableContact;
-use Friendica\Database\PostUpdate;
+use Friendica\Util\Proxy as ProxyUtils;
require_once 'include/dba.php';
require_once 'mod/nodeinfo.php';
clear_cache($a->get_basepath(), $a->get_basepath() . "/proxy");
$cachetime = Config::get('system', 'proxy_cache_time');
+
if (!$cachetime) {
- $cachetime = PROXY_DEFAULT_TIME;
+ $cachetime = ProxyUtils::DEFAULT_TIME;
}
+
$condition = ['`uid` = 0 AND `resource-id` LIKE "pic:%" AND `created` < NOW() - INTERVAL ? SECOND', $cachetime];
DBA::delete('photo', $condition);
}
use Friendica\Database\DBA;
use Friendica\Model\Contact;
use Friendica\Model\GContact;
-
-require_once "mod/proxy.php";
+use Friendica\Util\Proxy as ProxyUtils;
function vier_init(App $a)
{
$entry = replace_macros($tpl, [
'$id' => $rr['id'],
'$profile_link' => 'follow/?url='.urlencode($rr['url']),
- '$photo' => proxy_url($rr['photo'], false, PROXY_SIZE_MICRO),
+ '$photo' => ProxyUtils::proxifyUrl($rr['photo'], false, ProxyUtils::SIZE_MICRO),
'$alt_text' => $rr['name'],
]);
$aside['$comunity_profiles_items'][] = $entry;
'name' => $contact['name'],
'cid' => $contact['id'],
'selected' => $selected,
- 'micro' => System::removedBaseUrl(proxy_url($contact['micro'], false, PROXY_SIZE_MICRO)),
+ 'micro' => System::removedBaseUrl(ProxyUtils::proxifyUrl($contact['micro'], false, ProxyUtils::SIZE_MICRO)),
'id' => ++$id,
];
$entries[] = $entry;