/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "mod_session.h"
#include "apr_lib.h"
#include "apr_strings.h"
#include "util_filter.h"
#include "http_log.h"
#include "http_request.h"
#include "http_protocol.h"

#define SESSION_EXPIRY "expiry"
#define HTTP_SESSION "HTTP_SESSION"

APR_HOOK_STRUCT(
                APR_HOOK_LINK(session_load)
                APR_HOOK_LINK(session_save)
                APR_HOOK_LINK(session_encode)
                APR_HOOK_LINK(session_decode)
)
APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(ap, SESSION, int, session_load,
                      (request_rec * r, session_rec ** z), (r, z), DECLINED)
APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(ap, SESSION, int, session_save,
                       (request_rec * r, session_rec * z), (r, z), DECLINED)
APR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL(ap, SESSION, int, session_encode,
                   (request_rec * r, session_rec * z), (r, z), OK, DECLINED)
APR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL(ap, SESSION, int, session_decode,
                   (request_rec * r, session_rec * z), (r, z), OK, DECLINED)

static int session_identity_encode(request_rec * r, session_rec * z);
static int session_identity_decode(request_rec * r, session_rec * z);
static int session_fixups(request_rec * r);

/**
 * Should the session be included within this URL.
 *
 * This function tests whether a session is valid for this URL. It uses the
 * include and exclude arrays to determine whether they should be included.
 */
static int session_included(request_rec * r, session_dir_conf * conf)
{

    const char **includes = (const char **) conf->includes->elts;
    const char **excludes = (const char **) conf->excludes->elts;
    int included = 1;                /* defaults to included */
    int i;

    if (conf->includes->nelts) {
        included = 0;
        for (i = 0; !included && i < conf->includes->nelts; i++) {
            const char *include = includes[i];
            if (strncmp(r->uri, include, strlen(include)) == 0) {
                included = 1;
            }
        }
    }

    if (conf->excludes->nelts) {
        for (i = 0; included && i < conf->excludes->nelts; i++) {
            const char *exclude = excludes[i];
            if (strncmp(r->uri, exclude, strlen(exclude)) == 0) {
                included = 0;
            }
        }
    }

    return included;
}

/**
 * Load the session.
 *
 * If the session doesn't exist, a blank one will be created.
 *
 * @param r The request
 * @param z A pointer to where the session will be written.
 */
static apr_status_t ap_session_load(request_rec * r, session_rec ** z)
{

    session_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
                                                   &session_module);
    apr_time_t now;
    session_rec *zz = NULL;
    int rv = 0;

    /* is the session enabled? */
    if (!dconf || !dconf->enabled) {
        return APR_SUCCESS;
    }

    /* should the session be loaded at all? */
    if (!session_included(r, dconf)) {
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01814)
                      "excluded by configuration for: %s", r->uri);
        return APR_SUCCESS;
    }

    /* load the session from the session hook */
    rv = ap_run_session_load(r, &zz);
    if (DECLINED == rv) {
        ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01815)
                      "session is enabled but no session modules have been configured, "
                      "session not loaded: %s", r->uri);
        return APR_EGENERAL;
    }
    else if (OK != rv) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01816)
                      "error while loading the session, "
                      "session not loaded: %s", r->uri);
        return rv;
    }

    /* found a session that hasn't expired? */
    now = apr_time_now();
    if (zz) {
        if (zz->expiry && zz->expiry < now) {
            zz = NULL;
        }
        else {
            /* having a session we cannot decode is just as good as having
               none at all */
            rv = ap_run_session_decode(r, zz);
            if (OK != rv) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01817)
                              "error while decoding the session, "
                              "session not loaded: %s", r->uri);
                zz = NULL;
            }
        }
    }

    /* no luck, create a blank session */
    if (!zz) {
        zz = (session_rec *) apr_pcalloc(r->pool, sizeof(session_rec));
        zz->pool = r->pool;
        zz->entries = apr_table_make(zz->pool, 10);
    }

    /* make sure the expiry and maxage are set, if present */
    if (dconf->maxage) {
        if (!zz->expiry) {
            zz->expiry = now + dconf->maxage * APR_USEC_PER_SEC;
        }
        zz->maxage = dconf->maxage;
    }

    *z = zz;

    return APR_SUCCESS;

}

