Skip to content

Commit 9694df4

Browse files
authored
Merge pull request #170 from tacerus/unix
Support Unix sockets
2 parents a9484d7 + ae0c7c7 commit 9694df4

File tree

5 files changed

+69
-14
lines changed

5 files changed

+69
-14
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Unreleased
22

3+
- Accept `unix://` schemes as well as simple paths in the `url:` config parameter. #170.
34
- Make basic usage Ractor compatible.
45

56
# 0.19.1

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,9 @@ redis.call("GET", "mykey")
6262

6363
### Configuration
6464

65-
- `url`: A Redis connection URL, e.g. `redis://example.com:6379/5`, a `rediss://` scheme enable SSL, and the path is interpreted as a database number.
65+
- `url`: A Redis connection URL, e.g. `redis://example.com:6379/5` - a `rediss://` scheme enables SSL, and the path is interpreted as a database number.
66+
To connect to UNIX domain sockets, the `url` can also just be a path, and the database specified as query parameter: `/run/redis/foo.sock?db=5`, or optionally
67+
have a `unix://` scheme: `unix:///run/redis/foo.sock?db=5`
6668
Note that all other configurations take precedence, e.g. `RedisClient.config(url: "redis://localhost:3000", port: 6380)` will connect on port `6380`.
6769
- `host`: The server hostname or IP address. Defaults to `"localhost"`.
6870
- `port`: The server port. Defaults to `6379`.

lib/redis_client/config.rb

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,15 +176,20 @@ def initialize(
176176
}.compact.merge(kwargs)
177177
host ||= url_config.host
178178
port ||= url_config.port
179+
path ||= url_config.path
179180
username ||= url_config.username
180181
password ||= url_config.password
181182
end
182183

183184
super(username: username, password: password, **kwargs)
184185

185-
@host = host || DEFAULT_HOST
186-
@port = Integer(port || DEFAULT_PORT)
187-
@path = path
186+
if @path = path
187+
@host = nil
188+
@port = nil
189+
else
190+
@host = host || DEFAULT_HOST
191+
@port = Integer(port || DEFAULT_PORT)
192+
end
188193
end
189194
end
190195
end

lib/redis_client/url_config.rb

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,41 @@
44

55
class RedisClient
66
class URLConfig
7-
DEFAULT_SCHEMA = "redis"
8-
SSL_SCHEMA = "rediss"
9-
107
attr_reader :url, :uri
118

129
def initialize(url)
1310
@url = url
1411
@uri = URI(url)
15-
unless uri.scheme == DEFAULT_SCHEMA || uri.scheme == SSL_SCHEMA
16-
raise ArgumentError, "Invalid URL: #{url.inspect}"
12+
@unix = false
13+
@ssl = false
14+
case uri.scheme
15+
when "redis"
16+
# expected
17+
when "rediss"
18+
@ssl = true
19+
when "unix", nil
20+
@unix = true
21+
else
22+
raise ArgumentError, "Unknown URL scheme: #{url.inspect}"
1723
end
1824
end
1925

2026
def ssl?
21-
@uri.scheme == SSL_SCHEMA
27+
@ssl
2228
end
2329

2430
def db
25-
db_path = uri.path&.delete_prefix("/")
26-
Integer(db_path) if db_path && !db_path.empty?
31+
unless @unix
32+
db_path = uri.path&.delete_prefix("/")
33+
return Integer(db_path) if db_path && !db_path.empty?
34+
end
35+
36+
unless uri.query.nil? || uri.query.empty?
37+
_, db_query = URI.decode_www_form(uri.query).find do |key, _|
38+
key == "db"
39+
end
40+
return Integer(db_query) if db_query && !db_query.empty?
41+
end
2742
end
2843

2944
def username
@@ -44,6 +59,12 @@ def host
4459
uri.host.sub(/\A\[(.*)\]\z/, '\1')
4560
end
4661

62+
def path
63+
if @unix
64+
File.join(*[uri.host, uri.path].compact)
65+
end
66+
end
67+
4768
def port
4869
return unless uri.port
4970

test/redis_client/config_test.rb

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,42 @@ def test_simple_uri
1414
refute_predicate config, :ssl?
1515
end
1616

17+
def test_unix_uri
18+
config = Config.new(url: "/run/redis/test.sock?db=1")
19+
assert_equal "/run/redis/test.sock", config.path
20+
assert_nil config.host
21+
assert_nil config.port
22+
assert_equal 1, config.db
23+
24+
config = Config.new(url: "run/redis/test.sock?db=1")
25+
assert_equal "run/redis/test.sock", config.path
26+
assert_nil config.host
27+
assert_nil config.port
28+
assert_equal 1, config.db
29+
30+
config = Config.new(url: "unix:///run/redis/test.sock?db=1")
31+
assert_equal "/run/redis/test.sock", config.path
32+
assert_nil config.host
33+
assert_nil config.port
34+
assert_equal 1, config.db
35+
36+
config = Config.new(url: "unix://run/redis/test.sock?db=1")
37+
assert_equal "run/redis/test.sock", config.path
38+
assert_nil config.host
39+
assert_nil config.port
40+
assert_equal 1, config.db
41+
end
42+
1743
def test_uri_instance
1844
config = Config.new(url: URI.parse("redis://example.com"))
1945
assert_equal "example.com", config.host
2046
end
2147

2248
def test_invalid_url
2349
error = assert_raises ArgumentError do
24-
Config.new(url: "example.com")
50+
Config.new(url: "http://example.com")
2551
end
26-
assert_includes error.message, "Invalid URL"
52+
assert_includes error.message, "Unknown URL scheme"
2753
assert_includes error.message, "example.com"
2854
end
2955

0 commit comments

Comments
 (0)