truemail 2.1.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -24,13 +24,23 @@ module Truemail
24
24
 
25
25
  private
26
26
 
27
- def request
28
- smtp_results.last
27
+ def fail_fast?
28
+ configuration.smtp_fail_fast
29
+ end
30
+
31
+ def filtered_mail_servers_by_fail_fast_scenario
32
+ fail_fast? ? mail_servers.first(1) : mail_servers
29
33
  end
30
34
 
31
35
  def attempts
32
- @attempts ||=
33
- mail_servers.one? ? { attempts: configuration.connection_attempts } : {}
36
+ @attempts ||= begin
37
+ return {} if fail_fast? || !mail_servers.one?
38
+ { attempts: configuration.connection_attempts }
39
+ end
40
+ end
41
+
42
+ def request
43
+ smtp_results.last
34
44
  end
35
45
 
36
46
  def rcptto_error
@@ -38,7 +48,7 @@ module Truemail
38
48
  end
39
49
 
40
50
  def establish_smtp_connection
41
- mail_servers.each do |mail_server|
51
+ filtered_mail_servers_by_fail_fast_scenario.each do |mail_server|
42
52
  smtp_results << Truemail::Validate::Smtp::Request.new(
43
53
  configuration: configuration, host: mail_server, email: result.punycode_email, **attempts
44
54
  )
@@ -13,20 +13,24 @@ module Truemail
13
13
 
14
14
  attr_reader :configuration, :host, :email, :response
15
15
 
16
- def initialize(configuration:, host:, email:, attempts: nil)
16
+ def initialize(configuration:, host:, email:, attempts: nil, port_open_status: proc { true })
17
17
  @configuration = Truemail::Validate::Smtp::Request::Configuration.new(configuration)
18
18
  @response = Truemail::Validate::Smtp::Response.new
19
19
  @host = host
20
20
  @email = email
21
21
  @attempts = attempts
22
+ @port_open_status = port_open_status
22
23
  end
23
24
 
24
25
  def check_port
25
- Timeout.timeout(configuration.connection_timeout) do
26
- return response.port_opened = !TCPSocket.new(host, Truemail::Validate::Smtp::Request::SMTP_PORT).close
27
- end
26
+ response.port_opened = ::Socket.tcp(
27
+ host,
28
+ Truemail::Validate::Smtp::Request::SMTP_PORT,
29
+ connect_timeout: configuration.connection_timeout,
30
+ &port_open_status
31
+ )
28
32
  rescue => error
29
- retry if attempts_exist? && error.is_a?(Timeout::Error)
33
+ retry if attempts_exist? && error.is_a?(::Errno::ETIMEDOUT)
30
34
  response.port_opened = false
31
35
  end
32
36
 
@@ -53,7 +57,7 @@ module Truemail
53
57
  end
54
58
  end
55
59
 
56
- attr_reader :attempts
60
+ attr_reader :attempts, :port_open_status
57
61
 
58
62
  def attempts_exist?
59
63
  return false unless attempts
@@ -61,7 +65,7 @@ module Truemail
61
65
  end
62
66
 
63
67
  def session
64
- Net::SMTP.new(host, Truemail::Validate::Smtp::Request::SMTP_PORT).tap do |settings|
68
+ ::Net::SMTP.new(host, Truemail::Validate::Smtp::Request::SMTP_PORT).tap do |settings|
65
69
  settings.open_timeout = configuration.connection_timeout
66
70
  settings.read_timeout = configuration.response_timeout
67
71
  end
@@ -5,7 +5,7 @@ module Truemail
5
5
  class Smtp
6
6
  RESPONSE_ATTRS = %i[port_opened connection helo mailfrom rcptto errors].freeze
7
7
 
8
- Response = Struct.new(*RESPONSE_ATTRS, keyword_init: true) do
8
+ Response = ::Struct.new(*RESPONSE_ATTRS, keyword_init: true) do
9
9
  def initialize(errors: {}, **args)
10
10
  super
11
11
  end
@@ -5,13 +5,13 @@ module Truemail
5
5
  RESULT_ATTRS = %i[success email domain mail_servers errors smtp_debug configuration].freeze
6
6
  VALIDATION_TYPES = %i[regex mx smtp].freeze
7
7
 
8
- Result = Struct.new(*RESULT_ATTRS, keyword_init: true) do
8
+ Result = ::Struct.new(*RESULT_ATTRS, keyword_init: true) do
9
9
  def initialize(mail_servers: [], errors: {}, **args)
10
10
  super
11
11
  end
12
12
 
13
13
  def punycode_email
14
- @punycode_email ||= Truemail::PunycodeRepresenter.call(email)
14
+ @punycode_email ||= Truemail::Dns::PunycodeRepresenter.call(email)
15
15
  end
16
16
  alias_method :valid?, :success
17
17
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Truemail
4
- VERSION = '2.1.0'
4
+ VERSION = '2.3.0'
5
5
  end
@@ -15,10 +15,10 @@ module Truemail
15
15
  end
16
16
 
17
17
  def call(&block)
