From d4a2f6e313f08167ab39f500024593c3e2b4aa5c Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 24 Jan 2016 10:18:45 +0100 Subject: Compatibility PHP 5.2 with array_replace_recursive https://github.com/FreshRSS/FreshRSS/issues/1055 https://github.com/FreshRSS/FreshRSS/pull/926 https://github.com/FreshRSS/FreshRSS/issues/923 --- lib/lib_rss.php | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'lib') diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 2a23fca45..4852f7217 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -15,6 +15,35 @@ if (!function_exists('json_encode')) { } } +if (!function_exists('array_replace_recursive')) { + function array_replace_recursive($array, $array1) { //http://php.net/manual/function.array-replace-recursive.php#92574 + function recurse($array, $array1) { + foreach ($array1 as $key => $value) { + if (!isset($array[$key]) || (isset($array[$key]) && !is_array($array[$key]))) { + $array[$key] = array(); //create new key in $array, if it is empty or not an array + } + if (is_array($value)) { + $value = recurse($array[$key], $value); // overwrite the value in the base array + } + $array[$key] = $value; + } + return $array; + } + // handle the arguments, merge one by one + $args = func_get_args(); + $array = $args[0]; + if (!is_array($array)) { + return $array; + } + for ($i = 1; $i < count($args); $i++) { + if (is_array($args[$i])) { + $array = recurse($array, $args[$i]); + } + } + return $array; + } +} + /** * Build a directory path by concatenating a list of directory names. * -- cgit v1.2.3 From af942739137cd1c95c052157c1f44ea6d605f4c3 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Mon, 25 Jan 2016 21:05:35 +0100 Subject: More PHP 5.2 install compatibility https://github.com/FreshRSS/FreshRSS/issues/1055 --- app/install.php | 6 +++--- lib/lib_rss.php | 24 ++++++++++++------------ 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'lib') diff --git a/app/install.php b/app/install.php index 83526b60c..7ac1c4cec 100644 --- a/app/install.php +++ b/app/install.php @@ -130,7 +130,7 @@ function saveStep2() { $_SESSION['mail_login'] = filter_var(param('mail_login', ''), FILTER_VALIDATE_EMAIL); $password_plain = param('passwordPlain', false); - if ($password_plain !== false) { + if ($password_plain !== false && cryptAvailable()) { if (!function_exists('password_hash')) { include_once(LIB_PATH . '/password_compat.php'); } @@ -681,10 +681,10 @@ function printStep2() { } $auth_type = isset($_SESSION['auth_type']) ? $_SESSION['auth_type'] : ''; ?> - + - + diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 4852f7217..457fada3d 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -16,19 +16,19 @@ if (!function_exists('json_encode')) { } if (!function_exists('array_replace_recursive')) { - function array_replace_recursive($array, $array1) { //http://php.net/manual/function.array-replace-recursive.php#92574 - function recurse($array, $array1) { - foreach ($array1 as $key => $value) { - if (!isset($array[$key]) || (isset($array[$key]) && !is_array($array[$key]))) { - $array[$key] = array(); //create new key in $array, if it is empty or not an array - } - if (is_array($value)) { - $value = recurse($array[$key], $value); // overwrite the value in the base array - } - $array[$key] = $value; + function arr_recurse($array, $array1) { + foreach ($array1 as $key => $value) { + if (!isset($array[$key]) || (isset($array[$key]) && !is_array($array[$key]))) { + $array[$key] = array(); //create new key in $array, if it is empty or not an array } - return $array; + if (is_array($value)) { + $value = arr_recurse($array[$key], $value); // overwrite the value in the base array + } + $array[$key] = $value; } + return $array; + } + function array_replace_recursive($array, $array1) { //http://php.net/manual/function.array-replace-recursive.php#92574 // handle the arguments, merge one by one $args = func_get_args(); $array = $args[0]; @@ -37,7 +37,7 @@ if (!function_exists('array_replace_recursive')) { } for ($i = 1; $i < count($args); $i++) { if (is_array($args[$i])) { - $array = recurse($array, $args[$i]); + $array = arr_recurse($array, $args[$i]); } } return $array; -- cgit v1.2.3 From dfd0b9e9355c1e44e72b95583dd5e730f0ad5230 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Tue, 26 Jan 2016 19:34:23 +0100 Subject: Note about PHP 5.2 https://github.com/FreshRSS/FreshRSS/issues/1055 --- lib/lib_rss.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 457fada3d..b0189c162 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -15,7 +15,7 @@ if (!function_exists('json_encode')) { } } -if (!function_exists('array_replace_recursive')) { +if (!function_exists('array_replace_recursive')) { //PHP 5.2 function arr_recurse($array, $array1) { foreach ($array1 as $key => $value) { if (!isset($array[$key]) || (isset($array[$key]) && !is_array($array[$key]))) { -- cgit v1.2.3 From e4a459a6edc40b64cba7845b52f3e90666b2818a Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Tue, 16 Feb 2016 23:53:39 +0100 Subject: CSP no inline javascript draft https://github.com/FreshRSS/FreshRSS/issues/1075 --- app/FreshRSS.php | 62 +++++++++++++++++++++++++++++ app/layout/layout.phtml | 6 +-- app/views/helpers/javascript_vars.phtml | 70 --------------------------------- lib/Minz/Session.php | 15 ++++--- p/scripts/main.js | 13 +++++- p/scripts/persona.js | 2 +- 6 files changed, 87 insertions(+), 81 deletions(-) delete mode 100644 app/views/helpers/javascript_vars.phtml (limited to 'lib') diff --git a/app/FreshRSS.php b/app/FreshRSS.php index 044de9cd4..e0e82457c 100644 --- a/app/FreshRSS.php +++ b/app/FreshRSS.php @@ -110,6 +110,68 @@ class FreshRSS extends Minz_FrontController { } } + private static function setJavascriptCookie() { + $mark = FreshRSS_Context::$user_conf->mark_when; + $mail = Minz_Session::param('mail', false); + $s = FreshRSS_Context::$user_conf->shortcuts; + $json = json_encode(array( + 'context' => array( + 'auto_remove_article' => !!FreshRSS_Context::isAutoRemoveAvailable(), + 'hide_posts' => !(FreshRSS_Context::$user_conf->display_posts || Minz_Request::actionName() === 'reader'), + 'display_order' => Minz_Request::param('order', FreshRSS_Context::$user_conf->sort_order), + 'auto_mark_article' => !!$mark['article'], + 'auto_mark_site' => !!$mark['site'], + 'auto_mark_scroll' => !!$mark['scroll'], + 'auto_load_more' => !!FreshRSS_Context::$user_conf->auto_load_more, + 'auto_actualize_feeds' => !!Minz_Session::param('actualize_feeds', false), + 'does_lazyload' => !!FreshRSS_Context::$user_conf->lazyload , + 'sticky_post' => !!FreshRSS_Context::isStickyPostEnabled(), + 'html5_notif_timeout' => FreshRSS_Context::$user_conf->html5_notif_timeout, + 'auth_type' => FreshRSS_Context::$system_conf->auth_type, + 'current_user_mail' => $mail ? ('"' . $mail . '"') : null, + 'current_view' => Minz_Request::actionName(), + ), + 'shortcuts' => array( + 'mark_read' => @$s['mark_read'], + 'mark_favorite' => @$s['mark_favorite'], + 'go_website' => @$s['go_website'], + 'prev_entry' => @$s['prev_entry'], + 'next_entry' => @$s['next_entry'], + 'first_entry' => @$s['first_entry'], + 'last_entry' => @$s['last_entry'], + 'collapse_entry' => @$s['collapse_entry'], + 'load_more' => @$s['load_more'], + 'auto_share' => @$s['auto_share'], + 'focus_search' => @$s['focus_search'], + 'user_filter' => @$s['user_filter'], + 'help' => @$s['help'], + 'close_dropdown' => @$s['close_dropdown'], + ), + 'url' => array( + 'index' => _url('index', 'index'), + 'login' => Minz_Url::display(array('c' => 'auth', 'a' => 'login'), 'php'), + 'logout' => Minz_Url::display(array('c' => 'auth', 'a' => 'logout'), 'php'), + 'help' => FRESHRSS_WIKI, + ), + 'i18n' => array( + 'confirmation_default' => _t('gen.js.confirm_action'), + 'notif_title_articles' => _t('gen.js.feedback.title_new_articles'), + 'notif_body_articles' => _t('gen.js.feedback.body_new_articles'), + 'notif_request_failed' => _t('gen.js.feedback.request_failed'), + 'category_empty' => _t('gen.js.category_empty'), + ), + 'icons' => array( + 'close' => _i('close'), + ), + ), JSON_UNESCAPED_UNICODE); + setrawcookie('FreshRSS-vars', rawurlencode($json), 0, Minz_Session::getCookieDir()); + } + + public static function preLayout() { + header("Content-Security-Policy: default-src 'self'; img-src * data:; media-src *; style-src 'self' 'unsafe-inline'"); + self::setJavascriptCookie(); + } + private function loadNotifications() { $notif = Minz_Session::param('notification'); if ($notif) { diff --git a/app/layout/layout.phtml b/app/layout/layout.phtml index 1d3afbf71..7d718efbd 100644 --- a/app/layout/layout.phtml +++ b/app/layout/layout.phtml @@ -1,3 +1,6 @@ + @@ -5,9 +8,6 @@ - mark_when; -$mail = Minz_Session::param('mail', false); -$auto_actualize = Minz_Session::param('actualize_feeds', false); -$hide_posts = !(FreshRSS_Context::$user_conf->display_posts || Minz_Request::actionName() === 'reader'); -$s = FreshRSS_Context::$user_conf->shortcuts; - -$url_login = Minz_Url::display(array( - 'c' => 'auth', - 'a' => 'login' -), 'php'); -$url_logout = Minz_Url::display(array( - 'c' => 'auth', - 'a' => 'logout' -), 'php'); - -echo 'var context={', - 'auto_remove_article:', FreshRSS_Context::isAutoRemoveAvailable() ? 'true' : 'false', ',', - 'hide_posts:', $hide_posts ? 'true' : 'false', ',', - 'display_order:"', Minz_Request::param('order', FreshRSS_Context::$user_conf->sort_order), '",', - 'auto_mark_article:', $mark['article'] ? 'true' : 'false', ',', - 'auto_mark_site:', $mark['site'] ? 'true' : 'false', ',', - 'auto_mark_scroll:', $mark['scroll'] ? 'true' : 'false', ',', - 'auto_load_more:', FreshRSS_Context::$user_conf->auto_load_more ? 'true' : 'false', ',', - 'auto_actualize_feeds:', $auto_actualize ? 'true' : 'false', ',', - 'does_lazyload:', FreshRSS_Context::$user_conf->lazyload ? 'true' : 'false', ',', - 'sticky_post:', FreshRSS_Context::isStickyPostEnabled() ? 'true' : 'false', ',', - 'html5_notif_timeout:', FreshRSS_Context::$user_conf->html5_notif_timeout, ',', - 'auth_type:"', FreshRSS_Context::$system_conf->auth_type, '",', - 'current_user_mail:', $mail ? ('"' . $mail . '"') : 'null', ',', - 'current_view:"', Minz_Request::actionName(), '"', -"},\n"; - -echo 'shortcuts={', - 'mark_read:"', @$s['mark_read'], '",', - 'mark_favorite:"', @$s['mark_favorite'], '",', - 'go_website:"', @$s['go_website'], '",', - 'prev_entry:"', @$s['prev_entry'], '",', - 'next_entry:"', @$s['next_entry'], '",', - 'first_entry:"', @$s['first_entry'], '",', - 'last_entry:"', @$s['last_entry'], '",', - 'collapse_entry:"', @$s['collapse_entry'], '",', - 'load_more:"', @$s['load_more'], '",', - 'auto_share:"', @$s['auto_share'], '",', - 'focus_search:"', @$s['focus_search'], '",', - 'user_filter:"', @$s['user_filter'], '",', - 'help:"', @$s['help'], '",', - 'close_dropdown:"', @$s['close_dropdown'], '"', -"},\n"; - -echo 'url={', - 'index:"', _url('index', 'index'), '",', - 'login:"', $url_login, '",', - 'logout:"', $url_logout, '",', - 'help:"', FRESHRSS_WIKI, '"', -"},\n"; - -echo 'i18n={', - 'confirmation_default:"', _t('gen.js.confirm_action'), '",', - 'notif_title_articles:"', _t('gen.js.feedback.title_new_articles'), '",', - 'notif_body_articles:"', _t('gen.js.feedback.body_new_articles'), '",', - 'notif_request_failed:"', _t('gen.js.feedback.request_failed'), '",', - 'category_empty:"', _t('gen.js.category_empty'), '"', -"},\n"; - -echo 'icons={', - 'close:\'', _i('close'), '\'', -"}\n"; \ No newline at end of file diff --git a/lib/Minz/Session.php b/lib/Minz/Session.php index 057e7746a..940cd27d9 100644 --- a/lib/Minz/Session.php +++ b/lib/Minz/Session.php @@ -59,18 +59,21 @@ class Minz_Session { } } + public static function getCookieDir() { + // Get the script_name (e.g. /p/i/index.php) and keep only the path. + $cookie_dir = empty($_SERVER['REQUEST_URI']) ? '/' : $_SERVER['REQUEST_URI']; + if (substr($cookie_dir, -1) !== '/') { + $cookie_dir = dirname($cookie_dir) . '/'; + } + return $cookie_dir; + } /** * Spécifie la durée de vie des cookies * @param $l la durée de vie */ public static function keepCookie($l) { - // Get the script_name (e.g. /p/i/index.php) and keep only the path. - $cookie_dir = empty($_SERVER['REQUEST_URI']) ? '/' : $_SERVER['REQUEST_URI']; - if (substr($cookie_dir, -1) !== '/') { - $cookie_dir = dirname($cookie_dir) . '/'; - } - session_set_cookie_params($l, $cookie_dir, '', false, true); + session_set_cookie_params($l, self::getCookieDir(), '', false, true); } diff --git a/p/scripts/main.js b/p/scripts/main.js index 968c945c8..32a2ca913 100644 --- a/p/scripts/main.js +++ b/p/scripts/main.js @@ -1245,8 +1245,19 @@ function init_configuration_alert() { }); } +function parseJavaScriptCookie() { + var json = JSON.parse(decodeURIComponent(document.cookie.replace(/(?:(?:^|.*;\s*)FreshRSS-vars\s*\=\s*([^;]*).*$)|^.*$/, "$1"))) || {}; + document.cookie = 'FreshRSS-vars=; expires=Thu, 01 Jan 1970 00:00:00 GMT'; + window.context = json.context; + window.shortcuts = json.shortcuts; + window.url = json.url; + window.i18n = json.i18n; + window.icons = json.icons; +} + function init_all() { - if (!(window.$ && window.context)) { + parseJavaScriptCookie(); + if (!window.$) { if (window.console) { console.log('FreshRSS waiting for JS…'); } diff --git a/p/scripts/persona.js b/p/scripts/persona.js index 36aeeaf56..63ab43795 100644 --- a/p/scripts/persona.js +++ b/p/scripts/persona.js @@ -1,7 +1,7 @@ "use strict"; function init_persona() { - if (!(navigator.id && window.$)) { + if (!(navigator.id && window.$ && window.url)) { if (window.console) { console.log('FreshRSS (Persona) waiting for JS…'); } -- cgit v1.2.3 From 86e113ba80c395b60fc016228b11dd56636a85d7 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Wed, 17 Feb 2016 00:19:49 +0100 Subject: Filter-out img srcset for the time being https://github.com/FreshRSS/FreshRSS/issues/1077 --- lib/lib_rss.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/lib_rss.php b/lib/lib_rss.php index b0189c162..e7e59fe65 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -209,7 +209,7 @@ function customSimplePie() { $simplePie->strip_attributes(array_merge($simplePie->strip_attributes, array( 'autoplay', 'onload', 'onunload', 'onclick', 'ondblclick', 'onmousedown', 'onmouseup', 'onmouseover', 'onmousemove', 'onmouseout', 'onfocus', 'onblur', - 'onkeypress', 'onkeydown', 'onkeyup', 'onselect', 'onchange', 'seamless'))); + 'onkeypress', 'onkeydown', 'onkeyup', 'onselect', 'onchange', 'seamless', 'srcset'))); $simplePie->add_attributes(array( 'img' => array('lazyload' => '', 'postpone' => ''), //http://www.w3.org/TR/resource-priorities/ 'audio' => array('lazyload' => '', 'postpone' => '', 'preload' => 'none'), -- cgit v1.2.3 From 5a80127140f78d13f762facb4017e5ada965eca6 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 21 Feb 2016 00:36:30 +0100 Subject: Filter out img sizes https://github.com/FreshRSS/FreshRSS/issues/1077 https://github.com/FreshRSS/FreshRSS/issues/1081 --- lib/lib_rss.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/lib_rss.php b/lib/lib_rss.php index e7e59fe65..7d92b6fd7 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -209,7 +209,7 @@ function customSimplePie() { $simplePie->strip_attributes(array_merge($simplePie->strip_attributes, array( 'autoplay', 'onload', 'onunload', 'onclick', 'ondblclick', 'onmousedown', 'onmouseup', 'onmouseover', 'onmousemove', 'onmouseout', 'onfocus', 'onblur', - 'onkeypress', 'onkeydown', 'onkeyup', 'onselect', 'onchange', 'seamless', 'srcset'))); + 'onkeypress', 'onkeydown', 'onkeyup', 'onselect', 'onchange', 'seamless', 'sizes', 'srcset'))); $simplePie->add_attributes(array( 'img' => array('lazyload' => '', 'postpone' => ''), //http://www.w3.org/TR/resource-priorities/ 'audio' => array('lazyload' => '', 'postpone' => '', 'preload' => 'none'), -- cgit v1.2.3 From 83e58d375962f7bc1f30e34e2895836ddc8e80d1 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 21 Feb 2016 22:19:07 +0100 Subject: Experiment with forcing HTTPS for selected embed providers YouTube, DailyMotion, Tumblr https://github.com/FreshRSS/FreshRSS/issues/1083 --- lib/SimplePie/SimplePie/Misc.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/SimplePie/SimplePie/Misc.php b/lib/SimplePie/SimplePie/Misc.php index 9e7ac4fa8..1abfb3368 100644 --- a/lib/SimplePie/SimplePie/Misc.php +++ b/lib/SimplePie/SimplePie/Misc.php @@ -77,6 +77,15 @@ class SimplePie_Misc return $time; } + /** + * Force HTTPS for selected Web sites + * FreshRSS + */ + public static https_url($url) + { + return preg_replace('%^http://((?:[^/]*?\.)?(?:youtube|dailymotion|tumblr)\.com/)%i', '//$1', $url); + } + public static function absolutize_url($relative, $base) { if (substr($relative, 0, 2) === '//') @@ -88,7 +97,7 @@ class SimplePie_Misc { return false; } - return $iri->get_uri(); + return https_url($iri->get_uri()); } /** -- cgit v1.2.3 From bd0facbb739b7a6f90a6ff2bf7cc434bbda1cc95 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 21 Feb 2016 22:42:30 +0100 Subject: HTTPS SimplePie experiment Syntax bug https://github.com/FreshRSS/FreshRSS/issues/1083 --- lib/SimplePie/SimplePie/Misc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/SimplePie/SimplePie/Misc.php b/lib/SimplePie/SimplePie/Misc.php index 1abfb3368..4df529f59 100644 --- a/lib/SimplePie/SimplePie/Misc.php +++ b/lib/SimplePie/SimplePie/Misc.php @@ -97,7 +97,7 @@ class SimplePie_Misc { return false; } - return https_url($iri->get_uri()); + return SimplePie_Misc::https_url($iri->get_uri()); } /** -- cgit v1.2.3 From 4a9a7404bcbcc15765ae5876dfb845a34917cba4 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 21 Feb 2016 22:45:54 +0100 Subject: Syntax error --- lib/SimplePie/SimplePie/Misc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/SimplePie/SimplePie/Misc.php b/lib/SimplePie/SimplePie/Misc.php index 4df529f59..98565608f 100644 --- a/lib/SimplePie/SimplePie/Misc.php +++ b/lib/SimplePie/SimplePie/Misc.php @@ -81,7 +81,7 @@ class SimplePie_Misc * Force HTTPS for selected Web sites * FreshRSS */ - public static https_url($url) + public static function https_url($url) { return preg_replace('%^http://((?:[^/]*?\.)?(?:youtube|dailymotion|tumblr)\.com/)%i', '//$1', $url); } -- cgit v1.2.3 From 74ef8d9b1514600b4e18c0bd2f8fdbb6d9f3826c Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Mon, 22 Feb 2016 08:51:02 +0100 Subject: SimplePie force HTTPS, another approach https://github.com/FreshRSS/FreshRSS/issues/1083 --- lib/SimplePie/SimplePie/Misc.php | 2 +- lib/SimplePie/SimplePie/Sanitize.php | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/SimplePie/SimplePie/Misc.php b/lib/SimplePie/SimplePie/Misc.php index 98565608f..b13c70f4c 100644 --- a/lib/SimplePie/SimplePie/Misc.php +++ b/lib/SimplePie/SimplePie/Misc.php @@ -97,7 +97,7 @@ class SimplePie_Misc { return false; } - return SimplePie_Misc::https_url($iri->get_uri()); + return $iri->get_uri(); } /** diff --git a/lib/SimplePie/SimplePie/Sanitize.php b/lib/SimplePie/SimplePie/Sanitize.php index a6863ec03..fc916a259 100644 --- a/lib/SimplePie/SimplePie/Sanitize.php +++ b/lib/SimplePie/SimplePie/Sanitize.php @@ -451,7 +451,8 @@ class SimplePie_Sanitize if ($element->hasAttribute($attribute)) { $value = $this->registry->call('Misc', 'absolutize_url', array($element->getAttribute($attribute), $this->base)); - if ($value !== false) + $value = SimplePie_Misc::https_url($value); //FreshRSS + if ($value) { $element->setAttribute($attribute, $value); } -- cgit v1.2.3 From 0f870e800bc8a9315d572c01f2423b6c124f495f Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Mon, 22 Feb 2016 20:18:11 +0100 Subject: Avoid prototol-relative URLs Protocol-relative URLs do not seem to work well with API / mobile apps --- lib/SimplePie/SimplePie/Misc.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/SimplePie/SimplePie/Misc.php b/lib/SimplePie/SimplePie/Misc.php index 98565608f..1505f775f 100644 --- a/lib/SimplePie/SimplePie/Misc.php +++ b/lib/SimplePie/SimplePie/Misc.php @@ -83,14 +83,14 @@ class SimplePie_Misc */ public static function https_url($url) { - return preg_replace('%^http://((?:[^/]*?\.)?(?:youtube|dailymotion|tumblr)\.com/)%i', '//$1', $url); + return preg_replace('%^http://((?:[^/]*?\.)?(?:youtube|dailymotion|tumblr)\.com/)%i', 'https://$1', $url); } public static function absolutize_url($relative, $base) { if (substr($relative, 0, 2) === '//') - {//Allow protocol-relative URLs "//www.example.net" which will pick HTTP or HTTPS automatically - return $relative; + {//Protocol-relative URLs "//www.example.net" + return 'https:' . $relative; } $iri = SimplePie_IRI::absolutize(new SimplePie_IRI($base), $relative); if ($iri === false) -- cgit v1.2.3 From 9d4a4457587d04030118447847a5c99d9095b937 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Wed, 24 Feb 2016 21:08:24 +0100 Subject: Work in progress HTTPS --- data/force-https.txt | 3 +++ lib/SimplePie/SimplePie/Misc.php | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 data/force-https.txt (limited to 'lib') diff --git a/data/force-https.txt b/data/force-https.txt new file mode 100644 index 000000000..3da802d01 --- /dev/null +++ b/data/force-https.txt @@ -0,0 +1,3 @@ +dailymotion.com +tumblr.com +youtube.com diff --git a/lib/SimplePie/SimplePie/Misc.php b/lib/SimplePie/SimplePie/Misc.php index 4c9f8cff6..b9d74f894 100644 --- a/lib/SimplePie/SimplePie/Misc.php +++ b/lib/SimplePie/SimplePie/Misc.php @@ -83,7 +83,13 @@ class SimplePie_Misc */ public static function https_url($url) { - return preg_replace('%^http://((?:[^/]*?\.)?(?:youtube|dailymotion|tumblr)\.com/)%i', 'https://$1', $url); + if (strtolower(substr($url, 0, 7)) === 'http://') + { + $domain = parse_url($url, PHP_URL_HOST); + return preg_replace('%^http://((?:[^/]*?\.)?(?:youtube|dailymotion|tumblr)\.com/)%i', 'https://$1', $url); + return substr_replace($url, 's', 4, 0); //Add the 's' to HTTPS + } + return $url; } public static function absolutize_url($relative, $base) -- cgit v1.2.3 From 9adbd2ba9bfe885a4ccf4ec6ad99929e89cf6fb6 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Wed, 24 Feb 2016 21:16:21 +0100 Subject: json_decode fallback debug https://github.com/FreshRSS/FreshRSS/issues/1092 --- lib/lib_rss.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 7d92b6fd7..e74b26e3f 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -1,16 +1,16 @@ decode($var)); + function json_decode($var, $assoc) { + $JSON = new Services_JSON($assoc ? SERVICES_JSON_LOOSE_TYPE : 0); + return $JSON->decode($var, $assoc); } } if (!function_exists('json_encode')) { require_once('JSON.php'); function json_encode($var) { - $JSON = new Services_JSON; + $JSON = new Services_JSON(); return $JSON->encodeUnsafe($var); } } -- cgit v1.2.3 From bd47d14a536fee657a3ba2f7cfba9921567356b2 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Wed, 24 Feb 2016 21:20:37 +0100 Subject: json_decode fallback bug 2 --- lib/lib_rss.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/lib_rss.php b/lib/lib_rss.php index e74b26e3f..a09960de0 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -1,9 +1,9 @@ decode($var, $assoc); + return $JSON->decode($var); } } -- cgit v1.2.3 From 9711f02db75006d622d75142d46c3c8d714c957f Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 28 Feb 2016 21:34:54 +0100 Subject: SimplePie Force HTTPS custom list domains Load from data/force-https.default.txt and data/force-https.txt Efficient tree structure to search the domains https://github.com/FreshRSS/FreshRSS/pull/1087 --- data/.gitignore | 1 + data/force-https.default.txt | 4 ++ data/force-https.txt | 3 -- lib/SimplePie/SimplePie.php | 14 ++++++ lib/SimplePie/SimplePie/Misc.php | 15 ------- lib/SimplePie/SimplePie/Sanitize.php | 85 +++++++++++++++++++++++++++++++++++- lib/lib_rss.php | 10 +++++ 7 files changed, 113 insertions(+), 19 deletions(-) create mode 100644 data/force-https.default.txt delete mode 100644 data/force-https.txt (limited to 'lib') diff --git a/data/.gitignore b/data/.gitignore index 20364e266..c2ed350a6 100644 --- a/data/.gitignore +++ b/data/.gitignore @@ -7,3 +7,4 @@ no-cache.txt *.lock.txt last_update.txt update.php +force-https.txt diff --git a/data/force-https.default.txt b/data/force-https.default.txt new file mode 100644 index 000000000..a1bddd549 --- /dev/null +++ b/data/force-https.default.txt @@ -0,0 +1,4 @@ +dailymotion.com +feedburner.com +tumblr.com +youtube.com diff --git a/data/force-https.txt b/data/force-https.txt deleted file mode 100644 index 3da802d01..000000000 --- a/data/force-https.txt +++ /dev/null @@ -1,3 +0,0 @@ -dailymotion.com -tumblr.com -youtube.com diff --git a/lib/SimplePie/SimplePie.php b/lib/SimplePie/SimplePie.php index 6c0962a9f..61bad4e9d 100644 --- a/lib/SimplePie/SimplePie.php +++ b/lib/SimplePie/SimplePie.php @@ -1123,6 +1123,7 @@ class SimplePie $this->strip_attributes(false); $this->add_attributes(false); $this->set_image_handler(false); + $this->set_https_domains(array()); } } @@ -1233,6 +1234,19 @@ class SimplePie $this->sanitize->set_url_replacements($element_attribute); } + /** + * Set the list of domains for which force HTTPS. + * @see SimplePie_Misc::https_url() + * FreshRSS + */ + public function set_https_domains($domains = array()) + { + if (is_array($domains)) + { + $this->sanitize->set_https_domains($domains); + } + } + /** * Set the handler to enable the display of cached images. * diff --git a/lib/SimplePie/SimplePie/Misc.php b/lib/SimplePie/SimplePie/Misc.php index b9d74f894..2d154cbcb 100644 --- a/lib/SimplePie/SimplePie/Misc.php +++ b/lib/SimplePie/SimplePie/Misc.php @@ -77,21 +77,6 @@ class SimplePie_Misc return $time; } - /** - * Force HTTPS for selected Web sites - * FreshRSS - */ - public static function https_url($url) - { - if (strtolower(substr($url, 0, 7)) === 'http://') - { - $domain = parse_url($url, PHP_URL_HOST); - return preg_replace('%^http://((?:[^/]*?\.)?(?:youtube|dailymotion|tumblr)\.com/)%i', 'https://$1', $url); - return substr_replace($url, 's', 4, 0); //Add the 's' to HTTPS - } - return $url; - } - public static function absolutize_url($relative, $base) { if (substr($relative, 0, 2) === '//') diff --git a/lib/SimplePie/SimplePie/Sanitize.php b/lib/SimplePie/SimplePie/Sanitize.php index fc916a259..b37aeec3d 100644 --- a/lib/SimplePie/SimplePie/Sanitize.php +++ b/lib/SimplePie/SimplePie/Sanitize.php @@ -73,6 +73,14 @@ class SimplePie_Sanitize var $force_fsockopen = false; var $replace_url_attributes = null; + /** + * List of domains for which force HTTPS. + * @see SimplePie_Misc::https_url() + * Array is tree split at DNS levels. Example array('biz' => true, 'com' => array('example' => true), 'example' => array('test') => array('www' => true)); + * FreshRSS + */ + var $https_domains = array('com' => array('youtube' => true)); + public function __construct() { // Set defaults @@ -242,6 +250,81 @@ class SimplePie_Sanitize $this->replace_url_attributes = (array) $element_attribute; } + /** + * Set the list of domains for which force HTTPS. + * @see SimplePie_Misc::https_url() + * Example array('biz', 'example.com', 'example.org', 'www.example.net'); + * FreshRSS + */ + public function set_https_domains($domains) + { + $this->https_domains = array(); + foreach ($domains as $domain) + { + $domain = trim($domain, ". \t\n\r\0\x0B"); + $segments = array_reverse(explode('.', $domain)); + if (count($segments) > 0) + { + $node =& $this->https_domains; + foreach ($segments as $segment) + {//Build a tree + if ($node === true) + { + break; + } + if (!isset($node[$segment])) + { + $node[$segment] = array(); + } + $node =& $node[$segment]; + } + $node = true; + } + } + } + + /** + * Check if the domain is in the list of forced HTTPS + * FreshRSS + */ + protected function is_https_domain($domain) + { + $domain = trim($domain, '. '); + $segments = array_reverse(explode('.', $domain)); + if (count($segments) > 0) + { + $node =& $this->https_domains; + foreach ($segments as $segment) + {//Explore the tree + if ($node === true) + { + return true; + } + if (isset($node[$segment])) + { + $node =& $node[$segment]; + } + else + { + break; + } + } + } + return false; + } + + /** + * Force HTTPS for selected Web sites + * FreshRSS + */ + protected function https_url($url) + { + return (strtolower(substr($url, 0, 7)) === 'http://') && + $this->is_https_domain(parse_url($url, PHP_URL_HOST)) ? + substr_replace($url, 's', 4, 0) : //Add the 's' to HTTPS + $url; + } + public function sanitize($data, $type, $base = '') { $data = trim($data); @@ -451,7 +534,7 @@ class SimplePie_Sanitize if ($element->hasAttribute($attribute)) { $value = $this->registry->call('Misc', 'absolutize_url', array($element->getAttribute($attribute), $this->base)); - $value = SimplePie_Misc::https_url($value); //FreshRSS + $value = $this->https_url($value); //FreshRSS if ($value) { $element->setAttribute($attribute, $value); diff --git a/lib/lib_rss.php b/lib/lib_rss.php index b0189c162..5092982aa 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -238,6 +238,16 @@ function customSimplePie() { 'src', ), )); + $https_domains = array(); + $force = @file(DATA_PATH . '/force-https.default.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + if (is_array($force)) { + $https_domains = array_merge($https_domains, $force); + } + $force = @file(DATA_PATH . '/force-https.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + if (is_array($force)) { + $https_domains = array_merge($https_domains, $force); + } + $simplePie->set_https_domains($https_domains); return $simplePie; } -- cgit v1.2.3 From d344da59fdd2f818f53c6b4aab4ded4a9336851c Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Mon, 29 Feb 2016 17:09:44 +0100 Subject: HTTPS search tree: simplify code https://github.com/FreshRSS/FreshRSS/issues/1083 --- data/force-https.default.txt | 2 ++ lib/SimplePie/SimplePie/Sanitize.php | 58 ++++++++++++++++-------------------- 2 files changed, 28 insertions(+), 32 deletions(-) (limited to 'lib') diff --git a/data/force-https.default.txt b/data/force-https.default.txt index a1bddd549..668a7c0e8 100644 --- a/data/force-https.default.txt +++ b/data/force-https.default.txt @@ -1,4 +1,6 @@ dailymotion.com feedburner.com +gstatic.com tumblr.com +wordpress.com youtube.com diff --git a/lib/SimplePie/SimplePie/Sanitize.php b/lib/SimplePie/SimplePie/Sanitize.php index b37aeec3d..f656909a0 100644 --- a/lib/SimplePie/SimplePie/Sanitize.php +++ b/lib/SimplePie/SimplePie/Sanitize.php @@ -263,23 +263,20 @@ class SimplePie_Sanitize { $domain = trim($domain, ". \t\n\r\0\x0B"); $segments = array_reverse(explode('.', $domain)); - if (count($segments) > 0) - { - $node =& $this->https_domains; - foreach ($segments as $segment) - {//Build a tree - if ($node === true) - { - break; - } - if (!isset($node[$segment])) - { - $node[$segment] = array(); - } - $node =& $node[$segment]; + $node =& $this->https_domains; + foreach ($segments as $segment) + {//Build a tree + if ($node === true) + { + break; + } + if (!isset($node[$segment])) + { + $node[$segment] = array(); } - $node = true; + $node =& $node[$segment]; } + $node = true; } } @@ -291,23 +288,20 @@ class SimplePie_Sanitize { $domain = trim($domain, '. '); $segments = array_reverse(explode('.', $domain)); - if (count($segments) > 0) - { - $node =& $this->https_domains; - foreach ($segments as $segment) - {//Explore the tree - if ($node === true) - { - return true; - } - if (isset($node[$segment])) - { - $node =& $node[$segment]; - } - else - { - break; - } + $node =& $this->https_domains; + foreach ($segments as $segment) + {//Explore the tree + if ($node === true) + { + return true; + } + if (isset($node[$segment])) + { + $node =& $node[$segment]; + } + else + { + break; } } return false; -- cgit v1.2.3 From 685c0ad2f8a4f6e854240d3a11415bcd62157ca4 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Mon, 29 Feb 2016 17:20:23 +0100 Subject: SimplePie HTTPS updated comments https://github.com/FreshRSS/FreshRSS/issues/1083 --- lib/SimplePie/SimplePie.php | 2 +- lib/SimplePie/SimplePie/Sanitize.php | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/SimplePie/SimplePie.php b/lib/SimplePie/SimplePie.php index 61bad4e9d..a84f6dab3 100644 --- a/lib/SimplePie/SimplePie.php +++ b/lib/SimplePie/SimplePie.php @@ -1236,7 +1236,7 @@ class SimplePie /** * Set the list of domains for which force HTTPS. - * @see SimplePie_Misc::https_url() + * @see SimplePie_Sanitize::set_https_domains() * FreshRSS */ public function set_https_domains($domains = array()) diff --git a/lib/SimplePie/SimplePie/Sanitize.php b/lib/SimplePie/SimplePie/Sanitize.php index f656909a0..09294344e 100644 --- a/lib/SimplePie/SimplePie/Sanitize.php +++ b/lib/SimplePie/SimplePie/Sanitize.php @@ -75,11 +75,12 @@ class SimplePie_Sanitize /** * List of domains for which force HTTPS. - * @see SimplePie_Misc::https_url() - * Array is tree split at DNS levels. Example array('biz' => true, 'com' => array('example' => true), 'example' => array('test') => array('www' => true)); + * @see SimplePie_Sanitize::set_https_domains() + * Array is tree split at DNS levels. Example: + * array('biz' => true, 'com' => array('example' => true), 'net' => array('example') => array('www' => true)) * FreshRSS */ - var $https_domains = array('com' => array('youtube' => true)); + var $https_domains = array('com' => array('dailymotion' => true, 'youtube' => true)); public function __construct() { -- cgit v1.2.3 From 0eef625b6d3e18d6545485d33f55865a4d6d1e3b Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Mon, 29 Feb 2016 20:38:21 +0100 Subject: SimplePie force HTTPS for enclosures https://github.com/FreshRSS/FreshRSS/issues/1083 https://github.com/FreshRSS/FreshRSS/pull/1087 --- lib/SimplePie/SimplePie/Item.php | 1 + lib/SimplePie/SimplePie/Sanitize.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/SimplePie/SimplePie/Item.php b/lib/SimplePie/SimplePie/Item.php index 27e93456e..19ba7c8f4 100644 --- a/lib/SimplePie/SimplePie/Item.php +++ b/lib/SimplePie/SimplePie/Item.php @@ -2877,6 +2877,7 @@ class SimplePie_Item $width = null; $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0])); + $url = $this->feed->sanitize->https_url($url); //FreshRSS if (isset($enclosure[0]['attribs']['']['type'])) { $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); diff --git a/lib/SimplePie/SimplePie/Sanitize.php b/lib/SimplePie/SimplePie/Sanitize.php index 09294344e..021d38539 100644 --- a/lib/SimplePie/SimplePie/Sanitize.php +++ b/lib/SimplePie/SimplePie/Sanitize.php @@ -312,7 +312,7 @@ class SimplePie_Sanitize * Force HTTPS for selected Web sites * FreshRSS */ - protected function https_url($url) + public function https_url($url) { return (strtolower(substr($url, 0, 7)) === 'http://') && $this->is_https_domain(parse_url($url, PHP_URL_HOST)) ? -- cgit v1.2.3 From c1de11f17d9103d33ddfb5cbb1d2ef35762cc57c Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Tue, 1 Mar 2016 19:14:26 +0100 Subject: SimplePie force HTTPS bug with sub-domains https://github.com/FreshRSS/FreshRSS/issues/1083 --- lib/SimplePie/SimplePie/Sanitize.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/SimplePie/SimplePie/Sanitize.php b/lib/SimplePie/SimplePie/Sanitize.php index 021d38539..6f61fedb4 100644 --- a/lib/SimplePie/SimplePie/Sanitize.php +++ b/lib/SimplePie/SimplePie/Sanitize.php @@ -305,7 +305,7 @@ class SimplePie_Sanitize break; } } - return false; + return $node === true; } /** -- cgit v1.2.3 From 9e2e5fd594bb7c03aa3d7290b93930593accb03c Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Tue, 1 Mar 2016 19:48:52 +0100 Subject: SimplePie force HTTPS simplifie code https://github.com/FreshRSS/FreshRSS/issues/1083 https://github.com/FreshRSS/FreshRSS/pull/1087 --- lib/SimplePie/SimplePie/Sanitize.php | 4 ---- 1 file changed, 4 deletions(-) (limited to 'lib') diff --git a/lib/SimplePie/SimplePie/Sanitize.php b/lib/SimplePie/SimplePie/Sanitize.php index 6f61fedb4..bdc601100 100644 --- a/lib/SimplePie/SimplePie/Sanitize.php +++ b/lib/SimplePie/SimplePie/Sanitize.php @@ -292,10 +292,6 @@ class SimplePie_Sanitize $node =& $this->https_domains; foreach ($segments as $segment) {//Explore the tree - if ($node === true) - { - return true; - } if (isset($node[$segment])) { $node =& $node[$segment]; -- cgit v1.2.3 From e265c943190ad490c6da414b1e243ade14797652 Mon Sep 17 00:00:00 2001 From: Alexis Degrugillier Date: Sun, 6 Mar 2016 14:26:20 +0100 Subject: Fix url ending --- lib/Minz/Url.php | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib') diff --git a/lib/Minz/Url.php b/lib/Minz/Url.php index 4279b045b..382437e9a 100644 --- a/lib/Minz/Url.php +++ b/lib/Minz/Url.php @@ -27,6 +27,8 @@ class Minz_Url { $url_string = Minz_Request::getBaseUrl(PUBLIC_TO_INDEX_PATH); if ($url_string === PUBLIC_TO_INDEX_PATH) { $url_string = Minz_Request::guessBaseUrl(); + } else { + $url_string .= '/'; } } else { $url_string = $isArray ? '.' : PUBLIC_RELATIVE; -- cgit v1.2.3 From 9d1f35d4b859a44964e52a377e8718113e160862 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 6 Mar 2016 17:04:21 +0100 Subject: OPML bug import not using title Fix https://github.com/FreshRSS/FreshRSS/issues/1048 --- lib/lib_opml.php | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib') diff --git a/lib/lib_opml.php b/lib/lib_opml.php index 02ae5f55c..66b854313 100644 --- a/lib/lib_opml.php +++ b/lib/lib_opml.php @@ -105,6 +105,10 @@ function libopml_parse_outline($outline_xml, $strict = true) { ); } + if (empty($outline['text']) && isset($outline['title'])) { + $outline['text'] = $outline['title']; + } + foreach ($outline_xml->children() as $key => $value) { // An outline may contain any number of outline children if ($key === 'outline') { -- cgit v1.2.3 From ba9f4461d8935bb9de256a5bedf0c89d3d317c7f Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Tue, 8 Mar 2016 19:00:04 +0100 Subject: Secure cookie HTTPS --- CHANGELOG.md | 1 + lib/Minz/Request.php | 17 ++++++++++++----- lib/Minz/Session.php | 6 +++--- 3 files changed, 16 insertions(+), 8 deletions(-) (limited to 'lib') diff --git a/CHANGELOG.md b/CHANGELOG.md index 74cb9d250..7298c4523 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * Security * Added CSP `Content-Security-Policy: default-src 'self'; child-src *; frame-src *; img-src * data:; media-src *` [#1075](https://github.com/FreshRSS/FreshRSS/issues/1075), [#1114](https://github.com/FreshRSS/FreshRSS/issues/1114) * Added `X-Content-Type-Options: nosniff` [#1116](https://github.com/FreshRSS/FreshRSS/pull/1116) + * Cookie with `Secure` tag when used over HTTPS []() * Features * New list of domains for which to force HTTPS (for images, videos, iframes…) defined in `./data/force-https.default.txt` and `./data/force-https.txt` [#1083](https://github.com/FreshRSS/FreshRSS/issues/1083) * In particular useful for privacy and to avoid mixed content errors, e.g. to see YouTube videos when FreshRSS is in HTTPS diff --git a/lib/Minz/Request.php b/lib/Minz/Request.php index effb9943c..81457df9e 100644 --- a/lib/Minz/Request.php +++ b/lib/Minz/Request.php @@ -84,6 +84,17 @@ class Minz_Request { self::magicQuotesOff(); } + /** + * Return true if the request is over HTTPS, false otherwise (HTTP) + */ + public static function isHttps() { + if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) { + return strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https'; + } else { + return isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on'; + } + } + /** * Try to guess the base URL from $_SERVER information * @@ -92,11 +103,7 @@ class Minz_Request { public static function guessBaseUrl() { $url = 'http'; - if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) { - $https = strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https'; - } else { - $https = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on'; - } + $https = self::isHttps(); if (!empty($_SERVER['HTTP_HOST'])) { $host = $_SERVER['HTTP_HOST']; diff --git a/lib/Minz/Session.php b/lib/Minz/Session.php index 940cd27d9..c94f2b646 100644 --- a/lib/Minz/Session.php +++ b/lib/Minz/Session.php @@ -73,7 +73,7 @@ class Minz_Session { * @param $l la durée de vie */ public static function keepCookie($l) { - session_set_cookie_params($l, self::getCookieDir(), '', false, true); + session_set_cookie_params($l, self::getCookieDir(), '', Minz_Request::isHttps(), true); } @@ -86,11 +86,11 @@ class Minz_Session { } public static function deleteLongTermCookie($name) { - setcookie($name, '', 1, '', '', false, true); + setcookie($name, '', 1, '', '', Minz_Request::isHttps(), true); } public static function setLongTermCookie($name, $value, $expire) { - setcookie($name, $value, $expire, '', '', false, true); + setcookie($name, $value, $expire, '', '', Minz_Request::isHttps(), true); } public static function getLongTermCookie($name) { -- cgit v1.2.3 From b042d3a7728037db90a9306c61091be0a8ac42c4 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 23 Apr 2016 19:10:32 +0200 Subject: HTTP2 optimization Fast flush HTTP headers, push promise CSS. Requires PHP 5.3+ due to anonymous function. Do not load syles, scripts, and notifications for Ajax requests. https://github.com/FreshRSS/FreshRSS/issues/1089 --- README.fr.md | 2 +- README.md | 2 +- app/Controllers/indexController.php | 64 +++++++++++++++++++------------------ app/FreshRSS.php | 37 ++++++++++----------- app/Models/Themes.php | 4 --- app/layout/layout.phtml | 40 ++++++++++++----------- lib/Minz/Request.php | 5 ++- lib/Minz/Url.php | 12 ++++--- lib/lib_rss.php | 4 +++ 9 files changed, 89 insertions(+), 81 deletions(-) (limited to 'lib') diff --git a/README.fr.md b/README.fr.md index 794b1a9e1..a173f0a75 100644 --- a/README.fr.md +++ b/README.fr.md @@ -33,7 +33,7 @@ Nous sommes une communauté amicale. * Serveur modeste, par exemple sous Linux ou Windows * Fonctionne même sur un Raspberry Pi 1 avec des temps de réponse < 1s (testé sur 150 flux, 22k articles) * Serveur Web Apache2 (recommandé), ou nginx, lighttpd (non testé sur les autres) -* PHP 5.2.1+ (PHP 5.3.7+ recommandé, et PHP 5.5+ pour les performances) (support bêta de PHP 7 avec encore meilleures performances) +* PHP 5.3+ (PHP 5.3.7+ recommandé, et PHP 5.5+ pour les performances, et PHP 7+ pour d’encore meilleures performances) * Requis : [PDO_MySQL](http://php.net/pdo-mysql) ou [PDO_SQLite](http://php.net/pdo-sqlite), [cURL](http://php.net/curl), [GMP](http://php.net/gmp) (pour accès API sur plateformes < 64 bits), [IDN](http://php.net/intl.idn) (pour les noms de domaines internationalisés) * Recommandés : [iconv](http://php.net/iconv), [JSON](http://php.net/json), [mbstring](http://php.net/mbstring), [Zip](http://php.net/zip), [zlib](http://php.net/zlib) * Inclus par défaut : [DOM](http://php.net/dom), [XML](http://php.net/xml)… diff --git a/README.md b/README.md index 728204a38..4d3bb5c4c 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ We are a friendly community. * Light server running Linux or Windows * It even works on Raspberry Pi 1 with response time under a second (tested with 150 feeds, 22k articles) * A web server: Apache2 (recommended), nginx, lighttpd (not tested on others) -* PHP 5.2.1+ (PHP 5.3.7+ recommended, and PHP 5.5+ for performance) (beta support for PHP 7 with even higher performance) +* PHP 5.3+ (PHP 5.3.7+ recommended, and PHP 5.5+ for performance, and PHP 7 for even higher performance) * Required extensions: [PDO_MySQL](http://php.net/pdo-mysql) or [PDO_SQLite](http://php.net/pdo-sqlite), [cURL](http://php.net/curl), [GMP](http://php.net/gmp) (for API access on platforms < 64 bits), [IDN](http://php.net/intl.idn) (for Internationalized Domain Names) * Recommended extensions: [iconv](http://php.net/iconv), [JSON](http://php.net/json), [mbstring](http://php.net/mbstring), [Zip](http://php.net/zip), [zlib](http://php.net/zlib) * Enabled by default: [DOM](http://php.net/dom), [XML](http://php.net/xml)… diff --git a/app/Controllers/indexController.php b/app/Controllers/indexController.php index baaf99065..7e626720e 100755 --- a/app/Controllers/indexController.php +++ b/app/Controllers/indexController.php @@ -32,42 +32,44 @@ class FreshRSS_index_Controller extends Minz_ActionController { Minz_Error::error(404); } - try { - $entries = $this->listEntriesByContext(); - - $nb_entries = count($entries); - if ($nb_entries > FreshRSS_Context::$number) { - // We have more elements for pagination - $last_entry = array_pop($entries); - FreshRSS_Context::$next_id = $last_entry->id(); - } + $this->view->callbackBeforeContent = function() { + try { + $entries = $this->listEntriesByContext(); + + $nb_entries = count($entries); + if ($nb_entries > FreshRSS_Context::$number) { + // We have more elements for pagination + $last_entry = array_pop($entries); + FreshRSS_Context::$next_id = $last_entry->id(); + } - $first_entry = $nb_entries > 0 ? $entries[0] : null; - FreshRSS_Context::$id_max = $first_entry === null ? - (time() - 1) . '000000' : - $first_entry->id(); - if (FreshRSS_Context::$order === 'ASC') { - // In this case we do not know but we guess id_max - $id_max = (time() - 1) . '000000'; - if (strcmp($id_max, FreshRSS_Context::$id_max) > 0) { - FreshRSS_Context::$id_max = $id_max; + $first_entry = $nb_entries > 0 ? $entries[0] : null; + FreshRSS_Context::$id_max = $first_entry === null ? + (time() - 1) . '000000' : + $first_entry->id(); + if (FreshRSS_Context::$order === 'ASC') { + // In this case we do not know but we guess id_max + $id_max = (time() - 1) . '000000'; + if (strcmp($id_max, FreshRSS_Context::$id_max) > 0) { + FreshRSS_Context::$id_max = $id_max; + } } - } - $this->view->entries = $entries; - } catch (FreshRSS_EntriesGetter_Exception $e) { - Minz_Log::notice($e->getMessage()); - Minz_Error::error(404); - } + $this->view->entries = $entries; + } catch (FreshRSS_EntriesGetter_Exception $e) { + Minz_Log::notice($e->getMessage()); + Minz_Error::error(404); + } - $this->view->categories = FreshRSS_Context::$categories; + $this->view->categories = FreshRSS_Context::$categories; - $this->view->rss_title = FreshRSS_Context::$name . ' | ' . Minz_View::title(); - $title = FreshRSS_Context::$name; - if (FreshRSS_Context::$get_unread > 0) { - $title = '(' . FreshRSS_Context::$get_unread . ') ' . $title; - } - Minz_View::prependTitle($title . ' · '); + $this->view->rss_title = FreshRSS_Context::$name . ' | ' . Minz_View::title(); + $title = FreshRSS_Context::$name; + if (FreshRSS_Context::$get_unread > 0) { + $title = '(' . FreshRSS_Context::$get_unread . ') ' . $title; + } + Minz_View::prependTitle($title . ' · '); + }; } /** diff --git a/app/FreshRSS.php b/app/FreshRSS.php index bafa970da..562d8e2cd 100644 --- a/app/FreshRSS.php +++ b/app/FreshRSS.php @@ -34,7 +34,7 @@ class FreshRSS extends Minz_FrontController { // Auth has to be initialized before using currentUser session parameter // because it's this part which create this parameter. - $this->initAuth(); + self::initAuth(); // Then, register the user configuration and use the configuration setter // created above. @@ -46,10 +46,7 @@ class FreshRSS extends Minz_FrontController { // Finish to initialize the other FreshRSS / Minz components. FreshRSS_Context::init(); - $this->initI18n(); - FreshRSS_Share::load(join_path(DATA_PATH, 'shares.php')); - $this->loadStylesAndScripts(); - $this->loadNotifications(); + self::initI18n(); // Enable extensions for the current (logged) user. if (FreshRSS_Auth::hasAccess()) { $ext_list = FreshRSS_Context::$user_conf->extensions_enabled; @@ -57,7 +54,7 @@ class FreshRSS extends Minz_FrontController { } } - private function initAuth() { + private static function initAuth() { FreshRSS_Auth::init(); if (Minz_Request::isPost() && !is_referer_from_same_domain()) { // Basic protection against XSRF attacks @@ -74,12 +71,12 @@ class FreshRSS extends Minz_FrontController { } } - private function initI18n() { + private static function initI18n() { Minz_Session::_param('language', FreshRSS_Context::$user_conf->language); Minz_Translate::init(FreshRSS_Context::$user_conf->language); } - private function loadStylesAndScripts() { + private static function loadStylesAndScripts() { $theme = FreshRSS_Themes::load(FreshRSS_Context::$user_conf->theme); if ($theme) { foreach($theme['files'] as $file) { @@ -91,9 +88,9 @@ class FreshRSS extends Minz_FrontController { $filename = $file; } $filetime = @filemtime(PUBLIC_PATH . '/themes/' . $theme_id . '/' . $filename); - Minz_View::appendStyle(Minz_Url::display( - '/themes/' . $theme_id . '/' . $filename . '?' . $filetime - )); + $url = '/themes/' . $theme_id . '/' . $filename . '?' . $filetime; + header('Link: <' . Minz_Url::display($url, '', 'root') . '>;rel=preload', false); //HTTP2 + Minz_View::appendStyle(Minz_Url::display($url)); } } @@ -110,6 +107,14 @@ class FreshRSS extends Minz_FrontController { } } + private static function loadNotifications() { + $notif = Minz_Session::param('notification'); + if ($notif) { + Minz_View::_param('notification', $notif); + Minz_Session::_param('notification'); + } + } + public static function preLayout() { switch (Minz_Request::controllerName()) { case 'index': @@ -123,13 +128,9 @@ class FreshRSS extends Minz_FrontController { break; } header("X-Content-Type-Options: nosniff"); - } - private function loadNotifications() { - $notif = Minz_Session::param('notification'); - if ($notif) { - Minz_View::_param('notification', $notif); - Minz_Session::_param('notification'); - } + FreshRSS_Share::load(join_path(DATA_PATH, 'shares.php')); + self::loadStylesAndScripts(); + self::loadNotifications(); } } diff --git a/app/Models/Themes.php b/app/Models/Themes.php index e3b260261..5a6ec0a05 100644 --- a/app/Models/Themes.php +++ b/app/Models/Themes.php @@ -116,7 +116,3 @@ class FreshRSS_Themes extends Minz_Model { '' . $alts[$name] . ''; } } - -function _i($icon, $url_only = false) { - return FreshRSS_Themes::icon($icon, $url_only); -} diff --git a/app/layout/layout.phtml b/app/layout/layout.phtml index 99a3717bc..6906fa05f 100644 --- a/app/layout/layout.phtml +++ b/app/layout/layout.phtml @@ -1,17 +1,32 @@ - + - + + + + + + + + + + + +callbackBeforeContent)) { + call_user_func($this->callbackBeforeContent); + } +?> + - - - rss_title)) { + } if (isset($this->rss_title)) { $url_rss = $url_base; $url_rss['a'] = 'rss'; ?> - - - - - - - - - - -allow_robots) { ?> +allow_robots) { ?> diff --git a/lib/Minz/Request.php b/lib/Minz/Request.php index 81457df9e..f80b707d6 100644 --- a/lib/Minz/Request.php +++ b/lib/Minz/Request.php @@ -137,12 +137,11 @@ class Minz_Request { /** * Return the base_url from configuration and add a suffix if given. * - * @param $base_url_suffix a string to add at base_url (default: empty string) * @return the base_url with a suffix. */ - public static function getBaseUrl($base_url_suffix = '') { + public static function getBaseUrl() { $conf = Minz_Configuration::get('system'); - $url = rtrim($conf->base_url, '/\\') . $base_url_suffix; + $url = rtrim($conf->base_url, '/\\'); return filter_var($url, FILTER_SANITIZE_URL); } diff --git a/lib/Minz/Url.php b/lib/Minz/Url.php index 382437e9a..c7c67123e 100644 --- a/lib/Minz/Url.php +++ b/lib/Minz/Url.php @@ -24,11 +24,15 @@ class Minz_Url { $url_string = ''; if ($absolute) { - $url_string = Minz_Request::getBaseUrl(PUBLIC_TO_INDEX_PATH); - if ($url_string === PUBLIC_TO_INDEX_PATH) { + $url_string = Minz_Request::getBaseUrl(); + if ($url_string == '') { $url_string = Minz_Request::guessBaseUrl(); - } else { - $url_string .= '/'; + } + if ($isArray) { + $url_string .= PUBLIC_TO_INDEX_PATH; + } + if ($absolute === 'root') { + $url_string = parse_url($url_string, PHP_URL_PATH); } } else { $url_string = $isArray ? '.' : PUBLIC_RELATIVE; diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 135115ea5..f89baf9b1 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -548,3 +548,7 @@ function base64url_encode($data) { function base64url_decode($data) { return base64_decode(strtr($data, '-_', '+/')); } + +function _i($icon, $url_only = false) { + return FreshRSS_Themes::icon($icon, $url_only); +} -- cgit v1.2.3 From f3696784ea0acd15a11a4ca193abe623fd77dc33 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 23 Apr 2016 21:35:09 +0200 Subject: Favicon array bug Case problem and isset check --- lib/Favicon/DataAccess.php | 3 ++- lib/Favicon/Favicon.php | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/Favicon/DataAccess.php b/lib/Favicon/DataAccess.php index 2bfdf640e..17f26b333 100644 --- a/lib/Favicon/DataAccess.php +++ b/lib/Favicon/DataAccess.php @@ -15,7 +15,8 @@ class DataAccess { public function retrieveHeader($url) { $this->set_context(); - return @get_headers($url, TRUE); + $headers = @get_headers($url, 1); + return array_change_key_case($headers); } public function saveCache($file, $data) { diff --git a/lib/Favicon/Favicon.php b/lib/Favicon/Favicon.php index 7ea6ccf16..1912050d6 100644 --- a/lib/Favicon/Favicon.php +++ b/lib/Favicon/Favicon.php @@ -99,7 +99,7 @@ class Favicon switch ($status) { case '301': case '302': - $url = $headers['Location']; + $url = isset($headers['location']) ? $headers['location'] : ''; break; default: $loop = FALSE; -- cgit v1.2.3 From 8ae96d000a56021cadb0265fe127563a414687ca Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 30 Apr 2016 23:53:23 +0200 Subject: SimplePie trim https://github.com/FreshRSS/FreshRSS/issues/1142 --- lib/SimplePie/SimplePie.php | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/SimplePie/SimplePie.php b/lib/SimplePie/SimplePie.php index a84f6dab3..8af55c9fd 100644 --- a/lib/SimplePie/SimplePie.php +++ b/lib/SimplePie/SimplePie.php @@ -1668,6 +1668,7 @@ class SimplePie $locate = null; } + $file->body = trim($file->body); $this->raw_data = $file->body; $this->permanent_url = $file->permanent_url; $headers = $file->headers; -- cgit v1.2.3