diff --git a/php_memcached_session.c b/php_memcached_session.c index b04cd92..5f66e41 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) @@ -336,6 +336,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; } @@ -361,8 +363,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 */ @@ -403,4 +405,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) { +}