From 0021b5c08344b84cfe9504dc9b5cbfaac331942b Mon Sep 17 00:00:00 2001 From: Yasuo Ohgaki Date: Thu, 12 Feb 2015 13:28:52 +0900 Subject: [PATCH 1/2] Use new session save handler --- php_memcached_session.c | 62 +++++++++++++++++++++++++++++++++++++-- php_memcached_session.h | 5 +++- tests/session_basic2.phpt | 47 +++++++++++++++++++++++++++++ tests/session_basic3.phpt | 47 +++++++++++++++++++++++++++++ 4 files changed, 157 insertions(+), 4 deletions(-) create mode 100644 tests/session_basic2.phpt create mode 100644 tests/session_basic3.phpt diff --git a/php_memcached_session.c b/php_memcached_session.c index 1d2dbe3..4d1a257 100644 --- a/php_memcached_session.c +++ b/php_memcached_session.c @@ -24,7 +24,7 @@ extern ZEND_DECLARE_MODULE_GLOBALS(php_memcached) #define MEMC_SESS_LOCK_EXPIRATION 30 ps_module ps_mod_memcached = { - PS_MOD(memcached) + PS_MOD_UPDATE_TIMESTAMP(memcached) }; static int php_memc_sess_lock(memcached_st *memc, const char *key) @@ -346,8 +346,8 @@ PS_WRITE_FUNC(memcached) return FAILURE; } - if (PS(gc_maxlifetime) > 0) { - expiration = PS(gc_maxlifetime); + if (maxlifetime > 0) { + expiration = maxlifetime; } /* Set the number of write retry attempts to the number of replicas times the number of attempts to remove a server plus the initial write */ @@ -383,4 +383,60 @@ PS_GC_FUNC(memcached) { return SUCCESS; } + +PS_CREATE_SID_FUNC(memcached) +{ + zend_string *sid; + int maxfail = 3; + memcached_sess *memc_sess = PS_GET_MOD_DATA(); + + do { + sid = php_session_create_id((void**)&memc_sess); + if (!sid) { + if (--maxfail < 0) { + return NULL; + } else { + continue; + } + } + /* Check collision */ + /* FIXME: mod_data(memc_sess) should not be NULL (User handler could be NULL) */ + if (memc_sess && memcached_exist(memc_sess->memc_sess, sid->val, sid->len) == MEMCACHED_SUCCESS) { + if (sid) { + zend_string_release(sid); + sid = NULL; + } + if (--maxfail < 0) { + return NULL; + } + } + } while(!sid); + + return sid; +} + +PS_VALIDATE_SID_FUNC(memcached) +{ + memcached_sess *memc_sess = PS_GET_MOD_DATA(); + + if (memcached_exist(memc_sess->memc_sess, key->val, key->len) == MEMCACHED_SUCCESS) { + return SUCCESS; + } else { + return FAILURE; + } +} + +PS_UPDATE_TIMESTAMP_FUNC(memcached) +{ + memcached_sess *memc_sess = PS_GET_MOD_DATA(); + time_t expiration = 0; + + if (maxlifetime > 0) { + expiration = maxlifetime; + } + if (memcached_touch(memc_sess->memc_sess, key->val, key->len, expiration) == MEMCACHED_FAILURE) { + return FAILURE; + } + return SUCCESS; +} /* }}} */ diff --git a/php_memcached_session.h b/php_memcached_session.h index 97fe200..4118362 100644 --- a/php_memcached_session.h +++ b/php_memcached_session.h @@ -24,7 +24,7 @@ extern ps_module ps_mod_memcached; #define ps_memcached_ptr &ps_mod_memcached -PS_FUNCS(memcached); +PS_FUNCS_UPDATE_TIMESTAMP(memcached); PS_OPEN_FUNC(memcached); PS_CLOSE_FUNC(memcached); @@ -32,5 +32,8 @@ PS_READ_FUNC(memcached); PS_WRITE_FUNC(memcached); PS_DESTROY_FUNC(memcached); PS_GC_FUNC(memcached); +PS_CREATE_SID_FUNC(memcached); +PS_VALIDATE_SID_FUNC(memcached); +PS_UPDATE_TIMESTAMP_FUNC(memcached); #endif /* PHP_MEMCACHED_SESSION_H */ diff --git a/tests/session_basic2.phpt b/tests/session_basic2.phpt new file mode 100644 index 0000000..f99063a --- /dev/null +++ b/tests/session_basic2.phpt @@ -0,0 +1,47 @@ +--TEST-- +Session basic open, write, destroy +--SKIPIF-- + +--INI-- +memcached.sess_locking = on +memcached.sess_lock_wait = 150000 +memcached.sess_prefix = "memc.sess.key." +session.save_handler = memcached + +--FILE-- +TRUE); +$_SESSION['foo'] = 1; +session_write_close(); + +$_SESSION = NULL; + +var_dump($_SESSION); +session_start(); +var_dump($_SESSION); +session_write_close(); + +session_start(); +session_destroy(); + +session_start(); +var_dump($_SESSION); +session_write_close(); + + +--EXPECT-- +NULL +array(1) { + ["foo"]=> + int(1) +} +array(0) { +} diff --git a/tests/session_basic3.phpt b/tests/session_basic3.phpt new file mode 100644 index 0000000..fc4e7ae --- /dev/null +++ b/tests/session_basic3.phpt @@ -0,0 +1,47 @@ +--TEST-- +Session basic open, write, destroy +--SKIPIF-- + +--INI-- +memcached.sess_locking = on +memcached.sess_lock_wait = 150000 +memcached.sess_prefix = "memc.sess.key." +session.save_handler = memcached + +--FILE-- +TRUE); +$_SESSION['foo'] = 1; +session_write_close(); + +$_SESSION = NULL; + +var_dump($_SESSION); +session_start(); +var_dump($_SESSION); +session_write_close(); + +session_start(); +session_destroy(); + +session_start(); +var_dump($_SESSION); +session_write_close(); + + +--EXPECT-- +NULL +array(1) { + ["foo"]=> + int(1) +} +array(0) { +} From bd321830676d7e313b4b39bec6fbeb6ec9f9f7d8 Mon Sep 17 00:00:00 2001 From: Yasuo Ohgaki Date: Sat, 16 Jan 2016 06:19:50 +0900 Subject: [PATCH 2/2] Fixed session read return value --- php_memcached_session.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php_memcached_session.c b/php_memcached_session.c index 4d1a257..59b1246 100644 --- a/php_memcached_session.c +++ b/php_memcached_session.c @@ -326,6 +326,8 @@ PS_READ_FUNC(memcached) *val = zend_string_init(payload, payload_len, 1); free(payload); return SUCCESS; + } else if (status = MEMCACHED_NOTFOUND) { + *val = ZSTR_EMPTY_ALLOC(); } else { return FAILURE; }