mod_session.c revision 563787eb542f06298242d9e681c18be6611a6214
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy/* Licensed to the Apache Software Foundation (ASF) under one or more
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * contributor license agreements. See the NOTICE file distributed with
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * this work for additional information regarding copyright ownership.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * The ASF licenses this file to You under the Apache License, Version 2.0
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * (the "License"); you may not use this file except in compliance with
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * the License. You may obtain a copy of the License at
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * Unless required by applicable law or agreed to in writing, software
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * distributed under the License is distributed on an "AS IS" BASIS,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * See the License for the specific language governing permissions and
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * limitations under the License.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien RoyAPR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(ap, SESSION, int, session_load,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (request_rec * r, session_rec ** z), (r, z), DECLINED)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien RoyAPR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(ap, SESSION, int, session_save,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (request_rec * r, session_rec * z), (r, z), DECLINED)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien RoyAPR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL(ap, SESSION, int, session_encode,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (request_rec * r, session_rec * z), (r, z), OK, DECLINED)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien RoyAPR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL(ap, SESSION, int, session_decode,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy (request_rec * r, session_rec * z), (r, z), OK, DECLINED)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roystatic int session_identity_encode(request_rec * r, session_rec * z);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roystatic int session_identity_decode(request_rec * r, session_rec * z);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * Should the session be included within this URL.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * This function tests whether a session is valid for this URL. It uses the
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * include and exclude arrays to determine whether they should be included.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roystatic int session_included(request_rec * r, session_dir_conf * conf)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy const char **includes = (const char **) conf->includes->elts;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy const char **excludes = (const char **) conf->excludes->elts;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy for (i = 0; !included && i < conf->includes->nelts; i++) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy const char *include = includes[i];
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (strncmp(r->uri, include, strlen(include))) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy for (i = 0; included && i < conf->includes->nelts; i++) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (strncmp(r->uri, exclude, strlen(exclude))) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * Load the session.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * If the session doesn't exist, a blank one will be created.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * @param r The request
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * @param z A pointer to where the session will be written.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roystatic apr_status_t ap_session_load(request_rec * r, session_rec ** z)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy session_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /* is the session enabled? */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /* should the session be loaded at all? */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01814)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /* load the session from the session hook */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01815)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy "session is enabled but no session modules have been configured, "
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01816)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy "error while loading the session, "
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /* found a session that hasn't expired? */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (!zz || (zz->expiry && zz->expiry < now)) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /* no luck, create a blank session */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy zz = (session_rec *) apr_pcalloc(r->pool, sizeof(session_rec));
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy zz->uuid = (apr_uuid_t *) apr_pcalloc(zz->pool, sizeof(apr_uuid_t));
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01817)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy "error while decoding the session, "
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /* make sure the expiry is set, if present */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy zz->expiry = now + dconf->maxage * APR_USEC_PER_SEC;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * Save the session.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * In most implementations the session is only saved if the dirty flag is
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * true. This prevents the session being saved unnecessarily.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * @param r The request
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * @param z A pointer to where the session will be written.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roystatic apr_status_t ap_session_save(request_rec * r, session_rec * z)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy session_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /* sanity checks, should we try save at all? */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01818)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy "attempt made to save the session twice, "
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01819)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy "attempt made to save a session when the session had already expired, "
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /* reset the expiry back to maxage, if the expiry is present */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy z->expiry = now + dconf->maxage * APR_USEC_PER_SEC;
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /* encode the session */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01820)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy "error while encoding the session, "
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /* try the save */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01821)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy "session is enabled but no session modules have been configured, "
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01822)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy "error while saving the session, "
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * Get a particular value from the session.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * @param r The current request.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * @param z The current session. If this value is NULL, the session will be
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * looked up in the request, created if necessary, and saved to the request
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * @param key The key to get.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * @param value The buffer to write the value to.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roystatic apr_status_t ap_session_get(request_rec * r, session_rec * z,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (z && z->entries) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * Set a particular value to the session.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * Using this method ensures that the dirty flag is set correctly, so that
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * the session can be saved efficiently.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * @param r The current request.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * @param z The current session. If this value is NULL, the session will be
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * looked up in the request, created if necessary, and saved to the request
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * @param key The key to set. The existing key value will be replaced.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy * @param value The value to set.
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roystatic apr_status_t ap_session_set(request_rec * r, session_rec * z,
return APR_SUCCESS;
if (length) {
slider++;
slider++;
int length = 0;
if (z->expiry) {
apr_table_do((int (*) (void *, const char *, const char *))
apr_table_do((int (*) (void *, const char *, const char *))
return OK;
if (!z->encoded) {
return OK;
return OK;
ap_session_load(r, &z);
if (!z || z->written) {
r = r->next;
if (!override) {
if (override) {
session_identity_decode(r, z);
ap_session_save(r, z);
r = r->next;
ap_session_load(r, &z);
session_identity_encode(r, z);
if (z->encoded) {
return OK;
return (void *) new;
return new;
return NULL;
return NULL;
return NULL;
return NULL;
*new = f;
return NULL;
*new = f;
return NULL;
{NULL}