/**
 * Save the session.
 *
 * In most implementations the session is only saved if the dirty flag is
 * true. This prevents the session being saved unnecessarily.
 *
 * @param r The request
 * @param z A pointer to where the session will be written.
 */
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,
                                                       &session_module);

        /* sanity checks, should we try save at all? */
        if (z->written) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01818)
                          "attempt made to save the session twice, "
                          "session not saved: %s", r->uri);
            return APR_EGENERAL;
        }
        if (z->expiry && z->expiry < now) {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01819)
                          "attempt made to save a session when the session had already expired, "
                          "session not saved: %s", r->uri);
            return APR_EGENERAL;
        }

        /* reset the expiry back to maxage, if the expiry is present */
        if (dconf->maxage) {
            z->expiry = now + dconf->maxage * APR_USEC_PER_SEC;
            z->maxage = dconf->maxage;
        }

        /* reset the expiry before saving if present */
        if (z->dirty && z->maxage) {
            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) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01820)
                          "error while encoding the session, "
                          "session not saved: %s", r->uri);
            return rv;
        }

        /* try the save */
        rv = ap_run_session_save(r, z);
        if (DECLINED == rv) {
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01821)
                          "session is enabled but no session modules have been configured, "
                          "session not saved: %s", r->uri);
            return APR_EGENERAL;
        }
        else if (OK != rv) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01822)
                          "error while saving the session, "
                          "session not saved: %s", r->uri);
            return rv;
        }
        else {
            z->written = 1;
        }
    }

    return APR_SUCCESS;

}

/**
 * Get a particular value from the session.
 * @param r The current request.
 * @param z The current session. If this value is NULL, the session will be
 * looked up in the request, created if necessary, and saved to the request
 * notes.
 * @param key The key to get.
 * @param value The buffer to write the value to.
 */
static apr_status_t ap_session_get(request_rec * r, session_rec * z,
        const char *key, const char **value)
{
    if (!z) {
        apr_status_t rv;
        rv = ap_session_load(r, &z);
        if (APR_SUCCESS != rv) {
            return rv;
        }
    }
    if (z && z->entries) {
        *value = apr_table_get(z->entries, key);
    }

    return OK;
}

/**
 * Set a particular value to the session.
 *
 * Using this method ensures that the dirty flag is set correctly, so that
 * the session can be saved efficiently.
 * @param r The current request.
 * @param z The current session. If this value is NULL, the session will be
 * looked up in the request, created if necessary, and saved to the request
 * notes.
 * @param key The key to set. The existing key value will be replaced.
 * @param value The value to set.
 */
static apr_status_t ap_session_set(request_rec * r, session_rec * z,
        const char *key, const char *value)
{
    if (!z) {
        apr_status_t rv;
        rv = ap_session_load(r, &z);
        if (APR_SUCCESS != rv) {
            return rv;
        }
    }
    if (z) {
        if (value) {
            apr_table_set(z->entries, key, value);
        }
        else {
            apr_table_unset(z->entries, key);
        }
        z->dirty = 1;
    }
    return APR_SUCCESS;
}

static int identity_count(int *count, const char *key, const char *val)
{
    *count += strlen(key) * 3 + strlen(val) * 3 + 1;
    return 1;
}

static int identity_concat(char *buffer, const char *key, const char *val)
{
    char *slider = buffer;
    int length = strlen(slider);
    slider += length;
    if (length) {
        *slider = '&';
        slider++;
    }
    ap_escape_urlencoded_buffer(slider, key);
    slider += strlen(slider);
    *slider = '=';
    slider++;
    ap_escape_urlencoded_buffer(slider, val);
    return 1;
}

/**
 * Default identity encoding for the session.
 *
 * By default, the name value pairs in the session are URLEncoded, separated
 * by equals, and then in turn separated by ampersand, in the format of an
 * html form.
 *
 * This was chosen to make it easy for external code to unpack a session,
 * should there be a need to do so.
 *
 * @param r The request pointer.
 * @param z A pointer to where the session will be written.
 */
static apr_status_t session_identity_encode(request_rec * r, session_rec * z)
{

    char *buffer = NULL;
    int length = 0;
    if (z->expiry) {
        char *expiry = apr_psprintf(z->pool, "%" APR_INT64_T_FMT, z->expiry);
        apr_table_setn(z->entries, SESSION_EXPIRY, expiry);
    }
    apr_table_do((int (*) (void *, const char *, const char *))
                 identity_count, &length, z->entries, NULL);
    buffer = apr_pcalloc(r->pool, length + 1);
    apr_table_do((int (*) (void *, const char *, const char *))
                 identity_concat, buffer, z->entries, NULL);
    z->encoded = buffer;
    return OK;

}

