Skip to content

Commit 20e3b55

Browse files
committed
[threescale_utils] Do not terminate request but return error instead
Previously, if redis failed to connect for any reason, the next _M.error() call would call ngx.say and ngx.exit to terminate the current request and send an error back to the client, thereby revealing details about the Redis server. We want to return an error and let the caller decide how to handle the error.
1 parent 9572bf0 commit 20e3b55

5 files changed

Lines changed: 65 additions & 8 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
2525
- Remove "$id" from the policy schema [PR #1525](https://github.com/3scale/APIcast/pull/1525) [THEESCALE-11610](https://issues.redhat.com/browse/THREESCALE-11610)
2626
- Fixed Financial-grade API (FAPI) policy not showing up in the admin portal [PR #1528](https://github.com/3scale/APIcast/pull/1528) [THREESCALE-11620](https://issues.redhat.com/browse/THREESCALE-11620)
2727
- Remove Conditional Policy from the UI [PR #1534](https://github.com/3scale/APIcast/pull/1534) [THREESCALE-6116](https://issues.redhat.com/browse/THREESCALE-6116)
28+
- Remove redis connection error message from response body in edge limiting policy [PR #1537](https://github.com/3scale/APIcast/pull/1537) [THREESCALE-11701](https://issues.redhat.com/browse/THREESCALE-11701)
2829

2930
### Added
3031

gateway/src/apicast/threescale_utils.lua

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
local sub = string.sub
22
local tonumber = tonumber
3+
local fmt = string.format
34

45
local redis = require 'resty.redis'
56
local env = require 'resty.env'
@@ -152,22 +153,22 @@ function _M.connect_redis(options)
152153

153154
local ok, err = red:connect(_M.resolve(host, port))
154155
if not ok then
155-
return nil, _M.error("failed to connect to redis on ", host, ":", port, ": ", err)
156+
return nil, fmt("failed to connect to redis on %s:%d, err: %s",host, port, err)
156157
end
157158

158159
if opts.password then
159-
ok = red:auth(opts.password)
160+
ok, err = red:auth(opts.password)
160161

161162
if not ok then
162-
return nil, _M.error("failed to auth on redis ", host, ":", port)
163+
return nil, fmt("failed to auth on redis %s:%d, err: %s", host, port, err)
163164
end
164165
end
165166

166167
if opts.db then
167-
ok = red:select(opts.db)
168+
ok, err = red:select(opts.db)
168169

169170
if not ok then
170-
return nil, _M.error("failed to select db ", opts.db, " on redis ", host, ":", port)
171+
return nil, fmt("failed to select db %s on redis %s:%d, err: %s", opts.db, host, port, err)
171172
end
172173
end
173174

spec/policy/rate_limit/rate_limit_spec.lua

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ describe('Rate limit policy', function()
3535
redis:flushdb()
3636

3737
stub(ngx, 'exit')
38+
stub(ngx, 'say')
3839
stub(ngx, 'sleep')
3940

4041
stub(ngx, 'time', function() return 11111 end)
@@ -138,8 +139,9 @@ describe('Rate limit policy', function()
138139
redis_url = 'redis://invalidhost.domain:'..redis_port..'/1'
139140
})
140141

141-
assert.returns_error('failed to connect to redis on invalidhost.domain:6379: invalidhost.domain could not be resolved (3: Host not found)', rate_limit_policy:access(context))
142+
rate_limit_policy:access(context)
142143

144+
assert.spy(ngx.say).was_not_called_with('failed to connect to redis on invalidhost.domain:6379: invalidhost.domain could not be resolved (3: Host not found)')
143145
assert.spy(ngx.exit).was_called_with(500)
144146
end)
145147

spec/policy/rate_limit/redis_shdict_spec.lua

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,23 @@ describe('Redis Shared Dictionary', function()
1010
local redis
1111
local shdict
1212

13+
describe('new', function()
14+
it('invalid redis url', function()
15+
local _, err = redis_shdict.new{ host = "invalid", port = 6379 }
16+
assert.match("failed to connect to redis on invalid:6379", err)
17+
end)
18+
19+
it('invalid redis auth', function()
20+
local _, err = redis_shdict.new{ host = redis_host, port = redis_port, db=1 , password = "invalid"}
21+
assert.match("failed to auth on redis ".. redis_host .. ":" .. redis_port ..", err: ERR AUTH <password> called without any password configured for the default user. Are you sure your configuration is correct?", err)
22+
end)
23+
24+
it('invalid redis db', function()
25+
local _, err = redis_shdict.new{ host = redis_host, port = redis_port, db = 1000}
26+
assert.match("failed to select db 1000 on redis " .. redis_host ..":" .. redis_port .. ", err: ERR DB index is out of range", err)
27+
end)
28+
end)
29+
1330
before_each(function()
1431
local options = { host = redis_host, port = redis_port, db = 1 }
1532
redis = assert(ts.connect_redis(options))
@@ -18,6 +35,7 @@ describe('Redis Shared Dictionary', function()
1835
assert(redis:flushdb())
1936
end)
2037

38+
2139
describe('flush_all', function()
2240
it('removes all records', function()
2341
assert(redis:set('foo', 'bar'))

t/apicast-policy-rate-limit.t

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,6 @@ Return 500 code.
213213
--- request
214214
GET /
215215
--- error_code: 500
216-
--- no_error_log
217-
[error]
218216
--- error_log
219217
query for invalidhost finished with no answers
220218
@@ -1565,3 +1563,40 @@ location /transactions/authrep.xml {
15651563
[error]
15661564
--- error_log
15671565
Requests over the limit.
1566+
1567+
1568+
1569+
=== TEST 23: Invalid redis url and configuration_error set to log.
1570+
Return 200 code.
1571+
--- configuration
1572+
{
1573+
"services" : [
1574+
{
1575+
"id" : 42,
1576+
"proxy" : {
1577+
"policy_chain" : [
1578+
{
1579+
"name" : "apicast.policy.rate_limit",
1580+
"configuration" : {
1581+
"connection_limiters" : [
1582+
{
1583+
"key" : {"name" : "test3", "scope" : "global"},
1584+
"conn" : 20,
1585+
"burst" : 10,
1586+
"delay" : 0.5
1587+
}
1588+
],
1589+
"redis_url" : "redis://invalidhost:$TEST_NGINX_REDIS_PORT/1",
1590+
"configuration_error": {"error_handling": "log"}
1591+
}
1592+
}
1593+
]
1594+
}
1595+
}
1596+
]
1597+
}
1598+
--- request
1599+
GET /
1600+
--- error_code: 200
1601+
--- error_log
1602+
query for invalidhost finished with no answers

0 commit comments

Comments
 (0)