- new module cooler: Install, Handle, OpenRedis (no URL in errors), RateLimitStore (atomic fixed-window Lua script with MemoryStore semantics, per-instance fallback) - serve installs cooler and publishes the Redis surf.Store before BuildRouter; BuildRouter looks up a published Store, route:list keeps the memory store - config keys http.rate_limit.store and redis.url; go-redis v9.23.0 - cooler README, root table row, surf README and rate-limiting, configuration and scaling docs
37 lines
1.0 KiB
Go
37 lines
1.0 KiB
Go
package cooler
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// Smoke tests only; plan 05 of phase 19.3 owns full coverage.
|
|
|
|
func TestOpenRedisRedactsSmoke(t *testing.T) {
|
|
ctx := t.Context()
|
|
_, err := OpenRedis(ctx, "redis://alice:s3cretpw@cache.example.com:6379/0\x7f")
|
|
if err == nil {
|
|
t.Fatal("a URL with a control character must not parse")
|
|
}
|
|
msg := err.Error()
|
|
if strings.Contains(msg, "alice") || strings.Contains(msg, "s3cretpw") {
|
|
t.Fatalf("error leaks credentials: %q", msg)
|
|
}
|
|
if !strings.Contains(msg, RedisURLKey) {
|
|
t.Fatalf("error should name %s: %q", RedisURLKey, msg)
|
|
}
|
|
|
|
c, err := OpenRedis(ctx, "rediss://user:pw@cache.example.com:6380/1")
|
|
if err != nil {
|
|
t.Fatalf("rediss URL: %v", err)
|
|
}
|
|
defer c.Close()
|
|
opt := c.Options()
|
|
if opt.TLSConfig == nil || opt.Addr != "cache.example.com:6380" || opt.DB != 1 {
|
|
t.Fatalf("rediss options = addr %q db %d tls %v", opt.Addr, opt.DB, opt.TLSConfig != nil)
|
|
}
|
|
if !opt.DisableIdentity {
|
|
t.Fatal("OpenRedis must disable the CLIENT SETINFO handshake")
|
|
}
|
|
}
|