Merge #1615 선택적 세션 시작 (Proof of Concept) by kijin

* pr/1615:
  Force start session if SSO is used
  Improve and simplify session status detection
  Improve handling of session variables related to validator
  Start session automatically if an addon uses the session and exits
  If cache-friendly behavior is enabled, don't skip updateReadedCount()
  If cache-friendly behavior is enabled, don't update session when reading document or comment
  Add option to enable/disable cache-friendly behavior
  Improve the setCacheControl() method
  Context::setCacheControl() method added etc.
  do not always set mobile/user-agent cookies
  선택적 세션 시작 + 서드파티 자료 호환성 (Proof of Concept)
This commit is contained in:
Kijin Sung 2015-10-08 15:03:17 +09:00
commit 9364563f4a
13 changed files with 160 additions and 38 deletions

View file

@ -333,8 +333,29 @@ class Context
);
}
if($sess = $_POST[session_name()]) session_id($sess);
session_start();
// start session if it was previously started
$session_name = session_name();
$session_id = NULL;
if($session_id = $_POST[$session_name])
{
session_id($session_id);
}
else
{
$session_id = $_COOKIE[$session_name];
}
if($session_id !== NULL || $this->db_info->cache_friendly != 'Y')
{
$this->setCacheControl(0, false);
session_start();
}
else
{
$this->setCacheControl(-1, true);
register_shutdown_function(array($this, 'checkSessionStatus'));
$_SESSION = array();
}
// set authentication information in Context and session
if(self::isInstalled())
@ -420,6 +441,38 @@ class Context
}
}
/**
* Get the session status
*
* @return bool
*/
function getSessionStatus()
{
return (session_id() !== '');
}
/**
* Start the session if $_SESSION was touched
*
* @return void
*/
function checkSessionStatus($force_start = false)
{
is_a($this, 'Context') ? $self = $this : $self = self::getInstance();
if($self->getSessionStatus())
{
return;
}
if($force_start || (count($_SESSION) && !headers_sent()))
{
$tempSession = $_SESSION;
unset($_SESSION);
session_start();
$_SESSION = $tempSession;
}
}
/**
* Finalize using resources, such as DB connection
*
@ -430,6 +483,30 @@ class Context
session_write_close();
}
/**
* set Cache-Control header
*
* @return void
*/
function setCacheControl($ttl = 0, $public = true)
{
if($ttl == 0)
{
header('Cache-Control: ' . ($public ? 'public, ' : 'private, ') . 'must-revalidate, post-check=0, pre-check=0, no-store, no-cache');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
}
elseif($ttl == -1)
{
header('Cache-Control: ' . ($public ? 'public, ' : 'private, ') . 'must-revalidate, post-check=0, pre-check=0');
}
else
{
header('Cache-Control: ' . ($public ? 'public, ' : 'private, ') . 'must-revalidate, max-age=' . (int)$ttl);
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + (int)$ttl) . ' GMT');
}
}
/**
* Load the database information
*
@ -664,6 +741,7 @@ class Context
{
if(self::get('default_url'))
{
$this->checkSessionStatus(true);
$url = base64_decode(self::get('default_url'));
$url_info = parse_url($url);
@ -953,7 +1031,10 @@ class Context
$self->lang_type = $lang_type;
$self->set('lang_type', $lang_type);
$_SESSION['lang_type'] = $lang_type;
if($self->getSessionStatus())
{
$_SESSION['lang_type'] = $lang_type;
}
}
/**

View file

@ -78,6 +78,9 @@ class DisplayHandler extends Handler
$handler->prepareToPrint($output);
}
// Start the session if $_SESSION was touched
Context::getInstance()->checkSessionStatus();
// header output
$httpStatusCode = $oModule->getHttpStatusCode();
@ -321,11 +324,6 @@ class DisplayHandler extends Handler
function _printXMLHeader()
{
header("Content-Type: text/xml; charset=UTF-8");
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
}
/**
@ -335,11 +333,6 @@ class DisplayHandler extends Handler
function _printHTMLHeader()
{
header("Content-Type: text/html; charset=UTF-8");
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
}
/**
@ -349,11 +342,6 @@ class DisplayHandler extends Handler
function _printJSONHeader()
{
header("Content-Type: text/html; charset=UTF-8");
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
}
/**

View file

@ -123,13 +123,13 @@ class Mobile
setcookie("mobile", 'true', 0, $xe_web_path);
}
}
elseif($_COOKIE['mobile'] != 'false')
elseif(isset($_COOKIE['mobile']) && $_COOKIE['mobile'] != 'false')
{
$_COOKIE['mobile'] = 'false';
setcookie("mobile", 'false', 0, $xe_web_path);
}
if($_COOKIE['user-agent'] != md5($_SERVER['HTTP_USER_AGENT']))
if(isset($_COOKIE['mobile']) && $_COOKIE['user-agent'] != md5($_SERVER['HTTP_USER_AGENT']))
{
setcookie("user-agent", md5($_SERVER['HTTP_USER_AGENT']), 0, $xe_web_path);
}

View file

@ -729,15 +729,23 @@ class ModuleHandler extends Handler
}
$_SESSION['XE_VALIDATOR_ERROR'] = $error;
$_SESSION['XE_VALIDATOR_ID'] = Context::get('xe_validator_id');
if($error != 0)
{
$_SESSION['XE_VALIDATOR_ERROR'] = $error;
}
if($validator_id = Context::get('xe_validator_id'))
{
$_SESSION['XE_VALIDATOR_ID'] = $validator_id;
}
if($message != 'success')
{
$_SESSION['XE_VALIDATOR_MESSAGE'] = $message;
}
$_SESSION['XE_VALIDATOR_MESSAGE_TYPE'] = $messageType;
if(Context::get('xeVirtualRequestMethod') != 'xml')
if($messageType != 'info')
{
$_SESSION['XE_VALIDATOR_MESSAGE_TYPE'] = $messageType;
}
if(Context::get('xeVirtualRequestMethod') != 'xml' && $redirectUrl)
{
$_SESSION['XE_VALIDATOR_RETURN_URL'] = $redirectUrl;
}
@ -787,12 +795,12 @@ class ModuleHandler extends Handler
* */
function _clearErrorSession()
{
$_SESSION['XE_VALIDATOR_ERROR'] = '';
$_SESSION['XE_VALIDATOR_MESSAGE'] = '';
$_SESSION['XE_VALIDATOR_MESSAGE_TYPE'] = '';
$_SESSION['XE_VALIDATOR_RETURN_URL'] = '';
$_SESSION['XE_VALIDATOR_ID'] = '';
$_SESSION['INPUT_ERROR'] = '';
unset($_SESSION['XE_VALIDATOR_ERROR']);
unset($_SESSION['XE_VALIDATOR_MESSAGE']);
unset($_SESSION['XE_VALIDATOR_MESSAGE_TYPE']);
unset($_SESSION['XE_VALIDATOR_RETURN_URL']);
unset($_SESSION['XE_VALIDATOR_ID']);
unset($_SESSION['INPUT_ERROR']);
}
/**
@ -846,6 +854,7 @@ class ModuleHandler extends Handler
$display_handler = new DisplayHandler();
$display_handler->_debugOutput();
Context::getInstance()->checkSessionStatus();
header('location:' . $_SESSION['XE_VALIDATOR_RETURN_URL']);
return;
}

View file

@ -80,6 +80,7 @@ class addonController extends addon
{
// Add-on module for use in creating the cache file
$buff = array('<?php if(!defined("__XE__")) exit();', '$_m = Context::get(\'mid\');');
$buff[] = 'ob_start();';
$oAddonModel = getAdminModel('addon');
$addon_list = $oAddonModel->getInsertedAddons($site_srl, $gtype);
foreach($addon_list as $addon => $val)
@ -135,6 +136,7 @@ class addonController extends addon
$buff[] = '$addon_time_log->called_extension = "' . $addon . '";';
$buff[] = 'writeSlowlog("addon",$after_time-$before_time,$addon_time_log);';
}
$buff[] = 'ob_end_flush();';
$addon_path = _XE_PATH_ . 'files/cache/addons/';
FileHandler::makeDir($addon_path);
$addon_file = $addon_path . ($gtype == 'site' ? $site_srl : '') . $type . '.acivated_addons.cache.php';

View file

@ -71,6 +71,7 @@ class adminAdminView extends admin
Context::set('use_html5', $db_info->use_html5 == 'Y' ? 'Y' : 'N');
Context::set('use_spaceremover', $db_info->use_spaceremover ? $db_info->use_spaceremover : 'Y'); //not use
Context::set('qmail_compatibility', $db_info->qmail_compatibility == 'Y' ? 'Y' : 'N');
Context::set('cache_friendly', $db_info->cache_friendly == 'Y' ? 'Y' : 'N');
Context::set('use_db_session', $db_info->use_db_session == 'N' ? 'N' : 'Y');
Context::set('use_mobile_view', $db_info->use_mobile_view == 'Y' ? 'Y' : 'N');
Context::set('use_ssl', $db_info->use_ssl ? $db_info->use_ssl : "none");

View file

@ -760,6 +760,18 @@
<value xml:lang="zh-CN"><![CDATA[启用Qmail]]></value>
<value xml:lang="tr"><![CDATA[Qmail etkinleştirin]]></value>
</item>
<item name="cache_friendly">
<value xml:lang="ko"><![CDATA[캐싱 최적화]]></value>
<value xml:lang="en"><![CDATA[Optimize for caching]]></value>
<value xml:lang="jp"><![CDATA[キャッシュに最適化]]></value>
<value xml:lang="zh-CN"><![CDATA[优化缓存]]></value>
<value xml:lang="tr"><![CDATA[Önbelleğe alma optimize]]></value>
</item>
<item name="about_cache_friendly">
<value xml:lang="ko"><![CDATA[Varnish 등의 캐싱 서버 사용시 성능 개선을 위해, 로그인하지 않은 사용자에게는 인증 세션을 부여하지 않습니다.<br>이 옵션을 선택할 경우 방문자 수 및 조회수 집계가 정확하지 않을 수 있습니다.]]></value>
<value xml:lang="en"><![CDATA[To improve performance when using a caching server such as Varnish, do not issue sessions to visitors until they log in.<br>Selecting this option may cause view counts and visitor counts to become inaccurate.]]></value>
<value xml:lang="jp"><![CDATA[Varnishなどのキャッシュサーバ使用時のパフォーマンスを向上させるために、ログインしていないユーザーには、認証セッションを付与しません。<br>このオプションを選択した場合、訪問者数とヒット集計が正確でない場合があります。]]></value>
</item>
<item name="sftp">
<value xml:lang="ko"><![CDATA[SFTP 사용]]></value>
<value xml:lang="en"><![CDATA[Use SFTP]]></value>

View file

@ -225,6 +225,15 @@
<label for="qmail_compatibility_n" class="x_inline"><input type="radio" name="qmail_compatibility" id="qmail_compatibility_n" value="N" checked="checked"|cond="$qmail_compatibility!='Y'" /> {$lang->cmd_no}</label>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->cache_friendly}</label>
<div class="x_controls">
<label for="cache_friendly_y" class="x_inline"><input type="radio" name="cache_friendly" id="cache_friendly_y" value="Y" checked="checked"|cond="$cache_friendly=='Y'" /> {$lang->cmd_yes}</label>
<label for="cache_friendly_n" class="x_inline"><input type="radio" name="cache_friendly" id="cache_friendly_n" value="N" checked="checked"|cond="$cache_friendly!='Y'" /> {$lang->cmd_no}</label>
<br />
<p class="x_help-block">{$lang->about_cache_friendly}</p>
</div>
</div>
<div class="x_clearfix btnArea">
<div class="x_pull-right">
<button type="submit" class="x_btn x_btn-primary">{$lang->cmd_save}</button>

View file

@ -131,7 +131,10 @@ class commentItem extends Object
function setAccessible()
{
$_SESSION['accessibled_comment'][$this->comment_srl] = TRUE;
if(Context::getSessionStatus())
{
$_SESSION['accessibled_comment'][$this->comment_srl] = TRUE;
}
}
function isEditable()

View file

@ -889,7 +889,7 @@ class documentController extends document
if($_SESSION['readed_document'][$document_srl]) return false;
// Pass if the author's IP address is as same as visitor's.
if($oDocument->get('ipaddress') == $_SERVER['REMOTE_ADDR'])
if($oDocument->get('ipaddress') == $_SERVER['REMOTE_ADDR'] && Context::getSessionStatus())
{
$_SESSION['readed_document'][$document_srl] = true;
return false;
@ -928,7 +928,7 @@ class documentController extends document
}
// Register session
if(!$_SESSION['banned_document'][$document_srl])
if(!$_SESSION['banned_document'][$document_srl] && Context::getSessionStatus())
{
$_SESSION['readed_document'][$document_srl] = true;
}

View file

@ -391,7 +391,10 @@ class documentItem extends Object
if($this->isSecret() && !$this->isGranted() && !$this->isAccessible()) return Context::getLang('msg_is_secret');
$result = $this->_checkAccessibleFromStatus();
if($result) $_SESSION['accessible'][$this->document_srl] = true;
if($result && Context::getSessionStatus())
{
$_SESSION['accessible'][$this->document_srl] = true;
}
$content = $this->get('content');
$content = preg_replace_callback('/<(object|param|embed)[^>]*/is', array($this, '_checkAllowScriptAccess'), $content);
@ -452,7 +455,10 @@ class documentItem extends Object
if($this->isSecret() && !$this->isGranted() && !$this->isAccessible()) return Context::getLang('msg_is_secret');
$result = $this->_checkAccessibleFromStatus();
if($result) $_SESSION['accessible'][$this->document_srl] = true;
if($result && Context::getSessionStatus())
{
$_SESSION['accessible'][$this->document_srl] = true;
}
$content = $this->get('content');
if(!$stripEmbedTagException) stripEmbedTagForAdmin($content, $this->get('member_srl'));
@ -749,6 +755,7 @@ class documentItem extends Object
// If admin priviledge is granted on parent posts, you can read its child posts.
$accessible = array();
$comment_list = array();
$setAccessibleComments = Context::getSessionStatus();
foreach($output->data as $key => $val)
{
$oCommentItem = new commentItem();
@ -758,7 +765,10 @@ class documentItem extends Object
// If the comment is set to private and it belongs child post, it is allowable to read the comment for who has a admin privilege on its parent post
if($val->parent_srl>0 && $val->is_secret == 'Y' && !$oCommentItem->isAccessible() && $accessible[$val->parent_srl]===true)
{
$oCommentItem->setAccessible();
if($setAccessibleComments)
{
$oCommentItem->setAccessible();
}
}
$comment_list[$val->comment_srl] = $oCommentItem;
}

View file

@ -96,11 +96,15 @@ class installAdminController extends install
$qmail_compatibility = Context::get('qmail_compatibility');
if($qmail_compatibility!='Y') $qmail_compatibility = 'N';
$cache_friendly = Context::get('cache_friendly');
if($cache_friendly!='Y') $cache_friendly = 'N';
$use_html5 = Context::get('use_html5');
if(!$use_html5) $use_html5 = 'N';
$db_info->default_url = $default_url;
$db_info->qmail_compatibility = $qmail_compatibility;
$db_info->cache_friendly = $cache_friendly;
$db_info->use_db_session = $use_db_session;
$db_info->use_rewrite = $use_rewrite;
$db_info->use_sso = $use_sso;

View file

@ -207,7 +207,10 @@ class memberModel extends member
}
}
$_SESSION['is_logged'] = false;
if(Context::getSessionStatus())
{
$_SESSION['is_logged'] = false;
}
return false;
}