diff options
author | Hongbo Liu <hongbodev@gmail.com> | 2018-05-18 00:41:47 +0300 |
---|---|---|
committer | Pavlo Yatsukhnenko <yatsukhnenko@gmail.com> | 2018-06-04 09:38:35 +0300 |
commit | aaaf0f233afe404bc1d8c6a600af860448ee0bd6 (patch) | |
tree | 9997f70941acca06373418b3d9ea6943fe8b9373 /redis_session.c | |
parent | 28ec432247f597216846593d62b21e2eef8461c5 (diff) |
Add callbacks validate_sid() & update_timestamp() to session handler
Newer session handler API(PS_MOD_UPDATE_TIMESTAMP) supports 2 more callbacks:
* validate_sid() is used by session.use_strict_mode, which provides better security.
* update_timestamp() is used by session.lazy_write, which can improve performance in some situations.
Diffstat (limited to 'redis_session.c')
-rw-r--r-- | redis_session.c | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/redis_session.c b/redis_session.c index 06e7993a..90632269 100644 --- a/redis_session.c +++ b/redis_session.c @@ -61,9 +61,16 @@ /* Check if a response is the Redis +OK status response */ #define IS_REDIS_OK(r, len) (r != NULL && len == 3 && !memcmp(r, "+OK", 3)) +#if (PHP_MAJOR_VERSION < 7) ps_module ps_mod_redis = { PS_MOD_SID(redis) }; +#else +ps_module ps_mod_redis = { + PS_MOD_UPDATE_TIMESTAMP(redis) +}; +#endif + ps_module ps_mod_redis_cluster = { PS_MOD(rediscluster) }; @@ -636,6 +643,105 @@ PS_CREATE_SID_FUNC(redis) } /* }}} */ +#if (PHP_MAJOR_VERSION >= 7) +/* {{{ PS_VALIDATE_SID_FUNC + */ +PS_VALIDATE_SID_FUNC(redis) +{ + char *cmd, *response; + int cmd_len, response_len; +#if (PHP_MAJOR_VERSION < 7) + const char *skey = key; + size_t skeylen = strlen(key); +#else + const char *skey = ZSTR_VAL(key); + size_t skeylen = ZSTR_LEN(key); +#endif + + if (!skeylen) return FAILURE; + + redis_pool *pool = PS_GET_MOD_DATA(); + redis_pool_member *rpm = redis_pool_get_sock(pool, skey TSRMLS_CC); + RedisSock *redis_sock = rpm ? rpm->redis_sock : NULL; + if (!redis_sock) { + return FAILURE; + } + + /* send EXISTS command */ + zend_string *session = redis_session_key(rpm, skey, skeylen); + cmd_len = REDIS_SPPRINTF(&cmd, "EXISTS", "S", session); + zend_string_release(session); + if (redis_sock_write(redis_sock, cmd, cmd_len TSRMLS_CC) < 0) { + efree(cmd); + return FAILURE; + } + efree(cmd); + + /* read response */ + if ((response = redis_sock_read(redis_sock, &response_len TSRMLS_CC)) == NULL) { + return FAILURE; + } + + if (response_len == 2 && response[0] == ':' && response[1] == '1') { + efree(response); + return SUCCESS; + } else { + efree(response); + return FAILURE; + } +} +/* }}} */ + +/* {{{ PS_UPDATE_TIMESTAMP_FUNC + */ +PS_UPDATE_TIMESTAMP_FUNC(redis) +{ + char *cmd, *response; + int cmd_len, response_len; +#if (PHP_MAJOR_VERSION < 7) + const char *skey = key, *sval = val; + size_t skeylen = strlen(key), svallen = vallen; +#else + const char *skey = ZSTR_VAL(key), *sval = ZSTR_VAL(val); + size_t skeylen = ZSTR_LEN(key), svallen = ZSTR_LEN(val); +#endif + + if (!skeylen) return FAILURE; + + redis_pool *pool = PS_GET_MOD_DATA(); + redis_pool_member *rpm = redis_pool_get_sock(pool, skey TSRMLS_CC); + RedisSock *redis_sock = rpm ? rpm->redis_sock : NULL; + if (!redis_sock) { + return FAILURE; + } + + /* send EXPIRE command */ + zend_string *session = redis_session_key(rpm, skey, skeylen); + cmd_len = REDIS_SPPRINTF(&cmd, "EXPIRE", "Sd", session, INI_INT("session.gc_maxlifetime")); + zend_string_release(session); + + if (!write_allowed(redis_sock, &pool->lock_status TSRMLS_CC) || redis_sock_write(redis_sock, cmd, cmd_len TSRMLS_CC) < 0) { + efree(cmd); + return FAILURE; + } + efree(cmd); + + /* read response */ + if ((response = redis_sock_read(redis_sock, &response_len TSRMLS_CC)) == NULL) { + return FAILURE; + } + + if (response_len == 2 && response[0] == ':' && response[1] == '1') { + efree(response); + return SUCCESS; + } else { + efree(response); + return FAILURE; + } +} +/* }}} */ +#endif + /* {{{ PS_READ_FUNC */ PS_READ_FUNC(redis) |