uri-smtp 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/README.md +27 -5
- data/lib/uri/smtp/version.rb +1 -1
- data/lib/uri/smtp.rb +72 -11
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 457b3741b5ef4678c7f1c6e19574f24d68d5f515ef58c6879f64516c8d472049
|
4
|
+
data.tar.gz: ecd3d5e89df1874095936cd804fd4241feefed5f2e8f6eb0f3015906d1f63cf6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 98b76dad4efd9c9c53f674ef06139844f8845415592bb9927ad90a7d903c62ef388a944779f55987d219035fac120e67247f50251228016db86c346e4d3bc8d3
|
7
|
+
data.tar.gz: 530215f54f3c2e1e1c78d99f476b30c11438136e1313d6abc26e7e830ee885f999c0dc90ce3e4874ac9ca11c7e45c3606a156e236ccf676bba33917b58534e18
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,22 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.5.0] - 2025-07-25
|
4
|
+
|
5
|
+
- Add: `uri#read_timeout`, `uri#open_timeout`
|
6
|
+
Coerced integers from query:
|
7
|
+
```ruby
|
8
|
+
URI("smtp://foo?read_timeout=1").read_timeout #=> 1
|
9
|
+
```
|
10
|
+
Included in `to_h`.
|
11
|
+
- Add: `uri.decoded_userinfo(format: ...)`
|
12
|
+
`:format` can be one of `[:string :array :hash]`
|
13
|
+
- Add: domain can appear in fragment
|
14
|
+
```ruby
|
15
|
+
URI("smtp://foo.org#sender.org").domain #=> "sender.org"
|
16
|
+
```
|
17
|
+
NOTE Any domain from the query takes precedence.
|
18
|
+
- Fix: "smtps+foo://..." having no tls
|
19
|
+
|
3
20
|
## [0.4.0] - 2025-07-23
|
4
21
|
|
5
22
|
- FIX: correct settings for action_mailer using mail v2.8.1
|
@@ -11,3 +28,4 @@
|
|
11
28
|
## [0.2.0] - 2025-07-18
|
12
29
|
|
13
30
|
- Feature complete
|
31
|
+
|
data/README.md
CHANGED
@@ -1,6 +1,25 @@
|
|
1
1
|
# URI::SMTP
|
2
2
|
|
3
|
-
|
3
|
+
Extends Ruby's `URI` with support for SMTP-uri's.
|
4
|
+
This allows for more concise SMTP-config:
|
5
|
+
```diff
|
6
|
+
# config/environments/production.rb
|
7
|
+
config.action_mailer.delivery_method = :smtp
|
8
|
+
- config.action_mailer.smtp_settings = {
|
9
|
+
- address: "smtp.gmail.com",
|
10
|
+
- port: 587,
|
11
|
+
- domain: "example.com",
|
12
|
+
- user_name: Rails.application.credentials.dig(:smtp, :user_name),
|
13
|
+
- password: Rails.application.credentials.dig(:smtp, :password),
|
14
|
+
- authentication: "plain",
|
15
|
+
- enable_starttls: true,
|
16
|
+
- open_timeout: 5,
|
17
|
+
- read_timeout: 5
|
18
|
+
- }
|
19
|
+
# given ENV["SMPT_URL"]:
|
20
|
+
# "smtp://user_name:password@smtp.gmail.com?open_timeout=5&read_timeout=5#example.com"
|
21
|
+
+ config.action_mailer.smtp_settings = URI(ENV.fetch("SMTP_URL")).to_h(format: :am)
|
22
|
+
```
|
4
23
|
|
5
24
|
## Installation
|
6
25
|
|
@@ -21,27 +40,29 @@ gem install uri-smtp
|
|
21
40
|
### parse
|
22
41
|
|
23
42
|
```ruby
|
24
|
-
u = URI("smtps+login://user%40gmail.com:p%40ss@smtp.gmail.com
|
43
|
+
u = URI("smtps+login://user%40gmail.com:p%40ss@smtp.gmail.com#sender.org")
|
25
44
|
|
26
45
|
url.scheme #=> "smtps+login"
|
27
46
|
url.auth #=> "login"
|
28
47
|
url.starttls #=> false
|
48
|
+
url.starttls? #=> false
|
29
49
|
url.tls? #=> true
|
30
50
|
url.userinfo #=> "user%40gmail.com:p%40ss"
|
51
|
+
url.decoded_userinfo #=> ["user@gmail.com", "p@ss"]
|
31
52
|
url.decoded_user #=> "user@gmail.com"
|
32
53
|
url.user #=> "user%40gmail.com"
|
33
54
|
url.decoded_password #=> "p@ss"
|
34
55
|
url.password #=> "p%40ss"
|
35
56
|
url.host #=> "smtp.gmail.com"
|
36
57
|
url.port #=> 465
|
37
|
-
url.domain #=>
|
38
|
-
url.query #=> "domain=sender.org"
|
58
|
+
url.domain #=> "sender.org"
|
39
59
|
```
|
40
60
|
|
41
61
|
### to_h
|
42
62
|
|
43
63
|
```ruby
|
44
64
|
URI("smtps+login://user%40gmail.com:p%40ss@smtp.gmail.com?domain=sender.org").to_h
|
65
|
+
#=>
|
45
66
|
{auth: "login",
|
46
67
|
domain: "sender.org",
|
47
68
|
host: "smtp.gmail.com",
|
@@ -56,6 +77,7 @@ URI("smtps+login://user%40gmail.com:p%40ss@smtp.gmail.com?domain=sender.org").to
|
|
56
77
|
Formatting for action_mailer configuration, use `to_h(format: :am)`:
|
57
78
|
```ruby
|
58
79
|
URI("smtps+login://user%40gmail.com:p%40ss@smtp.gmail.com?domain=sender.org").to_h(format: :am)
|
80
|
+
#=>
|
59
81
|
{address: "smtp.gmail.com",
|
60
82
|
authentication: "login",
|
61
83
|
domain: "sender.org",
|
@@ -89,7 +111,7 @@ There's no official specification for SMTP-URIs. There's some prior work though.
|
|
89
111
|
SMTP with TLS.
|
90
112
|
|
91
113
|
> [!NOTE]
|
92
|
-
> to get `url.starttls #=> :auto`, provide it in the query: `smtp://foo?auth=auto`. In that case `net-smtp` uses STARTTLS when the server supports it (but won't halt like when using `:always`).
|
114
|
+
> to get `url.starttls #=> :auto`, provide it in the query: `smtp://user:pw@foo?auth=auto`. In that case `net-smtp` uses STARTTLS when the server supports it (but won't halt like when using `:always`).
|
93
115
|
|
94
116
|
|
95
117
|
### auth
|
data/lib/uri/smtp/version.rb
CHANGED
data/lib/uri/smtp.rb
CHANGED
@@ -21,6 +21,7 @@ module URI
|
|
21
21
|
return @port if @port
|
22
22
|
return 25 if host_local?
|
23
23
|
return 465 if tls?
|
24
|
+
|
24
25
|
587
|
25
26
|
end
|
26
27
|
|
@@ -30,15 +31,56 @@ module URI
|
|
30
31
|
return parsed_query["auth"] if parsed_query.has_key?("auth")
|
31
32
|
return nil if scheme_auth == "none"
|
32
33
|
return scheme_auth if scheme_auth
|
34
|
+
|
33
35
|
"plain"
|
34
36
|
end
|
35
37
|
|
38
|
+
# all formats: return nil when userinfo == nil.
|
39
|
+
#
|
40
|
+
# format: :array
|
41
|
+
# Never contains empty strings (as opposed to [#user, #password]).
|
42
|
+
# Example:
|
43
|
+
# Given #<URI::SMTP smtps://:token@smtp.gmail.com>
|
44
|
+
# Then:
|
45
|
+
# [uri.user, uri.password] #=> ["", "token"]
|
46
|
+
# uri.decoded_userinfo #=> [nil, "token"]
|
47
|
+
#
|
48
|
+
# format: :hash
|
49
|
+
# Keys are absent when value would be `nil`.
|
50
|
+
# Example:
|
51
|
+
# Given #<URI::SMTP smtps://:token@smtp.gmail.com>
|
52
|
+
# Then:
|
53
|
+
# uri.decoded_userinfo(format: :array) #=> [nil, "token"]
|
54
|
+
# uri.decoded_userinfo(format: :to_h) #=> {password: "token"}
|
55
|
+
def decoded_userinfo(format: :string)
|
56
|
+
return if userinfo.nil?
|
57
|
+
|
58
|
+
case format
|
59
|
+
when :string
|
60
|
+
[decoded_user, decoded_password].compact.join(":")
|
61
|
+
when :array
|
62
|
+
[string_presence(decoded_user), string_presence(decoded_password)]
|
63
|
+
when :hash
|
64
|
+
{
|
65
|
+
user: string_presence(decoded_user),
|
66
|
+
password: string_presence(decoded_password)
|
67
|
+
}.delete_if { |_k, v| v.nil? }
|
68
|
+
else
|
69
|
+
raise ArgumentError,
|
70
|
+
"Unknown format #{format.inspect}. Should be one of #{%i[string array hash].inspect}."
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
36
74
|
def domain
|
37
|
-
parsed_query["domain"]
|
75
|
+
parsed_query["domain"] || fragment
|
38
76
|
end
|
39
77
|
|
40
|
-
def
|
41
|
-
|
78
|
+
def read_timeout
|
79
|
+
parsed_query["read_timeout"]
|
80
|
+
end
|
81
|
+
|
82
|
+
def open_timeout
|
83
|
+
parsed_query["open_timeout"]
|
42
84
|
end
|
43
85
|
|
44
86
|
def starttls
|
@@ -46,12 +88,13 @@ module URI
|
|
46
88
|
return parsed_query["starttls"] if parsed_query.has_key?("starttls")
|
47
89
|
return false if host_local?
|
48
90
|
return false if insecure?
|
91
|
+
|
49
92
|
:always
|
50
93
|
end
|
51
94
|
alias_method :starttls?, :starttls
|
52
95
|
|
53
96
|
def tls
|
54
|
-
scheme
|
97
|
+
!!scheme[/^smtps/]
|
55
98
|
end
|
56
99
|
alias_method :tls?, :tls
|
57
100
|
|
@@ -64,14 +107,18 @@ module URI
|
|
64
107
|
end
|
65
108
|
|
66
109
|
def parsed_query
|
67
|
-
@parsed_query ||= URI.decode_www_form(query.to_s).to_h
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
110
|
+
@parsed_query ||= URI.decode_www_form(query.to_s).to_h
|
111
|
+
.delete_if { |_k, v| !string_presence(v) }
|
112
|
+
.tap do
|
113
|
+
_1["read_timeout"] &&= _1["read_timeout"].to_i
|
114
|
+
_1["open_timeout"] &&= _1["open_timeout"].to_i
|
115
|
+
_1["starttls"] &&= case _1["starttls"]
|
116
|
+
when "always", "auto" then _1["starttls"].to_sym
|
117
|
+
when "false" then false
|
118
|
+
else
|
119
|
+
:always
|
120
|
+
end
|
73
121
|
end
|
74
|
-
end
|
75
122
|
end
|
76
123
|
|
77
124
|
def to_h(format: nil)
|
@@ -83,7 +130,9 @@ module URI
|
|
83
130
|
domain:,
|
84
131
|
enable_starttls: starttls == :always,
|
85
132
|
enable_starttls_auto: starttls == :auto,
|
133
|
+
open_timeout:,
|
86
134
|
port:,
|
135
|
+
read_timeout:,
|
87
136
|
tls:
|
88
137
|
}.tap do
|
89
138
|
unless _1[:authentication].nil?
|
@@ -104,7 +153,9 @@ module URI
|
|
104
153
|
auth:,
|
105
154
|
domain:,
|
106
155
|
host:,
|
156
|
+
open_timeout:,
|
107
157
|
port:,
|
158
|
+
read_timeout:,
|
108
159
|
scheme:,
|
109
160
|
starttls:,
|
110
161
|
tls:
|
@@ -120,6 +171,16 @@ module URI
|
|
120
171
|
def self.parse(uri)
|
121
172
|
new(*URI.split(uri))
|
122
173
|
end
|
174
|
+
|
175
|
+
private
|
176
|
+
|
177
|
+
def scheme_auth
|
178
|
+
scheme[/.*(?:\+(.+))/, 1]
|
179
|
+
end
|
180
|
+
|
181
|
+
def string_presence(s)
|
182
|
+
s.to_s.strip.then { _1 unless _1.empty? }
|
183
|
+
end
|
123
184
|
end
|
124
185
|
|
125
186
|
register_scheme "SMTP", SMTP
|