/**
 * Default identity decoding for the session.
 *
 * By default, the name value pairs in the session are URLEncoded, separated
 * by equals, and then in turn separated by ampersand, in the format of an
 * html form.
 *
 * This was chosen to make it easy for external code to unpack a session,
 * should there be a need to do so.
 *
 * This function reverses that process, and populates the session table.
 *
 * Name / value pairs that are not encoded properly are ignored.
 *
 * @param r The request pointer.
 * @param z A pointer to where the session will be written.
 */
static apr_status_t session_identity_decode(request_rec * r, session_rec * z)
{

    char *last = NULL;
    char *encoded, *pair;
    const char *sep = "&";

    /* sanity check - anything to decode? */
    if (!z->encoded) {
        return OK;
    }

    /* decode what we have */
    encoded = apr_pstrdup(r->pool, z->encoded);
    pair = apr_strtok(encoded, sep, &last);
    while (pair && pair[0]) {
        char *plast = NULL;
        const char *psep = "=";
        char *key = apr_strtok(pair, psep, &plast);
        char *val = apr_strtok(NULL, psep, &plast);
        if (key && *key) {
            if (!val || !*val) {
                apr_table_unset(z->entries, key);
            }
            else if (!ap_unescape_urlencoded(key) && !ap_unescape_urlencoded(val)) {
                if (!strcmp(SESSION_EXPIRY, key)) {
                    z->expiry = (apr_time_t) apr_atoi64(val);
                }
                else {
                    apr_table_set(z->entries, key, val);
                }
            }
        }
        pair = apr_strtok(NULL, sep, &last);
    }
    z->encoded = NULL;
    return OK;

}

/**
 * Ensure any changes to the session are committed.
 *
 * This is done in an output filter so that our options for where to
 * store the session can include storing the session within a cookie:
 * As an HTTP header, the cookie must be set before the output is
 * written, but after the handler is run.
 *
 * NOTE: It is possible for internal redirects to cause more than one
 * request to be present, and each request might have a session
 * defined. We need to go through each session in turn, and save each
 * one.
 *
 * The same session might appear in more than one request. The first
 * attempt to save the session will be called
 */
static apr_status_t session_output_filter(ap_filter_t * f,
        apr_bucket_brigade * in)
{

    /* save all the sessions in all the requests */
    request_rec *r = f->r->main;
    if (!r) {
        r = f->r;
    }
    while (r) {
        session_rec *z = NULL;
        session_dir_conf *conf = ap_get_module_config(r->per_dir_config,
                                                      &session_module);

        /* load the session, or create one if necessary */
        /* when unset or on error, z will be NULL */
        ap_session_load(r, &z);
        if (!z || z->written) {
            r = r->next;
            continue;
        }

        /* if a header was specified, insert the new values from the header */
        if (conf->header_set) {
            const char *override = apr_table_get(r->err_headers_out, conf->header);
            if (!override) {
                override = apr_table_get(r->headers_out, conf->header);
            }
            if (override) {
                apr_table_unset(r->err_headers_out, conf->header);
                apr_table_unset(r->headers_out, conf->header);
                z->encoded = override;
                z->dirty = 1;
                session_identity_decode(r, z);
            }
        }

        /* save away the session, and we're done */
        /* when unset or on error, we've complained to the log */
        ap_session_save(r, z);

        r = r->next;
    }

    /* remove ourselves from the filter chain */
    ap_remove_output_filter(f);

    /* send the data up the stack */
    return ap_pass_brigade(f->next, in);

}

/**
 * Insert the output filter.
 */
static void session_insert_output_filter(request_rec * r)
{
    ap_add_output_filter("MOD_SESSION_OUT", NULL, r, r->connection);
}

/**
 * Fixups hook.
 *
 * Load the session within a fixup - this ensures that the session is
 * properly loaded prior to the handler being called.
 *
 * The fixup is also responsible for injecting the session into the CGI
 * environment, should the admin have configured it so.
 *
 * @param r The request
 */
static int session_fixups(request_rec * r)
{
    session_dir_conf *conf = ap_get_module_config(r->per_dir_config,
                                                  &session_module);

    session_rec *z = NULL;

    /* if an error occurs or no session has been configured, we ignore
     * the broken session and allow it to be recreated from scratch on save
     * if necessary.
     */
    ap_session_load(r, &z);

    if (z && conf->env) {
        session_identity_encode(r, z);
        if (z->encoded) {
            apr_table_set(r->subprocess_env, HTTP_SESSION, z->encoded);
            z->encoded = NULL;
        }
    }

    return OK;

}


static void *create_session_dir_config(apr_pool_t * p, char *dummy)
{
    session_dir_conf *new =
    (session_dir_conf *) apr_pcalloc(p, sizeof(session_dir_conf));

    new->includes = apr_array_make(p, 10, sizeof(const char **));
    new->excludes = apr_array_make(p, 10, sizeof(const char **));

    return (void *) new;
}

