From: Eric Covener Date: Fri, 9 Aug 2019 10:42:24 +0000 (+0000) Subject: Merge r1709121 from trunk: X-Git-Tag: 2.4.41~10 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6503755ecb59e03ef679493172f294ac81fae4df;p=thirdparty%2Fapache%2Fhttpd.git Merge r1709121 from trunk: mod_session: Introduce SessionExpiryUpdateInterval which allows to configure the session/cookie expiry's update interval. PR 57300. Submitted by: Paul Spangler Reviewed/Committed by: ylavic git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1864781 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 6814823f390..2021ad2c9ec 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,10 @@ -*- coding: utf-8 -*- Changes with Apache 2.4.41 + *) mod_session: Introduce SessionExpiryUpdateInterval which allows to + configure the session/cookie expiry's update interval. PR 57300. + [Paul Spangler ] + *) modules/filters: Fix broken compilation when using old GCC (<4.2.x). PR 63633. [Rainer Jung, Joe Orton] diff --git a/STATUS b/STATUS index dfe3da14a32..43672b4f77a 100644 --- a/STATUS +++ b/STATUS @@ -129,15 +129,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - *) mod_session: mod_session: Introduce SessionExpiryUpdateInterval which allows to - configure the session/cookie expiry's update interval. PR 57300. - trunk patch: http://svn.apache.org/r1709121 - 2.4.x patch: svn merge -c 1709121 ^/httpd/httpd/trunk . - +1: covener, jorton, rjung - rjung: one might add a "" item for 2.4.41 (or whereever the - feature goes in) to the docs part. - - PATCHES PROPOSED TO BACKPORT FROM TRUNK: [ New proposals should be added at the end of the list ] diff --git a/docs/manual/mod/mod_session.xml b/docs/manual/mod/mod_session.xml index dc48a96b757..b7e00034cd6 100644 --- a/docs/manual/mod/mod_session.xml +++ b/docs/manual/mod/mod_session.xml @@ -487,4 +487,42 @@ AuthName realm + +SessionExpiryUpdateInterval +Define the number of seconds a session's expiry may change without +the session being updated +SessionExpiryUpdateInterval interval +SessionExpiryUpdateInterval 0 (always update) +server config +virtual host +directory +.htaccess + +Available in Apache 2.4.41 and later + + +

The SessionExpiryUpdateInterval 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 + mod_session_dbd. 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.

+ +

Setting the interval to zero disables this directive, and the session + expiry is refreshed for each request.

+ +

This directive only has an effect when combined with + SessionMaxAge to enable session + expiry. Sessions without an expiry are only written when the data stored in + the session has changed.

+ + Warning +

Because the session expiry may not be refreshed with each request, it's + possible for sessions to expire up to interval seconds early. + Using a small interval usually provides sufficient savings while having a + minimal effect on expiry resolution.

+
+
+ diff --git a/modules/session/mod_session.c b/modules/session/mod_session.c index 64e6e4a8132..7ee477ce1dd 100644 --- a/modules/session/mod_session.c +++ b/modules/session/mod_session.c @@ -180,6 +180,7 @@ static apr_status_t ap_session_save(request_rec * r, session_rec * z) { if (z) { apr_time_t now = apr_time_now(); + apr_time_t initialExpiry = z->expiry; int rv = 0; session_dir_conf *dconf = ap_get_module_config(r->per_dir_config, @@ -210,6 +211,17 @@ static apr_status_t ap_session_save(request_rec * r, session_rec * z) 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 */ rv = ap_run_session_encode(r, z); if (OK != rv) { @@ -556,6 +568,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->includes = apr_array_append(p, base->includes, add->includes); 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; } @@ -625,6 +641,21 @@ static const char *add_session_exclude(cmd_parms * cmd, void *dconf, const char 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[] = { @@ -640,6 +671,9 @@ static const command_rec session_cmds[] = "URL prefixes to include in the session. Defaults to all URLs"), AP_INIT_TAKE1("SessionExclude", add_session_exclude, NULL, RSRC_CONF|OR_AUTHCFG, "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} }; diff --git a/modules/session/mod_session.h b/modules/session/mod_session.h index a6dd5e9f471..bdeb532a451 100644 --- a/modules/session/mod_session.h +++ b/modules/session/mod_session.h @@ -115,6 +115,9 @@ typedef struct { * URLs included if empty */ apr_array_header_t *excludes; /* URL prefixes to be excluded. No * 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; /** diff --git a/modules/session/mod_session_cookie.c b/modules/session/mod_session_cookie.c index a010ee7163a..36168b7ead7 100644 --- a/modules/session/mod_session_cookie.c +++ b/modules/session/mod_session_cookie.c @@ -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_module); - /* don't cache auth protected pages */ - apr_table_addn(r->headers_out, "Cache-Control", "no-cache"); - /* create RFC2109 compliant cookie */ if (conf->name_set) { 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 */ 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; } diff --git a/modules/session/mod_session_dbd.c b/modules/session/mod_session_dbd.c index 0be7306f820..f683da2172f 100644 --- a/modules/session/mod_session_dbd.c +++ b/modules/session/mod_session_dbd.c @@ -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 */ 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; } @@ -409,9 +412,6 @@ static apr_status_t session_dbd_save(request_rec * r, session_rec * z) if (conf->name_set || conf->name2_set) { 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 (z->uuid) { 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) { /* 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) { ret = dbd_save(r, r->user, r->user, z->encoded, z->expiry);