18
- Timeout.timeout(timeout, &block)
19
- rescue Resolv::ResolvError, IPAddr::InvalidAddressError
18
+ ::Timeout.timeout(timeout, &block)
19
+ rescue ::Resolv::ResolvError, ::IPAddr::InvalidAddressError
20
20
  false
21
- rescue Timeout::Error
21
+ rescue ::Timeout::Error
22
22
  retry unless (self.attempts -= 1).zero?
23
23
  false
24
24
  end
data/truemail.gemspec CHANGED
@@ -31,21 +31,23 @@ Gem::Specification.new do |spec|
31
31
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
32
32
  spec.require_paths = ['lib']
33
33
 
34
- spec.add_runtime_dependency 'simpleidn', '~> 0.1.1'
34
+ spec.add_runtime_dependency 'simpleidn', '~> 0.2.1'
35
35
 
36
36
  spec.add_development_dependency 'bundler', '~> 1.16'
37
37
  spec.add_development_dependency 'bundler-audit', '~> 0.7.0.1'
38
+ spec.add_development_dependency 'dns_mock', '~> 1.2'
39
+ spec.add_development_dependency 'faker', '~> 2.15', '>= 2.15.1'
38
40
  spec.add_development_dependency 'fasterer', '~> 0.8.3'
39
- spec.add_development_dependency 'ffaker', '~> 2.17'
40
41
  spec.add_development_dependency 'json_matchers', '~> 0.11.1'
41
42
  spec.add_development_dependency 'overcommit', '~> 0.57.0'
42
43
  spec.add_development_dependency 'pry-byebug', '~> 3.9'
43
- spec.add_development_dependency 'rake', '~> 13.0', '>= 13.0.1'
44
- spec.add_development_dependency 'reek', '~> 6.0', '>= 6.0.2'
44
+ spec.add_development_dependency 'rake', '~> 13.0', '>= 13.0.3'
45
+ spec.add_development_dependency 'reek', '~> 6.0', '>= 6.0.3'
45
46
  spec.add_development_dependency 'rspec', '~> 3.10'
46
- spec.add_development_dependency 'rubocop', '~> 1.3'
47
- spec.add_development_dependency 'rubocop-performance', '~> 1.8', '>= 1.8.1'
48
- spec.add_development_dependency 'rubocop-rspec', '~> 2.0'
47
+ spec.add_development_dependency 'rubocop', '~> 1.9', '>= 1.9.1'
48
+ spec.add_development_dependency 'rubocop-performance', '~> 1.9', '>= 1.9.2'
49
+ spec.add_development_dependency 'rubocop-rspec', '~> 2.2'
49
50
  spec.add_development_dependency 'simplecov', '~> 0.17.1'
50
- spec.add_development_dependency 'truemail-rspec', '~> 0.2.1'
51
+ spec.add_development_dependency 'truemail-rspec', '~> 0.3.3'
52
+ spec.add_development_dependency 'webmock', '~> 3.11', '>= 3.11.2'
51
53
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: truemail
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladislav Trotsenko
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-11-21 00:00:00.000000000 Z
11
+ date: 2021-02-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: simpleidn
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.1.1
19
+ version: 0.2.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.1.1
26
+ version: 0.2.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -53,33 +53,53 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: 0.7.0.1
55
55
  - !ruby/object:Gem::Dependency
56
- name: fasterer
56
+ name: dns_mock
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.8.3
61
+ version: '1.2'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 0.8.3
68
+ version: '1.2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: faker
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.15'
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: 2.15.1
79
+ type: :development
80
+ prerelease: false
81
+ version_requirements: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - "~>"
84
+ - !ruby/object:Gem::Version
85
+ version: '2.15'
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: 2.15.1
69
89
  - !ruby/object:Gem::Dependency
70
- name: ffaker
90
+ name: fasterer
71
91
  requirement: !ruby/object:Gem::Requirement
72
92
  requirements:
73
93
  - - "~>"
74
94
  - !ruby/object:Gem::Version
75
- version: '2.17'
95
+ version: 0.8.3
76
96
  type: :development
77
97
  prerelease: false
78
98
  version_requirements: !ruby/object:Gem::Requirement
79
99
  requirements:
80
100
  - - "~>"
81
101
  - !ruby/object:Gem::Version
82
- version: '2.17'
102
+ version: 0.8.3
83
103
  - !ruby/object:Gem::Dependency
84
104
  name: json_matchers
85
105
  requirement: !ruby/object:Gem::Requirement
@@ -131,7 +151,7 @@ dependencies:
131
151
  version: '13.0'
132
152
  - - ">="
133
153
  - !ruby/object:Gem::Version
134
- version: 13.0.1
154
+ version: 13.0.3
135
155
  type: :development
136
156
  prerelease: false
137
157
  version_requirements: !ruby/object:Gem::Requirement
@@ -141,7 +161,7 @@ dependencies:
141
161
  version: '13.0'
142
162
  - - ">="
143
163
  - !ruby/object:Gem::Version
144
- version: 13.0.1
164
+ version: 13.0.3
145
165
  - !ruby/object:Gem::Dependency