static void *merge_session_dir_config(apr_pool_t * p, void *basev, void *addv)
{
    session_dir_conf *new = (session_dir_conf *) apr_pcalloc(p, sizeof(session_dir_conf));
    session_dir_conf *add = (session_dir_conf *) addv;
    session_dir_conf *base = (session_dir_conf *) basev;

    new->enabled = (add->enabled_set == 0) ? base->enabled : add->enabled;
    new->enabled_set = add->enabled_set || base->enabled_set;
    new->maxage = (add->maxage_set == 0) ? base->maxage : add->maxage;
    new->maxage_set = add->maxage_set || base->maxage_set;
    new->header = (add->header_set == 0) ? base->header : add->header;
    new->header_set = add->header_set || base->header_set;
    new->env = (add->env_set == 0) ? base->env : add->env;
    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;
}


static const char *
     set_session_enable(cmd_parms * parms, void *dconf, int flag)
{
    session_dir_conf *conf = dconf;

    conf->enabled = flag;
    conf->enabled_set = 1;

    return NULL;
}

static const char *
     set_session_maxage(cmd_parms * parms, void *dconf, const char *arg)
{
    session_dir_conf *conf = dconf;

    conf->maxage = atol(arg);
    conf->maxage_set = 1;

    return NULL;
}

static const char *
     set_session_header(cmd_parms * parms, void *dconf, const char *arg)
{
    session_dir_conf *conf = dconf;

    conf->header = arg;
    conf->header_set = 1;

    return NULL;
}

static const char *
     set_session_env(cmd_parms * parms, void *dconf, int flag)
{
    session_dir_conf *conf = dconf;

    conf->env = flag;
    conf->env_set = 1;

    return NULL;
}

static const char *add_session_include(cmd_parms * cmd, void *dconf, const char *f)
{
    session_dir_conf *conf = dconf;

    const char **new = apr_array_push(conf->includes);
    *new = f;

    return NULL;
}

static const char *add_session_exclude(cmd_parms * cmd, void *dconf, const char *f)
{
    session_dir_conf *conf = dconf;

    const char **new = apr_array_push(conf->excludes);
    *new = f;

    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[] =
{
    AP_INIT_FLAG("Session", set_session_enable, NULL, RSRC_CONF|OR_AUTHCFG,
                 "on if a session should be maintained for these URLs"),
    AP_INIT_TAKE1("SessionMaxAge", set_session_maxage, NULL, RSRC_CONF|OR_AUTHCFG,
                  "length of time for which a session should be valid. Zero to disable"),
    AP_INIT_TAKE1("SessionHeader", set_session_header, NULL, RSRC_CONF|OR_AUTHCFG,
                  "output header, if present, whose contents will be injected into the session."),
    AP_INIT_FLAG("SessionEnv", set_session_env, NULL, RSRC_CONF|OR_AUTHCFG,
                 "on if a session should be written to the CGI environment. Defaults to off"),
    AP_INIT_TAKE1("SessionInclude", add_session_include, NULL, RSRC_CONF|OR_AUTHCFG,
                  "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}
};

static void register_hooks(apr_pool_t * p)
{
    ap_register_output_filter("MOD_SESSION_OUT", session_output_filter,
                              NULL, AP_FTYPE_CONTENT_SET);
    ap_hook_insert_filter(session_insert_output_filter, NULL, NULL,
                          APR_HOOK_MIDDLE);
    ap_hook_insert_error_filter(session_insert_output_filter,
                                NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_fixups(session_fixups, NULL, NULL, APR_HOOK_MIDDLE);
    ap_hook_session_encode(session_identity_encode, NULL, NULL,
                           APR_HOOK_REALLY_FIRST);
    ap_hook_session_decode(session_identity_decode, NULL, NULL,
                           APR_HOOK_REALLY_LAST);
    APR_REGISTER_OPTIONAL_FN(ap_session_get);
    APR_REGISTER_OPTIONAL_FN(ap_session_set);
    APR_REGISTER_OPTIONAL_FN(ap_session_load);
    APR_REGISTER_OPTIONAL_FN(ap_session_save);
}

AP_DECLARE_MODULE(session) =
{
    STANDARD20_MODULE_STUFF,
    create_session_dir_config,   /* dir config creater */
    merge_session_dir_config,    /* dir merger --- default is to override */
    NULL,                        /* server config */
    NULL,                        /* merge server config */
    session_cmds,                /* command apr_table_t */
    register_hooks               /* register hooks */
};
