From 5e9c60752c9a40e1540de50d02e19ba1d06e5491 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 1 Feb 2014 12:23:12 +0100 Subject: Actualize : Tolère PHP lancé en CGI plutôt que CLI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Corrige https://github.com/marienfressinaud/FreshRSS/issues/405 + Message d'erreur en cas de problème de droits dans ./data/ (par exemple si le cron utilise un mauvais utilisateur) --- app/actualize_script.php | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'app/actualize_script.php') diff --git a/app/actualize_script.php b/app/actualize_script.php index 9ac80a852..bef9bd218 100755 --- a/app/actualize_script.php +++ b/app/actualize_script.php @@ -8,7 +8,10 @@ if (file_exists($lock) && ((time() - @filemtime($lock)) > 3600)) { } if (($handle = @fopen($lock, 'x')) === false) { syslog(LOG_NOTICE, 'FreshRSS actualize already running?'); - fwrite(STDERR, 'FreshRSS actualize already running?' . "\n"); + if (defined('STDERR')) { + fwrite(STDERR, 'FreshRSS actualize already running?' . "\n"); + } + echo 'FreshRSS actualize already running?', "\n"; return; } register_shutdown_function('unlink', $lock); @@ -32,7 +35,9 @@ $users = array_unique($users); foreach ($users as $myUser) { syslog(LOG_INFO, 'FreshRSS actualize ' . $myUser); - fwrite(STDOUT, 'Actualize ' . $myUser . "...\n"); //Unbuffered + if (defined('STDOUT')) { + fwrite(STDOUT, 'Actualize ' . $myUser . "...\n"); //Unbuffered + } echo $myUser, ' '; //Buffered $_GET['c'] = 'feed'; @@ -44,16 +49,26 @@ foreach ($users as $myUser) { $freshRSS = new FreshRSS(); $freshRSS->_useOb(false); + Minz_Configuration::_authType('none'); + Minz_Session::init('FreshRSS'); Minz_Session::_param('currentUser', $myUser); $freshRSS->init(); $freshRSS->run(); - invalidateHttpCache(); + if (!invalidateHttpCache()) { + syslog(LOG_NOTICE, 'FreshRSS write access problem in ' . LOG_PATH . '/*.log!'); + if (defined('STDERR')) { + fwrite(STDERR, 'Write access problem in ' . LOG_PATH . '/*.log!' . "\n"); + } + } Minz_Session::unset_session(true); Minz_ModelPdo::clean(); } syslog(LOG_INFO, 'FreshRSS actualize done.'); +if (defined('STDOUT')) { + fwrite(STDOUT, 'Done.' . "\n"); +} +echo 'End.', "\n"; ob_end_flush(); -fwrite(STDOUT, 'Done.' . "\n"); -- cgit v1.2.3 From 0cabd1f50dd7d1cf0941a50139e6fbeed6825b4d Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Tue, 11 Feb 2014 21:48:10 +0100 Subject: Mutex par flux pour les actualisations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Contribue à https://github.com/marienfressinaud/FreshRSS/issues/351 Nouvelle constante TMP_PATH comme répertoire pour stocker des fichiers temporaires (si possible en mémoire et non sur disque, tel tmpfs pour /tmp sur certaines distributions Linux) Requiert PHP 5.2.1+ (contre 5.2.0 auparavant) pour le `sys_get_temp_dir()` --- README.md | 2 +- app/Controllers/feedController.php | 5 +++++ app/Models/Feed.php | 18 ++++++++++++++++++ app/actualize_script.php | 19 ------------------- constants.php | 2 ++ p/i/install.php | 5 +++-- 6 files changed, 29 insertions(+), 22 deletions(-) (limited to 'app/actualize_script.php') diff --git a/README.md b/README.md index 247d08799..1ed6d8f82 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Privilégiez pour cela des demandes sur GitHub * Serveur modeste, par exemple sous Linux ou Windows * Fonctionne même sur un Raspberry Pi avec des temps de réponse < 1s (testé sur 150 flux, 22k articles, soit 32Mo de données partiellement compressées) * Serveur Web Apache2 ou Nginx (non testé sur les autres) -* PHP 5.2+ (PHP 5.3.7+ recommandé) +* PHP 5.2.1+ (PHP 5.3.7+ recommandé) * Requis : [PDO_MySQL](http://php.net/pdo-mysql), [cURL](http://php.net/curl), [LibXML](http://php.net/xml), [PCRE](http://php.net/pcre), [ctype](http://php.net/ctype) * Recommandés : [JSON](http://php.net/json), [zlib](http://php.net/zlib), [mbstring](http://php.net/mbstring), [iconv](http://php.net/iconv) * MySQL 5.0.3+ (ou SQLite 3.7.4+ à venir) diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index 55e8f76cf..61bfc5919 100755 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -189,6 +189,10 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $flux_update = 0; $is_read = $this->view->conf->mark_when['reception'] ? 1 : 0; foreach ($feeds as $feed) { + if (!$feed->lock()) { + Minz_Log::record('Feed already being actualized: ' . $feed->url(), Minz_Log::NOTICE); + continue; + } try { $url = $feed->url(); $feedHistory = $feed->keepHistory(); @@ -251,6 +255,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $feedDAO->updateLastUpdate ($feed->id (), 1); } + $feed->unlock(); unset($feed); // On arrête à 10 flux pour ne pas surcharger le serveur diff --git a/app/Models/Feed.php b/app/Models/Feed.php index e94ae2b3a..73f9c32fb 100644 --- a/app/Models/Feed.php +++ b/app/Models/Feed.php @@ -281,4 +281,22 @@ class FreshRSS_Feed extends Minz_Model { $this->entries = $entries; } + + function lock() { + $lock = TMP_PATH . '/' . md5(Minz_Configuration::salt() . $this->url) . '.freshrss.lock'; + if (file_exists($lock) && ((time() - @filemtime($lock)) > 3600)) { + @unlink($lock); + } + if (($handle = @fopen($lock, 'x')) === false) { + return false; + } + //register_shutdown_function('unlink', $lock); + @fclose($handle); + return true; + } + + function unlock() { + $lock = TMP_PATH . '/' . md5(Minz_Configuration::salt() . $this->url) . '.freshrss.lock'; + @unlink($lock); + } } diff --git a/app/actualize_script.php b/app/actualize_script.php index bef9bd218..8d81e0189 100755 --- a/app/actualize_script.php +++ b/app/actualize_script.php @@ -1,24 +1,5 @@ -$lock = DATA_PATH . '/actualize.lock.txt'; -if (file_exists($lock) && ((time() - @filemtime($lock)) > 3600)) { - @unlink($lock); -} -if (($handle = @fopen($lock, 'x')) === false) { - syslog(LOG_NOTICE, 'FreshRSS actualize already running?'); - if (defined('STDERR')) { - fwrite(STDERR, 'FreshRSS actualize already running?' . "\n"); - } - echo 'FreshRSS actualize already running?', "\n"; - return; -} -register_shutdown_function('unlink', $lock); -//Could use http://php.net/function.pcntl-signal.php to catch interruptions -@fclose($handle); -// - require(LIB_PATH . '/lib_rss.php'); //Includes class autoloader session_cache_limiter(''); diff --git a/constants.php b/constants.php index a7c96f47b..4818f1565 100644 --- a/constants.php +++ b/constants.php @@ -15,3 +15,5 @@ define('FRESHRSS_PATH', dirname(__FILE__)); define('LIB_PATH', FRESHRSS_PATH . '/lib'); define('APP_PATH', FRESHRSS_PATH . '/app'); + +define('TMP_PATH', sys_get_temp_dir()); diff --git a/p/i/install.php b/p/i/install.php index bb49e3fdb..4b0b1d194 100644 --- a/p/i/install.php +++ b/p/i/install.php @@ -548,8 +548,9 @@ function checkStep0 () { 'all' => $language ? 'ok' : 'ko' ); } + function checkStep1 () { - $php = version_compare (PHP_VERSION, '5.2.0') >= 0; + $php = version_compare (PHP_VERSION, '5.2.1') >= 0; $minz = file_exists (LIB_PATH . '/Minz'); $curl = extension_loaded ('curl'); $pdo = extension_loaded ('pdo_mysql'); @@ -721,7 +722,7 @@ function printStep1 () {

