Update upstream source from tag 'upstream/0.06'
Update to upstream version '0.06'
with Debian dir 9be0ec0fd3e95d0dac7b67defa3d3955c862a277
ChangZhuo Chen (陳昌倬)
6 years ago
38 | 38 | connect_timeout = 50, |
39 | 39 | read_timeout = 5000, |
40 | 40 | keepalive_timeout = 30000, |
41 | ||
41 | ||
42 | 42 | host = "127.0.0.1", |
43 | 43 | port = 6379, |
44 | 44 | db = 2, |
52 | 52 | local ok, err = rc:set_keepalive(redis) |
53 | 53 | ``` |
54 | 54 | |
55 | `connect` can be used to override defaults given in `new` | |
55 | [connect](#connect) can be used to override some defaults given in [new](#new), which are pertinent to this connection only. | |
56 | 56 | |
57 | 57 | |
58 | 58 | ```lua |
70 | 70 | |
71 | 71 | ## DSN format |
72 | 72 | |
73 | If the `params.url` field is present then it will be parsed, overriding values supplied in the parameters table. | |
73 | If the `params.url` field is present then it will be parsed to set the other params. Any manually specified params will override values given in the DSN. | |
74 | ||
75 | *Note: this is a behaviour change as of v0.06. Previously, the DSN values would take precedence.* | |
74 | 76 | |
75 | 77 | ### Direct Redis connections |
76 | 78 | |
86 | 88 | |
87 | 89 | `sentinel://PASSWORD@MASTER_NAME:ROLE/DB` |
88 | 90 | |
89 | Again, `PASSWORD` and `DB` are optional. `ROLE` must be any of `m`, `s` or `a`, meaning: | |
90 | ||
91 | * `m`: master | |
92 | * `s`: slave | |
93 | * `a`: any (first tries the master, but will failover to a slave if required) | |
91 | Again, `PASSWORD` and `DB` are optional. `ROLE` must be either `m` or `s` for master / slave respectively. | |
94 | 92 | |
95 | 93 | A table of `sentinels` must also be supplied. e.g. |
96 | 94 | |
103 | 101 | } |
104 | 102 | ``` |
105 | 103 | |
104 | ## Proxy Mode | |
105 | ||
106 | Enable the `connection_is_proxied` parameter if connecting to Redis through a proxy service (e.g. Twemproxy). | |
107 | These proxies generally only support a limited sub-set of Redis commands, those which do not require state and do not affect multiple keys. | |
108 | Databases and transactions are also not supported. | |
109 | ||
110 | Proxy mode will disable switching to a DB on connect. | |
111 | Unsupported commands (defaults to those not supported by Twemproxy) will return `nil, err` immediately rather than being sent to the proxy, which can result in dropped connections. | |
112 | ||
113 | `discard` will not be sent when adding connections to the keepalive pool | |
114 | ||
115 | ||
116 | ## Disabled commands | |
117 | ||
118 | If configured as a table of commands, the command methods will be replaced by a function which immediately returns `nil, err` without forwarding the command to the server | |
106 | 119 | |
107 | 120 | ## Default Parameters |
108 | 121 | |
114 | 127 | connection_options = {}, -- pool, etc |
115 | 128 | keepalive_timeout = 60000, |
116 | 129 | keepalive_poolsize = 30, |
117 | ||
130 | ||
118 | 131 | host = "127.0.0.1", |
119 | 132 | port = "6379", |
120 | 133 | path = "", -- unix socket path, e.g. /tmp/redis.sock |
121 | 134 | password = "", |
122 | 135 | db = 0, |
123 | ||
136 | ||
124 | 137 | master_name = "mymaster", |
125 | role = "master", -- master | slave | any | |
138 | role = "master", -- master | slave | |
126 | 139 | sentinels = {}, |
140 | ||
141 | connection_is_proxied = false, | |
142 | ||
143 | disabled_commands = {}, | |
127 | 144 | } |
128 | 145 | ``` |
129 | 146 | |
132 | 149 | |
133 | 150 | * [new](#new) |
134 | 151 | * [connect](#connect) |
152 | * [set_keepalive](#set_keepalive) | |
135 | 153 | * [Utilities](#utilities) |
136 | 154 | * [connect_via_sentinel](#connect_via_sentinel) |
137 | 155 | * [try_hosts](#try_hosts) |
142 | 160 | |
143 | 161 | ### new |
144 | 162 | |
145 | `syntax: rc = redis_connector.new()` | |
146 | ||
147 | Creates the Redis Connector object. In case of failures, returns `nil` and a string describing the error. | |
163 | `syntax: rc = redis_connector.new(params)` | |
164 | ||
165 | Creates the Redis Connector object, overring default params with the ones given. In case of failures, returns `nil` and a string describing the error. | |
148 | 166 | |
149 | 167 | |
150 | 168 | ### connect |
151 | 169 | |
152 | 170 | `syntax: redis, err = rc:connect(params)` |
153 | 171 | |
154 | Attempts to create a connection, according to the [params](#parameters) supplied. If a connection cannot be made, returns `nil` and a string describing the reason. | |
172 | Attempts to create a connection, according to the [params](#parameters) supplied, falling back to defaults given in `new` or the predefined defaults. If a connection cannot be made, returns `nil` and a string describing the reason. | |
173 | ||
174 | Note that `params` given here do not change the connector's own configuration, and are only used to alter this particular connection operation. As such, the following parameters have no meaning when given in `connect`. | |
175 | ||
176 | * `keepalive_poolsize` | |
177 | * `keepalive_timeout` | |
178 | * `connection_is_proxied` | |
179 | * `disabled_commands` | |
180 | ||
181 | ||
182 | ### set_keepalive | |
183 | ||
184 | `syntax: ok, err = rc:set_keepalive(redis)` | |
185 | ||
186 | Attempts to place the given Redis connection on the keepalive pool, according to timeout and poolsize params given in `new` or the predefined defaults. | |
187 | ||
188 | This allows an application to release resources without having to keep track of application wide keepalive settings. | |
189 | ||
190 | Returns `1` or in the case of error, `nil` and a string describing the error. | |
155 | 191 | |
156 | 192 | |
157 | 193 | ## Utilities |
99 | 99 | url = "", -- DSN url |
100 | 100 | |
101 | 101 | master_name = "mymaster", |
102 | role = "master", -- master | slave | any | |
102 | role = "master", -- master | slave | |
103 | 103 | sentinels = {}, |
104 | 104 | |
105 | -- Redis proxies typically don't support full Redis capabilities | |
106 | connection_is_proxied = false, | |
107 | ||
108 | disabled_commands = {}, | |
109 | ||
105 | 110 | }, fixed_field_metatable) |
106 | 111 | |
107 | 112 | |
113 | -- This is the set of commands unsupported by Twemproxy | |
114 | local default_disabled_commands = { | |
115 | "migrate", "move", "object", "randomkey", "rename", "renamenx", "scan", | |
116 | "bitop", "msetnx", "blpop", "brpop", "brpoplpush", "psubscribe", "publish", | |
117 | "punsubscribe", "subscribe", "unsubscribe", "discard", "exec", "multi", | |
118 | "unwatch", "watch", "script", "auth", "echo", "select", "bgrewriteaof", | |
119 | "bgsave", "client", "config", "dbsize", "debug", "flushall", "flushdb", | |
120 | "info", "lastsave", "monitor", "save", "shutdown", "slaveof", "slowlog", | |
121 | "sync", "time" | |
122 | } | |
123 | ||
124 | ||
108 | 125 | local _M = { |
109 | _VERSION = '0.04', | |
126 | _VERSION = '0.06', | |
110 | 127 | } |
111 | 128 | |
112 | 129 | local mt = { __index = _M } |
113 | ||
114 | ||
115 | function _M.new(config) | |
116 | local ok, config = pcall(tbl_copy_merge_defaults, config, DEFAULTS) | |
117 | if not ok then | |
118 | return nil, config -- err | |
119 | else | |
120 | return setmetatable({ | |
121 | config = setmetatable(config, fixed_field_metatable) | |
122 | }, mt) | |
123 | end | |
124 | end | |
125 | 130 | |
126 | 131 | |
127 | 132 | local function parse_dsn(params) |
134 | 139 | return nil, "could not parse DSN: " .. tostring(err) |
135 | 140 | end |
136 | 141 | |
142 | -- TODO: Support a 'protocol' for proxied Redis? | |
137 | 143 | local fields |
138 | 144 | if m[1] == "redis" then |
139 | 145 | fields = { "password", "host", "port", "db" } |
144 | 150 | -- password may not be present |
145 | 151 | if #m < 5 then tbl_remove(fields, 1) end |
146 | 152 | |
147 | local roles = { m = "master", s = "slave", a = "any" } | |
153 | local roles = { m = "master", s = "slave" } | |
154 | ||
155 | local parsed_params = {} | |
148 | 156 | |
149 | 157 | for i,v in ipairs(fields) do |
150 | params[v] = m[i + 1] | |
158 | parsed_params[v] = m[i + 1] | |
151 | 159 | if v == "role" then |
152 | params[v] = roles[params[v]] | |
153 | end | |
154 | end | |
155 | end | |
156 | ||
157 | return true, nil | |
160 | parsed_params[v] = roles[parsed_params[v]] | |
161 | end | |
162 | end | |
163 | ||
164 | return tbl_copy_merge_defaults(params, parsed_params) | |
165 | end | |
158 | 166 | end |
159 | 167 | _M.parse_dsn = parse_dsn |
160 | 168 | |
161 | 169 | |
170 | function _M.new(config) | |
171 | -- Fill out gaps in config with any dsn params | |
172 | if config and config.url then | |
173 | local err | |
174 | config, err = parse_dsn(config) | |
175 | if not ok then ngx_log(ngx_ERR, err) end | |
176 | end | |
177 | ||
178 | local ok, config = pcall(tbl_copy_merge_defaults, config, DEFAULTS) | |
179 | if not ok then | |
180 | return nil, config -- err | |
181 | else | |
182 | -- In proxied Redis mode disable default commands | |
183 | if config.connection_is_proxied == true and | |
184 | not next(config.disabled_commands) then | |
185 | ||
186 | config.disabled_commands = default_disabled_commands | |
187 | end | |
188 | ||
189 | return setmetatable({ | |
190 | config = setmetatable(config, fixed_field_metatable) | |
191 | }, mt) | |
192 | end | |
193 | end | |
194 | ||
195 | ||
162 | 196 | function _M.connect(self, params) |
163 | local params = tbl_copy_merge_defaults(params, self.config) | |
164 | ||
165 | if params.url then | |
166 | local ok, err = parse_dsn(params) | |
197 | if params and params.url then | |
198 | local err | |
199 | params, err = parse_dsn(params) | |
167 | 200 | if not ok then ngx_log(ngx_ERR, err) end |
168 | 201 | end |
202 | ||
203 | params = tbl_copy_merge_defaults(params, self.config) | |
169 | 204 | |
170 | 205 | if #params.sentinels > 0 then |
171 | 206 | return self:connect_via_sentinel(params) |
196 | 231 | return nil, err, previous_errors |
197 | 232 | end |
198 | 233 | |
199 | if role == "master" or role == "any" then | |
234 | if role == "master" then | |
200 | 235 | local master, err = get_master(sentnl, master_name) |
201 | 236 | if master then |
202 | 237 | master.db = db |
212 | 247 | end |
213 | 248 | end |
214 | 249 | end |
215 | end | |
216 | ||
217 | -- We either wanted a slave, or are failing over to a slave "any" | |
218 | local slaves, err = get_slaves(sentnl, master_name) | |
219 | sentnl:set_keepalive() | |
220 | ||
221 | if not slaves then | |
222 | return nil, err | |
223 | end | |
224 | ||
225 | -- Put any slaves on 127.0.0.1 at the front | |
226 | tbl_sort(slaves, sort_by_localhost) | |
227 | ||
228 | if db or password then | |
229 | for i,slave in ipairs(slaves) do | |
230 | slave.db = db | |
231 | slave.password = password | |
232 | end | |
233 | end | |
234 | ||
235 | local slave, err, previous_errors = self:try_hosts(slaves) | |
236 | if not slave then | |
237 | return nil, err, previous_errors | |
238 | else | |
239 | return slave | |
250 | ||
251 | else | |
252 | -- We want a slave | |
253 | local slaves, err = get_slaves(sentnl, master_name) | |
254 | sentnl:set_keepalive() | |
255 | ||
256 | if not slaves then | |
257 | return nil, err | |
258 | end | |
259 | ||
260 | -- Put any slaves on 127.0.0.1 at the front | |
261 | tbl_sort(slaves, sort_by_localhost) | |
262 | ||
263 | if db or password then | |
264 | for i,slave in ipairs(slaves) do | |
265 | slave.db = db | |
266 | slave.password = password | |
267 | end | |
268 | end | |
269 | ||
270 | local slave, err, previous_errors = self:try_hosts(slaves) | |
271 | if not slave then | |
272 | return nil, err, previous_errors | |
273 | else | |
274 | return slave | |
275 | end | |
240 | 276 | end |
241 | 277 | end |
242 | 278 | |
263 | 299 | local r = redis.new() |
264 | 300 | local config = self.config |
265 | 301 | r:set_timeout(config.connect_timeout) |
302 | ||
303 | -- Stub out methods for disabled commands | |
304 | if next(config.disabled_commands) then | |
305 | for _, cmd in ipairs(config.disabled_commands) do | |
306 | r[cmd] = function(...) | |
307 | return nil, ("Command "..cmd.." is disabled") | |
308 | end | |
309 | end | |
310 | end | |
266 | 311 | |
267 | 312 | local ok, err |
268 | 313 | local path = host.path |
295 | 340 | end |
296 | 341 | end |
297 | 342 | |
298 | if host.db ~= nil then | |
343 | -- No support for DBs in proxied Redis. | |
344 | if config.connection_is_proxied ~= true and host.db ~= nil then | |
299 | 345 | r:select(host.db) |
300 | 346 | end |
301 | 347 | return r, nil |
306 | 352 | local function set_keepalive(self, redis) |
307 | 353 | -- Restore connection to "NORMAL" before putting into keepalive pool, |
308 | 354 | -- ignoring any errors. |
309 | redis:discard() | |
355 | -- Proxied Redis does not support transactions. | |
356 | if self.config.connection_is_proxied ~= true then | |
357 | redis:discard() | |
358 | end | |
310 | 359 | |
311 | 360 | local config = self.config |
312 | 361 | return redis:set_keepalive( |
0 | package = "lua-resty-redis-connector" | |
1 | version = "0.04-0" | |
2 | source = { | |
3 | url = "git://github.com/pintsized/lua-resty-redis-connector", | |
4 | tag = "v0.04" | |
5 | } | |
6 | description = { | |
7 | summary = "Connection utilities for lua-resty-redis.", | |
8 | detailed = [[ | |
9 | Connection utilities for lua-resty-redis, making it easy and | |
10 | reliable to connect to Redis hosts, either directly or via Redis | |
11 | Sentinel. | |
12 | ]], | |
13 | homepage = "https://github.com/pintsized/lua-resty-redis-connector", | |
14 | license = "2-clause BSD", | |
15 | maintainer = "James Hurst <james@pintsized.co.uk>" | |
16 | } | |
17 | dependencies = { | |
18 | "lua >= 5.1", | |
19 | } | |
20 | build = { | |
21 | type = "builtin", | |
22 | modules = { | |
23 | ["resty.redis.connector"] = "lib/resty/redis/connector.lua", | |
24 | ["resty.redis.sentinel"] = "lib/resty/redis/sentinel.lua" | |
25 | } | |
26 | } |
0 | package = "lua-resty-redis-connector" | |
1 | version = "0.06-0" | |
2 | source = { | |
3 | url = "git://github.com/pintsized/lua-resty-redis-connector", | |
4 | tag = "v0.06" | |
5 | } | |
6 | description = { | |
7 | summary = "Connection utilities for lua-resty-redis.", | |
8 | detailed = [[ | |
9 | Connection utilities for lua-resty-redis, making it easy and | |
10 | reliable to connect to Redis hosts, either directly or via Redis | |
11 | Sentinel. | |
12 | ]], | |
13 | homepage = "https://github.com/pintsized/lua-resty-redis-connector", | |
14 | license = "2-clause BSD", | |
15 | maintainer = "James Hurst <james@pintsized.co.uk>" | |
16 | } | |
17 | dependencies = { | |
18 | "lua >= 5.1", | |
19 | } | |
20 | build = { | |
21 | type = "builtin", | |
22 | modules = { | |
23 | ["resty.redis.connector"] = "lib/resty/redis/connector.lua", | |
24 | ["resty.redis.sentinel"] = "lib/resty/redis/sentinel.lua" | |
25 | } | |
26 | } |
222 | 222 | path = "unix://tmp/redis.sock", |
223 | 223 | }):connect() |
224 | 224 | |
225 | assert(not redis and err == "no such file or directory", | |
226 | "bad domain socket should fail") | |
225 | assert(not redis and err == "no such file or directory", | |
226 | "bad domain socket should fail") | |
227 | 227 | } |
228 | 228 | } |
229 | 229 | --- request |
240 | 240 | content_by_lua_block { |
241 | 241 | local rc = require("resty.redis.connector") |
242 | 242 | |
243 | local params = { | |
244 | url = "redis://foo@127.0.0.1:$TEST_NGINX_REDIS_PORT/4" | |
245 | } | |
246 | ||
247 | local ok, err = rc.parse_dsn(params) | |
248 | assert(ok and not err, | |
249 | "url should parse without error: " .. tostring(err)) | |
243 | local user_params = { | |
244 | url = "redis://foo@127.0.0.1:$TEST_NGINX_REDIS_PORT/4" | |
245 | } | |
246 | ||
247 | local params, err = rc.parse_dsn(user_params) | |
248 | assert(params and not err, | |
249 | "url should parse without error: " .. tostring(err)) | |
250 | 250 | |
251 | 251 | assert(params.host == "127.0.0.1", "host should be localhost") |
252 | 252 | assert(tonumber(params.port) == $TEST_NGINX_REDIS_PORT, |
255 | 255 | assert(params.password == "foo", "password should be foo") |
256 | 256 | |
257 | 257 | |
258 | local params = { | |
258 | local user_params = { | |
259 | 259 | url = "sentinel://foo@foomaster:s/2" |
260 | 260 | } |
261 | 261 | |
262 | local ok, err = rc.parse_dsn(params) | |
263 | assert(ok and not err, | |
262 | local params, err = rc.parse_dsn(user_params) | |
263 | assert(params and not err, | |
264 | 264 | "url should parse without error: " .. tostring(err)) |
265 | 265 | |
266 | 266 | assert(params.master_name == "foomaster", "master_name should be foomaster") |
281 | 281 | GET /t |
282 | 282 | --- no_error_log |
283 | 283 | [error] |
284 | ||
285 | ||
286 | === TEST 9: params override dsn components | |
287 | --- http_config eval: $::HttpConfig | |
288 | --- config | |
289 | location /t { | |
290 | lua_socket_log_errors Off; | |
291 | content_by_lua_block { | |
292 | local rc = require("resty.redis.connector") | |
293 | ||
294 | local user_params = { | |
295 | url = "redis://foo@127.0.0.1:6381/4", | |
296 | db = 2, | |
297 | password = "bar", | |
298 | host = "example.com", | |
299 | } | |
300 | ||
301 | local params, err = rc.parse_dsn(user_params) | |
302 | assert(params and not err, | |
303 | "url should parse without error: " .. tostring(err)) | |
304 | ||
305 | assert(tonumber(params.db) == 2, "db should be 2") | |
306 | assert(params.password == "bar", "password should be bar") | |
307 | assert(params.host == "example.com", "host should be example.com") | |
308 | ||
309 | assert(tonumber(params.port) == 6381, "ort should still be 6381") | |
310 | ||
311 | } | |
312 | } | |
313 | --- request | |
314 | GET /t | |
315 | --- no_error_log | |
316 | [error] | |
317 | ||
318 | ||
319 | === TEST 9: Integration test for parse_dsn | |
320 | --- http_config eval: $::HttpConfig | |
321 | --- config | |
322 | location /t { | |
323 | lua_socket_log_errors Off; | |
324 | content_by_lua_block { | |
325 | local user_params = { | |
326 | url = "redis://foo.example:$TEST_NGINX_REDIS_PORT/4", | |
327 | db = 2, | |
328 | host = "127.0.0.1", | |
329 | } | |
330 | ||
331 | local rc, err = require("resty.redis.connector").new(user_params) | |
332 | assert(rc and not err, "new should return positively") | |
333 | ||
334 | local redis, err = rc:connect() | |
335 | assert(redis and not err, "connect should return positively") | |
336 | assert(redis:set("cat", "dog") and redis:get("cat") == "dog") | |
337 | ||
338 | local redis, err = rc:connect({ | |
339 | url = "redis://foo.example:$TEST_NGINX_REDIS_PORT/4", | |
340 | db = 2, | |
341 | host = "127.0.0.1", | |
342 | }) | |
343 | assert(redis and not err, "connect should return positively") | |
344 | assert(redis:set("cat", "dog") and redis:get("cat") == "dog") | |
345 | ||
346 | ||
347 | local rc2, err = require("resty.redis.connector").new() | |
348 | local redis, err = rc2:connect({ | |
349 | url = "redis://foo.example:$TEST_NGINX_REDIS_PORT/4", | |
350 | db = 2, | |
351 | host = "127.0.0.1", | |
352 | }) | |
353 | assert(redis and not err, "connect should return positively") | |
354 | assert(redis:set("cat", "dog") and redis:get("cat") == "dog") | |
355 | ||
356 | } | |
357 | } | |
358 | --- request | |
359 | GET /t | |
360 | --- no_error_log | |
361 | [error] |
0 | use Test::Nginx::Socket 'no_plan'; | |
1 | use Cwd qw(cwd); | |
2 | ||
3 | my $pwd = cwd(); | |
4 | ||
5 | our $HttpConfig = qq{ | |
6 | lua_package_path "$pwd/lib/?.lua;;"; | |
7 | ||
8 | init_by_lua_block { | |
9 | require("luacov.runner").init() | |
10 | } | |
11 | }; | |
12 | ||
13 | $ENV{TEST_NGINX_RESOLVER} = '8.8.8.8'; | |
14 | $ENV{TEST_NGINX_REDIS_PORT} ||= 6379; | |
15 | ||
16 | no_long_string(); | |
17 | run_tests(); | |
18 | ||
19 | __DATA__ | |
20 | ||
21 | === TEST 1: Proxy mode disables commands | |
22 | --- http_config eval: $::HttpConfig | |
23 | --- config | |
24 | location /t { | |
25 | content_by_lua_block { | |
26 | local rc = require("resty.redis.connector").new({ | |
27 | port = $TEST_NGINX_REDIS_PORT, | |
28 | connection_is_proxied = true | |
29 | }) | |
30 | ||
31 | local redis, err = assert(rc:connect(params), | |
32 | "connect should return positively") | |
33 | ||
34 | assert(redis:set("dog", "an animal"), | |
35 | "redis:set should return positively") | |
36 | ||
37 | local ok, err = redis:multi() | |
38 | assert(ok == nil, "redis:multi should return nil") | |
39 | assert(err == "Command multi is disabled") | |
40 | ||
41 | redis:close() | |
42 | } | |
43 | } | |
44 | --- request | |
45 | GET /t | |
46 | --- no_error_log | |
47 | [error] | |
48 | ||
49 | ||
50 | === TEST 2: Proxy mode disables custom commands | |
51 | --- http_config eval: $::HttpConfig | |
52 | --- config | |
53 | location /t { | |
54 | content_by_lua_block { | |
55 | local rc = require("resty.redis.connector").new({ | |
56 | port = $TEST_NGINX_REDIS_PORT, | |
57 | connection_is_proxied = true, | |
58 | disabled_commands = { "foobar", "hget"} | |
59 | }) | |
60 | ||
61 | local redis, err = assert(rc:connect(params), | |
62 | "connect should return positively") | |
63 | ||
64 | assert(redis:set("dog", "an animal"), | |
65 | "redis:set should return positively") | |
66 | ||
67 | assert(redis:multi(), | |
68 | "redis:multi should return positively") | |
69 | ||
70 | local ok, err = redis:hget() | |
71 | assert(ok == nil, "redis:hget should return nil") | |
72 | assert(err == "Command hget is disabled") | |
73 | ||
74 | local ok, err = redis:foobar() | |
75 | assert(ok == nil, "redis:foobar should return nil") | |
76 | assert(err == "Command foobar is disabled") | |
77 | ||
78 | redis:close() | |
79 | } | |
80 | } | |
81 | --- request | |
82 | GET /t | |
83 | --- no_error_log | |
84 | [error] | |
85 | ||
86 | === TEST 3: Proxy mode does not switch DB | |
87 | --- http_config eval: $::HttpConfig | |
88 | --- config | |
89 | location /t { | |
90 | content_by_lua_block { | |
91 | local redis = require("resty.redis.connector").new({ | |
92 | port = $TEST_NGINX_REDIS_PORT, | |
93 | db = 2 | |
94 | }):connect() | |
95 | ||
96 | local proxy = require("resty.redis.connector").new({ | |
97 | port = $TEST_NGINX_REDIS_PORT, | |
98 | connection_is_proxied = true, | |
99 | db = 2 | |
100 | }):connect() | |
101 | ||
102 | assert(redis:set("proxy", "test"), | |
103 | "redis:set should return positively") | |
104 | ||
105 | assert(proxy:get("proxy") == ngx.null, | |
106 | "proxy key should not exist in proxy") | |
107 | ||
108 | redis:seelct(2) | |
109 | assert(redis:get("proxy") == "test", | |
110 | "proxy key should be 'test' in db 1") | |
111 | ||
112 | redis:close() | |
113 | } | |
114 | } | |
115 | --- request | |
116 | GET /t | |
117 | --- no_error_log | |
118 | [error] | |
119 | ||
120 | ||
121 | === TEST 4: Commands are disabled without proxy mode | |
122 | --- http_config eval: $::HttpConfig | |
123 | --- config | |
124 | location /t { | |
125 | content_by_lua_block { | |
126 | local rc = require("resty.redis.connector").new({ | |
127 | port = $TEST_NGINX_REDIS_PORT, | |
128 | disabled_commands = { "foobar", "hget"} | |
129 | }) | |
130 | ||
131 | local redis, err = assert(rc:connect(params), | |
132 | "connect should return positively") | |
133 | ||
134 | assert(redis:set("dog", "an animal"), | |
135 | "redis:set should return positively") | |
136 | ||
137 | assert(redis:multi(), | |
138 | "redis:multi should return positively") | |
139 | ||
140 | local ok, err = redis:hget() | |
141 | assert(ok == nil, "redis:hget should return nil") | |
142 | assert(err == "Command hget is disabled") | |
143 | ||
144 | local ok, err = redis:foobar() | |
145 | assert(ok == nil, "redis:foobar should return nil") | |
146 | assert(err == "Command foobar is disabled") | |
147 | ||
148 | redis:close() | |
149 | } | |
150 | } | |
151 | --- request | |
152 | GET /t | |
153 | --- no_error_log | |
154 | [error] |