summaryrefslogtreecommitdiffstats
path: root/debian/perl-framework/c-modules/test_session/mod_test_session.c
diff options
context:
space:
mode:
Diffstat (limited to 'debian/perl-framework/c-modules/test_session/mod_test_session.c')
-rw-r--r--debian/perl-framework/c-modules/test_session/mod_test_session.c348
1 files changed, 348 insertions, 0 deletions
diff --git a/debian/perl-framework/c-modules/test_session/mod_test_session.c b/debian/perl-framework/c-modules/test_session/mod_test_session.c
new file mode 100644
index 0000000..4099cbe
--- /dev/null
+++ b/debian/perl-framework/c-modules/test_session/mod_test_session.c
@@ -0,0 +1,348 @@
+#define HTTPD_TEST_REQUIRE_APACHE 2.3
+
+#if CONFIG_FOR_HTTPD_TEST
+
+<IfModule mod_session.c>
+ <Location /sessiontest>
+ Session Off
+ TestSession On
+ SetHandler test-session-handler
+ </Location>
+ <Location /sessiontest/on>
+ Session On
+ SessionHeader X-Test-Session-Override
+ </Location>
+ <Location /sessiontest/on/encode>
+ TestSessionEncoder On
+ </Location>
+ <IfModule mod_include.c>
+ Alias /sessiontest/on/env/on @DocumentRoot@/modules/session
+ <Directory @DocumentRoot@/modules/session>
+ Session On
+ SessionEnv Off
+ TestSession On
+ Options +IncludesNOEXEC
+ </Directory>
+ <Location /sessiontest/on/env>
+ SetHandler None
+ </Location>
+ <Location /sessiontest/on/env/on>
+ SessionEnv On
+ </Location>
+ </IfModule>
+ <Location /sessiontest/on/expire>
+ SessionMaxAge 100
+ </Location>
+ <IfModule mod_version.c>
+ <IfVersion >= 2.4.41>
+ <Location /sessiontest/on/expire/cache>
+ SessionExpiryUpdateInterval 50
+ </Location>
+ </IfVersion>
+ </IfModule>
+ <Location /sessiontest/on/include>
+ SessionInclude /sessiontest/on/include/yes
+ SessionExclude /sessiontest/on/include/yes/no
+ </Location>
+</IfModule>
+
+#endif
+
+#include "apr_strings.h"
+#include "mod_session.h"
+
+#define APACHE_HTTPD_TEST_EXTRA_HOOKS extra_hooks
+#define APACHE_HTTPD_TEST_CHILD_INIT test_session_init
+#define APACHE_HTTPD_TEST_HANDLER test_session_handler
+#define APACHE_HTTPD_TEST_COMMANDS test_session_cmds
+#define APACHE_HTTPD_TEST_PER_DIR_CREATE test_session_dcfg_create
+#define APACHE_HTTPD_TEST_PER_DIR_MERGE test_session_dcfg_merge
+
+#include "apache_httpd_test.h"
+
+#define TEST_SESSION_HANDLER "test-session-handler"
+#define TEST_SESSION_ENCODER "test-session-encoder"
+#define TEST_SESSION_NOTE "mod_test_session"
+#define TEST_SESSION_HEADER "X-Test-Session-Override"
+#define TEST_SESSION_ENCODING_PREFIX "TestEncoded:"
+
+typedef struct {
+ int session;
+ int session_set;
+ int encoder;
+ int encoder_set;
+} test_session_dcfg_t;
+
+typedef enum {
+ TEST_SESSION_ACTION_NONE,
+ TEST_SESSION_ACTION_GET,
+ TEST_SESSION_ACTION_SET
+} TestSessionAction;
+
+module AP_MODULE_DECLARE_DATA test_session_module;
+
+static APR_OPTIONAL_FN_TYPE(ap_session_get) *ap_session_get_fn = NULL;
+static APR_OPTIONAL_FN_TYPE(ap_session_set) *ap_session_set_fn = NULL;
+static APR_OPTIONAL_FN_TYPE(ap_session_load) *ap_session_load_fn = NULL;
+static APR_OPTIONAL_FN_TYPE(ap_session_save) *ap_session_save_fn = NULL;
+
+static void test_session_init(apr_pool_t *p, server_rec *s)
+{
+ ap_session_get_fn = APR_RETRIEVE_OPTIONAL_FN(ap_session_get);
+ ap_session_set_fn = APR_RETRIEVE_OPTIONAL_FN(ap_session_set);
+ ap_session_save_fn = APR_RETRIEVE_OPTIONAL_FN(ap_session_save);
+ ap_session_load_fn = APR_RETRIEVE_OPTIONAL_FN(ap_session_load);
+}
+
+static apr_status_t test_session_load(request_rec * r, session_rec ** z)
+{
+ session_rec *zz;
+ test_session_dcfg_t *dconf = ap_get_module_config(r->per_dir_config,
+ &test_session_module);
+ if (!dconf || !dconf->session)
+ return DECLINED;
+
+ zz = (session_rec *)apr_table_get(r->notes, TEST_SESSION_NOTE);
+
+ if (!zz) {
+ /* Create the session using the query string as the data. */
+ char *data = apr_pstrdup(r->pool, r->args);
+
+ if (data) {
+ int result = ap_unescape_urlencoded(data);
+ if (result)
+ return result;
+ }
+
+ zz = (session_rec *)apr_pcalloc(r->pool, sizeof(session_rec));
+ zz->pool = r->pool;
+ zz->entries = apr_table_make(r->pool, 10);
+ zz->encoded = data;
+ apr_table_setn(r->notes, TEST_SESSION_NOTE, (char *)zz);
+ }
+
+ *z = zz;
+ return OK;
+}
+
+static apr_status_t test_session_save(request_rec * r, session_rec * z)
+{
+ test_session_dcfg_t *dconf = ap_get_module_config(r->per_dir_config,
+ &test_session_module);
+ if (!dconf || !dconf->session)
+ return DECLINED;
+
+ /* Save the session into headers. */
+ apr_table_setn(r->headers_out, "X-Test-Session-Dirty",
+ z->dirty ? "1" : "0");
+
+ apr_table_set(r->headers_out, "X-Test-Session", z->encoded);
+
+ return OK;
+}
+
+static apr_status_t test_session_encode(request_rec * r, session_rec * z)
+{
+ test_session_dcfg_t *dconf = ap_get_module_config(r->per_dir_config,
+ &test_session_module);
+ if (!dconf || !dconf->encoder)
+ return DECLINED;
+
+ /* Simple encoding by adding a prefix. */
+ z->encoded = apr_pstrcat(r->pool, TEST_SESSION_ENCODING_PREFIX,
+ z->encoded, NULL);
+ return OK;
+}
+
+static apr_status_t test_session_decode(request_rec * r, session_rec * z)
+{
+ const size_t prefix_len = strlen(TEST_SESSION_ENCODING_PREFIX);
+ test_session_dcfg_t *dconf = ap_get_module_config(r->per_dir_config,
+ &test_session_module);
+ if (!dconf || !dconf->encoder || !z->encoded)
+ return DECLINED;
+
+ /* Simple decoding by removing a prefix. */
+ if (!strncmp(z->encoded, TEST_SESSION_ENCODING_PREFIX, prefix_len)) {
+ z->encoded += prefix_len;
+ return OK;
+ }
+
+ return HTTP_BAD_REQUEST;
+}
+
+static int test_session_get(request_rec *r, char *name)
+{
+ session_rec *z = NULL;
+ const char *value = NULL;
+ apr_status_t result = ap_session_load_fn(r, &z);
+
+ if (result == OK)
+ result = ap_session_get_fn(r, z, name, &value);
+
+ if (result == OK) {
+ if (value)
+ result = ap_rputs(value, r) > 0 ? OK : HTTP_INTERNAL_SERVER_ERROR;
+ else
+ result = HTTP_NOT_FOUND;
+ }
+
+ return result;
+}
+
+static int test_session_set(request_rec *r, char *name, char *value)
+{
+ session_rec *z = NULL;
+ apr_status_t result = ap_session_load_fn(r, &z);
+
+ if (result == OK)
+ result = ap_session_set_fn(r, z, name, value);
+
+ return result;
+}
+
+static int test_session_handler(request_rec *r)
+{
+ const char *overrides = NULL;
+
+ if (strcmp(r->handler, TEST_SESSION_HANDLER))
+ return DECLINED;
+
+ /* Copy the header for SessionHeader from the request to the response. */
+ if ((overrides = apr_table_get(r->headers_in, TEST_SESSION_HEADER)))
+ apr_table_setn(r->headers_out, TEST_SESSION_HEADER, overrides);
+
+ /* Additional commands to test the session API via POST. */
+ if (r->method_number == M_POST) {
+ char *fieldName = NULL;
+ char *fieldValue = NULL;
+ apr_array_header_t *pairs = NULL;
+ apr_status_t result;
+ TestSessionAction action;
+
+ if (!ap_session_get_fn || !ap_session_set_fn ||
+ !ap_session_load_fn || !ap_session_save_fn)
+ return HTTP_INTERNAL_SERVER_ERROR;
+
+ action = TEST_SESSION_ACTION_NONE;
+ result = ap_parse_form_data(r, NULL, &pairs, 3, 1024);
+
+ if (result != OK)
+ return result;
+
+ while (pairs && !apr_is_empty_array(pairs)) {
+ ap_form_pair_t *pair = (ap_form_pair_t *)apr_array_pop(pairs);
+ if (!strcmp(pair->name, "action")) {
+ apr_size_t len;
+ char *value = NULL;
+ result = apr_brigade_pflatten(pair->value, &value, &len,
+ r->pool);
+ if (result == OK && !strncmp(value, "get", len))
+ action = TEST_SESSION_ACTION_GET;
+ else if (result == OK && !strncmp(value, "set", len))
+ action = TEST_SESSION_ACTION_SET;
+ else
+ return HTTP_BAD_REQUEST;
+ }
+ else if (!strcmp(pair->name, "name")) {
+ apr_off_t off;
+ apr_size_t len;
+ apr_brigade_length(pair->value, 1, &off);
+ len = (apr_size_t)off;
+ fieldName = apr_pcalloc(r->pool, sizeof(char) * len + 1);
+ result = apr_brigade_flatten(pair->value, fieldName, &len);
+ }
+ else if (!strcmp(pair->name, "value")) {
+ apr_off_t off;
+ apr_size_t len;
+ apr_brigade_length(pair->value, 1, &off);
+ len = (apr_size_t)off;
+ fieldValue = apr_pcalloc(r->pool, sizeof(char) * len + 1);
+ result = apr_brigade_flatten(pair->value, fieldValue, &len);
+ }
+ else {
+ return HTTP_BAD_REQUEST;
+ }
+
+ if (result != OK)
+ return result;
+ }
+
+ switch (action) {
+ case TEST_SESSION_ACTION_GET:
+ return test_session_get(r, fieldName);
+
+ case TEST_SESSION_ACTION_SET:
+ return test_session_set(r, fieldName, fieldValue);
+
+ default:
+ return HTTP_BAD_REQUEST;
+ }
+ }
+
+ return OK;
+}
+
+static void *test_session_dcfg_create(apr_pool_t *p, char *dummy)
+{
+ return apr_pcalloc(p, sizeof(test_session_dcfg_t));
+}
+
+static void *test_session_dcfg_merge(apr_pool_t * p, void *basev, void *addv)
+{
+ test_session_dcfg_t *add = addv;
+ test_session_dcfg_t *base = basev;
+ test_session_dcfg_t *new = apr_pcalloc(p, sizeof(test_session_dcfg_t));
+
+ new->session = (add->session_set == 0) ? base->session : add->session;
+ new->session_set = add->session_set || base->session_set;
+ new->encoder = (add->encoder_set == 0) ? base->encoder : add->encoder;
+ new->encoder_set = add->encoder_set || base->encoder_set;
+
+ return new;
+}
+
+static const char *set_session_enable(cmd_parms * parms, void *dconf, int flag)
+{
+ test_session_dcfg_t *conf = dconf;
+
+ conf->session = flag;
+ conf->session_set = 1;
+
+ return NULL;
+}
+
+static const char *set_encoder_enable(cmd_parms * parms, void *dconf, int flag)
+{
+ test_session_dcfg_t *conf = dconf;
+
+ conf->encoder = flag;
+ conf->encoder_set = 1;
+
+ return NULL;
+}
+
+static const command_rec test_session_cmds[] = {
+ AP_INIT_FLAG("TestSession", set_session_enable, NULL, OR_ALL,
+ "Enable test sessions"),
+ AP_INIT_FLAG("TestSessionEncoder", set_encoder_enable, NULL, OR_ALL,
+ "Enable test session encoding"),
+ { NULL }
+};
+
+static void extra_hooks(apr_pool_t *pool)
+{
+ ap_hook_session_load(test_session_load,
+ NULL, NULL, APR_HOOK_MIDDLE);
+
+ ap_hook_session_save(test_session_save,
+ NULL, NULL, APR_HOOK_MIDDLE);
+
+ ap_hook_session_encode(test_session_encode,
+ NULL, NULL, APR_HOOK_MIDDLE);
+
+ ap_hook_session_decode(test_session_decode,
+ NULL, NULL, APR_HOOK_MIDDLE);
+}
+
+APACHE_HTTPD_TEST_MODULE(test_session);