-

+

-- cgit v1.2.3 From 5081ffaf39699398f83be97e47b72444e5bcd5d1 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 22 Mar 2014 17:56:07 +0100 Subject: Minz: remove one layer of ob_ (experimental) https://github.com/marienfressinaud/FreshRSS/issues/303#issuecomment-38351311 https://github.com/marienfressinaud/FreshRSS/issues/163 * Remove Minz_Response (not needed anymore) * Move Minz_Request::reseted to Minz_Dispatcher::reset() --- app/Controllers/importExportController.php | 14 ++---- app/actualize_script.php | 1 - lib/Minz/Dispatcher.php | 73 +++++++++++++----------------- lib/Minz/Error.php | 32 +++++++++---- lib/Minz/FrontController.php | 16 +------ lib/Minz/Request.php | 5 +- lib/Minz/Response.php | 60 ------------------------ lib/Minz/View.php | 10 ++++ lib/lib_rss.php | 2 +- 9 files changed, 73 insertions(+), 140 deletions(-) delete mode 100644 lib/Minz/Response.php (limited to 'app/actualize_script.php') diff --git a/app/Controllers/importExportController.php b/app/Controllers/importExportController.php index 458814676..f697f4c9e 100644 --- a/app/Controllers/importExportController.php +++ b/app/Controllers/importExportController.php @@ -65,7 +65,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { $export_all = Minz_Request::param('export_all', false); // code from https://stackoverflow.com/questions/1061710/php-zip-files-on-the-fly - $file = tempnam("tmp", "zip"); + $file = tempnam('tmp', 'zip'); $zip = new ZipArchive(); $zip->open($file, ZipArchive::OVERWRITE); @@ -101,17 +101,11 @@ class FreshRSS_importExport_Controller extends Minz_ActionController { } $this->view->categories = $list; - - // TODO: add a parameter to renderHelper in order to get a variable - ob_start(); - $this->view->renderHelper('export/opml'); - return ob_get_clean(); + return $this->view->helperToString('export/opml'); } private function generate_articles($type) { - // TODO: same here + we should get articles according to $type - ob_start(); - $this->view->renderHelper('export/articles'); - return ob_get_clean(); + // TODO: we should get articles according to $type + return $this->view->helperToString('export/articles'); } } diff --git a/app/actualize_script.php b/app/actualize_script.php index 8d81e0189..4c306b8da 100755 --- a/app/actualize_script.php +++ b/app/actualize_script.php @@ -28,7 +28,6 @@ foreach ($users as $myUser) { $_SERVER['HTTP_HOST'] = ''; $freshRSS = new FreshRSS(); - $freshRSS->_useOb(false); Minz_Configuration::_authType('none'); diff --git a/lib/Minz/Dispatcher.php b/lib/Minz/Dispatcher.php index 819f4cd5c..ca1fd1f5c 100644 --- a/lib/Minz/Dispatcher.php +++ b/lib/Minz/Dispatcher.php @@ -14,6 +14,7 @@ class Minz_Dispatcher { /* singleton */ private static $instance = null; + private static $needsReset; private $router; private $controller; @@ -40,44 +41,36 @@ class Minz_Dispatcher { * Remplit le body de Response à partir de la Vue * @exception Minz_Exception */ - public function run ($ob = true) { - // Le ob_start est dupliqué : sans ça il y a un bug sous Firefox - // ici on l'appelle avec 'ob_gzhandler', après sans. - // Vraisemblablement la compression fonctionne mais c'est sale - // J'ignore les effets de bord :( - if ($ob) { - ob_start ('ob_gzhandler'); - } - - $text = ''; //TODO: Clean this code - while (Minz_Request::$reseted) { - Minz_Request::$reseted = false; + public function run () { + do { + self::$needsReset = false; try { $this->createController ('FreshRSS_' . Minz_Request::controllerName () . '_Controller'); $this->controller->init (); $this->controller->firstAction (); - $this->launchAction ( - Minz_Request::actionName () - . 'Action' - ); + if (!self::$needsReset) { + $this->launchAction ( + Minz_Request::actionName () + . 'Action' + ); + } $this->controller->lastAction (); - if (!Minz_Request::$reseted) { - if ($ob) { - ob_start (); - } - $this->controller->view ()->build (); - if ($ob) { - $text = ob_get_clean(); - } + if (!self::$needsReset) { + echo $this->controller->view ()->build (); } } catch (Minz_Exception $e) { throw $e; } - } + } while (self::$needsReset); + } - Minz_Response::setBody ($text); + /** + * Informe le contrôleur qu'il doit recommancer car la requête a été modifiée + */ + public static function reset() { + self::$needsReset = true; } /** @@ -114,21 +107,19 @@ class Minz_Dispatcher { * le controller */ private function launchAction ($action_name) { - if (!Minz_Request::$reseted) { - if (!is_callable (array ( - $this->controller, - $action_name - ))) { - throw new Minz_ActionException ( - get_class ($this->controller), - $action_name, - Minz_Exception::ERROR - ); - } - call_user_func (array ( - $this->controller, - $action_name - )); + if (!is_callable (array ( + $this->controller, + $action_name + ))) { + throw new Minz_ActionException ( + get_class ($this->controller), + $action_name, + Minz_Exception::ERROR + ); } + call_user_func (array ( + $this->controller, + $action_name + )); } } diff --git a/lib/Minz/Error.php b/lib/Minz/Error.php index 337ab6c0a..c8222a430 100644 --- a/lib/Minz/Error.php +++ b/lib/Minz/Error.php @@ -23,13 +23,32 @@ class Minz_Error { $logs = self::processLogs ($logs); $error_filename = APP_PATH . '/Controllers/errorController.php'; + switch ($code) { + case 200 : + header('HTTP/1.1 200 OK'); + break; + case 403 : + header('HTTP/1.1 403 Forbidden'); + break; + case 404 : + header('HTTP/1.1 404 Not Found'); + break; + case 500 : + header('HTTP/1.1 500 Internal Server Error'); + break; + case 503 : + header('HTTP/1.1 503 Service Unavailable'); + break; + default : + header('HTTP/1.1 500 Internal Server Error'); + } + if (file_exists ($error_filename)) { $params = array ( 'code' => $code, 'logs' => $logs ); - Minz_Response::setHeader ($code); if ($redirect) { Minz_Request::forward (array ( 'c' => 'error' @@ -41,19 +60,16 @@ class Minz_Error { ), false); } } else { - $text = '

