Merge commit 'a3cd342f3e1fffd7b16b83a24e03bb9ed501b319' as 'src/deps/src/lua-resty-session'

This commit is contained in:
Théophile Diot 2023-06-30 15:38:54 -04:00
commit 6f8ff3f12e
55 changed files with 21241 additions and 0 deletions

View File

@ -0,0 +1,8 @@
return {
default = {
lua = "resty --shdict 'sessions 1m' --main-conf 'thread_pool default threads=32 max_queue=65536;'",
verbose = true,
coverage = true,
output = "gtest",
}
}

View File

@ -0,0 +1,19 @@
name: integration_tests
on: [pull_request]
jobs:
test:
strategy:
fail-fast: false
matrix:
luaVersion: ["luajit-openresty"]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup environment
run: docker build dev/ -t resty-session
- name: Run tests
run: docker run -v $PWD:/test -w /test resty-session bash -c "luarocks make && make prove"

View File

@ -0,0 +1,42 @@
name: unit_tests
on: [pull_request]
jobs:
test:
strategy:
fail-fast: false
matrix:
luaVersion: ["luajit-openresty"]
services:
redis:
image: bitnami/redis
env:
REDIS_PASSWORD: password
ports:
- 6379:6379
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
memcached:
image: memcached
ports:
- 11211:11211
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup environment
run: docker build dev/ -t resty-session
- name: Run tests
run: docker run --network=host -v $PWD:/test -w /test resty-session bash -c "luarocks make && make unit"
- name: Generate report
run: docker run --network=host -v $PWD:/test -w /test resty-session bash -c "luarocks make && luacov"
- name: Print report summary
run: docker run --network=host -v $PWD:/test -w /test resty-session sed -n '/Summary/,$p' luacov.report.out

View File

@ -0,0 +1 @@
/.project

View File

@ -0,0 +1,4 @@
std = "ngx_lua"
redefined = false
max_line_length = false
files["lib/resty/session/file.lua"] = { ignore = {"143"}}

View File

