puppet 5.5.0-x64-mingw32 → 5.5.1-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

Files changed (94) hide show
  1. data/Rakefile +1 -1
  2. data/ext/upload_facts.rb +1 -1
  3. data/lib/hiera/scope.rb +24 -2
  4. data/lib/puppet.rb +1 -1
  5. data/lib/puppet/application.rb +2 -2
  6. data/lib/puppet/application/face_base.rb +1 -1
  7. data/lib/puppet/application/resource.rb +1 -1
  8. data/lib/puppet/configurer.rb +15 -12
  9. data/lib/puppet/context.rb +1 -1
  10. data/lib/puppet/error.rb +2 -7
  11. data/lib/puppet/face/config.rb +10 -4
  12. data/lib/puppet/functions/break.rb +3 -7
  13. data/lib/puppet/functions/empty.rb +1 -3
  14. data/lib/puppet/functions/next.rb +1 -8
  15. data/lib/puppet/functions/return.rb +1 -8
  16. data/lib/puppet/functions/strftime.rb +1 -7
  17. data/lib/puppet/indirector/request.rb +6 -10
  18. data/lib/puppet/indirector/rest.rb +9 -9
  19. data/lib/puppet/module_tool/dependency.rb +1 -1
  20. data/lib/puppet/network/http/compression.rb +1 -1
  21. data/lib/puppet/network/http/connection.rb +8 -0
  22. data/lib/puppet/parser/compiler/catalog_validator/relationship_validator.rb +9 -2
  23. data/lib/puppet/parser/functions/create_resources.rb +1 -7
  24. data/lib/puppet/parser/functions/return.rb +22 -1
  25. data/lib/puppet/parser/scope.rb +2 -2
  26. data/lib/puppet/pops/evaluator/runtime3_support.rb +2 -7
  27. data/lib/puppet/pops/parser/epp_parser.rb +1 -1
  28. data/lib/puppet/pops/parser/lexer2.rb +1 -1
  29. data/lib/puppet/pops/puppet_stack.rb +15 -1
  30. data/lib/puppet/pops/serialization/to_data_converter.rb +5 -5
  31. data/lib/puppet/provider/augeas/augeas.rb +7 -0
  32. data/lib/puppet/provider/service/systemd.rb +1 -1
  33. data/lib/puppet/provider/user/aix.rb +1 -1
  34. data/lib/puppet/provider/yumrepo/inifile.rb +1 -0
  35. data/lib/puppet/settings.rb +9 -5
  36. data/lib/puppet/transaction/report.rb +0 -2
  37. data/lib/puppet/type/tidy.rb +4 -0
  38. data/lib/puppet/type/user.rb +34 -3
  39. data/lib/puppet/type/yumrepo.rb +4 -9
  40. data/lib/puppet/util/checksums.rb +0 -2
  41. data/lib/puppet/util/instance_loader.rb +1 -1
  42. data/lib/puppet/util/json.rb +9 -0
  43. data/lib/puppet/util/tagging.rb +16 -3
  44. data/lib/puppet/version.rb +1 -1
  45. data/locales/ja/puppet.po +318 -245
  46. data/locales/puppet.pot +65 -65
  47. data/man/man5/puppet.conf.5 +2 -2
  48. data/man/man8/puppet-agent.8 +1 -1
  49. data/man/man8/puppet-apply.8 +1 -1
  50. data/man/man8/puppet-ca.8 +1 -1
  51. data/man/man8/puppet-catalog.8 +1 -1
  52. data/man/man8/puppet-cert.8 +1 -1
  53. data/man/man8/puppet-certificate.8 +1 -1
  54. data/man/man8/puppet-certificate_request.8 +1 -1
  55. data/man/man8/puppet-certificate_revocation_list.8 +1 -1
  56. data/man/man8/puppet-config.8 +1 -1
  57. data/man/man8/puppet-describe.8 +1 -1
  58. data/man/man8/puppet-device.8 +1 -1
  59. data/man/man8/puppet-doc.8 +1 -1
  60. data/man/man8/puppet-epp.8 +1 -1
  61. data/man/man8/puppet-facts.8 +1 -1
  62. data/man/man8/puppet-filebucket.8 +1 -1
  63. data/man/man8/puppet-generate.8 +1 -1
  64. data/man/man8/puppet-help.8 +1 -1
  65. data/man/man8/puppet-key.8 +1 -1
  66. data/man/man8/puppet-lookup.8 +1 -1
  67. data/man/man8/puppet-man.8 +1 -1
  68. data/man/man8/puppet-master.8 +1 -1
  69. data/man/man8/puppet-module.8 +1 -1
  70. data/man/man8/puppet-node.8 +1 -1
  71. data/man/man8/puppet-parser.8 +1 -1
  72. data/man/man8/puppet-plugin.8 +1 -1
  73. data/man/man8/puppet-report.8 +1 -1
  74. data/man/man8/puppet-resource.8 +1 -1
  75. data/man/man8/puppet-script.8 +1 -1
  76. data/man/man8/puppet-status.8 +1 -1
  77. data/man/man8/puppet.8 +2 -2
  78. data/spec/integration/parser/compiler_spec.rb +9 -0
  79. data/spec/unit/configurer_spec.rb +31 -3
  80. data/spec/unit/face/config_spec.rb +37 -21
  81. data/spec/unit/functions/empty_spec.rb +2 -2
  82. data/spec/unit/functions/epp_spec.rb +5 -2
  83. data/spec/unit/indirector/rest_spec.rb +43 -0
  84. data/spec/unit/parser/functions/create_resources_spec.rb +1 -1
  85. data/spec/unit/pops/puppet_stack_spec.rb +38 -9
  86. data/spec/unit/provider/augeas/augeas_spec.rb +7 -1
  87. data/spec/unit/provider/service/systemd_spec.rb +1 -1
  88. data/spec/unit/provider/yumrepo/inifile_spec.rb +17 -1
  89. data/spec/unit/settings_spec.rb +43 -0
  90. data/spec/unit/transaction/report_spec.rb +1 -25
  91. data/spec/unit/type/tidy_spec.rb +2 -0
  92. data/spec/unit/type/yumrepo_spec.rb +37 -12
  93. data/spec/unit/util/tagging_spec.rb +15 -1
  94. metadata +3428 -3428
