mirror of
https://github.com/apache/httpd.git
synced 2025-08-07 04:02:58 +03:00
mod_session: Introduce SessionExpiryUpdateInterval which allows to
configure the session/cookie expiry's update interval. PR 57300. Submitted by: Paul Spangler <paul.spangler ni.com> Reviewed/Committed by: ylavic git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1709121 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
4
CHANGES
4
CHANGES
@@ -1,6 +1,10 @@
|
|||||||
-*- coding: utf-8 -*-
|
-*- coding: utf-8 -*-
|
||||||
Changes with Apache 2.5.0
|
Changes with Apache 2.5.0
|
||||||
|
|
||||||
|
*) mod_session: Introduce SessionExpiryUpdateInterval which allows to
|
||||||
|
configure the session/cookie expiry's update interval. PR 57300.
|
||||||
|
[Paul Spangler <paul.spangler ni.com>]
|
||||||
|
|
||||||
*) mod_ssl: Extend expression parser registration to support ssl variables
|
*) mod_ssl: Extend expression parser registration to support ssl variables
|
||||||
in any expression using mod_rewrite syntax "%{SSL:VARNAME}" or function
|
in any expression using mod_rewrite syntax "%{SSL:VARNAME}" or function
|
||||||
syntax "ssl(VARIABLE)". [Rainer Jung]
|
syntax "ssl(VARIABLE)". [Rainer Jung]
|
||||||
|
@@ -487,4 +487,41 @@ AuthName "realm"
|
|||||||
</usage>
|
</usage>
|
||||||
</directivesynopsis>
|
</directivesynopsis>
|
||||||
|
|
||||||
|
<directivesynopsis>
|
||||||
|
<name>SessionExpiryUpdateInterval</name>
|
||||||
|
<description>Define the number of seconds a session's expiry may change without
|
||||||
|
the session being updated</description>
|
||||||
|
<syntax>SessionExpiryUpdateInterval <var>interval</var></syntax>
|
||||||
|
<default>SessionExpiryUpdateInterval 0 (always update)</default>
|
||||||
|
<contextlist><context>server config</context>
|
||||||
|
<context>virtual host</context>
|
||||||
|
<context>directory</context>
|
||||||
|
<context>.htaccess</context>
|
||||||
|
</contextlist>
|
||||||
|
|
||||||
|
<usage>
|
||||||
|
<p>The <directive>SessionExpiryUpdateInterval</directive> directive allows
|
||||||
|
sessions to avoid the cost associated with writing the session each request
|
||||||
|
when only the expiry time has changed. This can be used to make a website
|
||||||
|
more efficient or reduce load on a database when using
|
||||||
|
<module>mod_session_dbd</module>. The session is always written if the data
|
||||||
|
stored in the session has changed or the expiry has changed by more than the
|
||||||
|
configured interval.</p>
|
||||||
|
|
||||||
|
<p>Setting the interval to zero disables this directive, and the session
|
||||||
|
expiry is refreshed for each request.</p>
|
||||||
|
|
||||||
|
<p>This directive only has an effect when combined with
|
||||||
|
<directive module="mod_session">SessionMaxAge</directive> to enable session
|
||||||
|
expiry. Sessions without an expiry are only written when the data stored in
|
||||||
|
the session has changed.</p>
|
||||||
|
|
||||||
|
<note type="warning"><title>Warning</title>
|
||||||
|
<p>Because the session expiry may not be refreshed with each request, it's
|
||||||
|
possible for sessions to expire up to <var>interval</var> seconds early.
|
||||||
|
Using a small interval usually provides sufficient savings while having a
|
||||||
|
minimal effect on expiry resolution.</p></note>
|
||||||
|
</usage>
|
||||||
|
</directivesynopsis>
|
||||||
|
|
||||||
</modulesynopsis>
|
</modulesynopsis>
|
||||||
|
@@ -177,6 +177,7 @@ static apr_status_t ap_session_save(request_rec * r, session_rec * z)
|
|||||||
{
|
{
|
||||||
if (z) {
|
if (z) {
|
||||||
apr_time_t now = apr_time_now();
|
apr_time_t now = apr_time_now();
|
||||||
|
apr_time_t initialExpiry = z->expiry;
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
|
|
||||||
session_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
|
session_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
|
||||||
@@ -207,6 +208,17 @@ static apr_status_t ap_session_save(request_rec * r, session_rec * z)
|
|||||||
z->expiry = now + z->maxage * APR_USEC_PER_SEC;
|
z->expiry = now + z->maxage * APR_USEC_PER_SEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* don't save if the only change is the expiry by a small amount */
|
||||||
|
if (!z->dirty && dconf->expiry_update_time
|
||||||
|
&& (z->expiry - initialExpiry < dconf->expiry_update_time)) {
|
||||||
|
return APR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* also don't save sessions that didn't change at all */
|
||||||
|
if (!z->dirty && !z->maxage) {
|
||||||
|
return APR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/* encode the session */
|
/* encode the session */
|
||||||
rv = ap_run_session_encode(r, z);
|
rv = ap_run_session_encode(r, z);
|
||||||
if (OK != rv) {
|
if (OK != rv) {
|
||||||
@@ -551,6 +563,10 @@ static void *merge_session_dir_config(apr_pool_t * p, void *basev, void *addv)
|
|||||||
new->env_set = add->env_set || base->env_set;
|
new->env_set = add->env_set || base->env_set;
|
||||||
new->includes = apr_array_append(p, base->includes, add->includes);
|
new->includes = apr_array_append(p, base->includes, add->includes);
|
||||||
new->excludes = apr_array_append(p, base->excludes, add->excludes);
|
new->excludes = apr_array_append(p, base->excludes, add->excludes);
|
||||||
|
new->expiry_update_time = (add->expiry_update_set == 0)
|
||||||
|
? base->expiry_update_time
|
||||||
|
: add->expiry_update_time;
|
||||||
|
new->expiry_update_set = add->expiry_update_set || base->expiry_update_set;
|
||||||
|
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
@@ -620,6 +636,21 @@ static const char *add_session_exclude(cmd_parms * cmd, void *dconf, const char
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
set_session_expiry_update(cmd_parms * parms, void *dconf, const char *arg)
|
||||||
|
{
|
||||||
|
session_dir_conf *conf = dconf;
|
||||||
|
|
||||||
|
conf->expiry_update_time = atoi(arg);
|
||||||
|
if (conf->expiry_update_time < 0) {
|
||||||
|
return "SessionExpiryUpdateInterval must be positive or nul";
|
||||||
|
}
|
||||||
|
conf->expiry_update_time = apr_time_from_sec(conf->expiry_update_time);
|
||||||
|
conf->expiry_update_set = 1;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static const command_rec session_cmds[] =
|
static const command_rec session_cmds[] =
|
||||||
{
|
{
|
||||||
@@ -635,6 +666,9 @@ static const command_rec session_cmds[] =
|
|||||||
"URL prefixes to include in the session. Defaults to all URLs"),
|
"URL prefixes to include in the session. Defaults to all URLs"),
|
||||||
AP_INIT_TAKE1("SessionExclude", add_session_exclude, NULL, RSRC_CONF|OR_AUTHCFG,
|
AP_INIT_TAKE1("SessionExclude", add_session_exclude, NULL, RSRC_CONF|OR_AUTHCFG,
|
||||||
"URL prefixes to exclude from the session. Defaults to no URLs"),
|
"URL prefixes to exclude from the session. Defaults to no URLs"),
|
||||||
|
AP_INIT_TAKE1("SessionExpiryUpdateInterval", set_session_expiry_update, NULL, RSRC_CONF|OR_AUTHCFG,
|
||||||
|
"time interval for which a session's expiry time may change "
|
||||||
|
"without having to be rewritten. Zero to disable"),
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -115,6 +115,9 @@ typedef struct {
|
|||||||
* URLs included if empty */
|
* URLs included if empty */
|
||||||
apr_array_header_t *excludes; /* URL prefixes to be excluded. No
|
apr_array_header_t *excludes; /* URL prefixes to be excluded. No
|
||||||
* URLs excluded if empty */
|
* URLs excluded if empty */
|
||||||
|
apr_time_t expiry_update_time; /* seconds the session expiry may change and
|
||||||
|
* not have to be rewritten */
|
||||||
|
int expiry_update_set;
|
||||||
} session_dir_conf;
|
} session_dir_conf;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -60,9 +60,6 @@ static apr_status_t session_cookie_save(request_rec * r, session_rec * z)
|
|||||||
session_cookie_dir_conf *conf = ap_get_module_config(r->per_dir_config,
|
session_cookie_dir_conf *conf = ap_get_module_config(r->per_dir_config,
|
||||||
&session_cookie_module);
|
&session_cookie_module);
|
||||||
|
|
||||||
/* don't cache auth protected pages */
|
|
||||||
apr_table_addn(r->headers_out, "Cache-Control", "no-cache");
|
|
||||||
|
|
||||||
/* create RFC2109 compliant cookie */
|
/* create RFC2109 compliant cookie */
|
||||||
if (conf->name_set) {
|
if (conf->name_set) {
|
||||||
if (z->encoded && z->encoded[0]) {
|
if (z->encoded && z->encoded[0]) {
|
||||||
@@ -162,6 +159,9 @@ static apr_status_t session_cookie_load(request_rec * r, session_rec ** z)
|
|||||||
/* put the session in the notes so we don't have to parse it again */
|
/* put the session in the notes so we don't have to parse it again */
|
||||||
apr_table_setn(m->notes, note, (char *)zz);
|
apr_table_setn(m->notes, note, (char *)zz);
|
||||||
|
|
||||||
|
/* don't cache auth protected pages */
|
||||||
|
apr_table_addn(r->headers_out, "Cache-Control", "no-cache, private");
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -245,6 +245,9 @@ static apr_status_t session_dbd_load(request_rec * r, session_rec ** z)
|
|||||||
/* put the session in the notes so we don't have to parse it again */
|
/* put the session in the notes so we don't have to parse it again */
|
||||||
apr_table_setn(m->notes, note, (char *)zz);
|
apr_table_setn(m->notes, note, (char *)zz);
|
||||||
|
|
||||||
|
/* don't cache pages with a session */
|
||||||
|
apr_table_addn(r->headers_out, "Cache-Control", "no-cache, private");
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -409,9 +412,6 @@ static apr_status_t session_dbd_save(request_rec * r, session_rec * z)
|
|||||||
if (conf->name_set || conf->name2_set) {
|
if (conf->name_set || conf->name2_set) {
|
||||||
char *oldkey = NULL, *newkey = NULL;
|
char *oldkey = NULL, *newkey = NULL;
|
||||||
|
|
||||||
/* don't cache pages with a session */
|
|
||||||
apr_table_addn(r->headers_out, "Cache-Control", "no-cache");
|
|
||||||
|
|
||||||
/* if the session is new or changed, make a new session ID */
|
/* if the session is new or changed, make a new session ID */
|
||||||
if (z->uuid) {
|
if (z->uuid) {
|
||||||
oldkey = apr_pcalloc(r->pool, APR_UUID_FORMATTED_LENGTH + 1);
|
oldkey = apr_pcalloc(r->pool, APR_UUID_FORMATTED_LENGTH + 1);
|
||||||
@@ -458,7 +458,7 @@ static apr_status_t session_dbd_save(request_rec * r, session_rec * z)
|
|||||||
else if (conf->peruser) {
|
else if (conf->peruser) {
|
||||||
|
|
||||||
/* don't cache pages with a session */
|
/* don't cache pages with a session */
|
||||||
apr_table_addn(r->headers_out, "Cache-Control", "no-cache");
|
apr_table_addn(r->headers_out, "Cache-Control", "no-cache, private");
|
||||||
|
|
||||||
if (r->user) {
|
if (r->user) {
|
||||||
ret = dbd_save(r, r->user, r->user, z->encoded, z->expiry);
|
ret = dbd_save(r, r->user, r->user, z->encoded, z->expiry);
|
||||||
|
Reference in New Issue
Block a user