@ -0,0 +1,31 @@
return {
-- filename to store stats collected
["statsfile"] = "luacov.stats.out",
-- filename to store report
["reportfile"] = "luacov.report.out",
-- Run reporter on completion? (won't work for ticks)
runreport = true,
-- Patterns for files to include when reporting
-- all will be included if nothing is listed
-- (exclude overrules include, do not include
-- the .lua extension, path separator is always '/')
["include"] = { 'resty/session' },
-- Patterns for files to exclude when reporting
-- all will be included if nothing is listed
-- (exclude overrules include, do not include
-- the .lua extension, path separator is always '/')
["exclude"] = {
"luacov$",
"luacov/reporter$",
"luacov/defaults$",
"luacov/runner$",
"luacov/stats$",
"luacov/tick$",
},
}

View File

@ -0,0 +1,467 @@
# Changelog
All notable changes to `lua-resty-session` will be documented in this file.
## [4.0.4] - 2023-06-05
### Changed
- chore(utils): remove dependency for lua_pack, fix #158
## [4.0.3] - 2023-02-21
### Fixed
- fix(*): redis authorization
## [4.0.2] - 2023-02-15
### Fixed
- fix(*): hkdf is not approved by FIPS, use PBKDF2 instead on FIPS-mode
## [4.0.1] - 2023-02-05
### Fixed
- fix(session): clear_request cookie to check remember_meta correctly before using it
### Added
- feat(opm): add more dependencies in requires
- feat(opm): add right version number requirements
- docs(readme): add remark on dependencies on installation section
## [4.0.0] - 2023-02-01
- Full rewrite of the library, and is not backwards compatible. Refer new
documentation on this new library.
## [3.10] - 2022-01-14
### Fixed
- 3.9 introduced an issue where calling session:regenerate with flush=true,
didn't really flush if the session strategy was `regenerate`.
## [3.9] - 2022-01-14
### Fixed
- Fix #138 issue of chunked cookies are not expired when session shrinks,
thanks @alexdowad.
- Fix #134 where regenerate strategy destroyed previous session when calling
`session:regenerate`, it should just `ttl` the old session.
### Added
- AES GCM mode support was added to AES cipher.
This is recommended, but for backward compatibility it was not set as default.
It will be changed in 4.0 release.
- Redis ACL authentication is now available.
- Add `session_redis_username`
- Add `session_redis_password`
- Deprecate `session_redis_auth`; use `session_redis_password`
### Changed
- Optimize Redis and Memcache storage adapters to not connect to database
when not needed.
## [3.8] - 2021-01-04
### Added
- Connection options are now passed to `redis cluster client` as well.
## [3.7] - 2020-10-27
### Fixed
- Fix #107 where `session.start` could release a lock for a short period
### Added
- Add `keep_lock` argument to `session.open`
- Add pluggable compressors, and implement `none` and `zlib` compressor
## [3.6] - 2020-06-24
### Fixed
- Fix `session:hide()` to only send a single `Cookie` header at most as
reported by @jharriman who also provided a fix with #103. Thank you!
## [3.5] - 2020-05-22
### Fixed
- Fix `session:hide()` to not clear non-session request cookies that it
seemed to do in some cases as reported by @altexy who also provided
initial fix with #100. Thank you!
## [3.4] - 2020-05-08
### Fixed
- Fix session_cookie_maxsize - error attempt to compare string with number,
fixes #98, thank you @vavra5
### Changed
- More robust and uniform configuration parsing
## [3.3] - 2020-05-06
### Fixed
- Fix `set_timeouts` is only called if all parameters are available,
should fix #96, thank you @notdodo.
### Added
- Add `$session_memcache_connect_timeout` configuration option
- Add `$session_memcache_read_timeout` configuration option
- Add `$session_memcache_send_timeout` configuration option
- Add `$session_memcache_pool_name` configuration option
- Add `$session_memcache_pool_backlog` configuration option
- Add `$session_dshm_connect_timeout` configuration option
- Add `$session_dshm_read_timeout` configuration option
- Add `$session_dshm_send_timeout` configuration option
- Add `$session_dshm_pool_name` configuration option
- Add `$session_dshm_pool_backlog` configuration option
## [3.2] - 2020-04-30
### Added
- Support for Redis clusters
- Add `$session_redis_connect_timeout` configuration option
- Add `$session_redis_read_timeout` configuration option
- Add `$session_redis_send_timeout` configuration option
- Add `$session_redis_pool_name` configuration option
- Add `$session_redis_pool_backlog` configuration option
- Add `$session_redis_cluster_name` configuration option
- Add `$session_redis_cluster_dict` configuration option
- Add `$session_redis_cluster_maxredirections` configuration option
- Add `$session_redis_cluster_nodes` configuration option
## [3.1] - 2020-03-28
### Added
- A more flexible way to specify custom implementations:
`require "resty.session".new { storage = require "my.storage" }`
## [3.0] - 2020-03-27
### Fixed
- Lock releasing is a lot more robust now
### Added
- Add idletime setting (thanks @Tieske), see `session.cookie.idletime`
- Add support for Cookie prefixes `__Host-` and `__Secure-` on Cookie
name (see: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-05#section-4.1.3)
### Changed
- The whole codebase was refactored and simplified, especially implementing
new storage adapters is now a lot easier
- Redis and Memcached `spinlockwait` was changed from microseconds to milliseconds and default
is set to `150` milliseconds,
- Redis and Memcache will only release locks that current session instance holds
- DSHM `session_dshm_store` was renamed to `session_dshm_region`
- BASE64 encoding now strips the padding
## [2.26] - 2020-02-11
### Added
- Add support for `SameSite=None` (#83) (thanks @bodewig)
- Style changes (#77) (thanks @Tieske)
## [2.25] - 2019-11-06
### Added
- Add SSL support for the Redis storage option (#75) (thanks @tieske)
- DSHM storage adapter (a distributed SHM storage based on Hazelcast for Nginx)
(thanks @grrolland)
## [2.24] - 2019-07-09
### Fixed
- Avoid use unix socket and redis password with empty string
- Provide session id when closing, otherwise the lock is not deleted
### Added
- Added a configuration for session cookie max size (`session.cookie.maxsize`)
## [2.23] - 2018-12-12
### Added
- Added pluggable strategies with `default` and a new `regenerate` strategy
- Added pluggable `hmac`s
- Added `session.close`
- Added `ttl` to `storages`
- Added `session.cookie.discard`, a `ttl` how long to keep old sessions when
renewing (used by `regenerate` strategy
## [2.22] - 2018-03-17
### Fixed
- Only sets self.cookie.secure if not defined.
## [2.21] - 2018-03-16
### Screwed
- Forgot to bump version number.
## [2.20] - 2018-03-16
### Fixed
- Fixes issue where check addr and check scheme could be faked.
See also: https://github.com/bungle/lua-resty-session/issues/47
Thanks @nielsole
## [2.19] - 2017-09-19
### Fixed
- Fixes small bug where aes could generate invalid salt on invalid input
that further crashes Lua with error: bad argument #2 to 'salt' (number
expected, got no value)
## [2.18] - 2017-07-10
### Fixed
- Automatically creates exactly 64 bits salt as required by the latest
lua-resty-string.
See also: https://github.com/bungle/lua-resty-session/issues/40
Thanks @peturorri
## [2.17] - 2017-06-12
### Added
- Added session.hide() function to hide session cookies from upstream
on reverse proxy scenarios.
## [2.16] - 2017-05-31
### Changed
- Delays setting the defaults until needed, allowing users to safely
require "resty.session" in different contexts.
## [2.15] - 2017-02-13
## Added
- Added a support for chunked cookies.
See also: https://github.com/bungle/lua-resty-session/issues/35
Thanks @zandbelt
## [2.14] - 2016-12-16
### Fixed
- Lua code configuration parsing corrections (especially on boolean
options).
## Added
- Added a more natural way to pass config arguments to storage
adapters and ciphers in Lua code.
See also: https://github.com/bungle/lua-resty-session/issues/34
Thanks @hanxi
## [2.13] - 2016-11-21
### Changed
- On start we do send cookie now also if the settings have changed
and the cookie expiry time needs to be reduced.
### Fixed
- Memcache storage adapter had a missing ngx.null.
## [2.12] - 2016-11-21
### Added
- Implemented pluggable session identifier generators.
- Implemented random session idenfier generator.
### Changed
- Now checks if headers were already sent before trying to set the
cookie headers.
- SSL session identifier is not checked by default anymore.
- Lua session.identifier.length changed to session.random.length.
- Nginx $session_identifier_length changed to $session_random_length.
## [2.11] - 2016-09-30
### Changed
- Just another OPM release to correct the name.
## [2.10] - 2016-09-29
### Added
- Support for the official OpenResty package manager (opm).
### Changed
- Changed the change log format to keep-a-changelog.
## [2.9] - 2016-09-01
### Fixed
- Bugfix: Weird bug where RAND_bytes was not working on Windows platform.
Code changed to use resty.random. See Also:
https://github.com/bungle/lua-resty-session/issues/31
Thanks @gtuxyco
## [2.8] - 2016-07-05
### Fixed
- Bugfix: AES Cipher used a wrong table for cipher sizes.
See Also: https://github.com/bungle/lua-resty-session/issues/30
Thanks @pronan
## [2.7] - 2016-05-18
### Added
- Redis storage adapter now supports Redis authentication.
See Also: https://github.com/bungle/lua-resty-session/pull/28
Thanks @cheng5533062
## [2.6] - 2016-04-18
### Changed
- Just cleanups and changed _VERSION to point correct version.
## [2.5] - 2016-04-18
### Fixed
- session.save close argument was not defaulting to true.
## [2.4] - 2016-04-17
### Added
- Cookie will now have SameSite attribute set as "Lax" by default.
You can turn it off or set to "Strict" by configuration.
### Changed
- Calling save will now also set session.id if the save was called
without calling start first.
See Also: https://github.com/bungle/lua-resty-session/issues/27
Thanks @hcaihao
## [2.3] - 2015-10-16
### Fixed
- Fixes issue #19 where regenerating session would throw an error
when using cookie storage.
See Also: https://github.com/bungle/lua-resty-session/issues/19
Thanks @hulu1522
## [2.2] - 2015-09-17
### Changed
- Removed all session_cipher_* deprecated settings (it was somewhat
broken in 2.1).
- Changed session secret to be by default 32 bytes random data
See Also: https://github.com/bungle/lua-resty-session/issues/18
Thanks @iain-buclaw-sociomantic
### Added
- Added documentation about removed features and corrected about
session secret size accordingly.
## [2.1] - 2015-09-07
### Added
- Added architecture for Cipher adapter plugins.
See Also: https://github.com/bungle/lua-resty-session/issues/16
Thanks @mingfang
- Implemented AES cipher adapter (just like it was before)
- Implemented None cipher adapter (no encryption)
- Added documentation about pluggable ciphers
### Changed
- Changed JSON serializer to use cjson.safe instead
## [2.0] - 2015-08-31
### Added
- Added architecture for Storage adapter plugins.
See Also: https://github.com/bungle/lua-resty-session/issues/13
- Implemented Client Side Cookie storage adapter.
- Implemented Memcache storage adapter.
See Also: https://github.com/bungle/lua-resty-session/pull/14
Thanks @zandbelt
- Implemented Redis storage adapter.
- Implemented Shared Dictionary (shm) storage adapter.
- Added architecture for Encoder and Decoder plugins.
- Implemented Base 64 encoder / decoder.
- Implemented Base 16 (hex) encoder / decoder.
- Added architecture for Serializer plugins
- Implemented JSON serializer.
- Persistent cookies will now also contain Max-Age in addition to Expires.
- Cookie domain attribute is not set anymore if not specified.
- Added notes about using lua-resty-session with Lua code cache turned off.
See also: https://github.com/bungle/lua-resty-session/issues/15
Thanks @BizShuk
## [1.7] - 2015-08-03
### Added
- Added session.open() function that only opens a session but doesn't send
the cookie (until start is called).
See also: https://github.com/bungle/lua-resty-session/issues/12
Thanks @junhanamaki
### Fixed
- Fixed cookie expiration time format on Firefox bug:
https://github.com/bungle/lua-resty-session/pull/10
Thanks @junhanamaki
- Bugfix: Fixed an issue of overwriting a variable:
https://github.com/bungle/lua-resty-session/pull/11
Thanks @junhanamaki
## [1.6] - 2015-05-05
### Fixed
- Fixed truncated cookie value bug:
https://github.com/bungle/lua-resty-session/pull/8
Thanks @kipras
## [1.5] - 2014-11-27
### Fixed
- Cookies are not always "secure":
https://github.com/bungle/lua-resty-session/issues/5
Thanks @vladimir-smirnov-sociomantic
### Added
- Added documentation about Nginx SSL/TLS configuration settings related
to session lifetime and ssl session ids.
## [1.4] - 2014-11-26
### Fixed
- Bugfix: Fixed an issue where session configurations did get cached
on a module level. This issue is discussed in pull-request #4:
https://github.com/bungle/lua-resty-session/pull/4
Thanks @kipras.
### Added
- Added session.new function.
- Added documentation about Nginx configuration used as defaults (not read
on every request), and documented session.new.
### Changed
- session.start{ ... } (a call with config parameters) works now as expected.
- session.start now returns additional extra boolean parameter that can be
used to check if the session is s new session (false) or a previously
started one (true).
## [1.3] - 2014-11-14
### Added
- Added support for persistent sessions. See issue #2.
- Added session.check.ssi, session.cookie.persistent and the related Nginx
configuration variables.
- Added Max-Age=0 to expiration code.
## [1.2] - 2014-10-12
### Fixed
- Changed encode and decode functions to operate with correct number of
arguments. See issue #1.
## [1.1] - 2014-10-03
### Security
- There was a bug where additional user agent, scheme, and remote addr
(disabled by default) was not checked.
### Added
- Added _VERSION field.
### Changed
- Simplied a code a lot (e.g. internal setcookie and getcookie functions are
now cleaner). Removed a lot of unneccessary lines from session.start by
adding configs directly to session prototype.
## [1.0] - 2014-09-24
### Added
- LuaRocks Support via MoonRocks.

View File

@ -0,0 +1,23 @@
Copyright (c) 2014 2023 Aapo Talvensaari, 2022 2023 Samuele Illuminati
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,16 @@
.PHONY: lint test docs
lint:
@luacheck -q ./lib
unit:
busted --exclude-tags=noci --coverage
unit-all:
busted --coverage
prove:
prove
docs:
ldoc .

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,10 @@
project = "resty.session"
description = "Session Library for OpenResty"
full_description = "`lua-resty-session` is a secure, and flexible session library for OpenResty"
title = "Session Library for OpenResty Documentation"
dir = "docs"
use_markdown_titles = true
package = "session"
format = "discount"
sort_modules=true
file = "./lib/resty"

View File

@ -0,0 +1,20 @@
FROM openresty/openresty:1.21.4.1-focal
ENV DEBIAN_FRONTEND noninteractive
ENV TEST_NGINX_BINARY openresty
USER root
RUN apt-get update && apt-get install -y gcc git cpanminus
RUN git clone https://github.com/Olivine-Labs/busted
RUN cd busted && luarocks make
RUN luarocks install pgmoon
RUN luarocks install lua-resty-rsa
RUN luarocks install lua-resty-redis-connector
RUN luarocks install lua-resty-redis-cluster
RUN luarocks install inspect
RUN luarocks install lua_pack
RUN luarocks install LuaCov
RUN cpanm --notest Test::Nginx

View File

@ -0,0 +1,7 @@
name = lua-resty-session
abstract = Session Library for OpenResty - Flexible and Secure
author = Aapo Talvensaari (@bungle), Samuele Illuminati (@samugi)
is_original = yes
license = 2bsd
repo_link = https://github.com/bungle/lua-resty-session
requires = luajit, nginx, ngx_http_lua, fffonion/lua-resty-openssl >= 0.8.0, hamishforbes/lua-ffi-zlib >= 0.5

View File

@ -0,0 +1,906 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head>
<title>Session Library for OpenResty Documentation</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head>
<body>
<div id="container">
<div id="product">
<div id="product_logo"></div>
<div id="product_name"><big><b></b></big></div>
<div id="product_description"></div>
</div> <!-- id="product" -->
<div id="main">
<!-- Menu -->
<div id="navigation">
<br/>
<h1>resty.session</h1>
<ul>
<li><a href="../index.html">Index</a></li>
</ul>
<h2>Contents</h2>
<ul>
<li><a href="#Session">Session </a></li>
<li><a href="#Constructors">Constructors </a></li>
</ul>
<h2>Classes</h2>
<ul class="nowrap">
<li><strong>resty.session</strong></li>
</ul>
<h2>Modules</h2>
<ul class="nowrap">
<li><a href="../modules/resty.session.dshm.html">resty.session.dshm</a></li>
<li><a href="../modules/resty.session.file.html">resty.session.file</a></li>
<li><a href="../modules/resty.session.memcached.html">resty.session.memcached</a></li>
<li><a href="../modules/resty.session.mysql.html">resty.session.mysql</a></li>
<li><a href="../modules/resty.session.postgres.html">resty.session.postgres</a></li>
<li><a href="../modules/resty.session.redis.html">resty.session.redis</a></li>
<li><a href="../modules/resty.session.redis-cluster.html">resty.session.redis-cluster</a></li>
<li><a href="../modules/resty.session.redis-sentinel.html">resty.session.redis-sentinel</a></li>
<li><a href="../modules/resty.session.shm.html">resty.session.shm</a></li>
<li><a href="../modules/resty.session.utils.html">resty.session.utils</a></li>
</ul>
</div>
<div id="content">
<h1>Class <code>resty.session</code></h1>
<p>Session library provides HTTP session management capabilities for OpenResty based
applications, libraries and proxies.</p>
<p>
</p>
<h2><a href="#Session">Session </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#session.info:set">session.info:set (key, value)</a></td>
<td class="summary">Set a value in session information store.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#session.info:get">session.info:get (key)</a></td>
<td class="summary">Get a value from session information store.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#session.info:save">session.info:save ()</a></td>
<td class="summary">Save information.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#resty.session:set">resty.session:set (key, value)</a></td>
<td class="summary">Set a value in session.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#resty.session:get">resty.session:get (key)</a></td>
<td class="summary">Get a value from session.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#resty.session:open">resty.session:open ()</a></td>
<td class="summary">Open a session.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#resty.session:save">resty.session:save ()</a></td>
<td class="summary">Save the session.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#resty.session:touch">resty.session:touch ()</a></td>
<td class="summary">Touch the session.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#resty.session:refresh">resty.session:refresh ()</a></td>
<td class="summary">Refresh the session.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#resty.session:logout">resty.session:logout ()</a></td>
<td class="summary">Logout the session.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#resty.session:destroy">resty.session:destroy ()</a></td>
<td class="summary">Destroy the session.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#resty.session:close">resty.session:close ()</a></td>
<td class="summary">Close the session.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:hide">instance:hide ()</a></td>
<td class="summary">Hide the session.</td>
</tr>
</table>
<h2><a href="#Constructors">Constructors </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#resty.session.configuration">resty.session.configuration</a></td>
<td class="summary">Session configuration.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#module.init">module.init ([configuration])</a></td>
<td class="summary">Initialize the session library.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#module.new">module.new ([configuration])</a></td>
<td class="summary">Create a new session.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#module.open">module.open ([configuration])</a></td>
<td class="summary">Open a session.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#module.start">module.start ([configuration])</a></td>
<td class="summary">Start a session and refresh it as needed.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#module.logout">module.logout ([configuration])</a></td>
<td class="summary">Logout a session.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#module.destroy">module.destroy ([configuration])</a></td>
<td class="summary">Destroy a session.</td>
</tr>
</table>
<br/>
<br/>
<h2 class="section-header "><a name="Session"></a>Session </h2>
<dl class="function">
<dt>
<a name = "session.info:set"></a>
<strong>session.info:set (key, value)</strong>
</dt>
<dd>
Set a value in session information store.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
<pre><code>key
</code></pre>
</li>
<li><span class="parameter">value</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
value
</li>
</ul>
</dd>
<dt>
<a name = "session.info:get"></a>
<strong>session.info:get (key)</strong>
</dt>
<dd>
Get a value from session information store.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
<pre><code>key
</code></pre>
</li>
</ul>
<h3>Returns:</h3>
<ol>
value
</ol>
</dd>
<dt>
<a name = "session.info:save"></a>
<strong>session.info:save ()</strong>
</dt>
<dd>
Save information. </p>
<p> Only updates backend storage. Does not send a new cookie.
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">true</span> or <span class="type">nil</span></span>
ok</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "resty.session:set"></a>
<strong>resty.session:set (key, value)</strong>
</dt>
<dd>
Set a value in session.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
<pre><code>key
</code></pre>
</li>
<li><span class="parameter">value</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
value
</li>
</ul>
</dd>
<dt>
<a name = "resty.session:get"></a>
<strong>resty.session:get (key)</strong>
</dt>
<dd>
Get a value from session.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
<pre><code>key
</code></pre>
</li>
</ul>
<h3>Returns:</h3>
<ol>
value
</ol>
</dd>
<dt>
<a name = "resty.session:open"></a>
<strong>resty.session:open ()</strong>
</dt>
<dd>
Open a session. </p>
<p> This can be used to open a session. It will either return an existing
session or a new session.
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">true</span> or <span class="type">nil</span></span>
ok</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "resty.session:save"></a>
<strong>resty.session:save ()</strong>
</dt>
<dd>
Save the session. </p>
<p> Saves the session data and issues a new session cookie with a new session id.
When <code>remember</code> is enabled, it will also issue a new persistent cookie and
possibly save the data in backend store.
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">true</span> or <span class="type">nil</span></span>
ok</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "resty.session:touch"></a>
<strong>resty.session:touch ()</strong>
</dt>
<dd>
Touch the session. </p>
<p> Updates idling offset of the session by sending an updated session cookie.
It only sends the client cookie and never calls any backend session store
APIs. Normally the <a href="../classes/resty.session.html#resty.session:refresh">session:refresh</a> is used to call this indirectly.
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">true</span> or <span class="type">nil</span></span>
ok</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "resty.session:refresh"></a>
<strong>resty.session:refresh ()</strong>
</dt>
<dd>
Refresh the session. </p>
<p> Either saves the session (creating a new session id) or touches the session
depending on whether the rolling timeout is getting closer. The touch has
a threshold, by default one minute, so it may be skipped in some cases.
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">true</span> or <span class="type">nil</span></span>
ok</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "resty.session:logout"></a>
<strong>resty.session:logout ()</strong>
</dt>
<dd>
Logout the session. </p>
<p> Logout either destroys the session or just clears the data for the current audience,
and saves it (logging out from the current audience).
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">true</span> or <span class="type">nil</span></span>
ok</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "resty.session:destroy"></a>
<strong>resty.session:destroy ()</strong>
</dt>
<dd>
Destroy the session. </p>
<p> Destroy the session and clear the cookies.
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">true</span> or <span class="type">nil</span></span>
ok</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "resty.session:close"></a>
<strong>resty.session:close ()</strong>
</dt>
<dd>
Close the session. </p>
<p> Just closes the session instance so that it cannot be used anymore.
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">true</span> or <span class="type">nil</span></span>
ok</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:hide"></a>
<strong>instance:hide ()</strong>
</dt>
<dd>
Hide the session. </p>
<p> Modifies the request headers by removing the session related
cookies. This is useful when you use the session library on
a proxy server and don&rsquo;t want the session cookies to be forwarded
to the upstream service.
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">true</span> or <span class="type">nil</span></span>
ok
</ol>
</dd>
</dl>
<h2 class="section-header "><a name="Constructors"></a>Constructors </h2>
<dl class="function">
<dt>
<a name = "resty.session.configuration"></a>
<strong>resty.session.configuration</strong>
</dt>
<dd>
Session configuration.
<h3>Fields:</h3>
<ul>
<li><span class="parameter">secret</span>
Secret used for the key derivation. The secret is hashed with SHA-256 before using it. E.g. <code>&quot;RaJKp8UQW1&quot;</code>.
</li>
<li><span class="parameter">secret_fallbacks</span>
Array of secrets that can be used as alternative secrets (when doing key rotation), E.g. <code>{ &quot;6RfrAYYzYq&quot;, &quot;MkbTkkyF9C&quot; }</code>.
</li>
<li><span class="parameter">ikm</span>
Initial key material (or ikm) can be specified directly (without using a secret) with exactly 32 bytes of data, e.g. <code>&quot;5ixIW4QVMk0dPtoIhn41Eh1I9enP2060&quot;</code>
</li>
<li><span class="parameter">ikm_fallbacks</span>
Array of initial key materials that can be used as alternative keys (when doing key rotation), E.g. <code>{ &quot;QvPtlPKxOKdP5MCu1oI3lOEXIVuDckp7&quot; }</code>.
</li>
<li><span class="parameter">cookie_prefix</span>
Cookie prefix, use <code>nil</code>, <code>&quot;__Host-&quot;</code> or <code>&quot;__Secure-&quot;</code> (defaults to <code>nil</code>)
</li>
<li><span class="parameter">cookie_name</span>
Session cookie name, e.g. <code>&quot;session&quot;</code> (defaults to <code>&quot;session&quot;</code>)
</li>
<li><span class="parameter">cookie_path</span>
Cookie path, e.g. <code>&quot;/&quot;</code> (defaults to <code>&quot;/&quot;</code>)
</li>
<li><span class="parameter">cookie_domain</span>
Cookie domain, e.g. <code>&quot;example.com&quot;</code> (defaults to <code>nil</code>)
</li>
<li><span class="parameter">cookie_http_only</span>
Mark cookie HTTP only, use <code>true</code> or <code>false</code> (defaults to <code>true</code>)
</li>
<li><span class="parameter">cookie_secure</span>
Mark cookie secure, use <code>nil</code>, <code>true</code> or <code>false</code> (defaults to <code>nil</code>)
</li>
<li><span class="parameter">cookie_priority</span>
Cookie priority, use <code>nil</code>, <code>&quot;Low&quot;</code>, <code>&quot;Medium&quot;</code>, or <code>&quot;High&quot;</code> (defaults to <code>nil</code>)
</li>
<li><span class="parameter">cookie_same_site</span>
Cookie same-site policy, use <code>nil</code>, <code>&quot;Lax&quot;</code>, <code>&quot;Strict&quot;</code>, or <code>&quot;None&quot;</code> (defaults to <code>&quot;Lax&quot;</code>)
</li>
<li><span class="parameter">cookie_same_party</span>
Mark cookie with same party flag, use <code>nil</code>, <code>true</code>, or <code>false</code> (default: <code>nil</code>)
</li>
<li><span class="parameter">cookie_partitioned</span>
Mark cookie with partitioned flag, use <code>nil</code>, <code>true</code>, or <code>false</code> (default: <code>nil</code>)
</li>
<li><span class="parameter">remember</span>
Enable or disable persistent sessions, use <code>nil</code>, <code>true</code>, or <code>false</code> (defaults to <code>false</code>)
</li>
<li><span class="parameter">remember_cookie_name</span>
Persistent session cookie name, e.g. <code>&quot;remember&quot;</code> (defaults to <code>&quot;remember&quot;</code>)
</li>
<li><span class="parameter">audience</span>
Session audience, e.g. <code>&quot;my-application&quot;</code> (defaults to <code>&quot;default&quot;</code>)
</li>
<li><span class="parameter">subject</span>
Session subject, e.g. <code>&quot;john.doe@example.com&quot;</code> (defaults to <code>nil</code>)
</li>
<li><span class="parameter">stale_ttl</span>
When session is saved a new session is created, stale ttl specifies how long the old one can still be used, e.g. <code>10</code> (defaults to <code>10</code>) (in seconds)
</li>
<li><span class="parameter">idling_timeout</span>
Idling timeout specifies how long the session can be inactive until it is considered invalid, e.g. <code>900</code> (defaults to <code>900</code>, or 15 minutes) (in seconds)
</li>
<li><span class="parameter">rolling_timeout</span>
Rolling timeout specifies how long the session can be used until it needs to be renewed, e.g. <code>3600</code> (defaults to <code>3600</code>, or an hour) (in seconds)
</li>
<li><span class="parameter">absolute_timeout</span>
Absolute timeout limits how long the session can be renewed, until re-authentication is required, e.g. <code>86400</code> (defaults to <code>86400</code>, or a day) (in seconds)
</li>
<li><span class="parameter">remember_timeout</span>
Remember timeout specifies how long the persistent session is considered valid, e.g. <code>604800</code> (defaults to <code>604800</code>, or a week) (in seconds)
</li>
<li><span class="parameter">touch_threshold</span>
Touch threshold controls how frequently or infrequently the <a href="../classes/resty.session.html#resty.session:refresh">session:refresh</a> touches the cookie, e.g. <code>60</code> (defaults to <code>60</code>, or a minute) (in seconds)
</li>
<li><span class="parameter">compression_threshold</span>
Compression threshold controls when the data is deflated, e.g. <code>1024</code> (defaults to <code>1024</code>, or a kilobyte) (in bytes)
</li>
<li><span class="parameter">storage</span>
Storage is responsible of storing session data, use <code>nil</code> (data is stored in cookie), <a href="../modules/resty.session.dshm.html">dshm</a>, <a href="../modules/resty.session.file.html">file</a>, <a href="../modules/resty.session.memcached.html">memcached</a>, <a href="../modules/resty.session.mysql.html">mysql</a>, <a href="../modules/resty.session.postgres.html">postgres</a>, <a href="../modules/resty.session.redis.html">redis</a>, <a href="../modules/resty.session.redis-cluster.html">redis-cluster</a>, <a href="../modules/resty.session.redis-sentinel.html">redis-sentinel</a>, or <a href="../modules/resty.session.shm.html">shm</a>, or give a name of custom module (<code>&quot;custom.session.storage&quot;</code>), or a <a href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a> that implements session storage interface (defaults to <code>nil</code>)
</li>
<li><span class="parameter">dshm</span>
Configuration for dshm storage, e.g. <code>{ prefix = &quot;sessions&quot; }</code>
</li>
<li><span class="parameter">file</span>
Configuration for file storage, e.g. <code>{ path = &quot;/tmp&quot;, suffix = &quot;session&quot; }</code>
</li>
<li><span class="parameter">memcached</span>
Configuration for memcached storage, e.g. <code>{ prefix = &quot;sessions&quot; }</code>
</li>
<li><span class="parameter">mysql</span>
Configuration for MySQL / MariaDB storage, e.g. <code>{ database = &quot;sessions&quot; }</code>
</li>
<li><span class="parameter">postgres</span>
Configuration for Postgres storage, e.g. <code>{ database = &quot;sessions&quot; }</code>
</li>
<li><span class="parameter">redis</span>
Configuration for Redis / Redis Sentinel / Redis Cluster storages, e.g. <code>{ prefix = &quot;sessions&quot; }</code>
</li>
<li><span class="parameter">shm</span>
Configuration for shared memory storage, e.g. <code>{ zone = &quot;sessions&quot; }</code>
</li>
</ul>
</dd>
<dt>
<a name = "module.init"></a>
<strong>module.init ([configuration])</strong>
</dt>
<dd>
Initialize the session library. </p>
<p> This function can be called on <a href="../classes/resty.session.html#module.init">init</a> or <code>init_worker</code> phases on OpenResty
to set global default configuration to all session instances created by this
library.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">configuration</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session <a href="../classes/resty.session.html#resty.session.configuration">configuration</a> overrides
(<em>optional</em>)
</li>
</ul>
<h3>Usage:</h3>
<ul>
<pre class="example"><span class="global">require</span> <span class="string">"resty.session"</span>.init({
audience = <span class="string">"my-application"</span>,
})</pre>
</ul>
</dd>
<dt>
<a name = "module.new"></a>
<strong>module.new ([configuration])</strong>
</dt>
<dd>
Create a new session. </p>
<p> This creates a new session instance.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">configuration</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session <a href="../classes/resty.session.html#resty.session.configuration">configuration</a> overrides
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session instance
</ol>
<h3>Usage:</h3>
<ul>
<pre class="example"><span class="keyword">local</span> session = <span class="global">require</span> <span class="string">"resty.session"</span>.new()
<span class="comment">-- OR
</span><span class="keyword">local</span> session = <span class="global">require</span> <span class="string">"resty.session"</span>.new({
audience = <span class="string">"my-application"</span>,
})</pre>
</ul>
</dd>
<dt>
<a name = "module.open"></a>
<strong>module.open ([configuration])</strong>
</dt>
<dd>
Open a session. </p>
<p> This can be used to open a session, and it will either return an existing
session or a new session.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">configuration</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session <a href="../classes/resty.session.html#resty.session.configuration">configuration</a> overrides
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session instance</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
information why session could not be opened</li>
<li>
<span class="types"><span class="type">boolean</span></span>
<code>true</code>, if session existed, otherwise <code>false</code></li>
</ol>
<h3>Usage:</h3>
<ul>
<pre class="example"><span class="keyword">local</span> session = <span class="global">require</span> <span class="string">"resty.session"</span>.open()
<span class="comment">-- OR
</span><span class="keyword">local</span> session, err, exists = <span class="global">require</span> <span class="string">"resty.session"</span>.open({
audience = <span class="string">"my-application"</span>,
})</pre>
</ul>
</dd>
<dt>
<a name = "module.start"></a>
<strong>module.start ([configuration])</strong>
</dt>
<dd>
Start a session and refresh it as needed. </p>
<p> This can be used to start a session, and it will either return an existing
session or a new session. In case there is an existing session, the
session will be refreshed as well (as needed).
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">configuration</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session <a href="../classes/resty.session.html#resty.session.configuration">configuration</a> overrides
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session instance</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
information why session could not be logged out</li>
<li>
<span class="types"><span class="type">boolean</span></span>
<code>true</code>, if session existed, otherwise <code>false</code></li>
<li>
<span class="types"><span class="type">boolean</span></span>
<code>true</code>, if session was refreshed, otherwise <code>false</code></li>
</ol>
<h3>Usage:</h3>
<ul>
<pre class="example"><span class="keyword">local</span> session = <span class="global">require</span> <span class="string">"resty.session"</span>.start()
<span class="comment">-- OR
</span><span class="keyword">local</span> session, err, exists, refreshed = <span class="global">require</span> <span class="string">"resty.session"</span>.start()
audience = <span class="string">"my-application"</span>,
})</pre>
</ul>
</dd>
<dt>
<a name = "module.logout"></a>
<strong>module.logout ([configuration])</strong>
</dt>
<dd>
Logout a session. </p>
<p> It logouts from a specific audience.</p>
<p> A single session cookie may be shared between multiple audiences
(or applications), thus there is a need to be able to logout from
just a single audience while keeping the session for the other
audiences.</p>
<p> When there is only a single audience, then this can be considered
equal to <a href="../classes/resty.session.html#resty.session:destroy">session.destroy</a>.</p>
<p> When the last audience is logged out, the cookie will be destroyed
as well and invalidated on a client.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">configuration</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session <a href="../classes/resty.session.html#resty.session.configuration">configuration</a> overrides
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">boolean</span></span>
<code>true</code> session exists for an audience and was logged out successfully, otherwise <code>false</code></li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
information why the session could not be logged out</li>
<li>
<span class="types"><span class="type">boolean</span></span>
<code>true</code> if session existed, otherwise <code>false</code></li>
<li>
<span class="types"><span class="type">boolean</span></span>
<code>true</code> if session was logged out, otherwise <code>false</code></li>
</ol>
<h3>Usage:</h3>
<ul>
<pre class="example"><span class="global">require</span> <span class="string">"resty.session"</span>.logout()
<span class="comment">-- OR
</span><span class="keyword">local</span> ok, err, exists, logged_out = <span class="global">require</span> <span class="string">"resty.session"</span>.logout({
audience = <span class="string">"my-application"</span>,
})</pre>
</ul>
</dd>
<dt>
<a name = "module.destroy"></a>
<strong>module.destroy ([configuration])</strong>
</dt>
<dd>
Destroy a session. </p>
<p> It destroys the whole session and clears the cookies.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">configuration</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session <a href="../classes/resty.session.html#resty.session.configuration">configuration</a> overrides
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">boolean</span></span>
<code>true</code> session exists and was destroyed successfully, otherwise <code>nil</code></li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
information why session could not be destroyed</li>
<li>
<span class="types"><span class="type">boolean</span></span>
<code>true</code> if session existed, otherwise <code>false</code></li>
<li>
<span class="types"><span class="type">boolean</span></span>
<code>true</code> if session was destroyed, otherwise <code>false</code></li>
</ol>
<h3>Usage:</h3>
<ul>
<pre class="example"><span class="global">require</span> <span class="string">"resty.session"</span>.destroy()
<span class="comment">-- OR
</span><span class="keyword">local</span> ok, err, exists = <span class="global">require</span> <span class="string">"resty.session"</span>.destroy({
cookie_name = <span class="string">"auth"</span>,
})</pre>
</ul>
</dd>
</dl>
</div> <!-- id="content" -->
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-16 17:07:08 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>

View File

@ -0,0 +1,545 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head>
<title>Session Library for OpenResty Documentation</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head>
<body>
<div id="container">
<div id="product">
<div id="product_logo"></div>
<div id="product_name"><big><b></b></big></div>
<div id="product_description"></div>
</div> <!-- id="product" -->
<div id="main">
<!-- Menu -->
<div id="navigation">
<br/>
<h1>resty.session</h1>
<ul>
<li><a href="../index.html">Index</a></li>
</ul>
<h2>Contents</h2>
<ul>
<li><a href="#Functions">Functions</a></li>
<li><a href="#Tables">Tables</a></li>
<li><a href="#Methods">Methods</a></li>
</ul>
<h2>Classes</h2>
<ul class="nowrap">
<li><strong>session</strong></li>
</ul>
<h2>Modules</h2>
<ul class="nowrap">
<li><a href="../modules/resty.session.dshm.html">resty.session.dshm</a></li>
<li><a href="../modules/resty.session.file.html">resty.session.file</a></li>
<li><a href="../modules/resty.session.memcached.html">resty.session.memcached</a></li>
<li><a href="../modules/resty.session.mysql.html">resty.session.mysql</a></li>
<li><a href="../modules/resty.session.postgres.html">resty.session.postgres</a></li>
<li><a href="../modules/resty.session.redis.html">resty.session.redis</a></li>
<li><a href="../modules/resty.session.redis-cluster.html">resty.session.redis-cluster</a></li>
<li><a href="../modules/resty.session.redis-sentinel.html">resty.session.redis-sentinel</a></li>
<li><a href="../modules/resty.session.shm.html">resty.session.shm</a></li>
<li><a href="../modules/resty.session.utils.html">resty.session.utils</a></li>
</ul>
</div>
<div id="content">
<h1>Class <code>session</code></h1>
<p>Session library provides HTTP session management capabilities for OpenResty based
applications, libraries and proxies.</p>
<p>
</p>
<h2><a href="#Functions">Functions</a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#session_instance:open">session_instance:open ()</a></td>
<td class="summary">Opens session</p>
<p> This can be used to open a session.</td>
</tr>
</table>
<h2><a href="#Tables">Tables</a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#session.configuration">session.configuration</a></td>
<td class="summary">Session configuration options</td>
</tr>
</table>
<h2><a href="#Methods">Methods</a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#session:init">session:init ([configuration])</a></td>
<td class="summary">Initializes session library</td>
</tr>
<tr>
<td class="name" nowrap><a href="#session:new">session:new ([configuration])</a></td>
<td class="summary">Creates new session</td>
</tr>
<tr>
<td class="name" nowrap><a href="#session:open">session:open ([configuration])</a></td>
<td class="summary">Opens session</p>
<p> This can be used to open a session.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#session:start">session:start ([configuration])</a></td>
<td class="summary">Starts the session and refreshes it as needed</p>
<p> This can be used to start a session.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#session:logout">session:logout ([configuration])</a></td>
<td class="summary">Logouts session</p>
<p> It logouts from a specific audience.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#session:destroy">session:destroy ([configuration])</a></td>
<td class="summary">Destroys session</td>
</tr>
</table>
<br/>
<br/>
<h2 class="section-header "><a name="Functions"></a>Functions</h2>
Methods
<dl class="function">
<dt>
<a name = "session_instance:open"></a>
<strong>session_instance:open ()</strong>
</dt>
<dd>
Opens session</p>
<p> This can be used to open a session. It will either return an existing
session or a new session.
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">true</span> or <span class="type">nil</span></span>
session instance</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
information why session could not be opened</li>
</ol>
</dd>
</dl>
<h2 class="section-header "><a name="Tables"></a>Tables</h2>
<dl class="function">
<dt>
<a name = "session.configuration"></a>
<strong>session.configuration</strong>
</dt>
<dd>
Session configuration options
<h3>Fields:</h3>
<ul>
<li><span class="parameter">secret</span>
Secret used for the key derivation. The secret is hashed with SHA-256 before using it. E.g. <code>&quot;RaJKp8UQW1&quot;</code>.
</li>
<li><span class="parameter">secret_fallbacks</span>
Array of secrets that can be used as alternative secrets (when doing key rotation), E.g. <code>{ &quot;6RfrAYYzYq&quot;, &quot;MkbTkkyF9C&quot; }</code>.
</li>
<li><span class="parameter">ikm</span>
Initial key material (or ikm) can be specified directly (without using a secret) with exactly 32 bytes of data, e.g. <code>&quot;5ixIW4QVMk0dPtoIhn41Eh1I9enP2060&quot;</code>
</li>
<li><span class="parameter">ikm_fallbacks</span>
Array of initial key materials that can be used as alternative keys (when doing key rotation), E.g. <code>{ &quot;QvPtlPKxOKdP5MCu1oI3lOEXIVuDckp7&quot; }</code>.
</li>
<li><span class="parameter">cookie_prefix</span>
Cookie prefix, use <code>nil</code>, <code>&quot;__Host-&quot;</code> or <code>&quot;__Secure-&quot;</code> (defaults to <code>nil</code>)
</li>
<li><span class="parameter">cookie_name</span>
Session cookie name, e.g. <code>&quot;session&quot;</code> (defaults to <code>&quot;session&quot;</code>)
</li>
<li><span class="parameter">cookie_path</span>
Cookie path, e.g. <code>&quot;/&quot;</code> (defaults to <code>&quot;/&quot;</code>)
</li>
<li><span class="parameter">cookie_domain</span>
Cookie domain, e.g. <code>&quot;example.com&quot;</code> (defaults to <code>nil</code>)
</li>
<li><span class="parameter">cookie_http_only</span>
Mark cookie HTTP only, use <code>true</code> or <code>false</code> (defaults to <code>true</code>)
</li>
<li><span class="parameter">cookie_secure</span>
Mark cookie secure, use <code>nil</code>, <code>true</code> or <code>false</code> (defaults to <code>nil</code>)
</li>
<li><span class="parameter">cookie_priority</span>
Cookie priority, use <code>nil</code>, <code>&quot;Low&quot;</code>, <code>&quot;Medium&quot;</code>, or <code>&quot;High&quot;</code> (defaults to <code>nil</code>)
</li>
<li><span class="parameter">cookie_same_site</span>
Cookie same-site policy, use <code>nil</code>, <code>&quot;Lax&quot;</code>, <code>&quot;Strict&quot;</code>, or <code>&quot;None&quot;</code> (defaults to <code>&quot;Lax&quot;</code>)
</li>
<li><span class="parameter">cookie_same_party</span>
Mark cookie with same party flag, use <code>nil</code>, <code>true</code>, or <code>false</code> (default: <code>nil</code>)
</li>
<li><span class="parameter">cookie_partitioned</span>
Mark cookie with partitioned flag, use <code>nil</code>, <code>true</code>, or <code>false</code> (default: <code>nil</code>)
</li>
<li><span class="parameter">remember</span>
Enable or disable persistent sessions, use <code>nil</code>, <code>true</code>, or <code>false</code> (defaults to <code>false</code>)
</li>
<li><span class="parameter">remember_cookie_name</span>
Persistent session cookie name, e.g. <code>&quot;remember&quot;</code> (defaults to <code>&quot;remember&quot;</code>)
</li>
<li><span class="parameter">audience</span>
Session audience, e.g. <code>&quot;my-application&quot;</code> (defaults to <code>&quot;default&quot;</code>)
</li>
<li><span class="parameter">subject</span>
Session subject, e.g. <code>&quot;john.doe@example.com&quot;</code> (defaults to <code>nil</code>)
</li>
<li><span class="parameter">stale_ttl</span>
When session is saved a new session is created, stale ttl specifies how long the old one can still be used, e.g. <code>10</code> (defaults to <code>10</code>) (in seconds)
</li>
<li><span class="parameter">idling_timeout</span>
Idling timeout specifies how long the session can be inactive until it is considered invalid, e.g. <code>900</code> (defaults to <code>900</code>, or 15 minutes) (in seconds)
</li>
<li><span class="parameter">rolling_timeout</span>
Rolling timeout specifies how long the session can be used until it needs to be renewed, e.g. <code>3600</code> (defaults to <code>3600</code>, or an hour) (in seconds)
</li>
<li><span class="parameter">absolute_timeout</span>
Absolute timeout limits how long the session can be renewed, until re-authentication is required, e.g. <code>86400</code> (defaults to <code>86400</code>, or a day) (in seconds)
</li>
<li><span class="parameter">remember_timeout</span>
Remember timeout specifies how long the persistent session is considered valid, e.g. <code>604800</code> (defaults to <code>604800</code>, or a week) (in seconds)
</li>
<li><span class="parameter">storage</span>
Storage is responsible of storing session data, use <code>nil</code> (data is stored in cookie), <code>dshm</code>, <code>file</code>, <code>memcached</code>, <code>mysql</code>, <code>postgres</code>, <code>redis</code>, <code>redis-cluster</code>, <code>redis-sentinel</code>, or <code>shm</code>, or give a name of custom module (<code>&quot;custom.session.storage&quot;</code>), or a <a href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a> that implements session storage interface (defaults to <code>nil</code>)
</li>
<li><span class="parameter">dshm</span>
Configuration for dshm storage, e.g. <code>{ prefix = &quot;sessions&quot; }</code>
</li>
<li><span class="parameter">file</span>
Configuration for file storage, e.g. <code>{ path = &quot;/tmp&quot;, suffix = &quot;session&quot; }</code>
</li>
<li><span class="parameter">memcached</span>
Configuration for memcached storage, e.g. <code>{ prefix = &quot;sessions&quot; }</code>
</li>
<li><span class="parameter">mysql</span>
Configuration for MySQL / MariaDB storage, e.g. <code>{ database = &quot;sessions&quot; }</code>
</li>
<li><span class="parameter">postgres</span>
Configuration for Postgres storage, e.g. <code>{ database = &quot;sessions&quot; }</code>
</li>
<li><span class="parameter">redis</span>
Configuration for Redis / Redis Sentinel / Redis Cluster storages, e.g. <code>{ prefix = &quot;sessions&quot; }</code>
</li>
<li><span class="parameter">shm</span>
Configuration for shared memory storage, e.g. <code>{ zone = &quot;sessions&quot; }</code>
</li>
</ul>
</dd>
</dl>
<h2 class="section-header "><a name="Methods"></a>Methods</h2>
<dl class="function">
<dt>
<a name = "session:init"></a>
<strong>session:init ([configuration])</strong>
</dt>
<dd>
Initializes session library This function can be called on <a href="../classes/session.html#session:init">init</a> or <code>init_worker</code> phases on OpenResty
to set global default configuration to all session instances created by this
library.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">configuration</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session <a href="../classes/session.html#session.configuration">configuration</a> overrides
(<em>optional</em>)
</li>
</ul>
<h3>Usage:</h3>
<ul>
<pre class="example"><span class="global">require</span> <span class="string">"resty.session"</span>.init({
audience = <span class="string">"my-application"</span>,
})</pre>
</ul>
</dd>
<dt>
<a name = "session:new"></a>
<strong>session:new ([configuration])</strong>
</dt>
<dd>
Creates new session This creates a new session instance.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">configuration</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session <a href="../classes/session.html#session.configuration">configuration</a> overrides
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session instance
</ol>
<h3>Usage:</h3>
<ul>
<pre class="example"><span class="keyword">local</span> session = <span class="global">require</span> <span class="string">"resty.session"</span>.new()
<span class="comment">-- OR
</span><span class="keyword">local</span> session = <span class="global">require</span> <span class="string">"resty.session"</span>.new({
audience = <span class="string">"my-application"</span>,
})</pre>
</ul>
</dd>
<dt>
<a name = "session:open"></a>
<strong>session:open ([configuration])</strong>
</dt>
<dd>
Opens session</p>
<p> This can be used to open a session. It will either return an existing
session or a new session.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">configuration</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session <a href="../classes/session.html#session.configuration">configuration</a> overrides
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session instance</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
information why session could not be opened</li>
<li>
<span class="types"><span class="type">boolean</span></span>
<code>true</code>, if session existed, otherwise <code>false</code></li>
</ol>
<h3>Usage:</h3>
<ul>
<pre class="example"><span class="keyword">local</span> session = <span class="global">require</span> <span class="string">"resty.session"</span>.open()
<span class="comment">-- OR
</span><span class="keyword">local</span> session, err, exists = <span class="global">require</span> <span class="string">"resty.session"</span>.open({
audience = <span class="string">"my-application"</span>,
})</pre>
</ul>
</dd>
<dt>
<a name = "session:start"></a>
<strong>session:start ([configuration])</strong>
</dt>
<dd>
Starts the session and refreshes it as needed</p>
<p> This can be used to start a session. It will either return an existing
session or a new session. In case there is an existing session, the
session will be refreshed as well (as needed).
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">configuration</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session <a href="../classes/session.html#session.configuration">configuration</a> overrides
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session instance</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
information why session could not be logged out</li>
<li>
<span class="types"><span class="type">boolean</span></span>
<code>true</code>, if session existed, otherwise <code>false</code></li>
<li>
<span class="types"><span class="type">boolean</span></span>
<code>true</code>, if session was refreshed, otherwise <code>false</code></li>
</ol>
<h3>Usage:</h3>
<ul>
<pre class="example"><span class="keyword">local</span> session = <span class="global">require</span> <span class="string">"resty.session"</span>.start()
<span class="comment">-- OR
</span><span class="keyword">local</span> session, err, exists, refreshed = <span class="global">require</span> <span class="string">"resty.session"</span>.start()
audience = <span class="string">"my-application"</span>,
})</pre>
</ul>
</dd>
<dt>
<a name = "session:logout"></a>
<strong>session:logout ([configuration])</strong>
</dt>
<dd>
Logouts session</p>
<p> It logouts from a specific audience. </p>
<p> A single session cookie may be shared between multiple audiences
(or applications), thus there is a need to be able to logout from
just a single audience while keeping the session for the other
audiences.</p>
<p> When there is only a single audience, then this can be considered
equal to <a href="../classes/session.html#session:destroy">session.destroy</a>.</p>
<p> When the last audience is logged out, the cookie will be destroyed
as well and invalidated on a client.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">configuration</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session <a href="../classes/session.html#session.configuration">configuration</a> overrides
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">boolean</span></span>
<code>true</code> session exists for an audience and was logged out successfully, otherwise <code>false</code></li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
information why the session could not be logged out</li>
<li>
<span class="types"><span class="type">boolean</span></span>
<code>true</code> if session existed, otherwise <code>false</code></li>
<li>
<span class="types"><span class="type">boolean</span></span>
<code>true</code> if session was logged out, otherwise <code>false</code></li>
</ol>
<h3>Usage:</h3>
<ul>
<pre class="example"><span class="global">require</span> <span class="string">"resty.session"</span>.logout()
<span class="comment">-- OR
</span><span class="keyword">local</span> ok, err, exists, logged_out = <span class="global">require</span> <span class="string">"resty.session"</span>.logout({
audience = <span class="string">"my-application"</span>,
})</pre>
</ul>
</dd>
<dt>
<a name = "session:destroy"></a>
<strong>session:destroy ([configuration])</strong>
</dt>
<dd>
Destroys session It destroys the whole session and clears the cookies.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">configuration</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session <a href="../classes/session.html#session.configuration">configuration</a> overrides
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">boolean</span></span>
<code>true</code> session exists and was destroyed successfully, otherwise <code>nil</code></li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
information why session could not be destroyed</li>
<li>
<span class="types"><span class="type">boolean</span></span>
<code>true</code> if session existed, otherwise <code>false</code></li>
<li>
<span class="types"><span class="type">boolean</span></span>
<code>true</code> if session was destroyed, otherwise <code>false</code></li>
</ol>
<h3>Usage:</h3>
<ul>
<pre class="example"><span class="global">require</span> <span class="string">"resty.session"</span>.destroy()
<span class="comment">-- OR
</span><span class="keyword">local</span> ok, err, exists = <span class="global">require</span> <span class="string">"resty.session"</span>.destroy({
cookie_name = <span class="string">"auth"</span>,
})</pre>
</ul>
</dd>
</dl>
</div> <!-- id="content" -->
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-16 00:35:34 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>

View File

@ -0,0 +1,127 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head>
<title>Session Library for OpenResty Documentation</title>
<link rel="stylesheet" href="ldoc.css" type="text/css" />
</head>
<body>
<div id="container">
<div id="product">
<div id="product_logo"></div>
<div id="product_name"><big><b></b></big></div>
<div id="product_description"></div>
</div> <!-- id="product" -->
<div id="main">
<!-- Menu -->
<div id="navigation">
<br/>
<h1>resty.session</h1>
<h2>Modules</h2>
<ul class="nowrap">
<li><a href="modules/resty.session.html">resty.session</a></li>
<li><a href="modules/resty.session.dshm.html">resty.session.dshm</a></li>
<li><a href="modules/resty.session.file.html">resty.session.file</a></li>
<li><a href="modules/resty.session.file.thread.html">resty.session.file.thread</a></li>
<li><a href="modules/resty.session.file.utils.html">resty.session.file.utils</a></li>
<li><a href="modules/resty.session.memcached.html">resty.session.memcached</a></li>
<li><a href="modules/resty.session.mysql.html">resty.session.mysql</a></li>
<li><a href="modules/resty.session.postgres.html">resty.session.postgres</a></li>
<li><a href="modules/resty.session.redis.html">resty.session.redis</a></li>
<li><a href="modules/resty.session.redis.cluster.html">resty.session.redis.cluster</a></li>
<li><a href="modules/resty.session.redis.common.html">resty.session.redis.common</a></li>
<li><a href="modules/resty.session.redis.sentinel.html">resty.session.redis.sentinel</a></li>
<li><a href="modules/resty.session.shm.html">resty.session.shm</a></li>
<li><a href="modules/resty.session.utils.html">resty.session.utils</a></li>
</ul>
</div>
<div id="content">
<h2>Session Library for OpenResty</h2>
<p><code>lua-resty-session</code> is a secure, and flexible session library for OpenResty</p>
<h2>Modules</h2>
<table class="module_list">
<tr>
<td class="name" nowrap><a href="modules/resty.session.html">resty.session</a></td>
<td class="summary">Session library.</td>
</tr>
<tr>
<td class="name" nowrap><a href="modules/resty.session.dshm.html">resty.session.dshm</a></td>
<td class="summary">Distributed Shared Memory (DSHM) backend for session library</td>
</tr>
<tr>
<td class="name" nowrap><a href="modules/resty.session.file.html">resty.session.file</a></td>
<td class="summary">File storage backend for session library.</td>
</tr>
<tr>
<td class="name" nowrap><a href="modules/resty.session.file.thread.html">resty.session.file.thread</a></td>
<td class="summary">File storage backend worker thread module</td>
</tr>
<tr>
<td class="name" nowrap><a href="modules/resty.session.file.utils.html">resty.session.file.utils</a></td>
<td class="summary">File storage utilities</td>
</tr>
<tr>
<td class="name" nowrap><a href="modules/resty.session.memcached.html">resty.session.memcached</a></td>
<td class="summary">Memcached backend for session library</td>
</tr>
<tr>
<td class="name" nowrap><a href="modules/resty.session.mysql.html">resty.session.mysql</a></td>
<td class="summary">MySQL / MariaDB backend for session library</td>
</tr>
<tr>
<td class="name" nowrap><a href="modules/resty.session.postgres.html">resty.session.postgres</a></td>
<td class="summary">Postgres backend for session library.</td>
</tr>
<tr>
<td class="name" nowrap><a href="modules/resty.session.redis.html">resty.session.redis</a></td>
<td class="summary">Redis backend for session library</td>
</tr>
<tr>
<td class="name" nowrap><a href="modules/resty.session.redis.cluster.html">resty.session.redis.cluster</a></td>
<td class="summary">Redis Cluster backend for session library</td>
</tr>
<tr>
<td class="name" nowrap><a href="modules/resty.session.redis.common.html">resty.session.redis.common</a></td>
<td class="summary">Common Redis functions shared between Redis,
Redis Cluster and Redis Sentinel implementations.</td>
</tr>
<tr>
<td class="name" nowrap><a href="modules/resty.session.redis.sentinel.html">resty.session.redis.sentinel</a></td>
<td class="summary">Redis Sentinel backend for session library</td>
</tr>
<tr>
<td class="name" nowrap><a href="modules/resty.session.shm.html">resty.session.shm</a></td>
<td class="summary">Shared Memory (SHM) backend for session library</td>
</tr>
<tr>
<td class="name" nowrap><a href="modules/resty.session.utils.html">resty.session.utils</a></td>
<td class="summary">Common utilities for session library and storage backends</td>
</tr>
</table>
</div> <!-- id="content" -->
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2023-06-05 17:05:22 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>

View File

@ -0,0 +1,303 @@
/* BEGIN RESET
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 2.8.2r1
*/
html {
color: #000;
background: #FFF;
}
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td {
margin: 0;
padding: 0;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
fieldset,img {
border: 0;
}
address,caption,cite,code,dfn,em,strong,th,var,optgroup {
font-style: inherit;
font-weight: inherit;
}
del,ins {
text-decoration: none;
}
li {
margin-left: 20px;
}
caption,th {
text-align: left;
}
h1,h2,h3,h4,h5,h6 {
font-size: 100%;
font-weight: bold;
}
q:before,q:after {
content: '';
}
abbr,acronym {
border: 0;
font-variant: normal;
}
sup {
vertical-align: baseline;
}
sub {
vertical-align: baseline;
}
legend {
color: #000;
}
input,button,textarea,select,optgroup,option {
font-family: inherit;
font-size: inherit;
font-style: inherit;
font-weight: inherit;
}
input,button,textarea,select {*font-size:100%;
}
/* END RESET */
body {
margin-left: 1em;
margin-right: 1em;
font-family: arial, helvetica, geneva, sans-serif;
background-color: #ffffff; margin: 0px;
}
code, tt { font-family: monospace; font-size: 1.1em; }
span.parameter { font-family:monospace; }
span.parameter:after { content:":"; }
span.types:before { content:"("; }
span.types:after { content:")"; }
.type { font-weight: bold; font-style:italic }
body, p, td, th { font-size: .95em; line-height: 1.2em;}
p, ul { margin: 10px 0 0 0px;}
strong { font-weight: bold;}
em { font-style: italic;}
h1 {
font-size: 1.5em;
margin: 20px 0 20px 0;
}
h2, h3, h4 { margin: 15px 0 10px 0; }
h2 { font-size: 1.25em; }
h3 { font-size: 1.15em; }
h4 { font-size: 1.06em; }
a:link { font-weight: bold; color: #004080; text-decoration: none; }
a:visited { font-weight: bold; color: #006699; text-decoration: none; }
a:link:hover { text-decoration: underline; }
hr {
color:#cccccc;
background: #00007f;
height: 1px;
}
blockquote { margin-left: 3em; }
ul { list-style-type: disc; }
p.name {
font-family: "Andale Mono", monospace;
padding-top: 1em;
}
pre {
background-color: rgb(245, 245, 245);
border: 1px solid #C0C0C0; /* silver */
padding: 10px;
margin: 10px 0 10px 0;
overflow: auto;
font-family: "Andale Mono", monospace;
}
pre.example {
font-size: .85em;
}
table.index { border: 1px #00007f; }
table.index td { text-align: left; vertical-align: top; }
#container {
margin-left: 1em;
margin-right: 1em;
background-color: #f0f0f0;
}
#product {
text-align: center;
border-bottom: 1px solid #cccccc;
background-color: #ffffff;
}
#product big {
font-size: 2em;
}
#main {
background-color: #f0f0f0;
border-left: 2px solid #cccccc;
}
#navigation {
float: left;
width: 14em;
vertical-align: top;
background-color: #f0f0f0;
overflow: visible;
}
#navigation h2 {
background-color:#e7e7e7;
font-size:1.1em;
color:#000000;
text-align: left;
padding:0.2em;
border-top:1px solid #dddddd;
border-bottom:1px solid #dddddd;
}
#navigation ul
{
font-size:1em;
list-style-type: none;
margin: 1px 1px 10px 1px;
}
#navigation li {
text-indent: -1em;
display: block;
margin: 3px 0px 0px 22px;
}
#navigation li li a {
margin: 0px 3px 0px -1em;
}
#content {
margin-left: 14em;
padding: 1em;
width: 700px;
border-left: 2px solid #cccccc;
border-right: 2px solid #cccccc;
background-color: #ffffff;
}
#about {
clear: both;
padding: 5px;
border-top: 2px solid #cccccc;
background-color: #ffffff;
}
@media print {
body {
font: 12pt "Times New Roman", "TimeNR", Times, serif;
}
a { font-weight: bold; color: #004080; text-decoration: underline; }
#main {
background-color: #ffffff;
border-left: 0px;
}
#container {
margin-left: 2%;
margin-right: 2%;
background-color: #ffffff;
}
#content {
padding: 1em;
background-color: #ffffff;
}
#navigation {
display: none;
}
pre.example {
font-family: "Andale Mono", monospace;
font-size: 10pt;
page-break-inside: avoid;
}
}
table.module_list {
border-width: 1px;
border-style: solid;
border-color: #cccccc;
border-collapse: collapse;
}
table.module_list td {
border-width: 1px;
padding: 3px;
border-style: solid;
border-color: #cccccc;
}
table.module_list td.name { background-color: #f0f0f0; min-width: 200px; }
table.module_list td.summary { width: 100%; }
table.function_list {
border-width: 1px;
border-style: solid;
border-color: #cccccc;
border-collapse: collapse;
}
table.function_list td {
border-width: 1px;
padding: 3px;
border-style: solid;
border-color: #cccccc;
}
table.function_list td.name { background-color: #f0f0f0; min-width: 200px; }
table.function_list td.summary { width: 100%; }
ul.nowrap {
overflow:auto;
white-space:nowrap;
}
dl.table dt, dl.function dt {border-top: 1px solid #ccc; padding-top: 1em;}
dl.table dd, dl.function dd {padding-bottom: 1em; margin: 10px 0 0 20px;}
dl.table h3, dl.function h3 {font-size: .95em;}
/* stop sublists from having initial vertical space */
ul ul { margin-top: 0px; }
ol ul { margin-top: 0px; }
ol ol { margin-top: 0px; }
ul ol { margin-top: 0px; }
/* make the target distinct; helps when we're navigating to a function */
a:target + * {
background-color: #FF9;
}
/* styles for prettification of source */
pre .comment { color: #558817; }
pre .constant { color: #a8660d; }
pre .escape { color: #844631; }
pre .keyword { color: #aa5050; font-weight: bold; }
pre .library { color: #0e7c6b; }
pre .marker { color: #512b1e; background: #fedc56; font-weight: bold; }
pre .string { color: #8080ff; }
pre .number { color: #f8660d; }
pre .operator { color: #2239a8; font-weight: bold; }
pre .preprocessor, pre .prepro { color: #a33243; }
pre .global { color: #800080; }
pre .user-keyword { color: #800080; }
pre .prompt { color: #558817; }
pre .url { color: #272fc2; text-decoration: underline; }

View File

@ -0,0 +1,397 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head>
<title>Session Library for OpenResty Documentation</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head>
<body>
<div id="container">
<div id="product">
<div id="product_logo"></div>
<div id="product_name"><big><b></b></big></div>
<div id="product_description"></div>
</div> <!-- id="product" -->
<div id="main">
<!-- Menu -->
<div id="navigation">
<br/>
<h1>resty.session</h1>
<ul>
<li><a href="../index.html">Index</a></li>
</ul>
<h2>Contents</h2>
<ul>
<li><a href="#Configuration">Configuration </a></li>
<li><a href="#Constructors">Constructors </a></li>
<li><a href="#Storage">Storage </a></li>
</ul>
<h2>Modules</h2>
<ul class="nowrap">
<li><a href="../modules/resty.session.html">resty.session</a></li>
<li><strong>resty.session.dshm</strong></li>
<li><a href="../modules/resty.session.file.html">resty.session.file</a></li>
<li><a href="../modules/resty.session.file.thread.html">resty.session.file.thread</a></li>
<li><a href="../modules/resty.session.file.utils.html">resty.session.file.utils</a></li>
<li><a href="../modules/resty.session.memcached.html">resty.session.memcached</a></li>
<li><a href="../modules/resty.session.mysql.html">resty.session.mysql</a></li>
<li><a href="../modules/resty.session.postgres.html">resty.session.postgres</a></li>
<li><a href="../modules/resty.session.redis.html">resty.session.redis</a></li>
<li><a href="../modules/resty.session.redis.cluster.html">resty.session.redis.cluster</a></li>
<li><a href="../modules/resty.session.redis.common.html">resty.session.redis.common</a></li>
<li><a href="../modules/resty.session.redis.sentinel.html">resty.session.redis.sentinel</a></li>
<li><a href="../modules/resty.session.shm.html">resty.session.shm</a></li>
<li><a href="../modules/resty.session.utils.html">resty.session.utils</a></li>
</ul>
</div>
<div id="content">
<h1>Module <code>resty.session.dshm</code></h1>
<p>Distributed Shared Memory (DSHM) backend for session library</p>
<p>
</p>
<h2><a href="#Configuration">Configuration </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#configuration">configuration</a></td>
<td class="summary">Distributed shared memory storage backend configuration</td>
</tr>
</table>
<h2><a href="#Constructors">Constructors </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#module.new">module.new ([configuration])</a></td>
<td class="summary">Create a distributed shared memory storage.</td>
</tr>
</table>
<h2><a href="#Storage">Storage </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#instance:set">instance:set (name, key, value, ttl, current_time[, old_key], stale_ttl[, metadata], remember)</a></td>
<td class="summary">Store session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:get">instance:get (name, key)</a></td>
<td class="summary">Retrieve session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:delete">instance:delete (name, key[, metadata])</a></td>
<td class="summary">Delete session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:read_metadata">instance:read_metadata (name, audience, subject, current_time)</a></td>
<td class="summary">Read session metadata.</td>
</tr>
</table>
<br/>
<br/>
<h2 class="section-header "><a name="Configuration"></a>Configuration </h2>
<dl class="function">
<dt>
<a name = "configuration"></a>
<strong>configuration</strong>
</dt>
<dd>
Distributed shared memory storage backend configuration
<h3>Fields:</h3>
<ul>
<li><span class="parameter">prefix</span>
The prefix for the keys stored in DSHM.
</li>
<li><span class="parameter">suffix</span>
The suffix for the keys stored in DSHM.
</li>
<li><span class="parameter">host</span>
The host to connect (defaults to <code>&quot;127.0.0.1&quot;</code>).
</li>
<li><span class="parameter">port</span>
The port to connect (defaults to <code>4321</code>).
</li>
<li><span class="parameter">connect_timeout</span>
Controls the default timeout value used in TCP/unix-domain socket object&rsquo;s <code>connect</code> method.
</li>
<li><span class="parameter">send_timeout</span>
Controls the default timeout value used in TCP/unix-domain socket object&rsquo;s <code>send</code> method.
</li>
<li><span class="parameter">read_timeout</span>
Controls the default timeout value used in TCP/unix-domain socket object&rsquo;s <code>receive</code> method.
</li>
<li><span class="parameter">keepalive_timeout</span>
Controls the default maximal idle time of the connections in the connection pool.
</li>
<li><span class="parameter">pool</span>
A custom name for the connection pool being used.
</li>
<li><span class="parameter">pool_size</span>
The size of the connection pool.
</li>
<li><span class="parameter">backlog</span>
A queue size to use when the connection pool is full (configured with @pool_size).
</li>
<li><span class="parameter">ssl</span>
Enable SSL (defaults to <code>false</code>).
</li>
<li><span class="parameter">ssl_verify</span>
Verify server certificate (defaults to <code>nil</code>).
</li>
<li><span class="parameter">server_name</span>
The server name for the new TLS extension Server Name Indication (SNI).
</li>
</ul>
</dd>
</dl>
<h2 class="section-header "><a name="Constructors"></a>Constructors </h2>
<dl class="function">
<dt>
<a name = "module.new"></a>
<strong>module.new ([configuration])</strong>
</dt>
<dd>
Create a distributed shared memory storage. </p>
<p> This creates a new distributed shared memory storage instance.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">configuration</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
DSHM storage <a href="../modules/resty.session.dshm.html#configuration">configuration</a>
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
DSHM storage instance
</ol>
</dd>
</dl>
<h2 class="section-header "><a name="Storage"></a>Storage </h2>
<dl class="function">
<dt>
<a name = "instance:set"></a>
<strong>instance:set (name, key, value, ttl, current_time[, old_key], stale_ttl[, metadata], remember)</strong>
</dt>
<dd>
Store session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">value</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session value
</li>
<li><span class="parameter">ttl</span>
<span class="types"><span class="type">number</span></span>
session ttl
</li>
<li><span class="parameter">current_time</span>
<span class="types"><span class="type">number</span></span>
current time
</li>
<li><span class="parameter">old_key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
old session id
(<em>optional</em>)
</li>
<li><span class="parameter">stale_ttl</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
stale ttl
</li>
<li><span class="parameter">metadata</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
table of metadata
(<em>optional</em>)
</li>
<li><span class="parameter">remember</span>
<span class="types"><span class="type">boolean</span></span>
whether storing persistent session or not
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">true</span> or <span class="type">nil</span></span>
ok</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:get"></a>
<strong>instance:get (name, key)</strong>
</dt>
<dd>
Retrieve session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
session data</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:delete"></a>
<strong>instance:delete (name, key[, metadata])</strong>
</dt>
<dd>
Delete session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">metadata</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session meta data
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">boolean</span> or <span class="type">nil</span></span>
session data</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:read_metadata"></a>
<strong>instance:read_metadata (name, audience, subject, current_time)</strong>
</dt>
<dd>
Read session metadata.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">audience</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">subject</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">current_time</span>
<span class="types"><span class="type">number</span></span>
current time
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a> or <span class="type">nil</span></span>
session metadata</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
</dl>
</div> <!-- id="content" -->
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2023-06-05 17:05:22 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>

View File

@ -0,0 +1,195 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head>
<title>Session Library for OpenResty Documentation</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head>
<body>
<div id="container">
<div id="product">
<div id="product_logo"></div>
<div id="product_name"><big><b></b></big></div>
<div id="product_description"></div>
</div> <!-- id="product" -->
<div id="main">
<!-- Menu -->
<div id="navigation">
<br/>
<h1>resty.session</h1>
<ul>
<li><a href="../index.html">Index</a></li>
</ul>
<h2>Contents</h2>
<ul>
<li><a href="#Functions">Functions</a></li>
</ul>
<h2>Modules</h2>
<ul class="nowrap">
<li><a href="../modules/resty.session.html">resty.session</a></li>
<li><a href="../modules/resty.session.dshm.html">resty.session.dshm</a></li>
<li><a href="../modules/resty.session.file.html">resty.session.file</a></li>
<li><strong>resty.session.file-thread</strong></li>
<li><a href="../modules/resty.session.memcached.html">resty.session.memcached</a></li>
<li><a href="../modules/resty.session.mysql.html">resty.session.mysql</a></li>
<li><a href="../modules/resty.session.postgres.html">resty.session.postgres</a></li>
<li><a href="../modules/resty.session.redis.html">resty.session.redis</a></li>
<li><a href="../modules/resty.session.redis-cluster.html">resty.session.redis-cluster</a></li>
<li><a href="../modules/resty.session.redis-sentinel.html">resty.session.redis-sentinel</a></li>
<li><a href="../modules/resty.session.shm.html">resty.session.shm</a></li>
<li><a href="../modules/resty.session.utils.html">resty.session.utils</a></li>
</ul>
</div>
<div id="content">
<h1>Module <code>resty.session.file-thread</code></h1>
<p>File storage backend worker thread module</p>
<p>
</p>
<h2><a href="#Functions">Functions</a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#set">set (path, content)</a></td>
<td class="summary">Store data in file.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#get">get (path)</a></td>
<td class="summary">Read data from a file.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#delete">delete (path)</a></td>
<td class="summary">Delete a file.</td>
</tr>
</table>
<br/>
<br/>
<h2 class="section-header "><a name="Functions"></a>Functions</h2>
<dl class="function">
<dt>
<a name = "set"></a>
<strong>set (path, content)</strong>
</dt>
<dd>
Store data in file.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">path</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
<pre><code> file path
</code></pre>
</li>
<li><span class="parameter">content</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
file content
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">true</span> or <span class="type">nil</span></span>
ok</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "get"></a>
<strong>get (path)</strong>
</dt>
<dd>
Read data from a file.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">path</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
file to read
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
content</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "delete"></a>
<strong>delete (path)</strong>
</dt>
<dd>
Delete a file.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">path</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
file to read
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
ok</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
</dl>
</div> <!-- id="content" -->
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-23 14:06:58 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>

View File

@ -0,0 +1,367 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head>
<title>Session Library for OpenResty Documentation</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head>
<body>
<div id="container">
<div id="product">
<div id="product_logo"></div>
<div id="product_name"><big><b></b></big></div>
<div id="product_description"></div>
</div> <!-- id="product" -->
<div id="main">
<!-- Menu -->
<div id="navigation">
<br/>
<h1>resty.session</h1>
<ul>
<li><a href="../index.html">Index</a></li>
</ul>
<h2>Contents</h2>
<ul>
<li><a href="#Configuration">Configuration </a></li>
<li><a href="#Constructors">Constructors </a></li>
<li><a href="#Storage">Storage </a></li>
</ul>
<h2>Modules</h2>
<ul class="nowrap">
<li><a href="../modules/resty.session.html">resty.session</a></li>
<li><a href="../modules/resty.session.dshm.html">resty.session.dshm</a></li>
<li><strong>resty.session.file</strong></li>
<li><a href="../modules/resty.session.file.thread.html">resty.session.file.thread</a></li>
<li><a href="../modules/resty.session.file.utils.html">resty.session.file.utils</a></li>
<li><a href="../modules/resty.session.memcached.html">resty.session.memcached</a></li>
<li><a href="../modules/resty.session.mysql.html">resty.session.mysql</a></li>
<li><a href="../modules/resty.session.postgres.html">resty.session.postgres</a></li>
<li><a href="../modules/resty.session.redis.html">resty.session.redis</a></li>
<li><a href="../modules/resty.session.redis.cluster.html">resty.session.redis.cluster</a></li>
<li><a href="../modules/resty.session.redis.common.html">resty.session.redis.common</a></li>
<li><a href="../modules/resty.session.redis.sentinel.html">resty.session.redis.sentinel</a></li>
<li><a href="../modules/resty.session.shm.html">resty.session.shm</a></li>
<li><a href="../modules/resty.session.utils.html">resty.session.utils</a></li>
</ul>
</div>
<div id="content">
<h1>Module <code>resty.session.file</code></h1>
<p>File storage backend for session library.</p>
<p>
</p>
<h2><a href="#Configuration">Configuration </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#configuration">configuration</a></td>
<td class="summary">File storage backend configuration</td>
</tr>
</table>
<h2><a href="#Constructors">Constructors </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#module.new">module.new ([configuration])</a></td>
<td class="summary">Create a file storage.</td>
</tr>
</table>
<h2><a href="#Storage">Storage </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#instance:set">instance:set (name, key, value, ttl, current_time[, old_key], stale_ttl[, metadata], remember)</a></td>
<td class="summary">Store session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:get">instance:get (name, key)</a></td>
<td class="summary">Retrieve session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:delete">instance:delete (name, key[, metadata])</a></td>
<td class="summary">Delete session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:read_metadata">instance:read_metadata (name, audience, subject, current_time)</a></td>
<td class="summary">Read session metadata.</td>
</tr>
</table>
<br/>
<br/>
<h2 class="section-header "><a name="Configuration"></a>Configuration </h2>
<dl class="function">
<dt>
<a name = "configuration"></a>
<strong>configuration</strong>
</dt>
<dd>
File storage backend configuration
<h3>Fields:</h3>
<ul>
<li><span class="parameter">prefix</span>
File prefix for session file.
</li>
<li><span class="parameter">suffix</span>
File suffix (or extension without <code>.</code>) for session file.
</li>
<li><span class="parameter">pool</span>
Name of the thread pool under which file writing happens (available on Linux only).
</li>
<li><span class="parameter">path</span>
Path (or directory) under which session files are created.
</li>
</ul>
</dd>
</dl>
<h2 class="section-header "><a name="Constructors"></a>Constructors </h2>
<dl class="function">
<dt>
<a name = "module.new"></a>
<strong>module.new ([configuration])</strong>
</dt>
<dd>
Create a file storage. </p>
<p> This creates a new file storage instance.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">configuration</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
file storage <a href="../modules/resty.session.file.html#configuration">configuration</a>
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
file storage instance
</ol>
</dd>
</dl>
<h2 class="section-header "><a name="Storage"></a>Storage </h2>
<dl class="function">
<dt>
<a name = "instance:set"></a>
<strong>instance:set (name, key, value, ttl, current_time[, old_key], stale_ttl[, metadata], remember)</strong>
</dt>
<dd>
Store session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">value</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session value
</li>
<li><span class="parameter">ttl</span>
<span class="types"><span class="type">number</span></span>
session ttl
</li>
<li><span class="parameter">current_time</span>
<span class="types"><span class="type">number</span></span>
current time
</li>
<li><span class="parameter">old_key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
old session id
(<em>optional</em>)
</li>
<li><span class="parameter">stale_ttl</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
stale ttl
</li>
<li><span class="parameter">metadata</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
table of metadata
(<em>optional</em>)
</li>
<li><span class="parameter">remember</span>
<span class="types"><span class="type">boolean</span></span>
whether storing persistent session or not
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">true</span> or <span class="type">nil</span></span>
ok</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:get"></a>
<strong>instance:get (name, key)</strong>
</dt>
<dd>
Retrieve session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
session data</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:delete"></a>
<strong>instance:delete (name, key[, metadata])</strong>
</dt>
<dd>
Delete session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">metadata</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session meta data
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">boolean</span> or <span class="type">nil</span></span>
session data</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:read_metadata"></a>
<strong>instance:read_metadata (name, audience, subject, current_time)</strong>
</dt>
<dd>
Read session metadata.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">audience</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">subject</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">current_time</span>
<span class="types"><span class="type">number</span></span>
current time
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a> or <span class="type">nil</span></span>
session metadata</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
</dl>
</div> <!-- id="content" -->
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2023-06-05 17:05:22 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>

View File

@ -0,0 +1,331 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head>
<title>Session Library for OpenResty Documentation</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head>
<body>
<div id="container">
<div id="product">
<div id="product_logo"></div>
<div id="product_name"><big><b></b></big></div>
<div id="product_description"></div>
</div> <!-- id="product" -->
<div id="main">
<!-- Menu -->
<div id="navigation">
<br/>
<h1>resty.session</h1>
<ul>
<li><a href="../index.html">Index</a></li>
</ul>
<h2>Contents</h2>
<ul>
<li><a href="#Functions">Functions</a></li>
</ul>
<h2>Modules</h2>
<ul class="nowrap">
<li><a href="../modules/resty.session.html">resty.session</a></li>
<li><a href="../modules/resty.session.dshm.html">resty.session.dshm</a></li>
<li><a href="../modules/resty.session.file.html">resty.session.file</a></li>
<li><strong>resty.session.file.thread</strong></li>
<li><a href="../modules/resty.session.file.utils.html">resty.session.file.utils</a></li>
<li><a href="../modules/resty.session.memcached.html">resty.session.memcached</a></li>
<li><a href="../modules/resty.session.mysql.html">resty.session.mysql</a></li>
<li><a href="../modules/resty.session.postgres.html">resty.session.postgres</a></li>
<li><a href="../modules/resty.session.redis.html">resty.session.redis</a></li>
<li><a href="../modules/resty.session.redis.cluster.html">resty.session.redis.cluster</a></li>
<li><a href="../modules/resty.session.redis.common.html">resty.session.redis.common</a></li>
<li><a href="../modules/resty.session.redis.sentinel.html">resty.session.redis.sentinel</a></li>
<li><a href="../modules/resty.session.shm.html">resty.session.shm</a></li>
<li><a href="../modules/resty.session.utils.html">resty.session.utils</a></li>
</ul>
</div>
<div id="content">
<h1>Module <code>resty.session.file.thread</code></h1>
<p>File storage backend worker thread module</p>
<p>
</p>
<h2><a href="#Functions">Functions</a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#module.set">module.set (path, prefix, suffix, name, key, value, ttl, current_time[, old_key], stale_ttl[, metadata], remember)</a></td>
<td class="summary">Store session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#module.GET">module.GET (path, prefix, suffix, name, key)</a></td>
<td class="summary">Retrieve session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#module.delete">module.delete (path, prefix, suffix, name, key, current_time)</a></td>
<td class="summary">Delete session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#module.read_metadata">module.read_metadata (path, prefix, suffix, name, audience, subject, current_time)</a></td>
<td class="summary">Read session metadata.</td>
</tr>
</table>
<br/>
<br/>
<h2 class="section-header "><a name="Functions"></a>Functions</h2>
<dl class="function">
<dt>
<a name = "module.set"></a>
<strong>module.set (path, prefix, suffix, name, key, value, ttl, current_time[, old_key], stale_ttl[, metadata], remember)</strong>
</dt>
<dd>
Store session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">path</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
the path where sessions are stored
</li>
<li><span class="parameter">prefix</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
the prefix for session files
</li>
<li><span class="parameter">suffix</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
the suffix for session files
</li>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
the cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">value</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session value
</li>
<li><span class="parameter">ttl</span>
<span class="types"><span class="type">number</span></span>
session ttl
</li>
<li><span class="parameter">current_time</span>
<span class="types"><span class="type">number</span></span>
current time
</li>
<li><span class="parameter">old_key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
old session id
(<em>optional</em>)
</li>
<li><span class="parameter">stale_ttl</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
stale ttl
</li>
<li><span class="parameter">metadata</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
table of metadata
(<em>optional</em>)
</li>
<li><span class="parameter">remember</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
whether storing persistent session or not
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a> or <span class="type">nil</span></span>
session metadata</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "module.GET"></a>
<strong>module.GET (path, prefix, suffix, name, key)</strong>
</dt>
<dd>
Retrieve session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">path</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
the path where sessions are stored
</li>
<li><span class="parameter">prefix</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
the prefix for session files
</li>
<li><span class="parameter">suffix</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
the suffix for session files
</li>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
session data</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "module.delete"></a>
<strong>module.delete (path, prefix, suffix, name, key, current_time)</strong>
</dt>
<dd>
Delete session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">path</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
the path where sessions are stored
</li>
<li><span class="parameter">prefix</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
the prefix for session files
</li>
<li><span class="parameter">suffix</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
the suffix for session files
</li>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
the cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">current_time</span>
<span class="types"><span class="type">number</span></span>
current time
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a> or <span class="type">nil</span></span>
session metadata</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "module.read_metadata"></a>
<strong>module.read_metadata (path, prefix, suffix, name, audience, subject, current_time)</strong>
</dt>
<dd>
Read session metadata.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">path</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
the path where sessions are stored
</li>
<li><span class="parameter">prefix</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
the prefix for session files
</li>
<li><span class="parameter">suffix</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
the suffix for session files
</li>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
the cookie name
</li>
<li><span class="parameter">audience</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session audience
</li>
<li><span class="parameter">subject</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session subject
</li>
<li><span class="parameter">current_time</span>
<span class="types"><span class="type">number</span></span>
current time
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a> or <span class="type">nil</span></span>
session metadata</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
</dl>
</div> <!-- id="content" -->
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2023-06-05 17:05:22 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>

View File

@ -0,0 +1,350 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head>
<title>Session Library for OpenResty Documentation</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head>
<body>
<div id="container">
<div id="product">
<div id="product_logo"></div>
<div id="product_name"><big><b></b></big></div>
<div id="product_description"></div>
</div> <!-- id="product" -->
<div id="main">
<!-- Menu -->
<div id="navigation">
<br/>
<h1>resty.session</h1>
<ul>
<li><a href="../index.html">Index</a></li>
</ul>
<h2>Contents</h2>
<ul>
<li><a href="#Functions">Functions</a></li>
</ul>
<h2>Modules</h2>
<ul class="nowrap">
<li><a href="../modules/resty.session.html">resty.session</a></li>
<li><a href="../modules/resty.session.dshm.html">resty.session.dshm</a></li>
<li><a href="../modules/resty.session.file.html">resty.session.file</a></li>
<li><a href="../modules/resty.session.file.thread.html">resty.session.file.thread</a></li>
<li><strong>resty.session.file.utils</strong></li>
<li><a href="../modules/resty.session.memcached.html">resty.session.memcached</a></li>
<li><a href="../modules/resty.session.mysql.html">resty.session.mysql</a></li>
<li><a href="../modules/resty.session.postgres.html">resty.session.postgres</a></li>
<li><a href="../modules/resty.session.redis.html">resty.session.redis</a></li>
<li><a href="../modules/resty.session.redis.cluster.html">resty.session.redis.cluster</a></li>
<li><a href="../modules/resty.session.redis.common.html">resty.session.redis.common</a></li>
<li><a href="../modules/resty.session.redis.sentinel.html">resty.session.redis.sentinel</a></li>
<li><a href="../modules/resty.session.shm.html">resty.session.shm</a></li>
<li><a href="../modules/resty.session.utils.html">resty.session.utils</a></li>
</ul>
</div>
<div id="content">
<h1>Module <code>resty.session.file.utils</code></h1>
<p>File storage utilities</p>
<p>
</p>
<h2><a href="#Functions">Functions</a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#file_create">file_create (path, content)</a></td>
<td class="summary">Store data in file.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#file_append">file_append (path, data)</a></td>
<td class="summary">Append data in file.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#file_read">file_read (path)</a></td>
<td class="summary">Read data from a file.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#get_modification">get_modification (path)</a></td>
<td class="summary">Get the value modification time of a file.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#meta_get_key">meta_get_key (audience, subject)</a></td>
<td class="summary">Given an audience and a subject, generate a metadata key.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#validate_file_name">validate_file_name (prefix, suffix, name, filename)</a></td>
<td class="summary">Validate a file name.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#cleanup">cleanup (path, prefix, suffix, name, current_time)</a></td>
<td class="summary">Clean up expired session and metadata files.</td>
</tr>
</table>
<br/>
<br/>
<h2 class="section-header "><a name="Functions"></a>Functions</h2>
<dl class="function">
<dt>
<a name = "file_create"></a>
<strong>file_create (path, content)</strong>
</dt>
<dd>
Store data in file.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">path</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
file path
</li>
<li><span class="parameter">content</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
file content
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">true</span> or <span class="type">nil</span></span>
ok</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "file_append"></a>
<strong>file_append (path, data)</strong>
</dt>
<dd>
Append data in file.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">path</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
file path
</li>
<li><span class="parameter">data</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
file data
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">true</span> or <span class="type">nil</span></span>
ok</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "file_read"></a>
<strong>file_read (path)</strong>
</dt>
<dd>
Read data from a file.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">path</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
file to read
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
content</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "get_modification"></a>
<strong>get_modification (path)</strong>
</dt>
<dd>
Get the value modification time of a file.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">path</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
the path to the file
</li>
</ul>
</dd>
<dt>
<a name = "meta_get_key"></a>
<strong>meta_get_key (audience, subject)</strong>
</dt>
<dd>
Given an audience and a subject, generate a metadata key.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">audience</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session audience
</li>
<li><span class="parameter">subject</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session subject
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
metadata key
</ol>
</dd>
<dt>
<a name = "validate_file_name"></a>
<strong>validate_file_name (prefix, suffix, name, filename)</strong>
</dt>
<dd>
Validate a file name.
Run a few checks to try to determine if the file is managed by this library
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">prefix</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
the prefix for session files
</li>
<li><span class="parameter">suffix</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
the suffix for session files
</li>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">filename</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
the name of the file
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">true</span> or <span class="type">false</span></span>
whether the file is managed by the library or not
</ol>
</dd>
<dt>
<a name = "cleanup"></a>
<strong>cleanup (path, prefix, suffix, name, current_time)</strong>
</dt>
<dd>
Clean up expired session and metadata files.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">path</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
the path where sessions are stored
</li>
<li><span class="parameter">prefix</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
the prefix for session files
</li>
<li><span class="parameter">suffix</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
the suffix for session files
</li>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">current_time</span>
<span class="types"><span class="type">number</span></span>
current time
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">true</span> or <span class="type">false</span></span>
whether clean up completed
</ol>
</dd>
</dl>
</div> <!-- id="content" -->
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2023-06-05 17:05:22 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,400 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head>
<title>Session Library for OpenResty Documentation</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head>
<body>
<div id="container">
<div id="product">
<div id="product_logo"></div>
<div id="product_name"><big><b></b></big></div>
<div id="product_description"></div>
</div> <!-- id="product" -->
<div id="main">
<!-- Menu -->
<div id="navigation">
<br/>
<h1>resty.session</h1>
<ul>
<li><a href="../index.html">Index</a></li>
</ul>
<h2>Contents</h2>
<ul>
<li><a href="#Configuration">Configuration </a></li>
<li><a href="#Constructors">Constructors </a></li>
<li><a href="#Storage">Storage </a></li>
</ul>
<h2>Modules</h2>
<ul class="nowrap">
<li><a href="../modules/resty.session.html">resty.session</a></li>
<li><a href="../modules/resty.session.dshm.html">resty.session.dshm</a></li>
<li><a href="../modules/resty.session.file.html">resty.session.file</a></li>
<li><a href="../modules/resty.session.file.thread.html">resty.session.file.thread</a></li>
<li><a href="../modules/resty.session.file.utils.html">resty.session.file.utils</a></li>
<li><strong>resty.session.memcached</strong></li>
<li><a href="../modules/resty.session.mysql.html">resty.session.mysql</a></li>
<li><a href="../modules/resty.session.postgres.html">resty.session.postgres</a></li>
<li><a href="../modules/resty.session.redis.html">resty.session.redis</a></li>
<li><a href="../modules/resty.session.redis.cluster.html">resty.session.redis.cluster</a></li>
<li><a href="../modules/resty.session.redis.common.html">resty.session.redis.common</a></li>
<li><a href="../modules/resty.session.redis.sentinel.html">resty.session.redis.sentinel</a></li>
<li><a href="../modules/resty.session.shm.html">resty.session.shm</a></li>
<li><a href="../modules/resty.session.utils.html">resty.session.utils</a></li>
</ul>
</div>
<div id="content">
<h1>Module <code>resty.session.memcached</code></h1>
<p>Memcached backend for session library</p>
<p>
</p>
<h2><a href="#Configuration">Configuration </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#configuration">configuration</a></td>
<td class="summary">Distributed shared memory storage backend configuration</td>
</tr>
</table>
<h2><a href="#Constructors">Constructors </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#module.new">module.new ([configuration])</a></td>
<td class="summary">Create a memcached storage.</td>
</tr>
</table>
<h2><a href="#Storage">Storage </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#instance:set">instance:set (name, key, value, ttl, current_time[, old_key], stale_ttl[, metadata], remember)</a></td>
<td class="summary">Store session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:get">instance:get (name, key)</a></td>
<td class="summary">Retrieve session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:delete">instance:delete (name, key[, metadata])</a></td>
<td class="summary">Delete session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:read_metadata">instance:read_metadata (name, audience, subject, current_time)</a></td>
<td class="summary">Read session metadata.</td>
</tr>
</table>
<br/>
<br/>
<h2 class="section-header "><a name="Configuration"></a>Configuration </h2>
<dl class="function">
<dt>
<a name = "configuration"></a>
<strong>configuration</strong>
</dt>
<dd>
Distributed shared memory storage backend configuration
<h3>Fields:</h3>
<ul>
<li><span class="parameter">prefix</span>
Prefix for the keys stored in memcached.
</li>
<li><span class="parameter">suffix</span>
Suffix for the keys stored in memcached.
</li>
<li><span class="parameter">host</span>
The host to connect (defaults to <code>&quot;127.0.0.1&quot;</code>).
</li>
<li><span class="parameter">port</span>
The port to connect (defaults to <code>11211</code>).
</li>
<li><span class="parameter">socket</span>
The socket file to connect to (defaults to <code>nil</code>).
</li>
<li><span class="parameter">connect_timeout</span>
Controls the default timeout value used in TCP/unix-domain socket object&rsquo;s <code>connect</code> method.
</li>
<li><span class="parameter">send_timeout</span>
Controls the default timeout value used in TCP/unix-domain socket object&rsquo;s <code>send</code> method.
</li>
<li><span class="parameter">read_timeout</span>
Controls the default timeout value used in TCP/unix-domain socket object&rsquo;s <code>receive</code> method.
</li>
<li><span class="parameter">keepalive_timeout</span>
Controls the default maximal idle time of the connections in the connection pool.
</li>
<li><span class="parameter">pool</span>
A custom name for the connection pool being used.
</li>
<li><span class="parameter">pool_size</span>
The size of the connection pool.
</li>
<li><span class="parameter">backlog</span>
A queue size to use when the connection pool is full (configured with @pool_size).
</li>
<li><span class="parameter">ssl</span>
Enable SSL (defaults to <code>false</code>).
</li>
<li><span class="parameter">ssl_verify</span>
Verify server certificate (defaults to <code>nil</code>).
</li>
<li><span class="parameter">server_name</span>
The server name for the new TLS extension Server Name Indication (SNI).
</li>
</ul>
</dd>
</dl>
<h2 class="section-header "><a name="Constructors"></a>Constructors </h2>
<dl class="function">
<dt>
<a name = "module.new"></a>
<strong>module.new ([configuration])</strong>
</dt>
<dd>
Create a memcached storage. </p>
<p> This creates a new memcached storage instance.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">configuration</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
memcached storage <a href="../modules/resty.session.memcached.html#configuration">configuration</a>
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
memcached storage instance
</ol>
</dd>
</dl>
<h2 class="section-header "><a name="Storage"></a>Storage </h2>
<dl class="function">
<dt>
<a name = "instance:set"></a>
<strong>instance:set (name, key, value, ttl, current_time[, old_key], stale_ttl[, metadata], remember)</strong>
</dt>
<dd>
Store session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">value</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session value
</li>
<li><span class="parameter">ttl</span>
<span class="types"><span class="type">number</span></span>
session ttl
</li>
<li><span class="parameter">current_time</span>
<span class="types"><span class="type">number</span></span>
current time
</li>
<li><span class="parameter">old_key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
old session id
(<em>optional</em>)
</li>
<li><span class="parameter">stale_ttl</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
stale ttl
</li>
<li><span class="parameter">metadata</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
table of metadata
(<em>optional</em>)
</li>
<li><span class="parameter">remember</span>
<span class="types"><span class="type">boolean</span></span>
whether storing persistent session or not
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">true</span> or <span class="type">nil</span></span>
ok</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:get"></a>
<strong>instance:get (name, key)</strong>
</dt>
<dd>
Retrieve session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
session data</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:delete"></a>
<strong>instance:delete (name, key[, metadata])</strong>
</dt>
<dd>
Delete session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">metadata</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session meta data
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">boolean</span> or <span class="type">nil</span></span>
session data</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:read_metadata"></a>
<strong>instance:read_metadata (name, audience, subject, current_time)</strong>
</dt>
<dd>
Read session metadata.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">audience</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">subject</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">current_time</span>
<span class="types"><span class="type">number</span></span>
current time
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a> or <span class="type">nil</span></span>
session metadata</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
</dl>
</div> <!-- id="content" -->
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2023-06-05 17:05:22 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>

View File

@ -0,0 +1,480 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head>
<title>Session Library for OpenResty Documentation</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head>
<body>
<div id="container">
<div id="product">
<div id="product_logo"></div>
<div id="product_name"><big><b></b></big></div>
<div id="product_description"></div>
</div> <!-- id="product" -->
<div id="main">
<!-- Menu -->
<div id="navigation">
<br/>
<h1>resty.session</h1>
<ul>
<li><a href="../index.html">Index</a></li>
</ul>
<h2>Contents</h2>
<ul>
<li><a href="#Configuration">Configuration </a></li>
<li><a href="#Constructors">Constructors </a></li>
<li><a href="#Storage">Storage </a></li>
<li><a href="#Database">Database </a></li>
</ul>
<h2>Modules</h2>
<ul class="nowrap">
<li><a href="../modules/resty.session.html">resty.session</a></li>
<li><a href="../modules/resty.session.dshm.html">resty.session.dshm</a></li>
<li><a href="../modules/resty.session.file.html">resty.session.file</a></li>
<li><a href="../modules/resty.session.file.thread.html">resty.session.file.thread</a></li>
<li><a href="../modules/resty.session.file.utils.html">resty.session.file.utils</a></li>
<li><a href="../modules/resty.session.memcached.html">resty.session.memcached</a></li>
<li><strong>resty.session.mysql</strong></li>
<li><a href="../modules/resty.session.postgres.html">resty.session.postgres</a></li>
<li><a href="../modules/resty.session.redis.html">resty.session.redis</a></li>
<li><a href="../modules/resty.session.redis.cluster.html">resty.session.redis.cluster</a></li>
<li><a href="../modules/resty.session.redis.common.html">resty.session.redis.common</a></li>
<li><a href="../modules/resty.session.redis.sentinel.html">resty.session.redis.sentinel</a></li>
<li><a href="../modules/resty.session.shm.html">resty.session.shm</a></li>
<li><a href="../modules/resty.session.utils.html">resty.session.utils</a></li>
</ul>
</div>
<div id="content">
<h1>Module <code>resty.session.mysql</code></h1>
<p>MySQL / MariaDB backend for session library</p>
<p>
</p>
<h2><a href="#Configuration">Configuration </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#configuration">configuration</a></td>
<td class="summary">Postgres storage backend configuration</td>
</tr>
</table>
<h2><a href="#Constructors">Constructors </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#module.new">module.new ([configuration])</a></td>
<td class="summary">Create a MySQL / MariaDB storage.</td>
</tr>
</table>
<h2><a href="#Storage">Storage </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#instance:set">instance:set (name, key, value, ttl, current_time[, old_key], stale_ttl[, metadata], remember)</a></td>
<td class="summary">Store session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:get">instance:get (name, key)</a></td>
<td class="summary">Retrieve session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:delete">instance:delete (name, key[, metadata])</a></td>
<td class="summary">Delete session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:read_metadata">instance:read_metadata (name, audience, subject, current_time)</a></td>
<td class="summary">Read session metadata.</td>
</tr>
</table>
<h2><a href="#Database">Database </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#sessions">sessions</a></td>
<td class="summary">Sessions table.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#metadata">metadata</a></td>
<td class="summary">Sessions metadata table.</td>
</tr>
</table>
<br/>
<br/>
<h2 class="section-header "><a name="Configuration"></a>Configuration </h2>
<dl class="function">
<dt>
<a name = "configuration"></a>
<strong>configuration</strong>
</dt>
<dd>
Postgres storage backend configuration
<h3>Fields:</h3>
<ul>
<li><span class="parameter">host</span>
The host to connect (defaults to <code>&quot;127.0.0.1&quot;</code>).
</li>
<li><span class="parameter">port</span>
The port to connect (defaults to <code>3306</code>).
</li>
<li><span class="parameter">socket</span>
The socket file to connect to (defaults to <code>nil</code>).
</li>
<li><span class="parameter">username</span>
The database username to authenticate (defaults to <code>nil</code>).
</li>
<li><span class="parameter">password</span>
Password for authentication, may be required depending on server configuration.
</li>
<li><span class="parameter">charset</span>
The character set used on the MySQL connection (defaults to <code>&quot;ascii&quot;</code>).
</li>
<li><span class="parameter">database</span>
The database name to connect.
</li>
<li><span class="parameter">table_name</span>
Name of database table to which to store session data (defaults to <code>&quot;sessions&quot;</code>).
</li>
<li><span class="parameter">table_name_meta</span>
Name of database meta data table to which to store session meta data (defaults to <code>&quot;sessions_meta&quot;</code>).
</li>
<li><span class="parameter">max_packet_size</span>
The upper limit for the reply packets sent from the MySQL server (defaults to 1 MB).
</li>
<li><span class="parameter">connect_timeout</span>
Controls the default timeout value used in TCP/unix-domain socket object&rsquo;s <code>connect</code> method.
</li>
<li><span class="parameter">send_timeout</span>
Controls the default timeout value used in TCP/unix-domain socket object&rsquo;s <code>send</code> method.
</li>
<li><span class="parameter">read_timeout</span>
Controls the default timeout value used in TCP/unix-domain socket object&rsquo;s <code>receive</code> method.
</li>
<li><span class="parameter">keepalive_timeout</span>
Controls the default maximal idle time of the connections in the connection pool.
</li>
<li><span class="parameter">pool</span>
A custom name for the connection pool being used.
</li>
<li><span class="parameter">pool_size</span>
The size of the connection pool.
</li>
<li><span class="parameter">backlog</span>
A queue size to use when the connection pool is full (configured with @pool_size).
</li>
<li><span class="parameter">ssl</span>
Enable SSL (defaults to <code>false</code>).
</li>
<li><span class="parameter">ssl_verify</span>
Verify server certificate (defaults to <code>nil</code>).
</li>
</ul>
</dd>
</dl>
<h2 class="section-header "><a name="Constructors"></a>Constructors </h2>
<dl class="function">
<dt>
<a name = "module.new"></a>
<strong>module.new ([configuration])</strong>
</dt>
<dd>
Create a MySQL / MariaDB storage. </p>
<p> This creates a new MySQL / MariaDB storage instance.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">configuration</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
mysql/mariadb storage <a href="../modules/resty.session.mysql.html#configuration">configuration</a>
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
mysql/mariadb storage instance
</ol>
</dd>
</dl>
<h2 class="section-header "><a name="Storage"></a>Storage </h2>
<dl class="function">
<dt>
<a name = "instance:set"></a>
<strong>instance:set (name, key, value, ttl, current_time[, old_key], stale_ttl[, metadata], remember)</strong>
</dt>
<dd>
Store session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">value</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session value
</li>
<li><span class="parameter">ttl</span>
<span class="types"><span class="type">number</span></span>
session ttl
</li>
<li><span class="parameter">current_time</span>
<span class="types"><span class="type">number</span></span>
current time
</li>
<li><span class="parameter">old_key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
old session id
(<em>optional</em>)
</li>
<li><span class="parameter">stale_ttl</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
stale ttl
</li>
<li><span class="parameter">metadata</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
table of metadata
(<em>optional</em>)
</li>
<li><span class="parameter">remember</span>
<span class="types"><span class="type">boolean</span></span>
whether storing persistent session or not
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">true</span> or <span class="type">nil</span></span>
ok</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:get"></a>
<strong>instance:get (name, key)</strong>
</dt>
<dd>
Retrieve session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
session data</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:delete"></a>
<strong>instance:delete (name, key[, metadata])</strong>
</dt>
<dd>
Delete session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">metadata</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session meta data
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">boolean</span> or <span class="type">nil</span></span>
session data</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:read_metadata"></a>
<strong>instance:read_metadata (name, audience, subject, current_time)</strong>
</dt>
<dd>
Read session metadata.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">audience</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">subject</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">current_time</span>
<span class="types"><span class="type">number</span></span>
current time
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a> or <span class="type">nil</span></span>
session metadata</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
</dl>
<h2 class="section-header "><a name="Database"></a>Database </h2>
<dl class="function">
<dt>
<a name = "sessions"></a>
<strong>sessions</strong>
</dt>
<dd>
Sessions table. </p>
<p> Database table that stores session data.
<h3>Usage:</h3>
<ul>
<pre class="example">CREATE TABLE IF NOT EXISTS sessions (
sid CHAR(<span class="number">43</span>) PRIMARY KEY,
name VARCHAR(<span class="number">255</span>),
data MEDIUMTEXT,
exp DATETIME,
INDEX (exp)
) CHARACTER SET ascii;</pre>
</ul>
</dd>
<dt>
<a name = "metadata"></a>
<strong>metadata</strong>
</dt>
<dd>
Sessions metadata table. </p>
<p> This is only needed if you want to store session metadata.
<h3>Usage:</h3>
<ul>
<pre class="example">CREATE TABLE IF NOT EXISTS sessions_meta (
aud VARCHAR(<span class="number">255</span>),
sub VARCHAR(<span class="number">255</span>),
sid CHAR(<span class="number">43</span>),
PRIMARY KEY (aud, sub, sid),
CONSTRAINT FOREIGN KEY (sid) REFERENCES sessions(sid) ON DELETE CASCADE ON UPDATE CASCADE
) CHARACTER SET ascii;</pre>
</ul>
</dd>
</dl>
</div> <!-- id="content" -->
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2023-06-05 17:05:22 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>

View File

@ -0,0 +1,476 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head>
<title>Session Library for OpenResty Documentation</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head>
<body>
<div id="container">
<div id="product">
<div id="product_logo"></div>
<div id="product_name"><big><b></b></big></div>
<div id="product_description"></div>
</div> <!-- id="product" -->
<div id="main">
<!-- Menu -->
<div id="navigation">
<br/>
<h1>resty.session</h1>
<ul>
<li><a href="../index.html">Index</a></li>
</ul>
<h2>Contents</h2>
<ul>
<li><a href="#Configuration">Configuration </a></li>
<li><a href="#Constructors">Constructors </a></li>
<li><a href="#Storage">Storage </a></li>
<li><a href="#Database">Database </a></li>
</ul>
<h2>Modules</h2>
<ul class="nowrap">
<li><a href="../modules/resty.session.html">resty.session</a></li>
<li><a href="../modules/resty.session.dshm.html">resty.session.dshm</a></li>
<li><a href="../modules/resty.session.file.html">resty.session.file</a></li>
<li><a href="../modules/resty.session.file.thread.html">resty.session.file.thread</a></li>
<li><a href="../modules/resty.session.file.utils.html">resty.session.file.utils</a></li>
<li><a href="../modules/resty.session.memcached.html">resty.session.memcached</a></li>
<li><a href="../modules/resty.session.mysql.html">resty.session.mysql</a></li>
<li><strong>resty.session.postgres</strong></li>
<li><a href="../modules/resty.session.redis.html">resty.session.redis</a></li>
<li><a href="../modules/resty.session.redis.cluster.html">resty.session.redis.cluster</a></li>
<li><a href="../modules/resty.session.redis.common.html">resty.session.redis.common</a></li>
<li><a href="../modules/resty.session.redis.sentinel.html">resty.session.redis.sentinel</a></li>
<li><a href="../modules/resty.session.shm.html">resty.session.shm</a></li>
<li><a href="../modules/resty.session.utils.html">resty.session.utils</a></li>
</ul>
</div>
<div id="content">
<h1>Module <code>resty.session.postgres</code></h1>
<p>Postgres backend for session library.</p>
<p>
</p>
<h2><a href="#Configuration">Configuration </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#configuration">configuration</a></td>
<td class="summary">Postgres storage backend configuration</td>
</tr>
</table>
<h2><a href="#Constructors">Constructors </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#module.new">module.new ([configuration])</a></td>
<td class="summary">Create a Postgres storage.</td>
</tr>
</table>
<h2><a href="#Storage">Storage </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#instance:set">instance:set (name, key, value, ttl, current_time[, old_key], stale_ttl[, metadata], remember)</a></td>
<td class="summary">Store session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:get">instance:get (name, key)</a></td>
<td class="summary">Retrieve session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:delete">instance:delete (name, key[, metadata])</a></td>
<td class="summary">Delete session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:read_metadata">instance:read_metadata (name, audience, subject, current_time)</a></td>
<td class="summary">Read session metadata.</td>
</tr>
</table>
<h2><a href="#Database">Database </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#sessions">sessions</a></td>
<td class="summary">Sessions table.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#metadata">metadata</a></td>
<td class="summary">Sessions metadata table.</td>
</tr>
</table>
<br/>
<br/>
<h2 class="section-header "><a name="Configuration"></a>Configuration </h2>
<dl class="function">
<dt>
<a name = "configuration"></a>
<strong>configuration</strong>
</dt>
<dd>
Postgres storage backend configuration
<h3>Fields:</h3>
<ul>
<li><span class="parameter">host</span>
The host to connect (defaults to <code>&quot;127.0.0.1&quot;</code>).
</li>
<li><span class="parameter">port</span>
The port to connect (defaults to <code>5432</code>).
</li>
<li><span class="parameter">application</span>
Set the name of the connection as displayed in pg_stat_activity (defaults to <code>&quot;pgmoon&quot;</code>).
</li>
<li><span class="parameter">username</span>
The database username to authenticate (defaults to <code>&quot;postgres&quot;</code>).
</li>
<li><span class="parameter">password</span>
Password for authentication, may be required depending on server configuration.
</li>
<li><span class="parameter">database</span>
The database name to connect.
</li>
<li><span class="parameter">table_name</span>
Name of database table to which to store session data (can be <code>database schema</code> prefixed) (defaults to <code>&quot;sessions&quot;</code>).
</li>
<li><span class="parameter">table_name_meta</span>
Name of database meta data table to which to store session meta data (can be <code>database schema</code> prefixed) (defaults to <code>&quot;sessions_meta&quot;</code>).
</li>
<li><span class="parameter">connect_timeout</span>
Controls the default timeout value used in TCP/unix-domain socket object&rsquo;s <code>connect</code> method.
</li>
<li><span class="parameter">send_timeout</span>
Controls the default timeout value used in TCP/unix-domain socket object&rsquo;s <code>send</code> method.
</li>
<li><span class="parameter">read_timeout</span>
Controls the default timeout value used in TCP/unix-domain socket object&rsquo;s <code>receive</code> method.
</li>
<li><span class="parameter">keepalive_timeout</span>
Controls the default maximal idle time of the connections in the connection pool.
</li>
<li><span class="parameter">pool</span>
A custom name for the connection pool being used.
</li>
<li><span class="parameter">pool_size</span>
The size of the connection pool.
</li>
<li><span class="parameter">backlog</span>
A queue size to use when the connection pool is full (configured with @pool_size).
</li>
<li><span class="parameter">ssl</span>
Enable SSL (defaults to <code>false</code>).
</li>
<li><span class="parameter">ssl_verify</span>
Verify server certificate (defaults to <code>nil</code>).
</li>
<li><span class="parameter">ssl_required</span>
Abort the connection if the server does not support SSL connections (defaults to <code>nil</code>).
</li>
</ul>
</dd>
</dl>
<h2 class="section-header "><a name="Constructors"></a>Constructors </h2>
<dl class="function">
<dt>
<a name = "module.new"></a>
<strong>module.new ([configuration])</strong>
</dt>
<dd>
Create a Postgres storage. </p>
<p> This creates a new Postgres storage instance.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">configuration</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
postgres storage <a href="../modules/resty.session.postgres.html#configuration">configuration</a>
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
postgres storage instance
</ol>
</dd>
</dl>
<h2 class="section-header "><a name="Storage"></a>Storage </h2>
<dl class="function">
<dt>
<a name = "instance:set"></a>
<strong>instance:set (name, key, value, ttl, current_time[, old_key], stale_ttl[, metadata], remember)</strong>
</dt>
<dd>
Store session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">value</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session value
</li>
<li><span class="parameter">ttl</span>
<span class="types"><span class="type">number</span></span>
session ttl
</li>
<li><span class="parameter">current_time</span>
<span class="types"><span class="type">number</span></span>
current time
</li>
<li><span class="parameter">old_key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
old session id
(<em>optional</em>)
</li>
<li><span class="parameter">stale_ttl</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
stale ttl
</li>
<li><span class="parameter">metadata</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
table of metadata
(<em>optional</em>)
</li>
<li><span class="parameter">remember</span>
<span class="types"><span class="type">boolean</span></span>
whether storing persistent session or not
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">true</span> or <span class="type">nil</span></span>
ok</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:get"></a>
<strong>instance:get (name, key)</strong>
</dt>
<dd>
Retrieve session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
session data</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:delete"></a>
<strong>instance:delete (name, key[, metadata])</strong>
</dt>
<dd>
Delete session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">metadata</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session meta data
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">boolean</span> or <span class="type">nil</span></span>
session data</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:read_metadata"></a>
<strong>instance:read_metadata (name, audience, subject, current_time)</strong>
</dt>
<dd>
Read session metadata.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">audience</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">subject</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">current_time</span>
<span class="types"><span class="type">number</span></span>
current time
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a> or <span class="type">nil</span></span>
session metadata</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
</dl>
<h2 class="section-header "><a name="Database"></a>Database </h2>
<dl class="function">
<dt>
<a name = "sessions"></a>
<strong>sessions</strong>
</dt>
<dd>
Sessions table. </p>
<p> Database table that stores session data.
<h3>Usage:</h3>
<ul>
<pre class="example">CREATE TABLE IF NOT EXISTS sessions (
sid TEXT PRIMARY KEY,
name TEXT,
data TEXT,
exp TIMESTAMP WITH TIME ZONE
);
CREATE INDEX ON sessions (exp);</pre>
</ul>
</dd>
<dt>
<a name = "metadata"></a>
<strong>metadata</strong>
</dt>
<dd>
Sessions metadata table. </p>
<p> This is only needed if you want to store session metadata.
<h3>Usage:</h3>
<ul>
<pre class="example">CREATE TABLE IF NOT EXISTS sessions_meta (
aud TEXT,
sub TEXT,
sid TEXT REFERENCES sessions (sid) ON DELETE CASCADE ON UPDATE CASCADE,
PRIMARY KEY (aud, sub, sid)
);</pre>
</ul>
</dd>
</dl>
</div> <!-- id="content" -->
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2023-06-05 17:05:22 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>

View File

@ -0,0 +1,413 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head>
<title>Session Library for OpenResty Documentation</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head>
<body>
<div id="container">
<div id="product">
<div id="product_logo"></div>
<div id="product_name"><big><b></b></big></div>
<div id="product_description"></div>
</div> <!-- id="product" -->
<div id="main">
<!-- Menu -->
<div id="navigation">
<br/>
<h1>resty.session</h1>
<ul>
<li><a href="../index.html">Index</a></li>
</ul>
<h2>Contents</h2>
<ul>
<li><a href="#Configuration">Configuration </a></li>
<li><a href="#Constructors">Constructors </a></li>
<li><a href="#Storage">Storage </a></li>
</ul>
<h2>Modules</h2>
<ul class="nowrap">
<li><a href="../modules/resty.session.html">resty.session</a></li>
<li><a href="../modules/resty.session.dshm.html">resty.session.dshm</a></li>
<li><a href="../modules/resty.session.file.html">resty.session.file</a></li>
<li><a href="../modules/resty.session.file-thread.html">resty.session.file-thread</a></li>
<li><a href="../modules/resty.session.memcached.html">resty.session.memcached</a></li>
<li><a href="../modules/resty.session.mysql.html">resty.session.mysql</a></li>
<li><a href="../modules/resty.session.postgres.html">resty.session.postgres</a></li>
<li><a href="../modules/resty.session.redis.html">resty.session.redis</a></li>
<li><strong>resty.session.redis-cluster</strong></li>
<li><a href="../modules/resty.session.redis-sentinel.html">resty.session.redis-sentinel</a></li>
<li><a href="../modules/resty.session.shm.html">resty.session.shm</a></li>
<li><a href="../modules/resty.session.utils.html">resty.session.utils</a></li>
</ul>
</div>
<div id="content">
<h1>Module <code>resty.session.redis-cluster</code></h1>
<p>Redis Cluster backend for session library</p>
<p>
</p>
<h2><a href="#Configuration">Configuration </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#configuration">configuration</a></td>
<td class="summary">Redis Cluster storage backend configuration</td>
</tr>
<tr>
<td class="name" nowrap><a href="#nodes">nodes</a></td>
<td class="summary">Cluster Nodes</td>
</tr>
<tr>
<td class="name" nowrap><a href="#node">node</a></td>
<td class="summary">Cluster Node</td>
</tr>
</table>
<h2><a href="#Constructors">Constructors </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#module.new">module.new ([configuration])</a></td>
<td class="summary">Create a Redis Cluster storage.</td>
</tr>
</table>
<h2><a href="#Storage">Storage </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#instance:set">instance:set (name, key, value, ttl, current_time, old_key, stale_ttl, metadata, remember)</a></td>
<td class="summary">Store session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:get">instance:get (name, key)</a></td>
<td class="summary">Retrieve session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:delete">instance:delete (name, key[, metadata])</a></td>
<td class="summary">Delete session data.</td>
</tr>
</table>
<br/>
<br/>
<h2 class="section-header "><a name="Configuration"></a>Configuration </h2>
<dl class="function">
<dt>
<a name = "configuration"></a>
<strong>configuration</strong>
</dt>
<dd>
Redis Cluster storage backend configuration
<h3>Fields:</h3>
<ul>
<li><span class="parameter">prefix</span>
prefix for the keys stored in redis
</li>
<li><span class="parameter">suffix</span>
suffix for the keys stored in redis
</li>
<li><span class="parameter">name</span>
redis cluster name
</li>
<li><span class="parameter">nodes</span>
redis cluster nodes
</li>
<li><span class="parameter">lock_zone</span>
shared dictionary name for locks
</li>
<li><span class="parameter">lock_prefix</span>
shared dictionary name prefix for lock
</li>
<li><span class="parameter">max_redirections</span>
maximum retry attempts for redirection
</li>
<li><span class="parameter">max_connection_attempts</span>
maximum retry attempts for connection
</li>
<li><span class="parameter">max_connection_timeout</span>
maximum connection timeout in total among the retries
</li>
<li><span class="parameter">username</span>
the database username to authenticate
</li>
<li><span class="parameter">password</span>
password for authentication
</li>
<li><span class="parameter">connect_timeout</span>
controls the default timeout value used in TCP/unix-domain socket object&rsquo;s <code>connect</code> method
</li>
<li><span class="parameter">send_timeout</span>
controls the default timeout value used in TCP/unix-domain socket object&rsquo;s <code>send</code> method
</li>
<li><span class="parameter">read_timeout</span>
controls the default timeout value used in TCP/unix-domain socket object&rsquo;s <code>receive</code> method
</li>
<li><span class="parameter">keepalive_timeout</span>
controls the default maximal idle time of the connections in the connection pool
</li>
<li><span class="parameter">pool</span>
a custom name for the connection pool being used.
</li>
<li><span class="parameter">pool_size</span>
the size of the connection pool,
</li>
<li><span class="parameter">backlog</span>
a queue size to use when the connection pool is full (configured with @pool_size)
</li>
<li><span class="parameter">ssl</span>
enable ssl (defaults to <code>false</code>)
</li>
<li><span class="parameter">ssl_verify</span>
verify server certificate (defaults to <code>nil</code>)
</li>
<li><span class="parameter">server_name</span>
the server name for the new TLS extension Server Name Indication (SNI)
</li>
</ul>
</dd>
<dt>
<a name = "nodes"></a>
<strong>nodes</strong>
</dt>
<dd>
Cluster Nodes An array of cluster nodes.
</dd>
<dt>
<a name = "node"></a>
<strong>node</strong>
</dt>
<dd>
Cluster Node
<h3>Fields:</h3>
<ul>
<li><span class="parameter">ip</span>
the ip address to connect (defaults to <code>&quot;127.0.0.1&quot;</code>)
</li>
<li><span class="parameter">port</span>
the port to connect (defaults to <code>6379</code>)
</li>
</ul>
</dd>
</dl>
<h2 class="section-header "><a name="Constructors"></a>Constructors </h2>
<dl class="function">
<dt>
<a name = "module.new"></a>
<strong>module.new ([configuration])</strong>
</dt>
<dd>
Create a Redis Cluster storage. </p>
<p> This creates a new Redis Cluster storage instance.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">configuration</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
redis cluster storage <a href="../modules/resty.session.redis-cluster.html#configuration">configuration</a>
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
redis cluster storage instance
</ol>
</dd>
</dl>
<h2 class="section-header "><a name="Storage"></a>Storage </h2>
<dl class="function">
<dt>
<a name = "instance:set"></a>
<strong>instance:set (name, key, value, ttl, current_time, old_key, stale_ttl, metadata, remember)</strong>
</dt>
<dd>
Store session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">value</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session value
</li>
<li><span class="parameter">ttl</span>
<span class="types"><span class="type">number</span></span>
session ttl
</li>
<li><span class="parameter">current_time</span>
<span class="types"><span class="type">number</span></span>
current time
</li>
<li><span class="parameter">old_key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
old session id
</li>
<li><span class="parameter">stale_ttl</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
stale ttl
</li>
<li><span class="parameter">metadata</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
table of metadata
</li>
<li><span class="parameter">remember</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
whether storing persistent session or not
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">true</span> or <span class="type">nil</span></span>
ok</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:get"></a>
<strong>instance:get (name, key)</strong>
</dt>
<dd>
Retrieve session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
session data</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:delete"></a>
<strong>instance:delete (name, key[, metadata])</strong>
</dt>
<dd>
Delete session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">metadata</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session meta data
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">boolean</span> or <span class="type">nil</span></span>
session data</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
</dl>
</div> <!-- id="content" -->
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-23 14:06:58 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>

View File

@ -0,0 +1,410 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head>
<title>Session Library for OpenResty Documentation</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head>
<body>
<div id="container">
<div id="product">
<div id="product_logo"></div>
<div id="product_name"><big><b></b></big></div>
<div id="product_description"></div>
</div> <!-- id="product" -->
<div id="main">
<!-- Menu -->
<div id="navigation">
<br/>
<h1>resty.session</h1>
<ul>
<li><a href="../index.html">Index</a></li>
</ul>
<h2>Contents</h2>
<ul>
<li><a href="#Configuration">Configuration </a></li>
<li><a href="#Constructors">Constructors </a></li>
<li><a href="#Storage">Storage </a></li>
</ul>
<h2>Modules</h2>
<ul class="nowrap">
<li><a href="../modules/resty.session.html">resty.session</a></li>
<li><a href="../modules/resty.session.dshm.html">resty.session.dshm</a></li>
<li><a href="../modules/resty.session.file.html">resty.session.file</a></li>
<li><a href="../modules/resty.session.file-thread.html">resty.session.file-thread</a></li>
<li><a href="../modules/resty.session.memcached.html">resty.session.memcached</a></li>
<li><a href="../modules/resty.session.mysql.html">resty.session.mysql</a></li>
<li><a href="../modules/resty.session.postgres.html">resty.session.postgres</a></li>
<li><a href="../modules/resty.session.redis.html">resty.session.redis</a></li>
<li><a href="../modules/resty.session.redis-cluster.html">resty.session.redis-cluster</a></li>
<li><strong>resty.session.redis-sentinel</strong></li>
<li><a href="../modules/resty.session.shm.html">resty.session.shm</a></li>
<li><a href="../modules/resty.session.utils.html">resty.session.utils</a></li>
</ul>
</div>
<div id="content">
<h1>Module <code>resty.session.redis-sentinel</code></h1>
<p>Redis Sentinel backend for session library</p>
<p>
</p>
<h2><a href="#Configuration">Configuration </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#configuration">configuration</a></td>
<td class="summary">Redis Sentinel storage backend configuration</td>
</tr>
<tr>
<td class="name" nowrap><a href="#sentinels">sentinels</a></td>
<td class="summary">Sentinels</td>
</tr>
<tr>
<td class="name" nowrap><a href="#sentinel">sentinel</a></td>
<td class="summary">Sentinel</td>
</tr>
</table>
<h2><a href="#Constructors">Constructors </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#module.new">module.new ([configuration])</a></td>
<td class="summary">Create a Redis Sentinel storage.</td>
</tr>
</table>
<h2><a href="#Storage">Storage </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#instance:set">instance:set (name, key, value, ttl, current_time, old_key, stale_ttl, metadata, remember)</a></td>
<td class="summary">Store session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:get">instance:get (name, key)</a></td>
<td class="summary">Retrieve session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:delete">instance:delete (name, key[, metadata])</a></td>
<td class="summary">Delete session data.</td>
</tr>
</table>
<br/>
<br/>
<h2 class="section-header "><a name="Configuration"></a>Configuration </h2>
<dl class="function">
<dt>
<a name = "configuration"></a>
<strong>configuration</strong>
</dt>
<dd>
Redis Sentinel storage backend configuration
<h3>Fields:</h3>
<ul>
<li><span class="parameter">prefix</span>
prefix for the keys stored in redis
</li>
<li><span class="parameter">suffix</span>
suffix for the keys stored in redis
</li>
<li><span class="parameter">master</span>
name of master
</li>
<li><span class="parameter">role</span>
<code>&quot;master&quot;</code> or <code>&quot;slave&quot;</code>
</li>
<li><span class="parameter">sentinels</span>
redis sentinels
</li>
<li><span class="parameter">sentinel_username</span>
optional sentinel username
</li>
<li><span class="parameter">sentinel_password</span>
optional sentinel password
</li>
<li><span class="parameter">username</span>
the database username to authenticate
</li>
<li><span class="parameter">password</span>
password for authentication
</li>
<li><span class="parameter">database</span>
the database to connect
</li>
<li><span class="parameter">connect_timeout</span>
controls the default timeout value used in TCP/unix-domain socket object&rsquo;s <code>connect</code> method
</li>
<li><span class="parameter">send_timeout</span>
controls the default timeout value used in TCP/unix-domain socket object&rsquo;s <code>send</code> method
</li>
<li><span class="parameter">read_timeout</span>
controls the default timeout value used in TCP/unix-domain socket object&rsquo;s <code>receive</code> method
</li>
<li><span class="parameter">keepalive_timeout</span>
controls the default maximal idle time of the connections in the connection pool
</li>
<li><span class="parameter">pool</span>
a custom name for the connection pool being used.
</li>
<li><span class="parameter">pool_size</span>
the size of the connection pool,
</li>
<li><span class="parameter">backlog</span>
a queue size to use when the connection pool is full (configured with @pool_size)
</li>
<li><span class="parameter">ssl</span>
enable ssl (defaults to <code>false</code>)
</li>
<li><span class="parameter">ssl_verify</span>
verify server certificate (defaults to <code>nil</code>)
</li>
<li><span class="parameter">server_name</span>
the server name for the new TLS extension Server Name Indication (SNI)
</li>
</ul>
</dd>
<dt>
<a name = "sentinels"></a>
<strong>sentinels</strong>
</dt>
<dd>
Sentinels An array of sentinels.
</dd>
<dt>
<a name = "sentinel"></a>
<strong>sentinel</strong>
</dt>
<dd>
Sentinel
<h3>Fields:</h3>
<ul>
<li><span class="parameter">host</span>
the host to connect
</li>
<li><span class="parameter">port</span>
the port to connect
</li>
</ul>
</dd>
</dl>
<h2 class="section-header "><a name="Constructors"></a>Constructors </h2>
<dl class="function">
<dt>
<a name = "module.new"></a>
<strong>module.new ([configuration])</strong>
</dt>
<dd>
Create a Redis Sentinel storage. </p>
<p> This creates a new Redis Sentinel storage instance.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">configuration</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
redis sentinel storage <a href="../modules/resty.session.redis-sentinel.html#configuration">configuration</a>
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
redis sentinel storage instance
</ol>
</dd>
</dl>
<h2 class="section-header "><a name="Storage"></a>Storage </h2>
<dl class="function">
<dt>
<a name = "instance:set"></a>
<strong>instance:set (name, key, value, ttl, current_time, old_key, stale_ttl, metadata, remember)</strong>
</dt>
<dd>
Store session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">value</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session value
</li>
<li><span class="parameter">ttl</span>
<span class="types"><span class="type">number</span></span>
session ttl
</li>
<li><span class="parameter">current_time</span>
<span class="types"><span class="type">number</span></span>
current time
</li>
<li><span class="parameter">old_key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
old session id
</li>
<li><span class="parameter">stale_ttl</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
stale ttl
</li>
<li><span class="parameter">metadata</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
table of metadata
</li>
<li><span class="parameter">remember</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
whether storing persistent session or not
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">true</span> or <span class="type">nil</span></span>
ok</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:get"></a>
<strong>instance:get (name, key)</strong>
</dt>
<dd>
Retrieve session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
session data</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:delete"></a>
<strong>instance:delete (name, key[, metadata])</strong>
</dt>
<dd>
Delete session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">metadata</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session meta data
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">boolean</span> or <span class="type">nil</span></span>
session data</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
</dl>
</div> <!-- id="content" -->
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-23 14:06:58 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>

View File

@ -0,0 +1,463 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head>
<title>Session Library for OpenResty Documentation</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head>
<body>
<div id="container">
<div id="product">
<div id="product_logo"></div>
<div id="product_name"><big><b></b></big></div>
<div id="product_description"></div>
</div> <!-- id="product" -->
<div id="main">
<!-- Menu -->
<div id="navigation">
<br/>
<h1>resty.session</h1>
<ul>
<li><a href="../index.html">Index</a></li>
</ul>
<h2>Contents</h2>
<ul>
<li><a href="#Configuration">Configuration </a></li>
<li><a href="#Constructors">Constructors </a></li>
<li><a href="#Storage">Storage </a></li>
</ul>
<h2>Modules</h2>
<ul class="nowrap">
<li><a href="../modules/resty.session.html">resty.session</a></li>
<li><a href="../modules/resty.session.dshm.html">resty.session.dshm</a></li>
<li><a href="../modules/resty.session.file.html">resty.session.file</a></li>
<li><a href="../modules/resty.session.file.thread.html">resty.session.file.thread</a></li>
<li><a href="../modules/resty.session.file.utils.html">resty.session.file.utils</a></li>
<li><a href="../modules/resty.session.memcached.html">resty.session.memcached</a></li>
<li><a href="../modules/resty.session.mysql.html">resty.session.mysql</a></li>
<li><a href="../modules/resty.session.postgres.html">resty.session.postgres</a></li>
<li><a href="../modules/resty.session.redis.html">resty.session.redis</a></li>
<li><strong>resty.session.redis.cluster</strong></li>
<li><a href="../modules/resty.session.redis.common.html">resty.session.redis.common</a></li>
<li><a href="../modules/resty.session.redis.sentinel.html">resty.session.redis.sentinel</a></li>
<li><a href="../modules/resty.session.shm.html">resty.session.shm</a></li>
<li><a href="../modules/resty.session.utils.html">resty.session.utils</a></li>
</ul>
</div>
<div id="content">
<h1>Module <code>resty.session.redis.cluster</code></h1>
<p>Redis Cluster backend for session library</p>
<p>
</p>
<h2><a href="#Configuration">Configuration </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#configuration">configuration</a></td>
<td class="summary">Redis Cluster storage backend configuration</td>
</tr>
<tr>
<td class="name" nowrap><a href="#nodes">nodes</a></td>
<td class="summary">Cluster Nodes</td>
</tr>
<tr>
<td class="name" nowrap><a href="#node">node</a></td>
<td class="summary">Cluster Node</td>
</tr>
</table>
<h2><a href="#Constructors">Constructors </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#module.new">module.new ([configuration])</a></td>
<td class="summary">Create a Redis Cluster storage.</td>
</tr>
</table>
<h2><a href="#Storage">Storage </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#instance:set">instance:set (name, key, value, ttl, current_time[, old_key], stale_ttl[, metadata], remember)</a></td>
<td class="summary">Store session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:get">instance:get (name, key)</a></td>
<td class="summary">Retrieve session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:delete">instance:delete (name, key[, metadata])</a></td>
<td class="summary">Delete session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:read_metadata">instance:read_metadata (name, audience, subject, current_time)</a></td>
<td class="summary">Read session metadata.</td>
</tr>
</table>
<br/>
<br/>
<h2 class="section-header "><a name="Configuration"></a>Configuration </h2>
<dl class="function">
<dt>
<a name = "configuration"></a>
<strong>configuration</strong>
</dt>
<dd>
Redis Cluster storage backend configuration
<h3>Fields:</h3>
<ul>
<li><span class="parameter">prefix</span>
Prefix for the keys stored in redis.
</li>
<li><span class="parameter">suffix</span>
Suffix for the keys stored in redis.
</li>
<li><span class="parameter">name</span>
Redis cluster name.
</li>
<li><span class="parameter">nodes</span>
Redis cluster nodes.
</li>
<li><span class="parameter">lock_zone</span>
Shared dictionary name for locks.
</li>
<li><span class="parameter">lock_prefix</span>
Shared dictionary name prefix for lock.
</li>
<li><span class="parameter">max_redirections</span>
Maximum retry attempts for redirection.
</li>
<li><span class="parameter">max_connection_attempts</span>
Maximum retry attempts for connection.
</li>
<li><span class="parameter">max_connection_timeout</span>
Maximum connection timeout in total among the retries.
</li>
<li><span class="parameter">username</span>
The database username to authenticate.
</li>
<li><span class="parameter">password</span>
Password for authentication.
</li>
<li><span class="parameter">connect_timeout</span>
Controls the default timeout value used in TCP/unix-domain socket object&rsquo;s <code>connect</code> method.
</li>
<li><span class="parameter">send_timeout</span>
controls The default timeout value used in TCP/unix-domain socket object&rsquo;s <code>send</code> method.
</li>
<li><span class="parameter">read_timeout</span>
controls The default timeout value used in TCP/unix-domain socket object&rsquo;s <code>receive</code> method.
</li>
<li><span class="parameter">keepalive_timeout</span>
Controls the default maximal idle time of the connections in the connection pool.
</li>
<li><span class="parameter">pool</span>
A custom name for the connection pool being used.
</li>
<li><span class="parameter">pool_size</span>
The size of the connection pool.
</li>
<li><span class="parameter">backlog</span>
A queue size to use when the connection pool is full (configured with @pool_size).
</li>
<li><span class="parameter">ssl</span>
Enable SSL (defaults to <code>false</code>).
</li>
<li><span class="parameter">ssl_verify</span>
Verify server certificate (defaults to <code>nil</code>).
</li>
<li><span class="parameter">server_name</span>
The server name for the new TLS extension Server Name Indication (SNI).
</li>
</ul>
</dd>
<dt>
<a name = "nodes"></a>
<strong>nodes</strong>
</dt>
<dd>
Cluster Nodes An array of cluster nodes.
</dd>
<dt>
<a name = "node"></a>
<strong>node</strong>
</dt>
<dd>
Cluster Node
<h3>Fields:</h3>
<ul>
<li><span class="parameter">ip</span>
The IP address to connect (defaults to <code>&quot;127.0.0.1&quot;</code>).
</li>
<li><span class="parameter">port</span>
The port to connect (defaults to <code>6379</code>).
</li>
</ul>
</dd>
</dl>
<h2 class="section-header "><a name="Constructors"></a>Constructors </h2>
<dl class="function">
<dt>
<a name = "module.new"></a>
<strong>module.new ([configuration])</strong>
</dt>
<dd>
Create a Redis Cluster storage. </p>
<p> This creates a new Redis Cluster storage instance.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">configuration</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
redis cluster storage <a href="../modules/resty.session.redis.cluster.html#configuration">configuration</a>
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
redis cluster storage instance
</ol>
</dd>
</dl>
<h2 class="section-header "><a name="Storage"></a>Storage </h2>
<dl class="function">
<dt>
<a name = "instance:set"></a>
<strong>instance:set (name, key, value, ttl, current_time[, old_key], stale_ttl[, metadata], remember)</strong>
</dt>
<dd>
Store session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">value</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session value
</li>
<li><span class="parameter">ttl</span>
<span class="types"><span class="type">number</span></span>
session ttl
</li>
<li><span class="parameter">current_time</span>
<span class="types"><span class="type">number</span></span>
current time
</li>
<li><span class="parameter">old_key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
old session id
(<em>optional</em>)
</li>
<li><span class="parameter">stale_ttl</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
stale ttl
</li>
<li><span class="parameter">metadata</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
table of metadata
(<em>optional</em>)
</li>
<li><span class="parameter">remember</span>
<span class="types"><span class="type">boolean</span></span>
whether storing persistent session or not
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">true</span> or <span class="type">nil</span></span>
ok</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:get"></a>
<strong>instance:get (name, key)</strong>
</dt>
<dd>
Retrieve session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
session data</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:delete"></a>
<strong>instance:delete (name, key[, metadata])</strong>
</dt>
<dd>
Delete session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">metadata</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session meta data
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">boolean</span> or <span class="type">nil</span></span>
session data</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:read_metadata"></a>
<strong>instance:read_metadata (name, audience, subject, current_time)</strong>
</dt>
<dd>
Read session metadata.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">audience</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">subject</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">current_time</span>
<span class="types"><span class="type">number</span></span>
current time
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a> or <span class="type">nil</span></span>
session metadata</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
</dl>
</div> <!-- id="content" -->
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2023-06-05 17:05:22 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>

View File

@ -0,0 +1,321 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head>
<title>Session Library for OpenResty Documentation</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head>
<body>
<div id="container">
<div id="product">
<div id="product_logo"></div>
<div id="product_name"><big><b></b></big></div>
<div id="product_description"></div>
</div> <!-- id="product" -->
<div id="main">
<!-- Menu -->
<div id="navigation">
<br/>
<h1>resty.session</h1>
<ul>
<li><a href="../index.html">Index</a></li>
</ul>
<h2>Contents</h2>
<ul>
<li><a href="#Functions">Functions</a></li>
</ul>
<h2>Modules</h2>
<ul class="nowrap">
<li><a href="../modules/resty.session.html">resty.session</a></li>
<li><a href="../modules/resty.session.dshm.html">resty.session.dshm</a></li>
<li><a href="../modules/resty.session.file.html">resty.session.file</a></li>
<li><a href="../modules/resty.session.file.thread.html">resty.session.file.thread</a></li>
<li><a href="../modules/resty.session.file.utils.html">resty.session.file.utils</a></li>
<li><a href="../modules/resty.session.memcached.html">resty.session.memcached</a></li>
<li><a href="../modules/resty.session.mysql.html">resty.session.mysql</a></li>
<li><a href="../modules/resty.session.postgres.html">resty.session.postgres</a></li>
<li><a href="../modules/resty.session.redis.html">resty.session.redis</a></li>
<li><a href="../modules/resty.session.redis.cluster.html">resty.session.redis.cluster</a></li>
<li><strong>resty.session.redis.common</strong></li>
<li><a href="../modules/resty.session.redis.sentinel.html">resty.session.redis.sentinel</a></li>
<li><a href="../modules/resty.session.shm.html">resty.session.shm</a></li>
<li><a href="../modules/resty.session.utils.html">resty.session.utils</a></li>
</ul>
</div>
<div id="content">
<h1>Module <code>resty.session.redis.common</code></h1>
<p>Common Redis functions shared between Redis,
Redis Cluster and Redis Sentinel implementations.</p>
<p>
</p>
<h2><a href="#Functions">Functions</a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#module.SET">module.SET (storage, red, name, key, value, ttl, current_time[, old_key], stale_ttl[, metadata], remember)</a></td>
<td class="summary">Store session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#module.GET">module.GET (storage, red, name, key)</a></td>
<td class="summary">Retrieve session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#module.UNLINK">module.UNLINK (storage, red, name, key, current_time[, metadata])</a></td>
<td class="summary">Delete session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#module.READ_METADATA">module.READ_METADATA (storage, red, name, audience, subject, current_time)</a></td>
<td class="summary">Read session metadata.</td>
</tr>
</table>
<br/>
<br/>
<h2 class="section-header "><a name="Functions"></a>Functions</h2>
<dl class="function">
<dt>
<a name = "module.SET"></a>
<strong>module.SET (storage, red, name, key, value, ttl, current_time[, old_key], stale_ttl[, metadata], remember)</strong>
</dt>
<dd>
Store session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">storage</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
the storage
</li>
<li><span class="parameter">red</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
the redis instance
</li>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
the cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">value</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session value
</li>
<li><span class="parameter">ttl</span>
<span class="types"><span class="type">number</span></span>
session ttl
</li>
<li><span class="parameter">current_time</span>
<span class="types"><span class="type">number</span></span>
current time
</li>
<li><span class="parameter">old_key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
old session id
(<em>optional</em>)
</li>
<li><span class="parameter">stale_ttl</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
stale ttl
</li>
<li><span class="parameter">metadata</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
table of metadata
(<em>optional</em>)
</li>
<li><span class="parameter">remember</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
whether storing persistent session or not
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">true</span> or <span class="type">nil</span></span>
ok</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "module.GET"></a>
<strong>module.GET (storage, red, name, key)</strong>
</dt>
<dd>
Retrieve session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">storage</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
the storage
</li>
<li><span class="parameter">red</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
the redis instance
</li>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
session data</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "module.UNLINK"></a>
<strong>module.UNLINK (storage, red, name, key, current_time[, metadata])</strong>
</dt>
<dd>
Delete session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">storage</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
the storage
</li>
<li><span class="parameter">red</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
the redis instance
</li>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">current_time</span>
<span class="types"><span class="type">number</span></span>
current time
</li>
<li><span class="parameter">metadata</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session meta data
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">boolean</span> or <span class="type">nil</span></span>
session data</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "module.READ_METADATA"></a>
<strong>module.READ_METADATA (storage, red, name, audience, subject, current_time)</strong>
</dt>
<dd>
Read session metadata.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">storage</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
the storage
</li>
<li><span class="parameter">red</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
the redis instance
</li>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">audience</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">subject</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">current_time</span>
<span class="types"><span class="type">number</span></span>
current time
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a> or <span class="type">nil</span></span>
session metadata</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
</dl>
</div> <!-- id="content" -->
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2023-06-05 17:05:22 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>

View File

@ -0,0 +1,409 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head>
<title>Session Library for OpenResty Documentation</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head>
<body>
<div id="container">
<div id="product">
<div id="product_logo"></div>
<div id="product_name"><big><b></b></big></div>
<div id="product_description"></div>
</div> <!-- id="product" -->
<div id="main">
<!-- Menu -->
<div id="navigation">
<br/>
<h1>resty.session</h1>
<ul>
<li><a href="../index.html">Index</a></li>
</ul>
<h2>Contents</h2>
<ul>
<li><a href="#Configuration">Configuration </a></li>
<li><a href="#Constructors">Constructors </a></li>
<li><a href="#Storage">Storage </a></li>
</ul>
<h2>Modules</h2>
<ul class="nowrap">
<li><a href="../modules/resty.session.html">resty.session</a></li>
<li><a href="../modules/resty.session.dshm.html">resty.session.dshm</a></li>
<li><a href="../modules/resty.session.file.html">resty.session.file</a></li>
<li><a href="../modules/resty.session.file.thread.html">resty.session.file.thread</a></li>
<li><a href="../modules/resty.session.file.utils.html">resty.session.file.utils</a></li>
<li><a href="../modules/resty.session.memcached.html">resty.session.memcached</a></li>
<li><a href="../modules/resty.session.mysql.html">resty.session.mysql</a></li>
<li><a href="../modules/resty.session.postgres.html">resty.session.postgres</a></li>
<li><strong>resty.session.redis</strong></li>
<li><a href="../modules/resty.session.redis.cluster.html">resty.session.redis.cluster</a></li>
<li><a href="../modules/resty.session.redis.common.html">resty.session.redis.common</a></li>
<li><a href="../modules/resty.session.redis.sentinel.html">resty.session.redis.sentinel</a></li>
<li><a href="../modules/resty.session.shm.html">resty.session.shm</a></li>
<li><a href="../modules/resty.session.utils.html">resty.session.utils</a></li>
</ul>
</div>
<div id="content">
<h1>Module <code>resty.session.redis</code></h1>
<p>Redis backend for session library</p>
<p>
</p>
<h2><a href="#Configuration">Configuration </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#configuration">configuration</a></td>
<td class="summary">Redis storage backend configuration</td>
</tr>
</table>
<h2><a href="#Constructors">Constructors </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#module.new">module.new ([configuration])</a></td>
<td class="summary">Create a Redis storage.</td>
</tr>
</table>
<h2><a href="#Storage">Storage </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#instance:set">instance:set (name, key, value, ttl, current_time[, old_key], stale_ttl[, metadata], remember)</a></td>
<td class="summary">Store session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:get">instance:get (name, key)</a></td>
<td class="summary">Retrieve session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:delete">instance:delete (name, key[, metadata])</a></td>
<td class="summary">Delete session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:read_metadata">instance:read_metadata (name, audience, subject, current_time)</a></td>
<td class="summary">Read session metadata.</td>
</tr>
</table>
<br/>
<br/>
<h2 class="section-header "><a name="Configuration"></a>Configuration </h2>
<dl class="function">
<dt>
<a name = "configuration"></a>
<strong>configuration</strong>
</dt>
<dd>
Redis storage backend configuration
<h3>Fields:</h3>
<ul>
<li><span class="parameter">prefix</span>
Prefix for the keys stored in Redis.
</li>
<li><span class="parameter">suffix</span>
Suffix for the keys stored in Redis.
</li>
<li><span class="parameter">host</span>
The host to connect (defaults to <code>&quot;127.0.0.1&quot;</code>).
</li>
<li><span class="parameter">port</span>
The port to connect (defaults to <code>6379</code>).
</li>
<li><span class="parameter">socket</span>
The socket file to connect to (defaults to <code>nil</code>).
</li>
<li><span class="parameter">username</span>
The database username to authenticate.
</li>
<li><span class="parameter">password</span>
Password for authentication.
</li>
<li><span class="parameter">database</span>
The database to connect.
</li>
<li><span class="parameter">connect_timeout</span>
Controls the default timeout value used in TCP/unix-domain socket object&rsquo;s <code>connect</code> method.
</li>
<li><span class="parameter">send_timeout</span>
Controls the default timeout value used in TCP/unix-domain socket object&rsquo;s <code>send</code> method.
</li>
<li><span class="parameter">read_timeout</span>
Controls the default timeout value used in TCP/unix-domain socket object&rsquo;s <code>receive</code> method.
</li>
<li><span class="parameter">keepalive_timeout</span>
Controls the default maximal idle time of the connections in the connection pool.
</li>
<li><span class="parameter">pool</span>
A custom name for the connection pool being used.
</li>
<li><span class="parameter">pool_size</span>
The size of the connection pool.
</li>
<li><span class="parameter">backlog</span>
A queue size to use when the connection pool is full (configured with @pool_size).
</li>
<li><span class="parameter">ssl</span>
Enable SSL (defaults to <code>false</code>).
</li>
<li><span class="parameter">ssl_verify</span>
Verify server certificate (defaults to <code>nil</code>).
</li>
<li><span class="parameter">server_name</span>
The server name for the new TLS extension Server Name Indication (SNI).
</li>
</ul>
</dd>
</dl>
<h2 class="section-header "><a name="Constructors"></a>Constructors </h2>
<dl class="function">
<dt>
<a name = "module.new"></a>
<strong>module.new ([configuration])</strong>
</dt>
<dd>
Create a Redis storage. </p>
<p> This creates a new Redis storage instance.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">configuration</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
redis storage <a href="../modules/resty.session.redis.html#configuration">configuration</a>
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
redis storage instance
</ol>
</dd>
</dl>
<h2 class="section-header "><a name="Storage"></a>Storage </h2>
<dl class="function">
<dt>
<a name = "instance:set"></a>
<strong>instance:set (name, key, value, ttl, current_time[, old_key], stale_ttl[, metadata], remember)</strong>
</dt>
<dd>
Store session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">value</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session value
</li>
<li><span class="parameter">ttl</span>
<span class="types"><span class="type">number</span></span>
session ttl
</li>
<li><span class="parameter">current_time</span>
<span class="types"><span class="type">number</span></span>
current time
</li>
<li><span class="parameter">old_key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
old session id
(<em>optional</em>)
</li>
<li><span class="parameter">stale_ttl</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
stale ttl
</li>
<li><span class="parameter">metadata</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
table of metadata
(<em>optional</em>)
</li>
<li><span class="parameter">remember</span>
<span class="types"><span class="type">boolean</span></span>
whether storing persistent session or not
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">true</span> or <span class="type">nil</span></span>
ok</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:get"></a>
<strong>instance:get (name, key)</strong>
</dt>
<dd>
Retrieve session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
session data</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:delete"></a>
<strong>instance:delete (name, key[, metadata])</strong>
</dt>
<dd>
Delete session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">metadata</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session meta data
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">boolean</span> or <span class="type">nil</span></span>
session data</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:read_metadata"></a>
<strong>instance:read_metadata (name, audience, subject, current_time)</strong>
</dt>
<dd>
Read session metadata.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">audience</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">subject</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">current_time</span>
<span class="types"><span class="type">number</span></span>
current time
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a> or <span class="type">nil</span></span>
session metadata</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
</dl>
</div> <!-- id="content" -->
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2023-06-05 17:05:22 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>

View File

@ -0,0 +1,460 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head>
<title>Session Library for OpenResty Documentation</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head>
<body>
<div id="container">
<div id="product">
<div id="product_logo"></div>
<div id="product_name"><big><b></b></big></div>
<div id="product_description"></div>
</div> <!-- id="product" -->
<div id="main">
<!-- Menu -->
<div id="navigation">
<br/>
<h1>resty.session</h1>
<ul>
<li><a href="../index.html">Index</a></li>
</ul>
<h2>Contents</h2>
<ul>
<li><a href="#Configuration">Configuration </a></li>
<li><a href="#Constructors">Constructors </a></li>
<li><a href="#Storage">Storage </a></li>
</ul>
<h2>Modules</h2>
<ul class="nowrap">
<li><a href="../modules/resty.session.html">resty.session</a></li>
<li><a href="../modules/resty.session.dshm.html">resty.session.dshm</a></li>
<li><a href="../modules/resty.session.file.html">resty.session.file</a></li>
<li><a href="../modules/resty.session.file.thread.html">resty.session.file.thread</a></li>
<li><a href="../modules/resty.session.file.utils.html">resty.session.file.utils</a></li>
<li><a href="../modules/resty.session.memcached.html">resty.session.memcached</a></li>
<li><a href="../modules/resty.session.mysql.html">resty.session.mysql</a></li>
<li><a href="../modules/resty.session.postgres.html">resty.session.postgres</a></li>
<li><a href="../modules/resty.session.redis.html">resty.session.redis</a></li>
<li><a href="../modules/resty.session.redis.cluster.html">resty.session.redis.cluster</a></li>
<li><a href="../modules/resty.session.redis.common.html">resty.session.redis.common</a></li>
<li><strong>resty.session.redis.sentinel</strong></li>
<li><a href="../modules/resty.session.shm.html">resty.session.shm</a></li>
<li><a href="../modules/resty.session.utils.html">resty.session.utils</a></li>
</ul>
</div>
<div id="content">
<h1>Module <code>resty.session.redis.sentinel</code></h1>
<p>Redis Sentinel backend for session library</p>
<p>
</p>
<h2><a href="#Configuration">Configuration </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#configuration">configuration</a></td>
<td class="summary">Redis Sentinel storage backend configuration</td>
</tr>
<tr>
<td class="name" nowrap><a href="#sentinels">sentinels</a></td>
<td class="summary">Sentinels</td>
</tr>
<tr>
<td class="name" nowrap><a href="#sentinel">sentinel</a></td>
<td class="summary">Sentinel</td>
</tr>
</table>
<h2><a href="#Constructors">Constructors </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#module.new">module.new ([configuration])</a></td>
<td class="summary">Create a Redis Sentinel storage.</td>
</tr>
</table>
<h2><a href="#Storage">Storage </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#instance:set">instance:set (name, key, value, ttl, current_time[, old_key], stale_ttl[, metadata], remember)</a></td>
<td class="summary">Store session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:get">instance:get (name, key)</a></td>
<td class="summary">Retrieve session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:delete">instance:delete (name, key[, metadata])</a></td>
<td class="summary">Delete session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:read_metadata">instance:read_metadata (name, audience, subject, current_time)</a></td>
<td class="summary">Read session metadata.</td>
</tr>
</table>
<br/>
<br/>
<h2 class="section-header "><a name="Configuration"></a>Configuration </h2>
<dl class="function">
<dt>
<a name = "configuration"></a>
<strong>configuration</strong>
</dt>
<dd>
Redis Sentinel storage backend configuration
<h3>Fields:</h3>
<ul>
<li><span class="parameter">prefix</span>
Prefix for the keys stored in redis.
</li>
<li><span class="parameter">suffix</span>
Suffix for the keys stored in redis.
</li>
<li><span class="parameter">master</span>
Name of master.
</li>
<li><span class="parameter">role</span>
<code>&quot;master&quot;</code> or <code>&quot;slave&quot;</code>.
</li>
<li><span class="parameter">sentinels</span>
Redis Sentinels.
</li>
<li><span class="parameter">sentinel_username</span>
Optional sentinel username.
</li>
<li><span class="parameter">sentinel_password</span>
Optional sentinel password.
</li>
<li><span class="parameter">username</span>
The database username to authenticate.
</li>
<li><span class="parameter">password</span>
Password for authentication.
</li>
<li><span class="parameter">database</span>
The database to connect.
</li>
<li><span class="parameter">connect_timeout</span>
Controls the default timeout value used in TCP/unix-domain socket object&rsquo;s <code>connect</code> method.
</li>
<li><span class="parameter">send_timeout</span>
Controls the default timeout value used in TCP/unix-domain socket object&rsquo;s <code>send</code> method.
</li>
<li><span class="parameter">read_timeout</span>
Controls the default timeout value used in TCP/unix-domain socket object&rsquo;s <code>receive</code> method.
</li>
<li><span class="parameter">keepalive_timeout</span>
Controls the default maximal idle time of the connections in the connection pool.
</li>
<li><span class="parameter">pool</span>
A custom name for the connection pool being used.
</li>
<li><span class="parameter">pool_size</span>
The size of the connection pool.
</li>
<li><span class="parameter">backlog</span>
A queue size to use when the connection pool is full (configured with @pool_size).
</li>
<li><span class="parameter">ssl</span>
Enable SSK (defaults to <code>false</code>).
</li>
<li><span class="parameter">ssl_verify</span>
Verify server certificate (defaults to <code>nil</code>).
</li>
<li><span class="parameter">server_name</span>
The server name for the new TLS extension Server Name Indication (SNI).
</li>
</ul>
</dd>
<dt>
<a name = "sentinels"></a>
<strong>sentinels</strong>
</dt>
<dd>
Sentinels An array of sentinels.
</dd>
<dt>
<a name = "sentinel"></a>
<strong>sentinel</strong>
</dt>
<dd>
Sentinel
<h3>Fields:</h3>
<ul>
<li><span class="parameter">host</span>
The host to connect.
</li>
<li><span class="parameter">port</span>
The port to connect.
</li>
</ul>
</dd>
</dl>
<h2 class="section-header "><a name="Constructors"></a>Constructors </h2>
<dl class="function">
<dt>
<a name = "module.new"></a>
<strong>module.new ([configuration])</strong>
</dt>
<dd>
Create a Redis Sentinel storage. </p>
<p> This creates a new Redis Sentinel storage instance.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">configuration</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
redis sentinel storage <a href="../modules/resty.session.redis.sentinel.html#configuration">configuration</a>
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
redis sentinel storage instance
</ol>
</dd>
</dl>
<h2 class="section-header "><a name="Storage"></a>Storage </h2>
<dl class="function">
<dt>
<a name = "instance:set"></a>
<strong>instance:set (name, key, value, ttl, current_time[, old_key], stale_ttl[, metadata], remember)</strong>
</dt>
<dd>
Store session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">value</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session value
</li>
<li><span class="parameter">ttl</span>
<span class="types"><span class="type">number</span></span>
session ttl
</li>
<li><span class="parameter">current_time</span>
<span class="types"><span class="type">number</span></span>
current time
</li>
<li><span class="parameter">old_key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
old session id
(<em>optional</em>)
</li>
<li><span class="parameter">stale_ttl</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
stale ttl
</li>
<li><span class="parameter">metadata</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
table of metadata
(<em>optional</em>)
</li>
<li><span class="parameter">remember</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
whether storing persistent session or not
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">true</span> or <span class="type">nil</span></span>
ok</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:get"></a>
<strong>instance:get (name, key)</strong>
</dt>
<dd>
Retrieve session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
session data</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:delete"></a>
<strong>instance:delete (name, key[, metadata])</strong>
</dt>
<dd>
Delete session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">metadata</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session meta data
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">boolean</span> or <span class="type">nil</span></span>
session data</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:read_metadata"></a>
<strong>instance:read_metadata (name, audience, subject, current_time)</strong>
</dt>
<dd>
Read session metadata.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">audience</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">subject</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">current_time</span>
<span class="types"><span class="type">number</span></span>
current time
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a> or <span class="type">nil</span></span>
session metadata</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
</dl>
</div> <!-- id="content" -->
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2023-06-05 17:05:22 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>

View File

@ -0,0 +1,364 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head>
<title>Session Library for OpenResty Documentation</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head>
<body>
<div id="container">
<div id="product">
<div id="product_logo"></div>
<div id="product_name"><big><b></b></big></div>
<div id="product_description"></div>
</div> <!-- id="product" -->
<div id="main">
<!-- Menu -->
<div id="navigation">
<br/>
<h1>resty.session</h1>
<ul>
<li><a href="../index.html">Index</a></li>
</ul>
<h2>Contents</h2>
<ul>
<li><a href="#Configuration">Configuration </a></li>
<li><a href="#Constructors">Constructors </a></li>
<li><a href="#Storage">Storage </a></li>
</ul>
<h2>Modules</h2>
<ul class="nowrap">
<li><a href="../modules/resty.session.html">resty.session</a></li>
<li><a href="../modules/resty.session.dshm.html">resty.session.dshm</a></li>
<li><a href="../modules/resty.session.file.html">resty.session.file</a></li>
<li><a href="../modules/resty.session.file.thread.html">resty.session.file.thread</a></li>
<li><a href="../modules/resty.session.file.utils.html">resty.session.file.utils</a></li>
<li><a href="../modules/resty.session.memcached.html">resty.session.memcached</a></li>
<li><a href="../modules/resty.session.mysql.html">resty.session.mysql</a></li>
<li><a href="../modules/resty.session.postgres.html">resty.session.postgres</a></li>
<li><a href="../modules/resty.session.redis.html">resty.session.redis</a></li>
<li><a href="../modules/resty.session.redis.cluster.html">resty.session.redis.cluster</a></li>
<li><a href="../modules/resty.session.redis.common.html">resty.session.redis.common</a></li>
<li><a href="../modules/resty.session.redis.sentinel.html">resty.session.redis.sentinel</a></li>
<li><strong>resty.session.shm</strong></li>
<li><a href="../modules/resty.session.utils.html">resty.session.utils</a></li>
</ul>
</div>
<div id="content">
<h1>Module <code>resty.session.shm</code></h1>
<p>Shared Memory (SHM) backend for session library</p>
<p>
</p>
<h2><a href="#Configuration">Configuration </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#configuration">configuration</a></td>
<td class="summary">Shared memory storage backend configuration</td>
</tr>
</table>
<h2><a href="#Constructors">Constructors </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#module.new">module.new ([configuration])</a></td>
<td class="summary">Create a SHM storage.</td>
</tr>
</table>
<h2><a href="#Storage">Storage </a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap><a href="#instance:set">instance:set (name, key, value, ttl, current_time[, old_key], stale_ttl[, metadata], remember)</a></td>
<td class="summary">Store session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:get">instance:get (name, key)</a></td>
<td class="summary">Retrieve session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:delete">instance:delete (name, key[, metadata])</a></td>
<td class="summary">Delete session data.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#instance:read_metadata">instance:read_metadata (name, audience, subject, current_time)</a></td>
<td class="summary">Read session metadata.</td>
</tr>
</table>
<br/>
<br/>
<h2 class="section-header "><a name="Configuration"></a>Configuration </h2>
<dl class="function">
<dt>
<a name = "configuration"></a>
<strong>configuration</strong>
</dt>
<dd>
Shared memory storage backend configuration
<h3>Fields:</h3>
<ul>
<li><span class="parameter">prefix</span>
Prefix for the keys stored in SHM.
</li>
<li><span class="parameter">suffix</span>
Suffix for the keys stored in SHM.
</li>
<li><span class="parameter">zone</span>
A name of shared memory zone (defaults to <code>sessions</code>).
</li>
</ul>
</dd>
</dl>
<h2 class="section-header "><a name="Constructors"></a>Constructors </h2>
<dl class="function">
<dt>
<a name = "module.new"></a>
<strong>module.new ([configuration])</strong>
</dt>
<dd>
Create a SHM storage. </p>
<p> This creates a new shared memory storage instance.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">configuration</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
shm storage <a href="../modules/resty.session.shm.html#configuration">configuration</a>
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
shm storage instance
</ol>
</dd>
</dl>
<h2 class="section-header "><a name="Storage"></a>Storage </h2>
<dl class="function">
<dt>
<a name = "instance:set"></a>
<strong>instance:set (name, key, value, ttl, current_time[, old_key], stale_ttl[, metadata], remember)</strong>
</dt>
<dd>
Store session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">value</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session value
</li>
<li><span class="parameter">ttl</span>
<span class="types"><span class="type">number</span></span>
session ttl
</li>
<li><span class="parameter">current_time</span>
<span class="types"><span class="type">number</span></span>
current time
</li>
<li><span class="parameter">old_key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
old session id
(<em>optional</em>)
</li>
<li><span class="parameter">stale_ttl</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
stale ttl
</li>
<li><span class="parameter">metadata</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
table of metadata
(<em>optional</em>)
</li>
<li><span class="parameter">remember</span>
<span class="types"><span class="type">boolean</span></span>
whether storing persistent session or not
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">true</span> or <span class="type">nil</span></span>
ok</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:get"></a>
<strong>instance:get (name, key)</strong>
</dt>
<dd>
Retrieve session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">nil</span></span>
session data</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:delete"></a>
<strong>instance:delete (name, key[, metadata])</strong>
</dt>
<dd>
Delete session data.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">key</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">metadata</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a></span>
session meta data
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><span class="type">boolean</span> or <span class="type">nil</span></span>
session data</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
<dt>
<a name = "instance:read_metadata"></a>
<strong>instance:read_metadata (name, audience, subject, current_time)</strong>
</dt>
<dd>
Read session metadata.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
cookie name
</li>
<li><span class="parameter">audience</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">subject</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
session key
</li>
<li><span class="parameter">current_time</span>
<span class="types"><span class="type">number</span></span>
current time
</li>
</ul>
<h3>Returns:</h3>
<ol>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a> or <span class="type">nil</span></span>
session metadata</li>
<li>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
error message</li>
</ol>
</dd>
</dl>
</div> <!-- id="content" -->
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2023-06-05 17:05:22 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,348 @@
---
-- Distributed Shared Memory (DSHM) backend for session library
--
-- @module resty.session.dshm
local buffer = require "string.buffer"
local utils = require "resty.session.utils"
local dshm = require "resty.dshm"
local meta_get_latest = utils.meta_get_latest
local meta_get_value = utils.meta_get_value
local get_name = utils.get_name
local setmetatable = setmetatable
local error = error
local pairs = pairs
local null = ngx.null
local max = math.max
local DEFAULT_HOST = "127.0.0.1"
local DEFAULT_PORT = 4321
local SESSIONS_BUFFER = buffer.new(128)
-- not safe for concurrent access
local function update_meta(dshmc, meta_key, key, exp, current_time)
local metadata = dshmc:get(meta_key)
local sessions = metadata and meta_get_latest(metadata, current_time) or {}
SESSIONS_BUFFER:reset()
sessions[key] = exp > 0 and exp or nil
local max_expiry = current_time
for s, e in pairs(sessions) do
SESSIONS_BUFFER:put(meta_get_value(s, e))
max_expiry = max(max_expiry, e)
end
local ser = SESSIONS_BUFFER:get()
if #ser > 0 then
return dshmc:set(meta_key, ser, max_expiry - current_time)
end
return dshmc:delete(meta_key)
end
local function READ_METADATA(self, dshmc, name, audience, subject, current_time)
local meta_key = get_name(self, name, audience, subject)
local res = dshmc:get(meta_key)
if not res then
return nil, "not found"
end
return meta_get_latest(res, current_time)
end
local function SET(self, dshmc, name, key, value, ttl, current_time, old_key, stale_ttl, metadata, remember)
local inferred_key = get_name(self, name, key)
if not metadata and not old_key then
return dshmc:set(inferred_key, value, ttl)
end
local ok, err = dshmc:set(inferred_key, value, ttl)
if err then
return nil, err
end
local old_name = old_key and get_name(self, name, old_key)
if old_name then
if remember then
dshmc:delete(old_name)
else
dshmc:touch(old_name, stale_ttl)
end
end
if metadata then
local audiences = metadata.audiences
local subjects = metadata.subjects
local count = #audiences
for i = 1, count do
local meta_key = get_name(self, name, audiences[i], subjects[i])
update_meta(dshmc, meta_key, key, current_time + ttl, current_time)
if old_key then
update_meta(dshmc, meta_key, old_key, 0, current_time)
end
end
end
return ok
end
local function GET(self, dshmc, name, key)
local res, err = dshmc:get(get_name(self, name, key))
if err then
return nil, err
end
return res
end
local function DELETE(self, dshmc, name, key, current_time, metadata)
local key_name = get_name(self, name, key)
local ok, err = dshmc:delete(key_name)
if not metadata then
return ok, err
end
local audiences = metadata.audiences
local subjects = metadata.subjects
local count = #audiences
for i = 1, count do
local meta_key = get_name(self, name, audiences[i], subjects[i])
update_meta(dshmc, meta_key, key, 0, current_time)
end
return ok, err
end
local function exec(self, func, ...)
local dshmc = dshm:new()
local connect_timeout = self.connect_timeout
local send_timeout = self.send_timeout
local read_timeout = self.read_timeout
if connect_timeout or send_timeout or read_timeout then
dshmc.sock:settimeouts(connect_timeout, send_timeout, read_timeout)
end
local ok, err = dshmc:connect(self.host, self.port, self.options)
if not ok then
return nil, err
end
if self.ssl and dshmc:get_reused_times() == 0 then
ok, err = dshmc.sock:sslhandshake(false, self.server_name, self.ssl_verify)
if not ok then
dshmc:close()
return nil, err
end
end
ok, err = func(self, dshmc, ...)
if err then
dshmc:close()
return nil, err
end
if not dshmc:set_keepalive(self.keepalive_timeout) then
dshmc:close()
end
if ok == null then
ok = nil
end
return ok, err
end
---
-- Storage
-- @section instance
local metatable = {}
metatable.__index = metatable
function metatable.__newindex()
error("attempt to update a read-only table", 2)
end
---
-- Store session data.
--
-- @function instance:set
-- @tparam string name cookie name
-- @tparam string key session key
-- @tparam string value session value
-- @tparam number ttl session ttl
-- @tparam number current_time current time
-- @tparam[opt] string old_key old session id
-- @tparam string stale_ttl stale ttl
-- @tparam[opt] table metadata table of metadata
-- @tparam boolean remember whether storing persistent session or not
-- @treturn true|nil ok
-- @treturn string error message
function metatable:set(...)
return exec(self, SET, ...)
end
---
-- Retrieve session data.
--
-- @function instance:get
-- @tparam string name cookie name
-- @tparam string key session key
-- @treturn string|nil session data
-- @treturn string error message
function metatable:get(...)
return exec(self, GET, ...)
end
---
-- Delete session data.
--
-- @function instance:delete
-- @tparam string name cookie name
-- @tparam string key session key
-- @tparam[opt] table metadata session meta data
-- @treturn boolean|nil session data
-- @treturn string error message
function metatable:delete(...)
return exec(self, DELETE, ...)
end
---
-- Read session metadata.
--
-- @function instance:read_metadata
-- @tparam string name cookie name
-- @tparam string audience session key
-- @tparam string subject session key
-- @tparam number current_time current time
-- @treturn table|nil session metadata
-- @treturn string error message
function metatable:read_metadata(...)
return exec(self, READ_METADATA, ...)
end
local storage = {}
---
-- Configuration
-- @section configuration
---
-- Distributed shared memory storage backend configuration
-- @field prefix The prefix for the keys stored in DSHM.
-- @field suffix The suffix for the keys stored in DSHM.
-- @field host The host to connect (defaults to `"127.0.0.1"`).
-- @field port The port to connect (defaults to `4321`).
-- @field connect_timeout Controls the default timeout value used in TCP/unix-domain socket object's `connect` method.
-- @field send_timeout Controls the default timeout value used in TCP/unix-domain socket object's `send` method.
-- @field read_timeout Controls the default timeout value used in TCP/unix-domain socket object's `receive` method.
-- @field keepalive_timeout Controls the default maximal idle time of the connections in the connection pool.
-- @field pool A custom name for the connection pool being used.
-- @field pool_size The size of the connection pool.
-- @field backlog A queue size to use when the connection pool is full (configured with @pool_size).
-- @field ssl Enable SSL (defaults to `false`).
-- @field ssl_verify Verify server certificate (defaults to `nil`).
-- @field server_name The server name for the new TLS extension Server Name Indication (SNI).
-- @table configuration
---
-- Constructors
-- @section constructors
---
-- Create a distributed shared memory storage.
--
-- This creates a new distributed shared memory storage instance.
--
-- @function module.new
-- @tparam[opt] table configuration DSHM storage @{configuration}
-- @treturn table DSHM storage instance
function storage.new(configuration)
local prefix = configuration and configuration.prefix
local suffix = configuration and configuration.suffix
local host = configuration and configuration.host or DEFAULT_HOST
local port = configuration and configuration.port or DEFAULT_PORT
local connect_timeout = configuration and configuration.connect_timeout
local send_timeout = configuration and configuration.send_timeout
local read_timeout = configuration and configuration.read_timeout
local keepalive_timeout = configuration and configuration.keepalive_timeout
local pool = configuration and configuration.pool
local pool_size = configuration and configuration.pool_size
local backlog = configuration and configuration.backlog
local ssl = configuration and configuration.ssl
local ssl_verify = configuration and configuration.ssl_verify
local server_name = configuration and configuration.server_name
if pool or pool_size or backlog then
setmetatable({
prefix = prefix,
suffix = suffix,
host = host,
port = port,
connect_timeout = connect_timeout,
send_timeout = send_timeout,
read_timeout = read_timeout,
keepalive_timeout = keepalive_timeout,
ssl = ssl,
ssl_verify = ssl_verify,
server_name = server_name,
options = {
pool = pool,
pool_size = pool_size,
backlog = backlog,
}
}, metatable)
end
return setmetatable({
prefix = prefix,
suffix = suffix,
host = host,
port = port,
connect_timeout = connect_timeout,
send_timeout = send_timeout,
read_timeout = read_timeout,
keepalive_timeout = keepalive_timeout,
ssl = ssl,
ssl_verify = ssl_verify,
server_name = server_name,
}, metatable)
end
return storage

View File

@ -0,0 +1,177 @@
---
-- File storage backend for session library.
--
-- @module resty.session.file
local file_utils = require "resty.session.file.utils"
local run_worker_thread = file_utils.run_worker_thread
local setmetatable = setmetatable
local error = error
local byte = string.byte
local SLASH_BYTE = byte("/")
local THREAD_MODULE = "resty.session.file.thread"
local DEFAULT_POOL = "default"
local DEFAULT_PATH do
local path = os.tmpname()
local pos
for i = #path, 1, -1 do
if byte(path, i) == SLASH_BYTE then
pos = i
break
end
end
DEFAULT_PATH = path:sub(1, pos)
end
local function run_thread(self, func, ...)
local ok, res, err = run_worker_thread(self.pool, THREAD_MODULE, func, self.path, self.prefix, self.suffix, ...)
if not ok then
return nil, res
end
return res, err
end
---
-- Storage
-- @section instance
local metatable = {}
metatable.__index = metatable
function metatable.__newindex()
error("attempt to update a read-only table", 2)
end
---
-- Store session data.
--
-- @function instance:set
-- @tparam string name cookie name
-- @tparam string key session key
-- @tparam string value session value
-- @tparam number ttl session ttl
-- @tparam number current_time current time
-- @tparam[opt] string old_key old session id
-- @tparam string stale_ttl stale ttl
-- @tparam[opt] table metadata table of metadata
-- @tparam boolean remember whether storing persistent session or not
-- @treturn true|nil ok
-- @treturn string error message
function metatable:set(...)
return run_thread(self, "set", ...)
end
---
-- Retrieve session data.
--
-- @function instance:get
-- @tparam string name cookie name
-- @tparam string key session key
-- @treturn string|nil session data
-- @treturn string error message
function metatable:get(...)
return run_thread(self, "get", ...)
end
---
-- Delete session data.
--
-- @function instance:delete
-- @tparam string name cookie name
-- @tparam string key session key
-- @tparam[opt] table metadata session meta data
-- @treturn boolean|nil session data
-- @treturn string error message
function metatable:delete(...)
return run_thread(self, "delete", ...)
end
---
-- Read session metadata.
--
-- @function instance:read_metadata
-- @tparam string name cookie name
-- @tparam string audience session key
-- @tparam string subject session key
-- @tparam number current_time current time
-- @treturn table|nil session metadata
-- @treturn string error message
function metatable:read_metadata(...)
return run_thread(self, "read_metadata", ...)
end
local storage = {}
---
-- Configuration
-- @section configuration
---
-- File storage backend configuration
-- @field prefix File prefix for session file.
-- @field suffix File suffix (or extension without `.`) for session file.
-- @field pool Name of the thread pool under which file writing happens (available on Linux only).
-- @field path Path (or directory) under which session files are created.
-- @table configuration
---
-- Constructors
-- @section constructors
---
-- Create a file storage.
--
-- This creates a new file storage instance.
--
-- @function module.new
-- @tparam[opt] table configuration file storage @{configuration}
-- @treturn table file storage instance
function storage.new(configuration)
local prefix = configuration and configuration.prefix
local suffix = configuration and configuration.suffix
local pool = configuration and configuration.pool or DEFAULT_POOL
local path = configuration and configuration.path or DEFAULT_PATH
if byte(path, -1) ~= SLASH_BYTE then
path = path .. "/"
end
return setmetatable({
prefix = prefix ~= "" and prefix or nil,
suffix = suffix ~= "" and suffix or nil,
pool = pool,
path = path,
}, metatable)
end
return storage

View File

@ -0,0 +1,209 @@
---
-- File storage backend worker thread module
--
-- @module resty.session.file.thread
local file_utils = require "resty.session.file.utils"
local utils = require "resty.session.utils"
local get_modification = file_utils.get_modification
local meta_get_key = file_utils.meta_get_key
local file_create = file_utils.file_create
local file_append = file_utils.file_append
local file_delete = file_utils.file_delete
local file_touch = file_utils.file_touch
local file_read = file_utils.file_read
local get_path = file_utils.get_path
local cleanup = file_utils.cleanup
local meta_get_latest = utils.meta_get_latest
local meta_get_value = utils.meta_get_value
local max = math.max
local function update_meta(path, prefix, suffix, name, meta_key, key, exp)
local meta_value = meta_get_value(key, exp)
if not meta_value then
return
end
local file_path = get_path(path, prefix, suffix, name, meta_key)
file_append(file_path, meta_value)
local current_expiry = get_modification(file_path) or 0
local new_expiry = max(current_expiry, exp)
file_touch(file_path, new_expiry)
end
---
-- Store session data.
--
-- @function module.set
-- @tparam string path the path where sessions are stored
-- @tparam string prefix the prefix for session files
-- @tparam string suffix the suffix for session files
-- @tparam string name the cookie name
-- @tparam string key session key
-- @tparam string value session value
-- @tparam number ttl session ttl
-- @tparam number current_time current time
-- @tparam[opt] string old_key old session id
-- @tparam string stale_ttl stale ttl
-- @tparam[opt] table metadata table of metadata
-- @tparam table remember whether storing persistent session or not
-- @treturn table|nil session metadata
-- @treturn string error message
local function set(path, prefix, suffix, name, key, value, ttl,
current_time, old_key, stale_ttl, metadata, remember)
local file_path = get_path(path, prefix, suffix, name, key)
if not metadata and not old_key then
local ok, err = file_create(file_path, value)
if ok and current_time and ttl then
file_touch(file_path, current_time + ttl)
end
cleanup(path, prefix, suffix, name, current_time)
return ok, err
end
local old_ttl, old_file_path
if old_key then
old_file_path = get_path(path, prefix, suffix, name, old_key)
if not remember then
local exp = get_modification(old_file_path)
if exp then
old_ttl = exp - current_time
end
end
end
local ok, err = file_create(file_path, value)
if ok and current_time and ttl then
file_touch(file_path, current_time + ttl)
end
if old_file_path then
if remember then
file_delete(old_file_path)
elseif not old_ttl or old_ttl > stale_ttl then
file_touch(old_file_path, current_time + stale_ttl)
end
end
if metadata then
local audiences = metadata.audiences
local subjects = metadata.subjects
local count = #audiences
for i = 1, count do
local meta_key = meta_get_key(audiences[i], subjects[i])
update_meta(path, prefix, suffix, name, meta_key, key, current_time + ttl)
if old_key then
update_meta(path, prefix, suffix, name, meta_key, old_key, 0)
end
end
end
cleanup(path, prefix, suffix, name, current_time)
return ok, err
end
---
-- Retrieve session data.
--
-- @function module.GET
-- @tparam string path the path where sessions are stored
-- @tparam string prefix the prefix for session files
-- @tparam string suffix the suffix for session files
-- @tparam string name cookie name
-- @tparam string key session key
-- @treturn string|nil session data
-- @treturn string error message
local function get(path, prefix, suffix, name, key, current_time)
local file_path = get_path(path, prefix, suffix, name, key)
-- TODO: do we want to check expiry here?
-- The cookie header already has the info and has a MAC too.
local exp = get_modification(file_path)
if exp and exp < current_time then
return nil, "expired"
end
return file_read(file_path)
end
---
-- Delete session data.
--
-- @function module.delete
-- @tparam string path the path where sessions are stored
-- @tparam string prefix the prefix for session files
-- @tparam string suffix the suffix for session files
-- @tparam string name the cookie name
-- @tparam string key session key
-- @tparam number current_time current time
-- @treturn table|nil session metadata
-- @treturn string error message
local function delete(path, prefix, suffix, name, key, current_time, metadata)
local file_path = get_path(path, prefix, suffix, name, key)
file_delete(file_path)
if metadata then
local audiences = metadata.audiences
local subjects = metadata.subjects
local count = #audiences
for i = 1, count do
local meta_key = meta_get_key(audiences[i], subjects[i])
update_meta(path, prefix, suffix, name, meta_key, key, 0)
end
end
cleanup(path, prefix, suffix, name, current_time)
return true
end
---
-- Read session metadata.
--
-- @function module.read_metadata
-- @tparam string path the path where sessions are stored
-- @tparam string prefix the prefix for session files
-- @tparam string suffix the suffix for session files
-- @tparam string name the cookie name
-- @tparam string audience session audience
-- @tparam string subject session subject
-- @tparam number current_time current time
-- @treturn table|nil session metadata
-- @treturn string error message
local function read_metadata(path, prefix, suffix, name, audience, subject, current_time)
local meta_key = meta_get_key(audience, subject)
local file_path = get_path(path, prefix, suffix, name, meta_key)
local metadata, err = file_read(file_path)
if not metadata then
return nil, err
end
return meta_get_latest(metadata, current_time)
end
return {
set = set,
get = get,
delete = delete,
read_metadata = read_metadata,
}

View File

@ -0,0 +1,290 @@
---
-- File storage utilities
--
-- @module resty.session.file.utils
local lfs = require "lfs"
local attributes = lfs.attributes
local touch = lfs.touch
local dir = lfs.dir
local file_delete = os.remove
local random = math.random
local pcall = pcall
local open = io.open
local fmt = string.format
local CLEANUP_PROBABILITY = 0.0005 -- 1 / 2000
local run_worker_thread do
run_worker_thread = ngx.run_worker_thread -- luacheck: ignore
if not run_worker_thread then
local require = require
run_worker_thread = function(_, module, func, ...)
local m = require(module)
return pcall(m[func], ...)
end
end
end
local function file_touch(path, mtime)
return touch(path, nil, mtime)
end
---
-- Store data in file.
--
-- @function file_create
-- @tparam string path file path
-- @tparam string content file content
-- @treturn true|nil ok
-- @treturn string error message
local function file_create(path, content)
local file, err = open(path, "wb")
if not file then
return nil, err
end
local ok, err = file:write(content)
file:close()
if not ok then
file_delete(path)
return nil, err
end
return true
end
---
-- Append data in file.
--
-- @function file_append
-- @tparam string path file path
-- @tparam string data file data
-- @treturn true|nil ok
-- @treturn string error message
local function file_append(path, data)
local file, err = open(path, "a")
if not file then
return nil, err
end
local ok, err = file:write(data)
file:close()
if not ok then
file_delete(path)
return nil, err
end
return true
end
---
-- Read data from a file.
--
-- @function file_read
-- @tparam string path file to read
-- @treturn string|nil content
-- @treturn string error message
local function file_read(path)
local file, err = open(path, "rb")
if not file then
return nil, err
end
local content, err = file:read("*a")
file:close()
if not content then
return nil, err
end
return content
end
---
-- Generate the path for a file to be stored at.
--
-- @tparam string path the path where sessions are stored
-- @tparam string prefix the prefix for session files
-- @tparam string suffix the suffix for session files
-- @tparam string name the cookie name
-- @tparam string key session key
-- @treturn string path
local function get_path(path, prefix, suffix, name, key)
if prefix and suffix then
return fmt("%s%s_%s_%s.%s", path, prefix, name, key, suffix)
elseif prefix then
return fmt("%s%s_%s_%s", path, prefix, name, key)
elseif suffix then
return fmt("%s%s_%s.%s", path, name, key, suffix)
else
return fmt("%s%s_%s", path, name, key)
end
end
---
-- Get the value modification time of a file.
--
-- @function utils.get_modification
-- @tparam string path the path to the file
local function get_modification(path)
local attr = attributes(path)
if not attr or attr.mode ~= "file" then
return
end
return attr.modification or nil
end
---
-- Given an audience and a subject, generate a metadata key.
--
-- @function utils.meta_get_key
-- @tparam string audience session audience
-- @tparam string subject session subject
-- @treturn string metadata key
local function meta_get_key(audience, subject)
return fmt("%s:%s", audience, subject)
end
---
-- Validate a file name.
-- Run a few checks to try to determine if the file is managed by this library
--
-- @function utils.validate_file_name
-- @tparam string prefix the prefix for session files
-- @tparam string suffix the suffix for session files
-- @tparam string name cookie name
-- @tparam string filename the name of the file
-- @treturn true|false whether the file is managed by the library or not
local validate_file_name do
local byte = string.byte
local sub = string.sub
local find = string.find
local UNDERSCORE = byte("_")
local DOT = byte(".")
validate_file_name = function(prefix, suffix, name, filename)
if filename == "." or filename == ".." then
return false
end
local plen = 0
if prefix then
plen = #prefix
if byte(filename, plen + 1) ~= UNDERSCORE or
(plen > 0 and sub(filename, 1, plen) ~= prefix) then
return false
end
end
local slen = 0
if suffix then
slen = #suffix
if byte(filename, -1 - slen) ~= DOT or
(slen > 0 and sub(filename, -slen) ~= suffix)
then
return false
end
end
local nlen = #name
local name_start = plen == 0 and 1 or plen + 2
local name_end = name_start + nlen - 1
if byte(filename, name_end + 1) ~= UNDERSCORE or
sub(filename, name_start, name_end) ~= name
then
return false
end
local rest
if slen == 0 then
rest = sub(filename, name_end + 2)
else
rest = sub(filename, name_end + 2, -2 - slen)
end
local rlen = #rest
if rlen < 3 then
return false
end
if rlen ~= 43 then
local colon_pos = find(rest, ":", 2, true)
if not colon_pos or colon_pos == 43 then
return false
end
end
return true
end
end
---
-- Clean up expired session and metadata files.
--
-- @function utils.cleanup
-- @tparam string path the path where sessions are stored
-- @tparam string prefix the prefix for session files
-- @tparam string suffix the suffix for session files
-- @tparam string name cookie name
-- @tparam number current_time current time
-- @treturn true|false whether clean up completed
local function cleanup(path, prefix, suffix, name, current_time)
if random() > CLEANUP_PROBABILITY then
return false
end
local deleted = 0
for file in dir(path) do
if validate_file_name(prefix, suffix, name, file) then
local exp = get_modification(path .. file)
if exp and exp < current_time then
file_delete(path .. file)
deleted = deleted + 1
end
end
end
return true
end
return {
validate_file_name = validate_file_name,
run_worker_thread = run_worker_thread,
get_modification = get_modification,
meta_get_key = meta_get_key,
file_create = file_create,
file_append = file_append,
file_delete = file_delete,
file_touch = file_touch,
file_read = file_read,
get_path = get_path,
cleanup = cleanup,
}

View File

@ -0,0 +1,395 @@
---
-- Memcached backend for session library
--
-- @module resty.session.memcached
local memcached = require "resty.memcached"
local buffer = require "string.buffer"
local utils = require "resty.session.utils"
local meta_get_latest = utils.meta_get_latest
local meta_get_value = utils.meta_get_value
local get_name = utils.get_name
local errmsg = utils.errmsg
local setmetatable = setmetatable
local random = math.random
local error = error
local pairs = pairs
local null = ngx.null
local log = ngx.log
local max = math.max
local WARN = ngx.WARN
local CLEANUP_PROBABILITY = 0.1 -- 1 / 10
local SESSIONS_BUFFER = buffer.new(128)
local function cleanup(memc, meta_key, current_time)
local res, _, cas_unique, err = memc:gets(meta_key)
if not res then
return nil, err
end
local sessions = meta_get_latest(res, current_time)
SESSIONS_BUFFER:reset()
local max_expiry = current_time
for key, exp in pairs(sessions) do
SESSIONS_BUFFER:put(meta_get_value(key, exp))
max_expiry = max(max_expiry, exp)
end
local exp = max_expiry - current_time
if exp > 0 then
return memc:cas(meta_key, SESSIONS_BUFFER:get(), cas_unique, exp)
end
return memc:delete(meta_key)
end
local function read_metadata(self, memc, name, audience, subject, current_time)
local meta_key = get_name(self, name, audience, subject)
local res, _, err = memc:get(meta_key)
if not res then
return nil, err
end
return meta_get_latest(res, current_time)
end
-- TODO possible improvement: when available in the lib, use pipelines
local function SET(self, memc, name, key, value, ttl, current_time, old_key, stale_ttl, metadata, remember)
local inferred_key = get_name(self, name, key)
if not metadata and not old_key then
return memc:set(inferred_key, value, ttl)
end
local ok, err = memc:set(inferred_key, value, ttl)
if not ok then
return nil, err
end
local old_name = old_key and get_name(self, name, old_key)
if old_name then
if remember then
memc:delete(old_name)
else
memc:touch(old_name, stale_ttl)
end
end
if not metadata then
return true
end
local audiences = metadata.audiences
local subjects = metadata.subjects
local count = #audiences
for i = 1, count do
local meta_key = get_name(self, name, audiences[i], subjects[i])
local meta_value = meta_get_value(key, current_time + ttl)
local added, err = memc:add(meta_key, meta_value)
if not added then
local appended, err2 = memc:append(meta_key, meta_value)
if not appended then
log(WARN, "[session] ", errmsg(err2 or err, "failed to store metadata"))
end
end
if old_key then
meta_value = meta_get_value(old_key, 0)
local ok, err = memc:append(meta_key, meta_value)
if not ok then
log(WARN, "[session] ", errmsg(err, "failed to update metadata"))
end
end
-- no need to clean up every time we write
-- it is just beneficial when a key is used a lot
if random() < CLEANUP_PROBABILITY then
cleanup(memc, meta_key, current_time)
end
end
return true
end
local function GET(self, memc, name, key)
local res, _, err = memc:get(get_name(self, name, key))
if err then
return nil, err
end
return res
end
local function DELETE(self, memc, name, key, current_time, metadata)
local key_name = get_name(self, name, key)
local ok, err = memc:delete(key_name)
if not metadata then
return ok, err
end
local audiences = metadata.audiences
local subjects = metadata.subjects
local count = #audiences
for i = 1, count do
local meta_key = get_name(self, name, audiences[i], subjects[i])
local meta_value = meta_get_value(key, 0)
local ok, err = memc:append(meta_key, meta_value)
if not ok and err ~= "NOT_STORED" then
log(WARN, "[session] ", errmsg(err, "failed to update metadata"))
end
cleanup(memc, meta_key, current_time)
end
return ok, err
end
local DEFAULT_HOST = "127.0.0.1"
local DEFAULT_PORT = 11211
local function exec(self, func, ...)
local memc = memcached:new()
local connect_timeout = self.connect_timeout
local send_timeout = self.send_timeout
local read_timeout = self.read_timeout
if connect_timeout or send_timeout or read_timeout then
memc:set_timeouts(connect_timeout, send_timeout, read_timeout)
end
local ok, err do
local socket = self.socket
if socket then
ok, err = memc:connect(socket, self.options)
else
ok, err = memc:connect(self.host, self.port, self.options)
end
end
if not ok then
return nil, err
end
if self.ssl and memc:get_reused_times() == 0 then
ok, err = memc:sslhandshake(false, self.server_name, self.ssl_verify)
if not ok then
memc:close()
return nil, err
end
end
ok, err = func(self, memc, ...)
if err then
memc:close()
return nil, err
end
if not memc:set_keepalive(self.keepalive_timeout) then
memc:close()
end
if ok == null then
ok = nil
end
return ok, err
end
---
-- Storage
-- @section instance
local metatable = {}
metatable.__index = metatable
function metatable.__newindex()
error("attempt to update a read-only table", 2)
end
---
-- Store session data.
--
-- @function instance:set
-- @tparam string name cookie name
-- @tparam string key session key
-- @tparam string value session value
-- @tparam number ttl session ttl
-- @tparam number current_time current time
-- @tparam[opt] string old_key old session id
-- @tparam string stale_ttl stale ttl
-- @tparam[opt] table metadata table of metadata
-- @tparam boolean remember whether storing persistent session or not
-- @treturn true|nil ok
-- @treturn string error message
function metatable:set(...)
return exec(self, SET, ...)
end
---
-- Retrieve session data.
--
-- @function instance:get
-- @tparam string name cookie name
-- @tparam string key session key
-- @treturn string|nil session data
-- @treturn string error message
function metatable:get(...)
return exec(self, GET, ...)
end
---
-- Delete session data.
--
-- @function instance:delete
-- @tparam string name cookie name
-- @tparam string key session key
-- @tparam[opt] table metadata session meta data
-- @treturn boolean|nil session data
-- @treturn string error message
function metatable:delete(...)
return exec(self, DELETE, ...)
end
---
-- Read session metadata.
--
-- @function instance:read_metadata
-- @tparam string name cookie name
-- @tparam string audience session key
-- @tparam string subject session key
-- @tparam number current_time current time
-- @treturn table|nil session metadata
-- @treturn string error message
function metatable:read_metadata(...)
return exec(self, read_metadata, ...)
end
local storage = {}
---
-- Configuration
-- @section configuration
---
-- Distributed shared memory storage backend configuration
-- @field prefix Prefix for the keys stored in memcached.
-- @field suffix Suffix for the keys stored in memcached.
-- @field host The host to connect (defaults to `"127.0.0.1"`).
-- @field port The port to connect (defaults to `11211`).
-- @field socket The socket file to connect to (defaults to `nil`).
-- @field connect_timeout Controls the default timeout value used in TCP/unix-domain socket object's `connect` method.
-- @field send_timeout Controls the default timeout value used in TCP/unix-domain socket object's `send` method.
-- @field read_timeout Controls the default timeout value used in TCP/unix-domain socket object's `receive` method.
-- @field keepalive_timeout Controls the default maximal idle time of the connections in the connection pool.
-- @field pool A custom name for the connection pool being used.
-- @field pool_size The size of the connection pool.
-- @field backlog A queue size to use when the connection pool is full (configured with @pool_size).
-- @field ssl Enable SSL (defaults to `false`).
-- @field ssl_verify Verify server certificate (defaults to `nil`).
-- @field server_name The server name for the new TLS extension Server Name Indication (SNI).
-- @table configuration
---
-- Constructors
-- @section constructors
---
-- Create a memcached storage.
--
-- This creates a new memcached storage instance.
--
-- @function module.new
-- @tparam[opt] table configuration memcached storage @{configuration}
-- @treturn table memcached storage instance
function storage.new(configuration)
local prefix = configuration and configuration.prefix
local suffix = configuration and configuration.suffix
local host = configuration and configuration.host or DEFAULT_HOST
local port = configuration and configuration.port or DEFAULT_PORT
local socket = configuration and configuration.socket
local connect_timeout = configuration and configuration.connect_timeout
local send_timeout = configuration and configuration.send_timeout
local read_timeout = configuration and configuration.read_timeout
local keepalive_timeout = configuration and configuration.keepalive_timeout
local pool = configuration and configuration.pool
local pool_size = configuration and configuration.pool_size
local backlog = configuration and configuration.backlog
local ssl = configuration and configuration.ssl
local ssl_verify = configuration and configuration.ssl_verify
local server_name = configuration and configuration.server_name
if pool or pool_size or backlog then
setmetatable({
prefix = prefix,
suffix = suffix,
host = host,
port = port,
socket = socket,
connect_timeout = connect_timeout,
send_timeout = send_timeout,
read_timeout = read_timeout,
keepalive_timeout = keepalive_timeout,
ssl = ssl,
ssl_verify = ssl_verify,
server_name = server_name,
options = {
pool = pool,
pool_size = pool_size,
backlog = backlog,
}
}, metatable)
end
return setmetatable({
prefix = prefix,
suffix = suffix,
host = host,
port = port,
socket = socket,
connect_timeout = connect_timeout,
send_timeout = send_timeout,
read_timeout = read_timeout,
keepalive_timeout = keepalive_timeout,
ssl = ssl,
ssl_verify = ssl_verify,
server_name = server_name,
}, metatable)
end
return storage

View File

@ -0,0 +1,379 @@
---
-- MySQL / MariaDB backend for session library
--
-- @module resty.session.mysql
---
-- Database
-- @section database
---
-- Sessions table.
--
-- Database table that stores session data.
--
-- @usage
-- CREATE TABLE IF NOT EXISTS sessions (
-- sid CHAR(43) PRIMARY KEY,
-- name VARCHAR(255),
-- data MEDIUMTEXT,
-- exp DATETIME,
-- INDEX (exp)
-- ) CHARACTER SET ascii;
-- @table sessions
---
-- Sessions metadata table.
--
-- This is only needed if you want to store session metadata.
--
-- @usage
-- CREATE TABLE IF NOT EXISTS sessions_meta (
-- aud VARCHAR(255),
-- sub VARCHAR(255),
-- sid CHAR(43),
-- PRIMARY KEY (aud, sub, sid),
-- CONSTRAINT FOREIGN KEY (sid) REFERENCES sessions(sid) ON DELETE CASCADE ON UPDATE CASCADE
-- ) CHARACTER SET ascii;
-- @table metadata
local buffer = require "string.buffer"
local mysql = require "resty.mysql"
local setmetatable = setmetatable
local random = math.random
local ipairs = ipairs
local error = error
local fmt = string.format
local DEFAULT_HOST = "127.0.0.1"
local DEFAULT_PORT = 3306
local DEFAULT_TABLE = "sessions"
local DEFAULT_CHARSET = "ascii"
local SET = "INSERT INTO %s (sid, name, data, exp) VALUES ('%s', '%s', '%s', FROM_UNIXTIME(%d)) AS new ON DUPLICATE KEY UPDATE data = new.data"
local SET_META_PREFIX = "INSERT INTO %s (aud, sub, sid) VALUES "
local SET_META_VALUES = "('%s', '%s', '%s')"
local SET_META_SUFFIX = " ON DUPLICATE KEY UPDATE sid = sid"
local GET_META = "SELECT sid, exp FROM %s JOIN %s USING (sid) WHERE aud = '%s' AND sub = '%s' AND exp >= FROM_UNIXTIME(%d)"
local GET = "SELECT data FROM %s WHERE sid = '%s' AND exp >= FROM_UNIXTIME(%d)"
local EXPIRE = "UPDATE %s SET exp = FROM_UNIXTIME(%d) WHERE sid = '%s' AND exp > FROM_UNIXTIME(%d)"
local DELETE = "DELETE FROM %s WHERE sid = '%s'"
local CLEANUP = "DELETE FROM %s WHERE exp < FROM_UNIXTIME(%d)"
local SQL = buffer.new()
local STM_DELIM = ";\n"
local VAL_DELIM = ", "
local CLEANUP_PROBABILITY = 0.001 -- 1 / 1000
local function exec(self, query)
local my = mysql:new()
local connect_timeout = self.connect_timeout
local send_timeout = self.send_timeout
local read_timeout = self.read_timeout
if connect_timeout or send_timeout or read_timeout then
if my.sock and my.sock.settimeouts then
my.sock:settimeouts(connect_timeout, send_timeout, read_timeout)
else
my:set_timeout(connect_timeout)
end
end
local ok, err = my:connect(self.options)
if not ok then
return nil, err
end
ok, err = my:query(query)
if not my:set_keepalive(self.keepalive_timeout) then
my:close()
end
return ok, err
end
---
-- Storage
-- @section instance
local metatable = {}
metatable.__index = metatable
function metatable.__newindex()
error("attempt to update a read-only table", 2)
end
---
-- Store session data.
--
-- @function instance:set
-- @tparam string name cookie name
-- @tparam string key session key
-- @tparam string value session value
-- @tparam number ttl session ttl
-- @tparam number current_time current time
-- @tparam[opt] string old_key old session id
-- @tparam string stale_ttl stale ttl
-- @tparam[opt] table metadata table of metadata
-- @tparam boolean remember whether storing persistent session or not
-- @treturn true|nil ok
-- @treturn string error message
function metatable:set(name, key, value, ttl, current_time, old_key, stale_ttl, metadata, remember)
local table = self.table
local exp = ttl + current_time
if not metadata and not old_key then
return exec(self, fmt(SET, table, key, name, value, exp))
end
SQL:reset():putf(SET, table, key, name, value, exp)
if old_key then
if remember then
SQL:put(STM_DELIM):putf(DELETE, table, old_key)
else
local stale_exp = stale_ttl + current_time
SQL:put(STM_DELIM):putf(EXPIRE, table, stale_exp, old_key, stale_exp)
end
end
local table_meta = self.table_meta
if metadata then
local audiences = metadata.audiences
local subjects = metadata.subjects
local count = #audiences
SQL:put(STM_DELIM):putf(SET_META_PREFIX, table_meta)
for i = 1, count do
if i > 1 then
SQL:put(VAL_DELIM)
end
SQL:putf(SET_META_VALUES, audiences[i], subjects[i], key)
end
SQL:putf(SET_META_SUFFIX)
end
if random() < CLEANUP_PROBABILITY then
SQL:put(STM_DELIM):putf(CLEANUP, self.table, current_time)
end
return exec(self, SQL:get())
end
---
-- Retrieve session data.
--
-- @function instance:get
-- @tparam string name cookie name
-- @tparam string key session key
-- @treturn string|nil session data
-- @treturn string error message
function metatable:get(name, key, current_time) -- luacheck: ignore
local res, err = exec(self, fmt(GET, self.table, key, current_time))
if not res then
return nil, err
end
local row = res[1]
if not row then
return nil, "session not found"
end
local data = row.data
if not row.data then
return nil, "session not found"
end
return data
end
---
-- Delete session data.
--
-- @function instance:delete
-- @tparam string name cookie name
-- @tparam string key session key
-- @tparam[opt] table metadata session meta data
-- @treturn boolean|nil session data
-- @treturn string error message
function metatable:delete(name, key, current_time, metadata) -- luacheck: ignore
SQL:reset():putf(DELETE, self.table, key)
if random() < CLEANUP_PROBABILITY then
SQL:put(STM_DELIM):putf(CLEANUP, self.table, current_time)
end
return exec(self, SQL:get())
end
---
-- Read session metadata.
--
-- @function instance:read_metadata
-- @tparam string name cookie name
-- @tparam string audience session key
-- @tparam string subject session key
-- @tparam number current_time current time
-- @treturn table|nil session metadata
-- @treturn string error message
function metatable:read_metadata(name, audience, subject, current_time) -- luacheck: ignore
local res = {}
local t = exec(self, fmt(GET_META, self.table_meta, self.table, audience, subject, current_time))
if not t then
return nil, "not found"
end
for _, v in ipairs(t) do
local key = v.sid
if key then
res[key] = v.exp
end
end
return res
end
local storage = {}
---
-- Configuration
-- @section configuration
---
-- Postgres storage backend configuration
-- @field host The host to connect (defaults to `"127.0.0.1"`).
-- @field port The port to connect (defaults to `3306`).
-- @field socket The socket file to connect to (defaults to `nil`).
-- @field username The database username to authenticate (defaults to `nil`).
-- @field password Password for authentication, may be required depending on server configuration.
-- @field charset The character set used on the MySQL connection (defaults to `"ascii"`).
-- @field database The database name to connect.
-- @field table_name Name of database table to which to store session data (defaults to `"sessions"`).
-- @field table_name_meta Name of database meta data table to which to store session meta data (defaults to `"sessions_meta"`).
-- @field max_packet_size The upper limit for the reply packets sent from the MySQL server (defaults to 1 MB).
-- @field connect_timeout Controls the default timeout value used in TCP/unix-domain socket object's `connect` method.
-- @field send_timeout Controls the default timeout value used in TCP/unix-domain socket object's `send` method.
-- @field read_timeout Controls the default timeout value used in TCP/unix-domain socket object's `receive` method.
-- @field keepalive_timeout Controls the default maximal idle time of the connections in the connection pool.
-- @field pool A custom name for the connection pool being used.
-- @field pool_size The size of the connection pool.
-- @field backlog A queue size to use when the connection pool is full (configured with @pool_size).
-- @field ssl Enable SSL (defaults to `false`).
-- @field ssl_verify Verify server certificate (defaults to `nil`).
-- @table configuration
---
-- Constructors
-- @section constructors
---
-- Create a MySQL / MariaDB storage.
--
-- This creates a new MySQL / MariaDB storage instance.
--
-- @function module.new
-- @tparam[opt] table configuration mysql/mariadb storage @{configuration}
-- @treturn table mysql/mariadb storage instance
function storage.new(configuration)
local host = configuration and configuration.host or DEFAULT_HOST
local port = configuration and configuration.port or DEFAULT_PORT
local socket = configuration and configuration.socket
local username = configuration and configuration.username
local password = configuration and configuration.password
local charset = configuration and configuration.charset or DEFAULT_CHARSET
local database = configuration and configuration.database
local max_packet_size = configuration and configuration.max_packet_size
local table_name = configuration and configuration.table or DEFAULT_TABLE
local table_name_meta = configuration and configuration.table_meta
local connect_timeout = configuration and configuration.connect_timeout
local send_timeout = configuration and configuration.send_timeout
local read_timeout = configuration and configuration.read_timeout
local keepalive_timeout = configuration and configuration.keepalive_timeout
local pool = configuration and configuration.pool
local pool_size = configuration and configuration.pool_size
local backlog = configuration and configuration.backlog
local ssl = configuration and configuration.ssl
local ssl_verify = configuration and configuration.ssl_verify
if socket then
return setmetatable({
table = table_name,
table_meta = table_name_meta or (table_name .. "_meta"),
connect_timeout = connect_timeout,
send_timeout = send_timeout,
read_timeout = read_timeout,
keepalive_timeout = keepalive_timeout,
options = {
path = socket,
user = username,
password = password,
charset = charset,
database = database,
max_packet_size = max_packet_size,
pool = pool,
pool_size = pool_size,
backlog = backlog,
ssl = ssl,
ssl_verify = ssl_verify,
}
}, metatable)
end
return setmetatable({
table = table_name,
table_meta = table_name_meta or (table_name .. "_meta"),
connect_timeout = connect_timeout,
send_timeout = send_timeout,
read_timeout = read_timeout,
keepalive_timeout = keepalive_timeout,
options = {
host = host,
port = port,
user = username,
password = password,
charset = charset,
database = database,
max_packet_size = max_packet_size,
pool = pool,
pool_size = pool_size,
backlog = backlog,
ssl = ssl,
ssl_verify = ssl_verify,
}
}, metatable)
end
return storage

View File

@ -0,0 +1,354 @@
---
-- Postgres backend for session library.
--
-- @module resty.session.postgres
---
-- Database
-- @section database
---
-- Sessions table.
--
-- Database table that stores session data.
--
-- @usage
-- CREATE TABLE IF NOT EXISTS sessions (
-- sid TEXT PRIMARY KEY,
-- name TEXT,
-- data TEXT,
-- exp TIMESTAMP WITH TIME ZONE
-- );
-- CREATE INDEX ON sessions (exp);
-- @table sessions
---
-- Sessions metadata table.
--
-- This is only needed if you want to store session metadata.
--
-- @usage
-- CREATE TABLE IF NOT EXISTS sessions_meta (
-- aud TEXT,
-- sub TEXT,
-- sid TEXT REFERENCES sessions (sid) ON DELETE CASCADE ON UPDATE CASCADE,
-- PRIMARY KEY (aud, sub, sid)
-- );
-- @table metadata
local buffer = require "string.buffer"
local pgmoon = require "pgmoon"
local setmetatable = setmetatable
local random = math.random
local ipairs = ipairs
local error = error
local fmt = string.format
local DEFAULT_HOST = "127.0.0.1"
local DEFAULT_PORT = 5432
local DEFAULT_TABLE = "sessions"
local SET = "INSERT INTO %s (sid, name, data, exp) VALUES ('%s', '%s', '%s', TO_TIMESTAMP(%d) AT TIME ZONE 'UTC') ON CONFLICT (sid) DO UPDATE SET data = EXCLUDED.data, exp = EXCLUDED.exp"
local SET_META_PREFIX = "INSERT INTO %s (aud, sub, sid) VALUES "
local SET_META_VALUES = "('%s', '%s', '%s')"
local SET_META_SUFFIX = " ON CONFLICT DO NOTHING"
local GET_META = "SELECT sid, exp FROM %s JOIN %s USING (sid) WHERE aud = '%s' AND sub = '%s' AND exp >= TO_TIMESTAMP(%d)"
local GET = "SELECT data FROM %s WHERE sid = '%s' AND exp >= TO_TIMESTAMP(%d) AT TIME ZONE 'UTC'"
local EXPIRE = "UPDATE %s SET exp = TO_TIMESTAMP(%d) AT TIME ZONE 'UTC' WHERE sid = '%s' AND exp > TO_TIMESTAMP(%d) AT TIME ZONE 'UTC'"
local DELETE = "DELETE FROM %s WHERE sid = '%s'"
local CLEANUP = "DELETE FROM %s WHERE exp < TO_TIMESTAMP(%d)"
local SQL = buffer.new()
local STM_DELIM = ";\n"
local VAL_DELIM = ", "
local CLEANUP_PROBABILITY = 0.001 -- 1 / 1000
local function exec(self, query)
local pg = pgmoon.new(self.options)
local connect_timeout = self.connect_timeout
local send_timeout = self.send_timeout
local read_timeout = self.read_timeout
if connect_timeout or send_timeout or read_timeout then
if pg.sock and pg.sock.settimeouts then
pg.sock:settimeouts(connect_timeout, send_timeout, read_timeout)
else
pg:settimeout(connect_timeout)
end
end
local ok, err = pg:connect()
if not ok then
return nil, err
end
ok, err = pg:query(query)
if not pg:keepalive(self.keepalive_timeout) then
pg:close()
end
return ok, err
end
---
-- Storage
-- @section instance
local metatable = {}
metatable.__index = metatable
function metatable.__newindex()
error("attempt to update a read-only table", 2)
end
---
-- Store session data.
--
-- @function instance:set
-- @tparam string name cookie name
-- @tparam string key session key
-- @tparam string value session value
-- @tparam number ttl session ttl
-- @tparam number current_time current time
-- @tparam[opt] string old_key old session id
-- @tparam string stale_ttl stale ttl
-- @tparam[opt] table metadata table of metadata
-- @tparam boolean remember whether storing persistent session or not
-- @treturn true|nil ok
-- @treturn string error message
function metatable:set(name, key, value, ttl, current_time, old_key, stale_ttl, metadata, remember)
local table = self.table
local exp = ttl + current_time
if not metadata and not old_key then
return exec(self, fmt(SET, table, key, name, value, exp))
end
SQL:reset():putf(SET, table, key, name, value, exp)
if old_key then
if remember then
SQL:put(STM_DELIM):putf(DELETE, table, old_key)
else
local stale_exp = stale_ttl + current_time
SQL:put(STM_DELIM):putf(EXPIRE, table, stale_exp, old_key, stale_exp)
end
end
local table_meta = self.table_meta
if metadata then
local audiences = metadata.audiences
local subjects = metadata.subjects
local count = #audiences
SQL:put(STM_DELIM):putf(SET_META_PREFIX, table_meta)
for i = 1, count do
if i > 1 then
SQL:put(VAL_DELIM)
end
SQL:putf(SET_META_VALUES, audiences[i], subjects[i], key)
end
SQL:putf(SET_META_SUFFIX)
end
if random() < CLEANUP_PROBABILITY then
SQL:put(STM_DELIM):putf(CLEANUP, self.table, current_time)
end
return exec(self, SQL:get())
end
---
-- Retrieve session data.
--
-- @function instance:get
-- @tparam string name cookie name
-- @tparam string key session key
-- @treturn string|nil session data
-- @treturn string error message
function metatable:get(name, key, current_time) -- luacheck: ignore
local res, err = exec(self, fmt(GET, self.table, key, current_time))
if not res then
return nil, err
end
local row = res[1]
if not row then
return nil
end
local data = row.data
if not row.data then
return nil
end
return data
end
---
-- Delete session data.
--
-- @function instance:delete
-- @tparam string name cookie name
-- @tparam string key session key
-- @tparam[opt] table metadata session meta data
-- @treturn boolean|nil session data
-- @treturn string error message
function metatable:delete(name, key, current_time, metadata) -- luacheck: ignore
SQL:reset():putf(DELETE, self.table, key)
if random() < CLEANUP_PROBABILITY then
SQL:put(STM_DELIM):putf(CLEANUP, self.table, current_time)
end
return exec(self, SQL:get())
end
---
-- Read session metadata.
--
-- @function instance:read_metadata
-- @tparam string name cookie name
-- @tparam string audience session key
-- @tparam string subject session key
-- @tparam number current_time current time
-- @treturn table|nil session metadata
-- @treturn string error message
function metatable:read_metadata(name, audience, subject, current_time) -- luacheck: ignore
local res = {}
local t = exec(self, fmt(GET_META, self.table_meta, self.table, audience, subject, current_time))
if not t then
return nil, "not found"
end
for _, v in ipairs(t) do
local key = v.sid
if key then
res[key] = v.exp
end
end
return res
end
local storage = {}
---
-- Configuration
-- @section configuration
---
-- Postgres storage backend configuration
-- @field host The host to connect (defaults to `"127.0.0.1"`).
-- @field port The port to connect (defaults to `5432`).
-- @field application Set the name of the connection as displayed in pg_stat_activity (defaults to `"pgmoon"`).
-- @field username The database username to authenticate (defaults to `"postgres"`).
-- @field password Password for authentication, may be required depending on server configuration.
-- @field database The database name to connect.
-- @field table_name Name of database table to which to store session data (can be `database schema` prefixed) (defaults to `"sessions"`).
-- @field table_name_meta Name of database meta data table to which to store session meta data (can be `database schema` prefixed) (defaults to `"sessions_meta"`).
-- @field connect_timeout Controls the default timeout value used in TCP/unix-domain socket object's `connect` method.
-- @field send_timeout Controls the default timeout value used in TCP/unix-domain socket object's `send` method.
-- @field read_timeout Controls the default timeout value used in TCP/unix-domain socket object's `receive` method.
-- @field keepalive_timeout Controls the default maximal idle time of the connections in the connection pool.
-- @field pool A custom name for the connection pool being used.
-- @field pool_size The size of the connection pool.
-- @field backlog A queue size to use when the connection pool is full (configured with @pool_size).
-- @field ssl Enable SSL (defaults to `false`).
-- @field ssl_verify Verify server certificate (defaults to `nil`).
-- @field ssl_required Abort the connection if the server does not support SSL connections (defaults to `nil`).
-- @table configuration
---
-- Constructors
-- @section constructors
---
-- Create a Postgres storage.
--
-- This creates a new Postgres storage instance.
--
-- @function module.new
-- @tparam[opt] table configuration postgres storage @{configuration}
-- @treturn table postgres storage instance
function storage.new(configuration)
local host = configuration and configuration.host or DEFAULT_HOST
local port = configuration and configuration.port or DEFAULT_PORT
local application = configuration and configuration.application
local username = configuration and configuration.username
local password = configuration and configuration.password
local database = configuration and configuration.database
local table_name = configuration and configuration.table or DEFAULT_TABLE
local table_name_meta = configuration and configuration.table_meta
local connect_timeout = configuration and configuration.connect_timeout
local send_timeout = configuration and configuration.send_timeout
local read_timeout = configuration and configuration.read_timeout
local keepalive_timeout = configuration and configuration.keepalive_timeout
local pool = configuration and configuration.pool
local pool_size = configuration and configuration.pool_size
local backlog = configuration and configuration.backlog
local ssl = configuration and configuration.ssl
local ssl_verify = configuration and configuration.ssl_verify
local ssl_required = configuration and configuration.ssl_required
return setmetatable({
table = table_name,
table_meta = table_name_meta or (table_name .. "_meta"),
connect_timeout = connect_timeout,
send_timeout = send_timeout,
read_timeout = read_timeout,
keepalive_timeout = keepalive_timeout,
options = {
host = host,
port = port,
application_name = application,
user = username,
password = password,
database = database,
socket_type = "nginx",
pool = pool,
pool_size = pool_size,
backlog = backlog,
ssl = ssl,
ssl_verify = ssl_verify,
ssl_required = ssl_required,
}
}, metatable)
end
return storage

View File

@ -0,0 +1,279 @@
---
-- Redis backend for session library
--
-- @module resty.session.redis
local common = require "resty.session.redis.common"
local redis = require "resty.redis"
local setmetatable = setmetatable
local error = error
local null = ngx.null
local DEFAULT_HOST = "127.0.0.1"
local DEFAULT_PORT = 6379
local SET = common.SET
local GET = common.GET
local UNLINK = common.UNLINK
local READ_METADATA = common.READ_METADATA
local function exec(self, func, ...)
local red = redis:new()
local connect_timeout = self.connect_timeout
local send_timeout = self.send_timeout
local read_timeout = self.read_timeout
if connect_timeout or send_timeout or read_timeout then
red:set_timeouts(connect_timeout, send_timeout, read_timeout)
end
local ok, err do
local socket = self.socket
if socket then
ok, err = red:connect(socket, self.options)
else
ok, err = red:connect(self.host, self.port, self.options)
end
end
if not ok then
return nil, err
end
if red:get_reused_times() == 0 then
local password = self.password
if password then
local username = self.username
if username then
ok, err = red:auth(username, password)
else
ok, err = red:auth(password)
end
if not ok then
red:close()
return nil, err
end
end
end
local database = self.database
if database then
ok, err = red:select(database)
if not ok then
return nil, err
end
end
ok, err = func(self, red, ...)
if err then
red:close()
return nil, err
end
if not red:set_keepalive(self.keepalive_timeout) then
red:close()
end
if ok == null then
ok = nil
end
return ok, err
end
---
-- Storage
-- @section instance
local metatable = {}
metatable.__index = metatable
function metatable.__newindex()
error("attempt to update a read-only table", 2)
end
---
-- Store session data.
--
-- @function instance:set
-- @tparam string name cookie name
-- @tparam string key session key
-- @tparam string value session value
-- @tparam number ttl session ttl
-- @tparam number current_time current time
-- @tparam[opt] string old_key old session id
-- @tparam string stale_ttl stale ttl
-- @tparam[opt] table metadata table of metadata
-- @tparam boolean remember whether storing persistent session or not
-- @treturn true|nil ok
-- @treturn string error message
function metatable:set(...)
return exec(self, SET, ...)
end
---
-- Retrieve session data.
--
-- @function instance:get
-- @tparam string name cookie name
-- @tparam string key session key
-- @treturn string|nil session data
-- @treturn string error message
function metatable:get(...)
return exec(self, GET, ...)
end
---
-- Delete session data.
--
-- @function instance:delete
-- @tparam string name cookie name
-- @tparam string key session key
-- @tparam[opt] table metadata session meta data
-- @treturn boolean|nil session data
-- @treturn string error message
function metatable:delete(...)
return exec(self, UNLINK, ...)
end
---
-- Read session metadata.
--
-- @function instance:read_metadata
-- @tparam string name cookie name
-- @tparam string audience session key
-- @tparam string subject session key
-- @tparam number current_time current time
-- @treturn table|nil session metadata
-- @treturn string error message
function metatable:read_metadata(...)
return exec(self, READ_METADATA, ...)
end
local storage = {}
---
-- Configuration
-- @section configuration
---
-- Redis storage backend configuration
-- @field prefix Prefix for the keys stored in Redis.
-- @field suffix Suffix for the keys stored in Redis.
-- @field host The host to connect (defaults to `"127.0.0.1"`).
-- @field port The port to connect (defaults to `6379`).
-- @field socket The socket file to connect to (defaults to `nil`).
-- @field username The database username to authenticate.
-- @field password Password for authentication.
-- @field database The database to connect.
-- @field connect_timeout Controls the default timeout value used in TCP/unix-domain socket object's `connect` method.
-- @field send_timeout Controls the default timeout value used in TCP/unix-domain socket object's `send` method.
-- @field read_timeout Controls the default timeout value used in TCP/unix-domain socket object's `receive` method.
-- @field keepalive_timeout Controls the default maximal idle time of the connections in the connection pool.
-- @field pool A custom name for the connection pool being used.
-- @field pool_size The size of the connection pool.
-- @field backlog A queue size to use when the connection pool is full (configured with @pool_size).
-- @field ssl Enable SSL (defaults to `false`).
-- @field ssl_verify Verify server certificate (defaults to `nil`).
-- @field server_name The server name for the new TLS extension Server Name Indication (SNI).
-- @table configuration
---
-- Constructors
-- @section constructors
---
-- Create a Redis storage.
--
-- This creates a new Redis storage instance.
--
-- @function module.new
-- @tparam[opt] table configuration redis storage @{configuration}
-- @treturn table redis storage instance
function storage.new(configuration)
local prefix = configuration and configuration.prefix
local suffix = configuration and configuration.suffix
local host = configuration and configuration.host or DEFAULT_HOST
local port = configuration and configuration.port or DEFAULT_PORT
local socket = configuration and configuration.socket
local username = configuration and configuration.username
local password = configuration and configuration.password
local database = configuration and configuration.database
local connect_timeout = configuration and configuration.connect_timeout
local send_timeout = configuration and configuration.send_timeout
local read_timeout = configuration and configuration.read_timeout
local keepalive_timeout = configuration and configuration.keepalive_timeout
local pool = configuration and configuration.pool
local pool_size = configuration and configuration.pool_size
local backlog = configuration and configuration.backlog
local ssl = configuration and configuration.ssl
local ssl_verify = configuration and configuration.ssl_verify
local server_name = configuration and configuration.server_name
if ssl ~= nil or ssl_verify ~= nil or server_name or pool or pool_size or backlog then
return setmetatable({
prefix = prefix,
suffix = suffix,
host = host,
port = port,
socket = socket,
username = username,
password = password,
database = database,
connect_timeout = connect_timeout,
send_timeout = send_timeout,
read_timeout = read_timeout,
keepalive_timeout = keepalive_timeout,
options = {
ssl = ssl,
ssl_verify = ssl_verify,
server_name = server_name,
pool = pool,
pool_size = pool_size,
backlog = backlog,
}
}, metatable)
end
return setmetatable({
prefix = prefix,
suffix = suffix,
host = host,
port = port,
socket = socket,
username = username,
password = password,
database = database,
connect_timeout = connect_timeout,
send_timeout = send_timeout,
read_timeout = read_timeout,
keepalive_timeout = keepalive_timeout,
}, metatable)
end
return storage

View File

@ -0,0 +1,271 @@
---
-- Redis Cluster backend for session library
--
-- @module resty.session.redis.cluster
local common = require "resty.session.redis.common"
local redis = require "resty.rediscluster"
local setmetatable = setmetatable
local error = error
local null = ngx.null
local SET = common.SET
local GET = common.GET
local UNLINK = common.UNLINK
local READ_METADATA = common.READ_METADATA
local function exec(self, func, ...)
local red, err = redis:new(self.options)
if err then
return nil, err
end
local ok, err = func(self, red, ...)
if err then
red:close()
return nil, err
end
if ok == null then
ok = nil
end
return ok, err
end
---
-- Storage
-- @section instance
local metatable = {}
metatable.__index = metatable
function metatable.__newindex()
error("attempt to update a read-only table", 2)
end
---
-- Store session data.
--
-- @function instance:set
-- @tparam string name cookie name
-- @tparam string key session key
-- @tparam string value session value
-- @tparam number ttl session ttl
-- @tparam number current_time current time
-- @tparam[opt] string old_key old session id
-- @tparam string stale_ttl stale ttl
-- @tparam[opt] table metadata table of metadata
-- @tparam boolean remember whether storing persistent session or not
-- @treturn true|nil ok
-- @treturn string error message
function metatable:set(...)
return exec(self, SET, ...)
end
---
-- Retrieve session data.
--
-- @function instance:get
-- @tparam string name cookie name
-- @tparam string key session key
-- @treturn string|nil session data
-- @treturn string error message
function metatable:get(...)
return exec(self, GET, ...)
end
---
-- Delete session data.
--
-- @function instance:delete
-- @tparam string name cookie name
-- @tparam string key session key
-- @tparam[opt] table metadata session meta data
-- @treturn boolean|nil session data
-- @treturn string error message
function metatable:delete(...)
return exec(self, UNLINK, ...)
end
---
-- Read session metadata.
--
-- @function instance:read_metadata
-- @tparam string name cookie name
-- @tparam string audience session key
-- @tparam string subject session key
-- @tparam number current_time current time
-- @treturn table|nil session metadata
-- @treturn string error message
function metatable:read_metadata(...)
return exec(self, READ_METADATA, ...)
end
local storage = {}
---
-- Configuration
-- @section configuration
---
-- Redis Cluster storage backend configuration
-- @field prefix Prefix for the keys stored in redis.
-- @field suffix Suffix for the keys stored in redis.
-- @field name Redis cluster name.
-- @field nodes Redis cluster nodes.
-- @field lock_zone Shared dictionary name for locks.
-- @field lock_prefix Shared dictionary name prefix for lock.
-- @field max_redirections Maximum retry attempts for redirection.
-- @field max_connection_attempts Maximum retry attempts for connection.
-- @field max_connection_timeout Maximum connection timeout in total among the retries.
-- @field username The database username to authenticate.
-- @field password Password for authentication.
-- @field connect_timeout Controls the default timeout value used in TCP/unix-domain socket object's `connect` method.
-- @field send_timeout controls The default timeout value used in TCP/unix-domain socket object's `send` method.
-- @field read_timeout controls The default timeout value used in TCP/unix-domain socket object's `receive` method.
-- @field keepalive_timeout Controls the default maximal idle time of the connections in the connection pool.
-- @field pool A custom name for the connection pool being used.
-- @field pool_size The size of the connection pool.
-- @field backlog A queue size to use when the connection pool is full (configured with @pool_size).
-- @field ssl Enable SSL (defaults to `false`).
-- @field ssl_verify Verify server certificate (defaults to `nil`).
-- @field server_name The server name for the new TLS extension Server Name Indication (SNI).
-- @table configuration
---
-- Cluster Nodes
--
-- An array of cluster nodes.
--
-- @table nodes
---
-- Cluster Node
-- @field ip The IP address to connect (defaults to `"127.0.0.1"`).
-- @field port The port to connect (defaults to `6379`).
-- @table node
---
-- Constructors
-- @section constructors
---
-- Create a Redis Cluster storage.
--
-- This creates a new Redis Cluster storage instance.
--
-- @function module.new
-- @tparam[opt] table configuration redis cluster storage @{configuration}
-- @treturn table redis cluster storage instance
function storage.new(configuration)
local prefix = configuration and configuration.prefix
local suffix = configuration and configuration.suffix
local name = configuration and configuration.name
local nodes = configuration and configuration.nodes
local lock_zone = configuration and configuration.lock_zone
local lock_prefix = configuration and configuration.lock_prefix
local max_redirections = configuration and configuration.max_redirections
local max_connection_attempts = configuration and configuration.max_connection_attempts
local max_connection_timeout = configuration and configuration.max_connection_timeout
local username = configuration and configuration.username
local password = configuration and configuration.password
local connect_timeout = configuration and configuration.connect_timeout
local send_timeout = configuration and configuration.send_timeout
local read_timeout = configuration and configuration.read_timeout
local keepalive_timeout = configuration and configuration.keepalive_timeout
local pool = configuration and configuration.pool
local pool_size = configuration and configuration.pool_size
local backlog = configuration and configuration.backlog
local ssl = configuration and configuration.ssl
local ssl_verify = configuration and configuration.ssl_verify
local server_name = configuration and configuration.server_name
local auth
if password then
if username then
auth = username .. " " .. password
else
auth = password
end
end
if ssl ~= nil or ssl_verify ~= nil or server_name or pool or pool_size or backlog then
return setmetatable({
prefix = prefix,
suffix = suffix,
options = {
name = name,
dict_name = lock_zone,
refresh_lock_key = lock_prefix,
serv_list = nodes,
connect_timeout = connect_timeout,
send_timeout = send_timeout,
read_timeout = read_timeout,
keepalive_timeout = keepalive_timeout,
keepalive_cons = pool_size,
max_redirection = max_redirections,
max_connection_attempts = max_connection_attempts,
max_connection_timeout = max_connection_timeout,
auth = auth,
connect_opts = {
ssl = ssl,
ssl_verify = ssl_verify,
server_name = server_name,
pool = pool,
pool_size = pool_size,
backlog = backlog,
},
},
}, metatable)
end
return setmetatable({
prefix = prefix,
suffix = suffix,
options = {
name = name,
dict_name = lock_zone,
refresh_lock_key = lock_prefix,
serv_list = nodes,
connect_timeout = connect_timeout,
send_timeout = send_timeout,
read_timeout = read_timeout,
keepalive_timeout = keepalive_timeout,
keepalive_cons = pool_size,
max_redirection = max_redirections,
max_connection_attempts = max_connection_attempts,
max_connection_timeout = max_connection_timeout,
auth = auth,
},
}, metatable)
end
return storage

View File

@ -0,0 +1,172 @@
---
-- Common Redis functions shared between Redis,
-- Redis Cluster and Redis Sentinel implementations.
--
-- @module resty.session.redis.common
local utils = require "resty.session.utils"
local get_name = utils.get_name
local ipairs = ipairs
---
-- Store session data.
--
-- @function module.SET
-- @tparam table storage the storage
-- @tparam table red the redis instance
-- @tparam string name the cookie name
-- @tparam string key session key
-- @tparam string value session value
-- @tparam number ttl session ttl
-- @tparam number current_time current time
-- @tparam[opt] string old_key old session id
-- @tparam string stale_ttl stale ttl
-- @tparam[opt] table metadata table of metadata
-- @tparam table remember whether storing persistent session or not
-- @treturn true|nil ok
-- @treturn string error message
local function SET(storage, red, name, key, value, ttl, current_time, old_key, stale_ttl, metadata, remember)
if not metadata and not old_key then
return red:set(get_name(storage, name, key), value, "EX", ttl)
end
local old_name
local old_ttl
if old_key then
old_name = get_name(storage, name, old_key)
if not remember then
-- redis < 7.0
old_ttl = red:ttl(old_name)
end
end
red:init_pipeline()
red:set(get_name(storage, name, key), value, "EX", ttl)
-- redis < 7.0
if old_name then
if remember then
red:unlink(old_name)
elseif not old_ttl or old_ttl > stale_ttl then
red:expire(old_name, stale_ttl)
end
end
-- redis >= 7.0
--if old_key then
-- if remember then
-- red:unlink(get_name(storage, name, old_key))
-- else
-- red:expire(get_name(storage, name, old_key), stale_ttl, "LT")
-- end
--end
if metadata then
local audiences = metadata.audiences
local subjects = metadata.subjects
local score = current_time - 1
local new_score = current_time + ttl
local count = #audiences
for i = 1, count do
local meta_key = get_name(storage, name, audiences[i], subjects[i])
red:zremrangebyscore(meta_key, 0, score)
red:zadd(meta_key, new_score, key)
if old_key then
red:zrem(meta_key, old_key)
end
red:expire(meta_key, ttl)
end
end
return red:commit_pipeline()
end
---
-- Retrieve session data.
--
-- @function module.GET
-- @tparam table storage the storage
-- @tparam table red the redis instance
-- @tparam string name cookie name
-- @tparam string key session key
-- @treturn string|nil session data
-- @treturn string error message
local function GET(storage, red, name, key)
return red:get(get_name(storage, name, key))
end
---
-- Delete session data.
--
-- @function module.UNLINK
-- @tparam table storage the storage
-- @tparam table red the redis instance
-- @tparam string name cookie name
-- @tparam string key session key
-- @tparam number current_time current time
-- @tparam[opt] table metadata session meta data
-- @treturn boolean|nil session data
-- @treturn string error message
local function UNLINK(storage, red, name, key, current_time, metadata)
if not metadata then
return red:unlink(get_name(storage, name, key))
end
red:init_pipeline()
red:unlink(get_name(storage, name, key))
local audiences = metadata.audiences
local subjects = metadata.subjects
local score = current_time - 1
local count = #audiences
for i = 1, count do
local meta_key = get_name(storage, name, audiences[i], subjects[i])
red:zremrangebyscore(meta_key, 0, score)
red:zrem(meta_key, key)
end
return red:commit_pipeline()
end
---
-- Read session metadata.
--
-- @function module.READ_METADATA
-- @tparam table storage the storage
-- @tparam table red the redis instance
-- @tparam string name cookie name
-- @tparam string audience session key
-- @tparam string subject session key
-- @tparam number current_time current time
-- @treturn table|nil session metadata
-- @treturn string error message
local function READ_METADATA(storage, red, name, audience, subject, current_time)
local sessions = {}
local meta_key = get_name(storage, name, audience, subject)
local res, err = red:zrange(meta_key, current_time, "+inf", "BYSCORE", "WITHSCORES")
if not res then
return nil, err
end
for i, v in ipairs(res) do
if i % 2 ~= 0 then
sessions[v] = res[i + 1]
end
end
return sessions
end
return {
SET = SET,
GET = GET,
UNLINK = UNLINK,
READ_METADATA = READ_METADATA,
}

View File

@ -0,0 +1,260 @@
---
-- Redis Sentinel backend for session library
--
-- @module resty.session.redis.sentinel
local common = require "resty.session.redis.common"
local redis = require "resty.redis.connector"
local setmetatable = setmetatable
local error = error
local null = ngx.null
local SET = common.SET
local GET = common.GET
local UNLINK = common.UNLINK
local READ_METADATA = common.READ_METADATA
local function exec(self, func, ...)
local red, err = self.connector:connect()
if not red then
return nil, err
end
local ok, err = func(self, red, ...)
if err then
red:close()
return nil, err
end
if ok == null then
ok = nil
end
self.connector:set_keepalive(red)
return ok, err
end
---
-- Storage
-- @section instance
local metatable = {}
metatable.__index = metatable
function metatable.__newindex()
error("attempt to update a read-only table", 2)
end
---
-- Store session data.
--
-- @function instance:set
-- @tparam string name cookie name
-- @tparam string key session key
-- @tparam string value session value
-- @tparam number ttl session ttl
-- @tparam number current_time current time
-- @tparam[opt] string old_key old session id
-- @tparam string stale_ttl stale ttl
-- @tparam[opt] table metadata table of metadata
-- @tparam table remember whether storing persistent session or not
-- @treturn true|nil ok
-- @treturn string error message
function metatable:set(...)
return exec(self, SET, ...)
end
---
-- Retrieve session data.
--
-- @function instance:get
-- @tparam string name cookie name
-- @tparam string key session key
-- @treturn string|nil session data
-- @treturn string error message
function metatable:get(...)
return exec(self, GET, ...)
end
---
-- Delete session data.
--
-- @function instance:delete
-- @tparam string name cookie name
-- @tparam string key session key
-- @tparam[opt] table metadata session meta data
-- @treturn boolean|nil session data
-- @treturn string error message
function metatable:delete(...)
return exec(self, UNLINK, ...)
end
---
-- Read session metadata.
--
-- @function instance:read_metadata
-- @tparam string name cookie name
-- @tparam string audience session key
-- @tparam string subject session key
-- @tparam number current_time current time
-- @treturn table|nil session metadata
-- @treturn string error message
function metatable:read_metadata(...)
return exec(self, READ_METADATA, ...)
end
local storage = {}
---
-- Configuration
-- @section configuration
---
-- Redis Sentinel storage backend configuration
-- @field prefix Prefix for the keys stored in redis.
-- @field suffix Suffix for the keys stored in redis.
-- @field master Name of master.
-- @field role `"master"` or `"slave"`.
-- @field sentinels Redis Sentinels.
-- @field sentinel_username Optional sentinel username.
-- @field sentinel_password Optional sentinel password.
-- @field username The database username to authenticate.
-- @field password Password for authentication.
-- @field database The database to connect.
-- @field connect_timeout Controls the default timeout value used in TCP/unix-domain socket object's `connect` method.
-- @field send_timeout Controls the default timeout value used in TCP/unix-domain socket object's `send` method.
-- @field read_timeout Controls the default timeout value used in TCP/unix-domain socket object's `receive` method.
-- @field keepalive_timeout Controls the default maximal idle time of the connections in the connection pool.
-- @field pool A custom name for the connection pool being used.
-- @field pool_size The size of the connection pool.
-- @field backlog A queue size to use when the connection pool is full (configured with @pool_size).
-- @field ssl Enable SSK (defaults to `false`).
-- @field ssl_verify Verify server certificate (defaults to `nil`).
-- @field server_name The server name for the new TLS extension Server Name Indication (SNI).
-- @table configuration
---
-- Sentinels
--
-- An array of sentinels.
--
-- @table sentinels
---
-- Sentinel
-- @field host The host to connect.
-- @field port The port to connect.
-- @table sentinel
---
-- Constructors
-- @section constructors
---
-- Create a Redis Sentinel storage.
--
-- This creates a new Redis Sentinel storage instance.
--
-- @function module.new
-- @tparam[opt] table configuration redis sentinel storage @{configuration}
-- @treturn table redis sentinel storage instance
function storage.new(configuration)
local prefix = configuration and configuration.prefix
local suffix = configuration and configuration.suffix
local master = configuration and configuration.master
local role = configuration and configuration.role
local sentinels = configuration and configuration.sentinels
local sentinel_username = configuration and configuration.sentinel_username
local sentinel_password = configuration and configuration.sentinel_password
local username = configuration and configuration.username
local password = configuration and configuration.password
local database = configuration and configuration.database
local connect_timeout = configuration and configuration.connect_timeout
local send_timeout = configuration and configuration.send_timeout
local read_timeout = configuration and configuration.read_timeout
local keepalive_timeout = configuration and configuration.keepalive_timeout
local pool = configuration and configuration.pool
local pool_size = configuration and configuration.pool_size
local backlog = configuration and configuration.backlog
local ssl = configuration and configuration.ssl
local ssl_verify = configuration and configuration.ssl_verify
local server_name = configuration and configuration.server_name
local connector
if ssl ~= nil or ssl_verify ~= nil or server_name or pool or pool_size or backlog then
connector = redis.new({
master_name = master,
role = role,
sentinels = sentinels,
sentinel_username = sentinel_username,
sentinel_password = sentinel_password,
username = username,
password = password,
db = database,
connect_timeout = connect_timeout,
send_timeout = send_timeout,
read_timeout = read_timeout,
keepalive_timeout = keepalive_timeout,
keepalive_poolsize = pool_size,
connection_options = {
ssl = ssl,
ssl_verify = ssl_verify,
server_name = server_name,
pool = pool,
pool_size = pool_size,
backlog = backlog,
}
})
else
connector = redis.new({
master_name = master,
role = role,
sentinels = sentinels,
sentinel_username = sentinel_username,
sentinel_password = sentinel_password,
username = username,
password = password,
db = database,
connect_timeout = connect_timeout,
send_timeout = send_timeout,
read_timeout = read_timeout,
keepalive_timeout = keepalive_timeout,
keepalive_poolsize = pool_size,
})
end
return setmetatable({
prefix = prefix,
suffix = suffix,
connector = connector,
}, metatable)
end
return storage

View File

@ -0,0 +1,315 @@
---
-- Shared Memory (SHM) backend for session library
--
-- @module resty.session.shm
local table_new = require "table.new"
local utils = require "resty.session.utils"
local meta_get_value = utils.meta_get_value
local meta_get_next = utils.meta_get_next
local get_name = utils.get_name
local errmsg = utils.errmsg
local setmetatable = setmetatable
local shared = ngx.shared
local random = math.random
local assert = assert
local error = error
local pairs = pairs
local max = math.max
local log = ngx.log
local WARN = ngx.WARN
local DEFAULT_ZONE = "sessions"
local CLEANUP_PROBABILITY = 0.1 -- 1 / 10
local function get_and_clean_metadata(dict, meta_key, current_time)
local size = dict:llen(meta_key)
if not size or size == 0 then
return
end
local max_expiry = current_time
local sessions = table_new(0, size)
for _ = 1, size do
local meta_value, err = dict:lpop(meta_key)
if not meta_value then
log(WARN, "[session] ", errmsg(err, "failed read meta value"))
break
end
local key, err, exp = meta_get_next(meta_value, 1)
if err then
return nil, err
end
if exp and exp > current_time then
sessions[key] = exp
max_expiry = max(max_expiry, exp)
else
sessions[key] = nil
end
end
for key, exp in pairs(sessions) do
local meta_value = meta_get_value(key, exp)
local ok, err = dict:rpush(meta_key, meta_value)
if not ok then
log(WARN, "[session] ", errmsg(err, "failed to update metadata"))
end
end
local exp = max_expiry - current_time
if exp > 0 then
local ok, err = dict:expire(meta_key, max_expiry - current_time)
if not ok and err ~= "not found" then
log(WARN, "[session] ", errmsg(err, "failed to touch metadata"))
end
else
dict:delete(meta_key)
end
return sessions
end
local function cleanup(dict, meta_key, current_time)
get_and_clean_metadata(dict, meta_key, current_time)
end
local function read_metadata(self, meta_key, current_time)
return get_and_clean_metadata(self.dict, meta_key, current_time)
end
---
-- Storage
-- @section instance
local metatable = {}
metatable.__index = metatable
function metatable.__newindex()
error("attempt to update a read-only table", 2)
end
---
-- Store session data.
--
-- @function instance:set
-- @tparam string name cookie name
-- @tparam string key session key
-- @tparam string value session value
-- @tparam number ttl session ttl
-- @tparam number current_time current time
-- @tparam[opt] string old_key old session id
-- @tparam string stale_ttl stale ttl
-- @tparam[opt] table metadata table of metadata
-- @tparam boolean remember whether storing persistent session or not
-- @treturn true|nil ok
-- @treturn string error message
function metatable:set(name, key, value, ttl, current_time, old_key, stale_ttl, metadata, remember)
local dict = self.dict
if not metadata and not old_key then
local ok, err = dict:set(get_name(self, name, key), value, ttl)
if not ok then
return nil, err
end
return true
end
local old_name, old_ttl
if old_key then
old_name = get_name(self, name, old_key)
if not remember then
old_ttl = dict:ttl(old_name)
end
end
local ok, err = dict:set(get_name(self, name, key), value, ttl)
if not ok then
return nil, err
end
if old_name then
if remember then
dict:delete(old_name)
elseif (not old_ttl or old_ttl > stale_ttl) then
local ok, err = dict:expire(old_name, stale_ttl)
if not ok then
log(WARN, "[session] ", errmsg(err, "failed to touch old session"))
end
end
end
if not metadata then
return true
end
local audiences = metadata.audiences
local subjects = metadata.subjects
local count = #audiences
for i = 1, count do
local meta_key = get_name(self, name, audiences[i], subjects[i])
local meta_value = meta_get_value(key, current_time + ttl)
local ok, err = dict:rpush(meta_key, meta_value)
if not ok then
log(WARN, "[session] ", errmsg(err, "failed to update metadata"))
end
if old_key then
meta_value = meta_get_value(old_key, 0)
local ok, err = dict:rpush(meta_key, meta_value)
if not ok then
log(WARN, "[session] ", errmsg(err, "failed to update old metadata"))
end
end
-- no need to clean up every time we write
-- it is just beneficial when a key is used a lot
if random() < CLEANUP_PROBABILITY then
cleanup(dict, meta_key, current_time)
end
end
return true
end
---
-- Retrieve session data.
--
-- @function instance:get
-- @tparam string name cookie name
-- @tparam string key session key
-- @treturn string|nil session data
-- @treturn string error message
function metatable:get(name, key)
local value, err = self.dict:get(get_name(self, name, key))
if not value then
return nil, err
end
return value
end
---
-- Delete session data.
--
-- @function instance:delete
-- @tparam string name cookie name
-- @tparam string key session key
-- @tparam[opt] table metadata session meta data
-- @treturn boolean|nil session data
-- @treturn string error message
function metatable:delete(name, key, current_time, metadata)
local dict = self.dict
dict:delete(get_name(self, name, key))
if not metadata then
return true
end
local audiences = metadata.audiences
local subjects = metadata.subjects
local count = #audiences
for i = 1, count do
local meta_key = get_name(self, name, audiences[i], subjects[i])
local meta_value = meta_get_value(key, 0)
local ok, err = dict:rpush(meta_key, meta_value)
if not ok then
if not ok then
log(WARN, "[session] ", errmsg(err, "failed to update metadata"))
end
end
cleanup(dict, meta_key, current_time)
end
return true
end
---
-- Read session metadata.
--
-- @function instance:read_metadata
-- @tparam string name cookie name
-- @tparam string audience session key
-- @tparam string subject session key
-- @tparam number current_time current time
-- @treturn table|nil session metadata
-- @treturn string error message
function metatable:read_metadata(name, audience, subject, current_time)
local meta_key = get_name(self, name, audience, subject)
return read_metadata(self, meta_key, current_time)
end
local storage = {}
---
-- Configuration
-- @section configuration
---
-- Shared memory storage backend configuration
-- @field prefix Prefix for the keys stored in SHM.
-- @field suffix Suffix for the keys stored in SHM.
-- @field zone A name of shared memory zone (defaults to `sessions`).
-- @table configuration
---
-- Constructors
-- @section constructors
---
-- Create a SHM storage.
--
-- This creates a new shared memory storage instance.
--
-- @function module.new
-- @tparam[opt] table configuration shm storage @{configuration}
-- @treturn table shm storage instance
function storage.new(configuration)
local prefix = configuration and configuration.prefix
local suffix = configuration and configuration.suffix
local zone = configuration and configuration.zone or DEFAULT_ZONE
local dict = assert(shared[zone], "lua_shared_dict " .. zone .. " is missing")
return setmetatable({
prefix = prefix,
suffix = suffix,
dict = dict,
}, metatable)
end
return storage

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,37 @@
package = "lua-resty-session"
version = "4.0.4-1"
source = {
url = "git+https://github.com/bungle/lua-resty-session.git",
tag = "v4.0.4",
}
description = {
summary = "Session Library for OpenResty - Flexible and Secure",
detailed = "lua-resty-session is a secure, and flexible session library for OpenResty.",
homepage = "https://github.com/bungle/lua-resty-session",
maintainer = "Aapo Talvensaari <aapo.talvensaari@gmail.com>, Samuele Illuminati <samuele@konghq.com>",
license = "BSD",
}
dependencies = {
"lua >= 5.1",
"lua-ffi-zlib >= 0.5",
"lua-resty-openssl >= 0.8.0",
}
build = {
type = "builtin",
modules = {
["resty.session"] = "lib/resty/session.lua",
["resty.session.dshm"] = "lib/resty/session/dshm.lua",
["resty.session.file"] = "lib/resty/session/file.lua",
["resty.session.file.thread"] = "lib/resty/session/file/thread.lua",
["resty.session.file.utils"] = "lib/resty/session/file/utils.lua",
["resty.session.memcached"] = "lib/resty/session/memcached.lua",
["resty.session.mysql"] = "lib/resty/session/mysql.lua",
["resty.session.postgres"] = "lib/resty/session/postgres.lua",
["resty.session.redis"] = "lib/resty/session/redis.lua",
["resty.session.redis.cluster"] = "lib/resty/session/redis/cluster.lua",
["resty.session.redis.sentinel"] = "lib/resty/session/redis/sentinel.lua",
["resty.session.redis.common"] = "lib/resty/session/redis/common.lua",
["resty.session.shm"] = "lib/resty/session/shm.lua",
["resty.session.utils"] = "lib/resty/session/utils.lua",
},
}

View File

@ -0,0 +1,139 @@
local utils = require "resty.session.utils"
local describe = describe
local tostring = tostring
local random = math.random
local assert = assert
local ipairs = ipairs
local match = string.match
local it = it
describe("Testing utils", function()
describe("pack/unpack data", function()
local function range_max(bytes)
if bytes == 8 then
bytes = bytes - 1
end
return 2 ^ (8 * bytes) - 1
end
it("bpack and bunpack produce consistent output", function()
for _, i in ipairs{ 1, 2, 4, 8 } do
local input = random(1, range_max(i))
local packed = utils.bpack(i, input)
local unpacked = utils.bunpack(i, packed)
assert.equals(i, #packed)
assert.equals(unpacked, input)
end
end)
end)
describe("trim", function()
it("characters are trimmed as expected", function()
local input = " \t\t\r\n\n\v\f\f\fyay\ntrim!\f\f\v\n\r\t "
local expected_output = "yay\ntrim!"
local output = utils.trim(input)
assert.equals(output, expected_output)
end)
end)
describe("encode/decode json", function()
it("produce consistent output", function()
local input = {
foo = "bar",
test = 123
}
local encoded = utils.encode_json(input)
local decoded = utils.decode_json(encoded)
assert.same(decoded, input)
end)
end)
describe("encode/decode base64url", function()
it("produce consistent output", function()
local input = "<<<!?>>>?!"
local encoded = utils.encode_base64url(input)
assert.is_nil(match(encoded, "[/=+]"))
local decoded = utils.decode_base64url(encoded)
assert.equals(input, decoded)
end)
end)
describe("deflate/inflate", function()
it("produce consistent output", function()
local input = utils.rand_bytes(1024)
local deflated = utils.deflate(input)
local inflated = utils.inflate(deflated)
assert.equals(input, inflated)
end)
end)
describe("Derive keys, encrypt and decrypt", function()
local ikm = "some key material"
local nonce = "0000000000000000"
local usage = "encryption"
local size = 44
it("derives key of expected size with derive_hkdf_sha256", function()
local k_bytes, err = utils.derive_hkdf_sha256(ikm, nonce, usage, size)
assert.is_not_nil(k_bytes)
assert.is_nil(err)
assert.equals(size, #tostring(k_bytes))
end)
it("derives key of expected size with derive_pbkdf2_hmac_sha256", function()
local k_bytes, err = utils.derive_pbkdf2_hmac_sha256(ikm, nonce, usage, size)
assert.is_not_nil(k_bytes)
assert.is_nil(err)
assert.equals(size, #tostring(k_bytes))
end)
it("derives a valid key and calculates mac with it", function()
local key, err, mac
key, err = utils.derive_hmac_sha256_key(ikm, nonce)
assert.is_not_nil(key)
assert.is_nil(err)
assert.equals(32, #key)
mac, err = utils.hmac_sha256(key, "some message")
assert.is_not_nil(mac)
assert.is_nil(err)
end)
it("successfully derives key and iv; encryption and decryption succeeds", function()
local data = {
foo = "bar",
tab = { "val" },
num = 123,
}
local aad = "some_aad"
local input_data = utils.encode_json(data)
local key, err, iv, ciphertext, tag, plaintext
for _, slow in ipairs({ true, false }) do
key, err, iv = utils.derive_aes_gcm_256_key_and_iv(ikm, nonce, slow)
assert.is_not_nil(key)
assert.is_not_nil(iv)
assert.is_nil(err)
ciphertext, err, tag = utils.encrypt_aes_256_gcm(key, iv, input_data, aad)
assert.is_not_nil(ciphertext)
assert.is_not_nil(tag)
assert.is_nil(err)
plaintext, err = utils.decrypt_aes_256_gcm(key, iv, ciphertext, aad, tag)
assert.is_not_nil(plaintext)
assert.is_nil(err)
assert.equals(plaintext, input_data)
end
end)
end)
end)

View File

@ -0,0 +1,108 @@
local file_utils = require "resty.session.file.utils"
local fmt = string.format
local describe = describe
local assert = assert
local it = it
describe("Testing file utils", function()
describe("validate file name", function()
local validate_file_name = file_utils.validate_file_name
local name = "name"
local sid1 = "ABCdef123_-iJqwertYUIOpasdfgHJKLzxcvbnmJuis"
local aud_sub1 = "some-aud:some-sub"
local simple_prefix = "pref"
local special_prefix = "@-_-"
local simple_suffix = "suff"
local special_suffix = "-_-@"
local filename_inv1 = "some.conf"
local filename_inv2 = "abc"
local filename_inv3 = name.."_".. "abc"
it("validation fails with invalid files with prefix and suffix", function()
assert.is_false(validate_file_name(simple_prefix, simple_suffix, name, filename_inv1))
assert.is_false(validate_file_name(simple_prefix, simple_suffix, name, filename_inv2))
assert.is_false(validate_file_name(simple_prefix, simple_suffix, name, filename_inv3))
end)
it("validation fails with invalid files with prefix only", function()
assert.is_false(validate_file_name(simple_prefix, nil, name, filename_inv1))
assert.is_false(validate_file_name(simple_prefix, nil, name, filename_inv2))
assert.is_false(validate_file_name(simple_prefix, nil, name, filename_inv3))
end)
it("validation fails with invalid files with suffix only", function()
assert.is_false(validate_file_name(nil, simple_suffix, name, filename_inv1))
assert.is_false(validate_file_name(nil, simple_suffix, name, filename_inv2))
assert.is_false(validate_file_name(nil, simple_suffix, name, filename_inv3))
end)
it("validation fails with invalid files with no prefix or suffix", function()
assert.is_false(validate_file_name(nil, nil, name, filename_inv1))
assert.is_false(validate_file_name(nil, nil, name, filename_inv2))
assert.is_false(validate_file_name(nil, nil, name, filename_inv3))
end)
it("validation passes with prefix and suffix", function()
local filename_sess = fmt("%s_%s_%s.%s", simple_prefix, name, sid1, simple_suffix)
local filename_meta = fmt("%s_%s_%s.%s", simple_prefix, name, aud_sub1, simple_suffix)
assert.is_true(validate_file_name(simple_prefix, simple_suffix, name, filename_sess))
assert.is_true(validate_file_name(simple_prefix, simple_suffix, name, filename_meta))
assert.is_false(validate_file_name(simple_prefix, simple_suffix, name, filename_inv1))
assert.is_false(validate_file_name(simple_prefix, simple_suffix, name, filename_inv2))
end)
it("validation passes with special prefix and suffix", function()
local sp_filename_sess = fmt("%s_%s_%s.%s", special_prefix, name, sid1, special_suffix)
local sp_filename_meta = fmt("%s_%s_%s.%s", special_prefix, name, aud_sub1, special_suffix)
assert.is_true(validate_file_name(special_prefix, special_suffix, name, sp_filename_sess))
assert.is_true(validate_file_name(special_prefix, special_suffix, name, sp_filename_meta))
end)
it("validation passes with prefix", function()
local filename_sess = fmt("%s_%s_%s", simple_prefix, name, sid1)
local filename_meta = fmt("%s_%s_%s", simple_prefix, name, aud_sub1)
assert.is_true(validate_file_name(simple_prefix, nil, name, filename_sess))
assert.is_true(validate_file_name(simple_prefix, nil, name, filename_meta))
end)
it("validation passes with special prefix", function()
local sp_filename_sess = fmt("%s_%s_%s", special_prefix, name, sid1)
local sp_filename_meta = fmt("%s_%s_%s", special_prefix, name, aud_sub1)
assert.is_true(validate_file_name(special_prefix, nil, name, sp_filename_sess))
assert.is_true(validate_file_name(special_prefix, nil, name, sp_filename_meta))
end)
it("#only validation passes with suffix", function()
local filename_sess = fmt("%s_%s.%s", name, sid1, simple_suffix)
local filename_meta = fmt("%s_%s.%s", name, aud_sub1, simple_suffix)
assert.is_true(validate_file_name(nil, simple_suffix, name, filename_sess))
assert.is_true(validate_file_name(nil, simple_suffix, name, filename_meta))
end)
it("validation passes with special suffix", function()
local sp_filename_sess = fmt("%s_%s.%s", name, sid1, special_suffix)
local sp_filename_meta = fmt("%s_%s.%s", name, aud_sub1, special_suffix)
assert.is_true(validate_file_name(nil, special_suffix, name, sp_filename_sess))
assert.is_true(validate_file_name(nil, special_suffix, name, sp_filename_meta))
end)
it("validation passes with no prefix or suffix", function()
local filename_sess = fmt("%s_%s", name, sid1)
local filename_meta = fmt("%s_%s", name, aud_sub1)
assert.is_true(validate_file_name(nil, nil, name, filename_sess))
assert.is_true(validate_file_name(nil, nil, name, filename_meta))
end)
end)
end)

View File

@ -0,0 +1,405 @@
local session = require "resty.session"
local before_each = before_each
local describe = describe
local assert = assert
local pcall = pcall
local it = it
local function extract_cookie(cookie_name, cookies)
local session_cookie
if type(cookies) == "table" then
for _, v in ipairs(cookies) do
session_cookie = ngx.re.match(v, cookie_name .. "=([\\w-]+);")
if session_cookie then
return session_cookie[1]
end
end
return ""
end
session_cookie = ngx.re.match(cookies, cookie_name .. "=([\\w-]+);")
return session_cookie and session_cookie[1] or ""
end
describe("Session", function()
local configuration = {}
describe("instance methods behave as expected", function()
local cookie_name = "session_cookie"
local remember_cookie_name = "remember_cookie"
local test_key = "test_key"
local data = "test_data"
local test_subject = "test_subject"
local test_audience = "test_audience"
local lout_subject = "lout_subject"
local lout_audience = "lout_audience"
local function test_session_set_get(s)
assert.is_nil(
s:get(test_key) or
s:get(test_subject) or
s:get(test_audience)
)
s:set(test_key, data)
s:set_subject(test_subject)
s:set_audience(test_audience)
assert.equals(s:get(test_key), data)
assert.equals(s:get_subject(), test_subject)
assert.equals(s:get_audience(), test_audience)
end
local function test_session_save(s, cookies)
session.__set_ngx_header(cookies)
local ok, err = s:save()
assert.equals(s.state, "open")
assert.is_true(ok)
assert.is_nil(err)
assert.is_not_nil(s.meta)
assert.is_not_nil(s.meta.data_size)
assert(s.meta.data_size > 0)
local session_cookie = extract_cookie(cookie_name, cookies["Set-Cookie"])
return session_cookie
end
local function test_session_close_open(s, session_cookie)
s:close()
assert.equals(s.state, "closed")
local ok, err = pcall(s.get, s, "anything")
assert.is_false(ok)
assert.matches("unable to get session data", err)
session.__set_ngx_var({
["cookie_" .. cookie_name] = session_cookie
})
ok, err = s:open()
assert.is_true(ok)
assert.is_nil(err)
assert.equals(s.state, "open")
assert.equals(data, s:get(test_key))
end
local function test_session_get_property(s)
assert.equals(43, #s:get_property("id"))
assert.equals(32, #s:get_property("nonce"))
assert.equals(test_audience, s:get_property("audience"))
assert.equals(test_subject, s:get_property("subject"))
assert.match.is_number(s:get_property("timeout"))
assert.match.is_number(s:get_property("idling-timeout"))
assert.match.is_number(s:get_property("rolling-timeout"))
assert.match.is_number(s:get_property("absolute-timeout"))
end
local function test_session_touch(s)
local ok, err = s:touch()
assert.is_true(ok)
assert.is_nil(err)
assert.equals(s.state, "open")
end
local function test_session_destroy_open(s)
local cookies = {}
session.__set_ngx_header(cookies)
local ok, err = s:destroy()
assert.is_true(ok)
assert.is_nil(err)
assert.equals(s.state, "closed")
ok, err = pcall(s.get, s, "anything")
assert.is_false(ok)
assert.matches("unable to get session data", err)
local session_cookie = extract_cookie(cookie_name, cookies["Set-Cookie"]) -- empty
session.__set_ngx_var({
["cookie_" .. cookie_name] = session_cookie
})
ok, err = s:open()
assert.is_nil(ok)
assert.equals("invalid session header", err)
assert.equals(s.state, "closed")
ok, err = pcall(s.get, s, "anything")
assert.is_false(ok)
assert.matches("unable to get session data", err)
end
local function test_session(s)
local session_cookie
local cookies = {}
test_session_set_get(s)
session_cookie = test_session_save(s, cookies)
test_session_close_open(s, session_cookie)
test_session_get_property(s)
test_session_touch(s)
test_session_destroy_open(s)
end
before_each(function()
configuration = {
cookie_name = cookie_name,
remember_cookie_name = remember_cookie_name
}
end)
it("with default values", function()
session.init(configuration)
local s = session.new()
assert.is_not_nil(s)
test_session(s)
end)
it("with custom secret", function()
configuration.secret = "t"
session.init(configuration)
local s = session.new()
assert.is_not_nil(s)
test_session(s)
end)
it("custom ikm takes precedence on secret", function()
configuration.secret = "t"
configuration.ikm = "00000000000000000000000000000000"
session.init(configuration)
local s = session.new()
assert.is_not_nil(s)
test_session(s)
assert.equals(configuration.ikm, s.meta.ikm)
end)
it("logout individual audience and subject", function()
local cookies = {}
session.__set_ngx_header(cookies)
session.init(configuration)
configuration.audience = test_audience
configuration.subject = test_subject
local s1 = session.new(configuration)
assert.is_not_nil(s1)
test_session_save(s1, cookies)
local session_cookie = extract_cookie(cookie_name, cookies["Set-Cookie"])
session.__set_ngx_var({
["cookie_" .. cookie_name] = session_cookie
})
assert.is_not_nil(session_cookie)
assert.is_not_equal("", session_cookie)
assert.match(s1:get_audience(), configuration.audience)
configuration.audience = lout_audience
configuration.subject = lout_subject
local s2 = session.open(configuration)
assert.is_not_nil(s2)
test_session_save(s2, cookies)
session_cookie = extract_cookie(cookie_name, cookies["Set-Cookie"])
session.__set_ngx_var({
["cookie_" .. cookie_name] = session_cookie
})
assert.is_not_nil(session_cookie)
assert.is_not_equal("", session_cookie)
assert.equals(configuration.audience, s2:get_audience())
s2:logout()
assert.equals(s1.state, "open")
assert.equals(s2.state, "closed")
session_cookie = extract_cookie(cookie_name, cookies["Set-Cookie"])
session.__set_ngx_var({
["cookie_" .. cookie_name] = session_cookie
})
assert.is_not_nil(session_cookie)
assert.is_not_equal("", session_cookie)
s1:logout()
assert.equals(s1.state, "closed")
session_cookie = extract_cookie(cookie_name, cookies["Set-Cookie"])
assert.is_not_nil(session_cookie)
assert.equals("", session_cookie)
end)
it("set_remember=true produces remember cookie, get_remember returns expected values", function()
local cookies = {}
session.__set_ngx_header(cookies)
session.init(configuration)
local s = session.new()
assert.is_not_nil(s)
assert.is_false(s:get_remember())
s:save()
assert.equals(s.state, "open")
local session_cookie = extract_cookie(cookie_name, cookies["Set-Cookie"])
local remember_cookie = extract_cookie(remember_cookie_name, cookies["Set-Cookie"])
assert.is_not_nil(remember_cookie)
assert.equals("", remember_cookie)
session.__set_ngx_var({
["cookie_" .. cookie_name] = session_cookie,
["cookie_" .. remember_cookie_name] = remember_cookie,
})
s:set_remember(true)
assert.is_true(s:get_remember())
s:save()
assert.equals(s.state, "open")
remember_cookie = extract_cookie(remember_cookie_name, cookies["Set-Cookie"])
assert.is_not_nil(remember_cookie)
assert.is_not_equal(remember_cookie, "")
end)
describe("with custom cookie attribute", function()
it("Domain", function()
configuration.cookie_domain = "example.org"
session.init(configuration)
local s = session.new()
assert.is_not_nil(s)
test_session(s)
assert.matches("Domain=example.org", s.cookie_flags)
end)
it("Path", function()
configuration.cookie_path = "/test"
session.init(configuration)
local s = session.new()
assert.is_not_nil(s)
test_session(s)
assert.matches("Path=/test", s.cookie_flags)
end)
it("SameSite", function()
configuration.cookie_same_site = "Default"
session.init(configuration)
local s = session.new()
assert.is_not_nil(s)
test_session(s)
assert.matches("SameSite=Default", s.cookie_flags)
end)
it("HttpOnly", function()
configuration.cookie_http_only = false
session.init(configuration)
local s = session.new()
assert.is_not_nil(s)
test_session(s)
assert.does_not.match("HttpOnly", s.cookie_flags)
end)
it("Secure", function()
configuration.cookie_secure = true
session.init(configuration)
local s = session.new()
assert.is_not_nil(s)
test_session(s)
assert.matches("Secure", s.cookie_flags)
end)
it("Priority", function()
configuration.cookie_priority = "High"
session.init(configuration)
local s = session.new()
assert.is_not_nil(s)
test_session(s)
assert.matches("Priority=High", s.cookie_flags)
end)
it("Partitioned", function()
configuration.cookie_partitioned = true
session.init(configuration)
local s = session.new()
assert.is_not_nil(s)
test_session(s)
assert.matches("Partitioned", s.cookie_flags)
end)
it("SameParty", function()
configuration.cookie_same_party = true
session.init(configuration)
local s = session.new()
assert.is_not_nil(s)
test_session(s)
assert.matches("SameParty", s.cookie_flags)
end)
end)
end)
describe("Fields validation", function()
describe("init validates fields", function()
before_each(function()
configuration = {}
end)
it("custom ikm must be 32 bytes", function()
configuration.ikm = "12345"
local ok, err = pcall(session.init,configuration)
assert.is_false(ok)
assert.matches("invalid ikm size", err)
end)
it("custom ikm_fallbacks must be 32 bytes", function()
configuration.ikm_fallbacks = {
"00000000000000000000000000000000",
"123456",
}
local ok, err = pcall(session.init,configuration)
assert.is_false(ok)
assert.matches("invalid ikm size in ikm_fallbacks", err)
end)
end)
describe("new validates fields", function()
before_each(function()
configuration = {}
end)
it("custom ikm must be 32 bytes", function()
configuration.ikm = "12345"
local ok, err = pcall(session.new, configuration)
assert.is_false(ok)
assert.matches("invalid ikm size", err)
end)
it("custom ikm_fallbacks must be 32 bytes", function()
configuration.ikm_fallbacks = {
"00000000000000000000000000000000",
"123456",
}
local ok, err = pcall(session.new, configuration)
assert.is_false(ok)
assert.matches("invalid ikm size", err)
end)
it("SameParty and SameSite=strict fails to instantiate session", function()
configuration.cookie_same_party = true
configuration.cookie_same_site = "Strict"
local ok, err = pcall(session.new, configuration)
assert.is_false(ok)
assert.matches("SameParty session cookies cannot use SameSite=Strict", err)
end)
end)
end)
end)

View File

@ -0,0 +1,223 @@
---
-- Ensure to keep the tests consistent with those in 05-storage-1_spec.lua
local utils = require "resty.session.utils"
local before_each = before_each
local after_each = after_each
local lazy_setup = lazy_setup
local describe = describe
local ipairs = ipairs
local assert = assert
local sleep = ngx.sleep
local time = ngx.time
local it = it
local storage_configs = {
file = {
suffix = "session",
},
shm = {
prefix = "sessions",
connect_timeout = 10000,
send_timeout = 10000,
read_timeout = 10000,
},
redis = {
prefix = "sessions",
password = "password",
},
memcached = {
prefix = "sessions",
connect_timeout = 10000,
send_timeout = 10000,
read_timeout = 10000,
},
}
for _, st in ipairs({
"file",
"shm",
"redis",
"memcached",
}) do
describe("Storage tests 1", function()
local current_time
local storage
local long_ttl = 60
local short_ttl = 2
local key = "test_key_1iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"
local key1 = "test_key_2iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"
local key2 = "test_key_3iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"
local old_key = "old_key_iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"
local name = "test_name"
local value = "test_value"
lazy_setup(function()
local conf = {
remember = true,
store_metadata = true,
}
conf[st] = storage_configs[st]
storage = utils.load_storage(st, conf)
assert.is_not_nil(storage)
end)
before_each(function()
current_time = time()
end)
describe("[#" .. st .. "] storage: SET + GET", function()
local audiences = { "foo", "bar" }
local subjects = { "john", "jane" }
local metadata = {
audiences = audiences,
subjects = subjects,
}
after_each(function()
storage:delete(name, key, current_time, metadata)
storage:delete(name, key1, current_time, metadata)
storage:delete(name, key2, current_time, metadata)
end)
it("SET: simple set does not return errors, GET fetches value correctly", function()
local ok = storage:set(name, key, value, long_ttl, current_time)
assert.is_not_nil(ok)
local v, err = storage:get(name, key, current_time)
assert.is_not_nil(v)
assert.is_nil(err)
assert.equals(v, value)
end)
it("SET: with metadata and remember works correctly", function()
local ok = storage:set(name, key, value, long_ttl, current_time, nil, nil, metadata, true)
assert.is_not_nil(ok)
sleep(1)
local v, err = storage:get(name, key, time())
assert.is_not_nil(v)
assert.is_nil(err)
assert.equals(v, value)
end)
it("SET: with metadata (long ttl) correctly appends metadata to collection", function()
local ok = storage:set(name, key, value, long_ttl, current_time, nil, nil, metadata, true)
ok = ok and storage:set(name, key1, value, long_ttl, current_time, nil, nil, metadata, true)
ok = ok and storage:set(name, key2, value, long_ttl, current_time, nil, nil, metadata, true)
assert.is_not_nil(ok)
sleep(1)
for i = 1, #audiences do
local meta_values = storage:read_metadata(name, audiences[i], subjects[i], time())
assert.is_not_nil(meta_values)
assert.truthy(meta_values[key ])
assert.truthy(meta_values[key1])
assert.truthy(meta_values[key2])
end
end)
it("SET: with metadata (short ttl) correctly expires metadata", function()
local ok = storage:set(name, key, value, short_ttl, current_time, nil, nil, metadata, true)
sleep(short_ttl + 1)
ok = ok and storage:set(name, key1, value, long_ttl, time(), nil, nil, metadata, true)
assert.is_not_nil(ok)
sleep(1)
for i = 1, #audiences do
local meta_values = storage:read_metadata(name, audiences[i], subjects[i], time())
assert.falsy(meta_values[key])
assert.truthy(meta_values[key1])
end
end)
it("SET: with old_key correctly applies stale ttl on old key", function()
local stale_ttl = 1
local ok = storage:set(name, old_key, value, long_ttl, current_time)
assert.is_not_nil(ok)
ok = storage:set(name, key, value, long_ttl, current_time, old_key, stale_ttl, nil, false)
assert.is_not_nil(ok)
sleep(3)
local v = storage:get(name, old_key, time())
assert.is_nil(v)
end)
it("SET: remember deletes file in old_key", function()
local stale_ttl = long_ttl
local ok = storage:set(name, old_key, value, long_ttl, current_time)
assert.is_not_nil(ok)
ok = storage:set(name, key, value, long_ttl, current_time, old_key, stale_ttl, nil, true)
assert.is_not_nil(ok)
local v = storage:get(name, old_key, current_time)
assert.is_nil(v)
end)
it("SET: ttl works as expected", function()
local ok = storage:set(name, key, value, short_ttl, current_time)
assert.is_not_nil(ok)
sleep(3)
local v = storage:get(name, key, time())
assert.is_nil(v)
end)
end)
describe("[#" .. st .. "] storage: DELETE", function()
local audiences = { "foo" }
local subjects = { "john" }
local metadata = {
audiences = audiences,
subjects = subjects,
}
it("deleted file is really deleted", function()
local ok = storage:set(name, key, value, short_ttl, current_time)
assert.is_not_nil(ok)
storage:delete(name, key, current_time, nil)
local v = storage:get(name, key, current_time)
assert.is_nil(v)
end)
it("with metadata correctly deletes metadata collection", function()
local ok = storage:set(name, key1, value, long_ttl, current_time, nil, nil, metadata, true)
assert.is_not_nil(ok)
sleep(1)
for i = 1, #audiences do
local meta_values = storage:read_metadata(name, audiences[i], subjects[i], time())
assert.truthy(meta_values[key1])
ok = storage:delete(name, key1, time(), metadata)
assert.is_not_nil(ok)
sleep(2)
meta_values = storage:read_metadata(name, audiences[i], subjects[i], time()) or {}
assert.falsy(meta_values[key1])
end
end)
end)
end)
end

View File

@ -0,0 +1,252 @@
---
-- For now these tests don't run on CI.
-- Ensure to keep the tests consistent with those in 04-storage-1_spec.lua
local utils = require "resty.session.utils"
local before_each = before_each
local after_each = after_each
local lazy_setup = lazy_setup
local describe = describe
local ipairs = ipairs
local assert = assert
local sleep = ngx.sleep
local time = ngx.time
local it = it
local storage_configs = {
mysql = {
username = "root",
password = "password",
database = "test",
},
postgres = {
username = "postgres",
password = "password",
database = "test",
},
redis_sentinel = {
prefix = "sessions",
password = "password",
sentinels = {
{ host = "127.0.0.1", port = "26379" }
},
connect_timeout = 10000,
send_timeout = 10000,
read_timeout = 10000,
},
redis_cluster = {
password = "password",
nodes = {
{ ip = "127.0.0.1", port = "6380" }
},
name = "somecluster",
lock_zone = "sessions",
connect_timeout = 10000,
send_timeout = 10000,
read_timeout = 10000,
},
dshm = {
prefix = "sessions",
connect_timeout = 10000,
send_timeout = 10000,
read_timeout = 10000,
},
}
local function storage_type(ty)
if ty == "redis_cluster" or ty == "redis_sentinel" then
return "redis"
end
return ty
end
for _, st in ipairs({
"mysql",
"postgres",
"redis_cluster",
"redis_sentinel",
"dshm"
}) do
describe("Storage tests 2 #noci", function()
local current_time
local storage
local long_ttl = 60
local short_ttl = 2
local key = "test_key_1iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"
local key1 = "test_key_2iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"
local key2 = "test_key_3iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"
local old_key = "old_key_iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"
local name = "test_name"
local value = "test_value"
lazy_setup(function()
local conf = {
remember = true,
store_metadata = true,
}
conf[storage_type(st)] = storage_configs[st]
storage = utils.load_storage(storage_type(st), conf)
assert.is_not_nil(storage)
end)
before_each(function()
current_time = time()
end)
describe("[#" .. st .. "] storage: SET + GET", function()
local audiences = { "foo", "bar" }
local subjects = { "john", "jane" }
local metadata = {
audiences = audiences,
subjects = subjects,
}
after_each(function()
current_time = time()
storage:delete(name, key, current_time, metadata)
storage:delete(name, key1, current_time, metadata)
storage:delete(name, key2, current_time, metadata)
end)
it("SET: simple set does not return errors, GET fetches value correctly", function()
local ok = storage:set(name, key, value, long_ttl, current_time)
assert.is_not_nil(ok)
local v, err = storage:get(name, key, current_time)
assert.is_not_nil(v)
assert.is_nil(err)
assert.equals(v, value)
end)
it("SET: with metadata and remember works correctly", function()
local ok = storage:set(name, key, value, long_ttl, time(), nil, nil, metadata, true)
assert.is_not_nil(ok)
sleep(1)
local v, err = storage:get(name, key, time())
assert.is_not_nil(v)
assert.is_nil(err)
assert.equals(v, value)
end)
it("SET: with metadata (long ttl) correctly appends metadata to collection", function()
local ok = storage:set(name, key, value, long_ttl, current_time, nil, nil, metadata, true)
ok = ok and storage:set(name, key1, value, long_ttl, current_time, nil, nil, metadata, true)
ok = ok and storage:set(name, key2, value, long_ttl, current_time, nil, nil, metadata, true)
assert.is_not_nil(ok)
sleep(1)
for i = 1, #audiences do
local meta_values = storage:read_metadata(name, audiences[i], subjects[i], time())
assert.is_not_nil(meta_values)
assert.truthy(meta_values[key ])
assert.truthy(meta_values[key1])
assert.truthy(meta_values[key2])
end
end)
it("SET: with metadata (short ttl) correctly expires metadata", function()
local ok = storage:set(name, key, value, short_ttl, current_time, nil, nil, metadata, true)
sleep(short_ttl + 1)
ok = ok and storage:set(name, key1, value, long_ttl, time(), nil, nil, metadata, true)
assert.is_not_nil(ok)
sleep(1)
for i = 1, #audiences do
local meta_values = storage:read_metadata(name, audiences[i], subjects[i], time())
assert.falsy(meta_values[key])
assert.truthy(meta_values[key1])
end
end)
it("SET: with old_key correctly applies stale ttl on old key", function()
local stale_ttl = 1
local ok = storage:set(name, old_key, value, long_ttl, current_time)
assert.is_not_nil(ok)
ok = storage:set(name, key, value, long_ttl, current_time, old_key, stale_ttl, nil, false)
assert.is_not_nil(ok)
sleep(3)
local v = storage:get(name, old_key, time())
assert.is_nil(v)
end)
it("SET: remember deletes file in old_key", function()
local stale_ttl = long_ttl
local ok = storage:set(name, old_key, value, long_ttl, current_time)
assert.is_not_nil(ok)
ok = storage:set(name, key, value, long_ttl, current_time, old_key, stale_ttl, nil, true)
assert.is_not_nil(ok)
local v = storage:get(name, old_key, current_time)
assert.is_nil(v)
end)
it("SET: ttl works as expected", function()
local ok = storage:set(name, key, value, short_ttl, current_time)
assert.is_not_nil(ok)
sleep(3)
local v = storage:get(name, key, time())
assert.is_nil(v)
end)
end)
describe("[#" .. st .. "] storage: DELETE", function()
local audiences = { "foo" }
local subjects = { "john" }
local metadata = {
audiences = audiences,
subjects = subjects,
}
it("deleted file is really deleted", function()
local ok = storage:set(name, key, value, short_ttl, current_time)
assert.is_not_nil(ok)
storage:delete(name, key, current_time)
local v = storage:get(name, key, current_time)
assert.is_nil(v)
end)
it("with metadata correctly deletes metadata collection", function()
local ok = storage:set(name, key1, value, long_ttl, current_time, nil, nil, metadata, true)
assert.is_not_nil(ok)
sleep(1)
for i = 1, #audiences do
local meta_values = storage:read_metadata(name, audiences[i], subjects[i], time())
assert.truthy(meta_values[key1])
ok = storage:delete(name, key1, time(), metadata)
assert.is_not_nil(ok)
sleep(2)
meta_values = storage:read_metadata(name, audiences[i], subjects[i], time()) or {}
assert.falsy(meta_values[key1])
end
end)
end)
end)
end

View File

@ -0,0 +1,149 @@
use Test::Nginx::Socket;
repeat_each(2);
$ENV{TEST_NGINX_NXSOCK} ||= html_dir();
plan tests => repeat_each() * blocks() * 3 + 4;
run_tests();
__DATA__
=== TEST 1: session cookie is returned
--- http_config
init_by_lua_block {
require("resty.session").init({
storage = "cookie",
})
}
--- config
location = /test {
content_by_lua_block {
local session = require "resty.session".new()
local ok = session:save()
if ok then
ngx.say("yay")
end
}
}
--- request
GET /test
--- response_body
yay
--- response_headers_like
Set-Cookie: .*session=.+;.*
--- error_code: 200
--- no_error_log
[error]
=== TEST 2: remember cookie is returned when remember=true
--- http_config
init_by_lua_block {
require("resty.session").init({
remember = true,
storage = "cookie",
})
}
--- config
location = /test {
content_by_lua_block {
local session = require "resty.session".new()
local ok = session:save()
if ok then
ngx.say("yay")
end
}
}
--- request
GET /test
--- response_body
yay
--- response_headers_like
Set-Cookie: .*remember=.+;.*
--- error_code: 200
--- no_error_log
[error]
=== TEST 3: session.open() opens a session from a valid cookie and data is
extracted correctly
--- http_config
init_by_lua_block {
require("resty.session").init({
secret = "RaJKp8UQW1",
storage = "cookie",
audience = "my_application",
idling_timeout = 0,
rolling_timeout = 0,
absolute_timeout = 0,
})
}
--- config
location = /test {
content_by_lua_block {
local session = require "resty.session".open()
local sub = session:get_subject()
local aud = session:get_audience()
local quote = session:get("quote")
ngx.say(sub .. "|" .. aud .. "|" .. quote)
}
}
--- request
GET /test
--- more_headers
Cookie: session=AQAAS3ZGU0k8tUKsWSci9Fb6PM5xbm469FlR5g_B5HWZ6KYGSOZjAAAAAABcAABTCuHjqpE7B6Ux7m4GCylZAAAAzcWnTvzG51whooR_4QQwDgGdMOOa5W7tG4JWiDFU3zuYLFzakWEi-y-ogrwTpnt24zQXP_uJK7r5lMPNzRSMJM9H1a_MIegzEMm-QSgVRaoZVJq3Oo; Path=/; SameSite=Lax; HttpOnly
--- response_body
Lua Fan|my_application|Lorem ipsum dolor sit amet
--- error_code: 200
--- no_error_log
[error]
=== TEST 4: clear_request_cookie() clears session Cookie from request to
upstream
--- http_config
init_by_lua_block {
require("resty.session").init({
secret = "RaJKp8UQW1",
storage = "cookie",
audience = "my_application",
idling_timeout = 0,
rolling_timeout = 0,
absolute_timeout = 0,
})
}
server {
listen unix:/$TEST_NGINX_NXSOCK/nginx.sock;
location /t {
content_by_lua_block {
local headers = ngx.req.get_headers()
ngx.say("session_cookie: [", tostring(headers["Cookie"]), "]")
}
}
}
--- config
location = /test {
access_by_lua_block {
local session = require "resty.session".open()
session:clear_request_cookie()
}
proxy_pass http://unix:/$TEST_NGINX_NXSOCK/nginx.sock;
}
--- request
GET /test
--- more_headers
Cookie: session=AQAAS3ZGU0k8tUKsWSci9Fb6PM5xbm469FlR5g_B5HWZ6KYGSOZjAAAAAABcAABTCuHjqpE7B6Ux7m4GCylZAAAAzcWnTvzG51whooR_4QQwDgGdMOOa5W7tG4JWiDFU3zuYLFzakWEi-y-ogrwTpnt24zQXP_uJK7r5lMPNzRSMJM9H1a_MIegzEMm-QSgVRaoZVJq3Oo; Path=/; SameSite=Lax; HttpOnly
--- response_body
session_cookie: [Path=/; SameSite=Lax; HttpOnly]
--- error_code: 200
--- no_error_log
[error]