/** * Read session data from the database to return into the $_SESSION global. * Verifies against a number of parameters for security purposes. * * @param string $session_id The id generated by PHP for the session. * @return string The retrieved session. */ public static function read( $session_id ) { $remote_address = Utils::get_ip(); // not always set, even by real browsers $user_agent = isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : ''; $session = DB::get_row( 'SELECT * FROM {sessions} WHERE token = ?', array( $session_id ) ); // Verify session exists if ( !$session ) { self::$initial_data = false; return false; } $dodelete = false; if ( !defined( 'SESSION_SKIP_SUBNET' ) || SESSION_SKIP_SUBNET != true ) { // Verify on the same subnet $subnet = self::get_subnet( $remote_address ); if ( $session->ip != $subnet ) { $dodelete = true; } } // Verify expiry if ( HabariDateTime::date_create()->int > $session->expires ) { Session::error( _t( 'Your session expired.' ), 'expired_session' ); $dodelete = true; } // Verify User Agent if ( $user_agent != $session->ua ) { $dodelete = true; } // Let plugins ultimately decide $dodelete = Plugins::filter( 'session_read', $dodelete, $session, $session_id ); if ( $dodelete ) { $sql = 'DELETE FROM {sessions} WHERE token = ?'; $args = array( $session_id ); $sql = Plugins::filter( 'sessions_clean', $sql, 'read', $args ); DB::query( $sql, $args ); return false; } // Do garbage collection, since PHP is bad at it $probability = ini_get( 'session.gc_probability' ); // Allow plugins to control the probability of a gc event, return >=100 to always collect garbage $probability = Plugins::filter( 'session_gc_probability', ( is_numeric( $probability ) && $probability > 0 ) ? $probability : 1 ); if ( rand( 1, 100 ) <= $probability ) { self::gc( self::$lifetime ); } // save the initial data we loaded so we can write only if it's changed self::$initial_data = $session->data; // but if the expiration is close (less than half the session lifetime away), null it out so the session always gets written so we extend the session if ( ( $session->expires - HabariDateTime::date_create()->int ) < ( self::$lifetime / 2 ) ) { self::$initial_data = null; } return $session->data; }
/** * Read session data from the database to return into the $_SESSION global. * Verifies against a number of parameters for security purposes. * * @param string $session_id The id generated by PHP for the session. * @return string The retrieved session. */ static function read($session_id) { // for offline testing $remote_address = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '127.0.0.1'; // not always set, even by real browsers $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''; $session = DB::get_row('SELECT * FROM {sessions} WHERE token = ?', array($session_id)); // Verify session exists if (!$session) { self::$initial_data = false; return false; } $dodelete = false; if (!defined('SESSION_SKIP_SUBNET') || SESSION_SKIP_SUBNET != true) { // Verify on the same subnet $subnet = self::get_subnet($remote_address); if ($session->subnet != $subnet) { $dodelete = true; } } // Verify expiry if (HabariDateTime::date_create(time())->int > $session->expires) { Session::error(_t('Your session expired.'), 'expired_session'); $dodelete = true; } // Verify User Agent if ($user_agent != $session->ua) { $dodelete = true; } // Let plugins ultimately decide $dodelete = Plugins::filter('session_read', $dodelete, $session, $session_id); if ($dodelete) { $sql = 'DELETE FROM {sessions} WHERE token = ?'; $args = array($session_id); $sql = Plugins::filter('sessions_clean', $sql, 'read', $args); DB::query($sql, $args); return false; } // Do garbage collection, since PHP is bad at it $probability = ini_get('session.gc_probability'); // Allow plugins to control the probability of a gc event, return >=100 to always collect garbage $probability = Plugins::filter('gc_probability', is_numeric($probability) && $probability > 0 ? $probability : 1); if (rand(1, 100) <= $probability) { self::gc(ini_get('session.gc_maxlifetime')); } // Throttle session writes, so as to not hammer the DB self::$initial_data = ini_get('session.gc_maxlifetime') - $session->expires + HabariDateTime::date_create(time())->int < 120 ? $session->data : FALSE; return $session->data; }