146
166
  name: reek
147
167
  requirement: !ruby/object:Gem::Requirement
@@ -151,7 +171,7 @@ dependencies:
151
171
  version: '6.0'
152
172
  - - ">="
153
173
  - !ruby/object:Gem::Version
154
- version: 6.0.2
174
+ version: 6.0.3
155
175
  type: :development
156
176
  prerelease: false
157
177
  version_requirements: !ruby/object:Gem::Requirement
@@ -161,7 +181,7 @@ dependencies:
161
181
  version: '6.0'
162
182
  - - ">="
163
183
  - !ruby/object:Gem::Version
164
- version: 6.0.2
184
+ version: 6.0.3
165
185
  - !ruby/object:Gem::Dependency
166
186
  name: rspec
167
187
  requirement: !ruby/object:Gem::Requirement
@@ -182,48 +202,54 @@ dependencies:
182
202
  requirements:
183
203
  - - "~>"
184
204
  - !ruby/object:Gem::Version
185
- version: '1.3'
205
+ version: '1.9'
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: 1.9.1
186
209
  type: :development
187
210
  prerelease: false
188
211
  version_requirements: !ruby/object:Gem::Requirement
189
212
  requirements:
190
213
  - - "~>"
191
214
  - !ruby/object:Gem::Version
192
- version: '1.3'
215
+ version: '1.9'
216
+ - - ">="
217
+ - !ruby/object:Gem::Version
218
+ version: 1.9.1
193
219
  - !ruby/object:Gem::Dependency
194
220
  name: rubocop-performance
195
221
  requirement: !ruby/object:Gem::Requirement
196
222
  requirements:
197
223
  - - "~>"
198
224
  - !ruby/object:Gem::Version
199
- version: '1.8'
225
+ version: '1.9'
200
226
  - - ">="
201
227
  - !ruby/object:Gem::Version
202
- version: 1.8.1
228
+ version: 1.9.2
203
229
  type: :development
204
230
  prerelease: false
205
231
  version_requirements: !ruby/object:Gem::Requirement
206
232
  requirements:
207
233
  - - "~>"
208
234
  - !ruby/object:Gem::Version
209
- version: '1.8'
235
+ version: '1.9'
210
236
  - - ">="
211
237
  - !ruby/object:Gem::Version
212
- version: 1.8.1
238
+ version: 1.9.2
213
239
  - !ruby/object:Gem::Dependency
214
240
  name: rubocop-rspec
215
241
  requirement: !ruby/object:Gem::Requirement
216
242
  requirements:
217
243
  - - "~>"
218
244
  - !ruby/object:Gem::Version
219
- version: '2.0'
245
+ version: '2.2'
220
246
  type: :development
221
247
  prerelease: false
222
248
  version_requirements: !ruby/object:Gem::Requirement
223
249
  requirements:
224
250
  - - "~>"
225
251
  - !ruby/object:Gem::Version
226
- version: '2.0'
252
+ version: '2.2'
227
253
  - !ruby/object:Gem::Dependency
228
254
  name: simplecov
229
255
  requirement: !ruby/object:Gem::Requirement
@@ -244,14 +270,34 @@ dependencies:
244
270
  requirements:
245
271
  - - "~>"
246
272
  - !ruby/object:Gem::Version
247
- version: 0.2.1
273
+ version: 0.3.3
248
274
  type: :development
249
275
  prerelease: false
250
276
  version_requirements: !ruby/object:Gem::Requirement
251
277
  requirements:
252
278
  - - "~>"
253
279
  - !ruby/object:Gem::Version
254
- version: 0.2.1
280
+ version: 0.3.3
281
+ - !ruby/object:Gem::Dependency
282
+ name: webmock
283
+ requirement: !ruby/object:Gem::Requirement
284
+ requirements:
285
+ - - "~>"
286
+ - !ruby/object:Gem::Version
287
+ version: '3.11'
288
+ - - ">="
289
+ - !ruby/object:Gem::Version
290
+ version: 3.11.2
291
+ type: :development
292
+ prerelease: false
293
+ version_requirements: !ruby/object:Gem::Requirement
294
+ requirements:
295
+ - - "~>"
296
+ - !ruby/object:Gem::Version
297
+ version: '3.11'
298
+ - - ">="
299
+ - !ruby/object:Gem::Version
300
+ version: 3.11.2
255
301
  description: Configurable framework agnostic plain Ruby email validator. Verify email
256
302
  via Regex, DNS and SMTP.
257
303
  email:
@@ -293,6 +339,9 @@ files:
293
339
  - lib/truemail/auditor.rb
294
340
  - lib/truemail/configuration.rb
295
341
  - lib/truemail/core.rb
342
+ - lib/truemail/dns/punycode_representer.rb
343
+ - lib/truemail/dns/resolver.rb
344
+ - lib/truemail/dns/worker.rb
296
345
  - lib/truemail/executor.rb
297
346
  - lib/truemail/log/event.rb
298
347
  - lib/truemail/log/serializer/auditor_json.rb