data/Rakefile CHANGED
@@ -121,7 +121,7 @@ task(:warnings) do
121
121
  commit_range = ENV['TRAVIS_COMMIT_RANGE'].nil? ? 'master...HEAD' : ENV['TRAVIS_COMMIT_RANGE']
122
122
  ruby_files_ok = true
123
123
  puts "Checking modified files #{commit_range}"
124
- %x{git diff --name-only #{commit_range}}.each_line do |modified_file|
124
+ %x{git diff --diff-filter=ACM --name-only #{commit_range}}.each_line do |modified_file|
125
125
  modified_file.chomp!
126
126
  next unless File.extname(modified_file) == '.rb'
127
127
  puts modified_file
data/ext/upload_facts.rb CHANGED
@@ -102,7 +102,7 @@ HELP
102
102
  files.each do |file|
103
103
  facts = YAML.load_file(file)
104
104
 
105
- request = Puppet::Indirector::Request.new(:facts, :save, facts)
105
+ request = Puppet::Indirector::Request.new(:facts, :save, facts, nil)
106
106
 
107
107
  # The terminus warns for us if we fail.
108
108
  if terminus.save(request)
data/lib/hiera/scope.rb CHANGED
@@ -20,13 +20,35 @@ class Hiera
20
20
  elsif key == CALLING_CLASS_PATH
21
21
  ans = find_hostclass(@real).gsub(/::/, '/')
22
22
  elsif key == CALLING_MODULE
23
- ans = @real.lookupvar(MODULE_NAME)
23
+ ans = safe_lookupvar(MODULE_NAME)
24
24
  else
25
- ans = @real.lookupvar(key)
25
+ ans = safe_lookupvar(key)
26
26
  end
27
27
  ans == EMPTY_STRING ? nil : ans
28
28
  end
29
29
 
30
+ # This method is used to handle the throw of :undefined_variable since when
31
+ # strict variables is not in effect, missing handling of the throw leads to
32
+ # a more expensive code path.
33
+ #
34
+ def safe_lookupvar(key)
35
+ reason = catch :undefined_variable do
36
+ return @real.lookupvar(key)
37
+ end
38
+
39
+ case Puppet[:strict]
40
+ when :off
41
+ # do nothing
42
+ when :warning
43
+ Puppet.warn_once(Puppet::Parser::Scope::UNDEFINED_VARIABLES_KIND, _("Variable: %{name}") % { name: key },
44
+ _("Undefined variable '%{name}'; %{reason}") % { name: key, reason: reason } )
45
+ when :error
46
+ raise ArgumentError, _("Undefined variable '%{name}'; %{reason}") % { name: key, reason: reason }
47
+ end
48
+ nil
49
+ end
50
+ private :safe_lookupvar
51
+
30
52
  def exist?(key)
31
53
  CALLING_KEYS.include?(key) || @real.exist?(key)
32
54
  end
data/lib/puppet.rb CHANGED
@@ -4,7 +4,7 @@ if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new("1.9.3")
4
4
  raise LoadError, _("Puppet %{version} requires ruby 1.9.3 or greater.") % { version: Puppet.version }
5
5
  end
6
6
 
7
- Puppet::OLDEST_RECOMMENDED_RUBY_VERSION = '2.1.0'
7
+ Puppet::OLDEST_RECOMMENDED_RUBY_VERSION = '2.3.0'
8
8
 
9
9
  # see the bottom of the file for further inclusions
10
10
  # Also see the new Vendor support - towards the end
@@ -311,13 +311,13 @@ class Application
311
311
  # handling of this.
312
312
  option("--version", "-V") do |arg|
313
313
  puts "#{Puppet.version}"
314
- exit
314
+ exit(0)
315
315
  end
316
316
 
317
317
  # Every app responds to --help
318
318
  option("--help", "-h") do |v|
319
319
  puts help
320
- exit
320
+ exit(0)
321
321
  end
322
322
 
323
323
  def app_defaults()
@@ -24,7 +24,7 @@ class Puppet::Application::FaceBase < Puppet::Application
24
24
  else
25
25
  puts Puppet::Face[:help, :current].help(face.name)
26
26
  end
27
- exit
27
+ exit(0)
28
28
  end
29
29
 
30
30
  attr_accessor :face, :action, :type, :arguments, :render_as
@@ -21,7 +21,7 @@ class Puppet::Application::Resource < Puppet::Application
21
21
  types << t.name.to_s
22
22
  end
23
23
  puts types.sort
24
- exit
24
+ exit(0)
25
25
  end
26
26
 
27
27
  option("--param PARAM", "-p") do |arg|
@@ -179,18 +179,15 @@ class Puppet::Configurer
179
179
  # Apply supplied catalog and return associated application report
180
180
  def apply_catalog(catalog, options)
181
181
  report = options[:report]
182
- begin
183
- report.configuration_version = catalog.version
182
+ report.configuration_version = catalog.version
184
183
 
185
- benchmark(:notice, _("Applied catalog in %{seconds} seconds")) do
186
- apply_catalog_time = thinmark do
187
- catalog.apply(options)
188
- end
189
- options[:report].add_times(:catalog_application, apply_catalog_time)
184
+ benchmark(:notice, _("Applied catalog in %{seconds} seconds")) do
185
+ apply_catalog_time = thinmark do
186
+ catalog.apply(options)
190
187
  end
191
- ensure
192
- report.finalize_report
188
+ options[:report].add_times(:catalog_application, apply_catalog_time)
193
189
  end
190
+
194
191
  report
195
192
  end
196
193
 
@@ -209,6 +206,7 @@ class Puppet::Configurer
209
206
 
210
207
  Puppet::Util::Log.newdestination(report)
211
208
 
209
+ completed = nil
212
210
  begin
213
211
  Puppet.override(:http_pool => pool) do
214
212
 
@@ -233,18 +231,21 @@ class Puppet::Configurer
233
231
  report.master_used = "#{server[0]}:#{server[1]}"
234
232
  end
235
233
 
236
- run_internal(options.merge(:node => found[:node]))
234
+ completed = run_internal(options.merge(:node => found[:node]))
237
235
  end
238
236
  else
239
- run_internal(options)
237
+ completed = run_internal(options)
240
238
  end
241
239
  end
242
240
  ensure
243
241
  pool.close
244
242
  end
243
+
244
+ completed ? report.exit_status : nil
245
245
  end
246
246
 
247
247
  def run_internal(options)
248
+ start = Time.now
248
249
  report = options[:report]
249
250
 
250
251
  # If a cached catalog is explicitly requested, attempt to retrieve it. Skip the node request,
@@ -366,7 +367,7 @@ class Puppet::Configurer
366
367
  options[:report].catalog_uuid = catalog.catalog_uuid
367
368
  options[:report].cached_catalog_status = @cached_catalog_status
368
369
  apply_catalog(catalog, options)
369
- report.exit_status
370
+ true
370
371
  rescue => detail
371
372
  Puppet.log_exception(detail, _("Failed to apply catalog: %{detail}") % { detail: detail })
372
373
  return nil
@@ -375,6 +376,8 @@ class Puppet::Configurer
375
376
  end
376
377
  ensure
377
378
  report.cached_catalog_status ||= @cached_catalog_status
379
+ report.add_times(:total, Time.now - start)
380
+ report.finalize_report
378
381
  Puppet::Util::Log.close(report)
379
382
  send_report(report)
380
383
  Puppet.pop_context
@@ -52,7 +52,7 @@ class Puppet::Context
52
52
  elsif block
53
53
  block.call
54
54
  else
55
- raise UndefinedBindingError, _("no '%{name}' in %{table} at top of %{stack}") % { name: name, table: @table.inspect, stack: @stack.inspect }
55
+ raise UndefinedBindingError, _("Unable to lookup '%{name}'") % { name: name }
56
56
  end
57
57
  end
58
58
 
data/lib/puppet/error.rb CHANGED
@@ -72,13 +72,8 @@ module Puppet
72
72
  end
73
73
 
74
74
  def self.from_issue_and_stack(issue, args = {})
75
- stacktrace = Puppet::Pops::PuppetStack.stacktrace()
76
- if stacktrace.size > 0
77
- filename, line = stacktrace[0]
78
- else
79
- filename = nil
80
- line = nil
81
- end
75
+ filename, line = Puppet::Pops::PuppetStack.top_of_stack
76
+
82
77
  self.new(
83
78
  issue.format(args),
84
79
  filename,
@@ -85,8 +85,10 @@ Puppet::Face.define(:config, '0.0.1') do
85
85
  # the requested section
86
86
  values = Puppet.settings.values(Puppet[:environment].to_sym, options[:section].to_sym)
87
87
 
88
- warn_default_section(options[:section]) if @default_section
89
- report_section_and_environment(options[:section], Puppet.settings[:environment])
88
+ if Puppet::Util::Log.sendlevel?(:info)
89
+ warn_default_section(options[:section]) if @default_section
90
+ report_section_and_environment(options[:section], Puppet.settings[:environment])
91
+ end
90
92
 
91
93
  to_be_rendered = {}
92
94
  args.sort.each do |setting_name|
@@ -191,7 +193,9 @@ https://puppet.com/docs/puppet/latest/configuration.html#environment
191
193
  EOM
192
194
  end
193
195
 
194
- report_section_and_environment(options[:section], Puppet.settings[:environment])
196
+ if Puppet::Util::Log.sendlevel?(:info)
197
+ report_section_and_environment(options[:section], Puppet.settings[:environment])
198
+ end
195
199
 
196
200
  path = Puppet::FileSystem.pathname(Puppet.settings.which_configuration_file)
197
201
  Puppet::FileSystem.touch(path)
@@ -239,7 +243,9 @@ https://puppet.com/docs/puppet/latest/configuration.html#environment
239
243
  setting_string = config.delete(options[:section], name)
240
244
  if setting_string
241
245
 
242
- report_section_and_environment(options[:section], Puppet.settings[:environment])
246
+ if Puppet::Util::Log.sendlevel?(:info)
247
+ report_section_and_environment(options[:section], Puppet.settings[:environment])
248
+ end
243
249
 
244
250
  puts(_("Deleted setting from '%{section_name}': '%{setting_string}'") %
245
251
  { section_name: options[:section], name: name, setting_string: setting_string.strip })
@@ -36,13 +36,9 @@ Puppet::Functions.create_function(:break) do
36
36
  end
37
37
 
38
38
  def break_impl()
39
- stacktrace = Puppet::Pops::PuppetStack.stacktrace()
40
- if stacktrace.size > 0
41
- file, line = stacktrace[0]
42
- else
43
- file = nil
44
- line = nil
45
- end
39
+ # get file, line if available, else they are set to nil
40
+ file, line = Puppet::Pops::PuppetStack.top_of_stack
41
+
46
42
  # PuppetStopIteration contains file and line and is a StopIteration exception
47
43
  # so it can break a Ruby Kernel#loop or enumeration
48
44
  #
@@ -66,13 +66,11 @@ Puppet::Functions.create_function(:empty) do
66
66
  # (Yes, it is strange, but undef was passed as empty string in 3.x API)
67
67
  #
68
68
  def undef_empty(x)
69
- deprecation_warning_for('Undef')
70
69
  true
71
70
  end
72
71
 
73
72
  def deprecation_warning_for(arg_type)
74
- stacktrace = Puppet::Pops::PuppetStack.stacktrace()
75
- file, line = stacktrace[0] # defaults to nil
73
+ file, line = Puppet::Pops::PuppetStack.top_of_stack
76
74
  msg = _("Calling function empty() with %{arg_type} value is deprecated.") % { arg_type: arg_type }
77
75
  Puppet.warn_once('deprecations', "empty-from-#{file}-#{line}", msg, file, line)
78
76
  end
@@ -9,14 +9,7 @@ Puppet::Functions.create_function(:next) do
9
9
  end
10
10
 
11
11
  def next_impl(value = nil)
12
- stacktrace = Puppet::Pops::PuppetStack.stacktrace()
13
- if stacktrace.size > 0
14
- file, line = stacktrace[0]
15
- else
16
- file = nil
17
- line = nil
18
- end
19
-
12
+ file, line = Puppet::Pops::PuppetStack.top_of_stack
20
13
  exc = Puppet::Pops::Evaluator::Next.new(value, file, line)
21
14
  raise exc
22
15
  end
@@ -9,14 +9,7 @@ Puppet::Functions.create_function(:return, Puppet::Functions::InternalFunction)
9
9
  end
10
10
 
11
11
  def return_impl(value = nil)
12
- stacktrace = Puppet::Pops::PuppetStack.stacktrace()
13
- if stacktrace.size > 0
14
- file, line = stacktrace[0]
15
- else
16
- file = nil
17
- line = nil
18
- end
19
-
12
+ file, line = Puppet::Pops::PuppetStack.top_of_stack
20
13
  raise Puppet::Pops::Evaluator::Return.new(value, file, line)
21
14
  end
22
15
  end
@@ -202,13 +202,7 @@ Puppet::Functions.create_function(:strftime) do
202
202
  end
203
203
 
204
204
  def legacy_strftime(format, timezone = nil)
205
- stacktrace = Puppet::Pops::PuppetStack.stacktrace()
206
- if stacktrace.size > 0
207
- file, line = stacktrace[0]
208
- else
209
- file = nil
210
- line = nil
211
- end
205
+ file, line = Puppet::Pops::PuppetStack.top_of_stack
212
206
  Puppet.warn_once('deprecations', 'legacy#strftime',
213
207
  _('The argument signature (String format, [String timezone]) is deprecated for #strftime. See #strftime documentation and Timespan type for more info'),
214
208
  file, line)
@@ -197,23 +197,19 @@ class Puppet::Indirector::Request
197
197
  end
198
198
 
199
199
  # ... Fall back onto the default server.
200
- begin
201
- bound_server = Puppet.lookup(:server)
202
- rescue
200
+ bound_server = Puppet.lookup(:server) do
203
201
  if primary_server = Puppet.settings[:server_list][0]
204
- bound_server = primary_server[0]
202
+ primary_server[0]
205
203
  else
206
- bound_server = Puppet.settings[:server]
204
+ Puppet.settings[:server]
207
205
  end
208
206
  end
209
207
 
210
- begin
211
- bound_port = Puppet.lookup(:serverport)
212
- rescue
208
+ bound_port = Puppet.lookup(:serverport) do
213
209
  if primary_server = Puppet.settings[:server_list][0]
214
- bound_port = primary_server[1]
210
+ primary_server[1]
215
211
  else
216
- bound_port = Puppet.settings[:masterport]
212
+ Puppet.settings[:masterport]
217
213
  end
218
214
  end
219
215
  self.server = default_server || bound_server
@@ -57,9 +57,7 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus
57
57
  if setting && setting != :server && Puppet.settings.set_by_config?(setting)
58
58
  Puppet.settings[setting]
59
59
  else
60
- begin
61
- Puppet.lookup(:server)
62
- rescue
60
+ server = Puppet.lookup(:server) do
63
61
  if primary_server = Puppet.settings[:server_list][0]
64
62
  Puppet.debug "Dynamically-bound server lookup failed; using first entry"
65
63
  primary_server[0]
@@ -69,6 +67,7 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus
69
67
  Puppet.settings[setting]
70
68
  end
71
69
  end
70
+ server
72
71
  end
73
72
  end
74
73
 
@@ -84,22 +83,21 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus
84
83
  (srv_setting && srv_setting != :server && Puppet.settings.set_by_config?(srv_setting))
85
84
  Puppet.settings[setting].to_i
86
85
  else
87
- begin
88
- Puppet.lookup(:serverport).to_i
89
- rescue
86
+ port = Puppet.lookup(:serverport) do
90
87
  if primary_server = Puppet.settings[:server_list][0]
91
88
  Puppet.debug "Dynamically-bound port lookup failed; using first entry"
92
89
 
93
90
  # Port might not be set, so we want to fallback in that
94
91
  # case. We know we don't need to use `setting` here, since
95
92
  # the default value of every port setting is `masterport`
96
- (primary_server[1] || Puppet.settings[:masterport]).to_i
93
+ (primary_server[1] || Puppet.settings[:masterport])
97
94
  else
98
95
  setting ||= :masterport
99
96
  Puppet.debug "Dynamically-bound port lookup failed; falling back to #{setting} setting"
100
- Puppet.settings[setting].to_i
97
+ Puppet.settings[setting]
101
98
  end
102
99
  end
100
+ port.to_i
103
101
  end
104
102
  end
105
103
 
@@ -263,7 +261,9 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus
263
261
  def handle_response(request, response)
264
262
  server_version = response[Puppet::Network::HTTP::HEADER_PUPPET_VERSION]
265
263
  if server_version
266
- Puppet.push_context({:server_agent_version => server_version})
264
+ Puppet.lookup(:server_agent_version) do
265
+ Puppet.push_context(:server_agent_version => server_version)
266
+ end
267
267
  if SemanticPuppet::Version.parse(server_version).major < MAJOR_VERSION_JSON_DEFAULT &&
268
268
  Puppet[:preferred_serialization_format] != 'pson'
269
269
  #TRANSLATORS "PSON" should not be translated
@@ -16,7 +16,7 @@ module Puppet::ModuleTool
16
16
  # TODO: add error checking, the next line raises ArgumentError when +full_module_name+ is invalid
17
17
  @username, @name = Puppet::ModuleTool.username_and_modname_from(full_module_name)
18
18
  @version_requirement = version_requirement
19
- @repository = repository ? Puppet::Forge::Repository.new(repository) : nil
19
+ @repository = repository ? Puppet::Forge::Repository.new(repository, nil) : nil
20
20
  end
21
21
 
22
22
  # We override Object's ==, eql, and hash so we can more easily find identical
@@ -32,7 +32,7 @@ module Puppet::Network::HTTP::Compression
32
32
  end
33
33
 
34
34
  def uncompress(response)
35
- raise Net::HTTPError.new("No block passed") unless block_given?
35
+ raise Net::HTTPError.new("No block passed", response) unless block_given?
36
36
 
37
37
  case response['content-encoding']
38
38
  when 'gzip','deflate'
@@ -5,6 +5,7 @@ require 'puppet/ssl/validator'
5
5
  require 'puppet/network/http'
6
6
  require 'uri'
7
7
  require 'date'
8
+ require 'time'
8
9
 
9
10
  module Puppet::Network::HTTP
10
11
 
@@ -297,7 +298,14 @@ module Puppet::Network::HTTP
297
298
  end
298
299
 
299
300
  def execute_request(connection, request)
301
+ start = Time.now
300
302
  connection.request(request)
303
+ rescue EOFError => e
304
+ elapsed = (Time.now - start).to_f.round(3)
305
+ uri = @site.addr + request.path.split('?')[0]
306
+ eof = EOFError.new(_('request %{uri} interrupted after %{elapsed} seconds') % {uri: uri, elapsed: elapsed})
307
+ eof.set_backtrace(e.backtrace) unless e.backtrace.empty?
308
+ raise eof
301
309
  end
302
310
 
303
311
  def with_connection(site, &block)