An error occured

'."\n"; + echo '

An error occured

' . "\n"; if (!empty ($logs)) { - $text .= '
    '."\n"; + echo '
      ' . "\n"; foreach ($logs as $log) { - $text .= '
    • ' . $log . '
    • '."\n"; + echo '
    • ' . $log . '
    • ' . "\n"; } - $text .= '
    '."\n"; + echo '
' . "\n"; } - Minz_Response::setHeader ($code); - Minz_Response::setBody ($text); - Minz_Response::send (); exit (); } } diff --git a/lib/Minz/FrontController.php b/lib/Minz/FrontController.php index 80eda8877..3e50db1cf 100644 --- a/lib/Minz/FrontController.php +++ b/lib/Minz/FrontController.php @@ -26,8 +26,6 @@ class Minz_FrontController { protected $dispatcher; protected $router; - private $useOb = true; - /** * Constructeur * Initialise le router et le dispatcher @@ -63,8 +61,7 @@ class Minz_FrontController { */ public function run () { try { - $this->dispatcher->run ($this->useOb); - Minz_Response::send (); + $this->dispatcher->run(); } catch (Minz_Exception $e) { try { Minz_Log::record ($e->getMessage (), Minz_Log::ERROR); @@ -96,15 +93,4 @@ class Minz_FrontController { } exit ('### Application problem ###
'."\n".$txt); } - - public function useOb() { - return $this->useOb; - } - - /** - * Use ob_start('ob_gzhandler') or not. - */ - public function _useOb($ob) { - return $this->useOb = (bool)$ob; - } } diff --git a/lib/Minz/Request.php b/lib/Minz/Request.php index 282d47a77..7e3c59990 100644 --- a/lib/Minz/Request.php +++ b/lib/Minz/Request.php @@ -15,8 +15,6 @@ class Minz_Request { private static $default_controller_name = 'index'; private static $default_action_name = 'index'; - public static $reseted = true; - /** * Getteurs */ @@ -137,14 +135,13 @@ class Minz_Request { header ('Location: ' . Minz_Url::display ($url, 'php')); exit (); } else { - self::$reseted = true; - self::_controllerName ($url['c']); self::_actionName ($url['a']); self::_params (array_merge ( self::$params, $url['params'] )); + Minz_Dispatcher::reset(); } } diff --git a/lib/Minz/Response.php b/lib/Minz/Response.php deleted file mode 100644 index f8ea3d946..000000000 --- a/lib/Minz/Response.php +++ /dev/null @@ -1,60 +0,0 @@ - -*/ - -/** - * Response représente la requête http renvoyée à l'utilisateur - */ -class Minz_Response { - private static $header = 'HTTP/1.0 200 OK'; - private static $body = ''; - - /** - * Mets à jour le body de la Response - * @param $text le texte à incorporer dans le body - */ - public static function setBody ($text) { - self::$body = $text; - } - - /** - * Mets à jour le header de la Response - * @param $code le code HTTP, valeurs possibles - * - 200 (OK) - * - 403 (Forbidden) - * - 404 (Forbidden) - * - 500 (Forbidden) -> par défaut si $code erroné - * - 503 (Forbidden) - */ - public static function setHeader ($code) { - switch ($code) { - case 200 : - self::$header = 'HTTP/1.0 200 OK'; - break; - case 403 : - self::$header = 'HTTP/1.0 403 Forbidden'; - break; - case 404 : - self::$header = 'HTTP/1.0 404 Not Found'; - break; - case 500 : - self::$header = 'HTTP/1.0 500 Internal Server Error'; - break; - case 503 : - self::$header = 'HTTP/1.0 503 Service Unavailable'; - break; - default : - self::$header = 'HTTP/1.0 500 Internal Server Error'; - } - } - - /** - * Envoie la Response à l'utilisateur - */ - public static function send () { - header (self::$header); - echo self::$body; - } -} diff --git a/lib/Minz/View.php b/lib/Minz/View.php index e170bd406..00d9a1a6d 100644 --- a/lib/Minz/View.php +++ b/lib/Minz/View.php @@ -102,6 +102,16 @@ class Minz_View { } } + /** + * Retourne renderHelper() dans une chaîne + * @param $helper l'élément à traîter + */ + public function helperToString($helper) { + ob_start(); + renderHelper($helper); + return ob_get_clean(); + } + /** * Permet de choisir si on souhaite utiliser le layout * @param $use true si on souhaite utiliser le layout, false sinon diff --git a/lib/lib_rss.php b/lib/lib_rss.php index 83edbf015..2077fe63f 100644 --- a/lib/lib_rss.php +++ b/lib/lib_rss.php @@ -27,7 +27,7 @@ function classAutoloader($class) { include(APP_PATH . '/Models/' . $components[1] . '.php'); return; case 3: //Controllers, Exceptions - include(APP_PATH . '/' . $components[2] . 's/' . $components[1] . $components[2] . '.php'); + @include(APP_PATH . '/' . $components[2] . 's/' . $components[1] . $components[2] . '.php'); return; } } elseif (strpos($class, 'Minz') === 0) { -- cgit v1.2.3