vagrant-unbundled 2.2.18.0 → 2.2.19.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (176) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/Gemfile.lock +6 -6
  4. data/contrib/zsh/generate_zsh_completion.rb +2 -2
  5. data/lib/vagrant/errors.rb +8 -0
  6. data/plugins/commands/upload/command.rb +1 -1
  7. data/plugins/guests/atomic/guest.rb +1 -1
  8. data/plugins/guests/coreos/cap/configure_networks.rb +65 -0
  9. data/plugins/guests/darwin/cap/mount_smb_shared_folder.rb +6 -3
  10. data/plugins/guests/suse/cap/halt.rb +5 -1
  11. data/plugins/guests/windows/cap/rsync.rb +5 -1
  12. data/plugins/hosts/darwin/cap/path.rb +4 -0
  13. data/plugins/hosts/darwin/cap/version.rb +23 -0
  14. data/plugins/hosts/darwin/plugin.rb +5 -0
  15. data/plugins/hosts/windows/cap/ssh.rb +1 -1
  16. data/plugins/providers/virtualbox/action/network.rb +39 -2
  17. data/plugins/provisioners/chef/cap/freebsd/chef_installed.rb +5 -3
  18. data/plugins/provisioners/chef/cap/linux/chef_installed.rb +5 -3
  19. data/plugins/provisioners/chef/cap/omnios/chef_installed.rb +7 -5
  20. data/plugins/provisioners/chef/cap/windows/chef_installed.rb +3 -2
  21. data/templates/locales/en.yml +25 -0
  22. data/vagrant.gemspec +1 -1
  23. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/CONTRIBUTING.md +23 -0
  24. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/CONTRIBUTORS.md +140 -0
  25. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/LICENSE.md +20 -0
  26. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/README.md +492 -0
  27. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/data/cacert.pem +3232 -0
  28. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/excon.gemspec +45 -0
  29. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon/connection.rb +599 -0
  30. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon/constants.rb +172 -0
  31. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon/error.rb +229 -0
  32. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon/extensions/uri.rb +34 -0
  33. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon/headers.rb +85 -0
  34. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon/instrumentors/logging_instrumentor.rb +48 -0
  35. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon/instrumentors/standard_instrumentor.rb +21 -0
  36. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon/middlewares/base.rb +31 -0
  37. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon/middlewares/capture_cookies.rb +32 -0
  38. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon/middlewares/decompress.rb +44 -0
  39. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon/middlewares/escape_path.rb +12 -0
  40. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon/middlewares/expects.rb +25 -0
  41. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon/middlewares/idempotent.rb +57 -0
  42. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon/middlewares/instrumentor.rb +49 -0
  43. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon/middlewares/mock.rb +61 -0
  44. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon/middlewares/redirect_follower.rb +87 -0
  45. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon/middlewares/response_parser.rb +16 -0
  46. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon/pretty_printer.rb +39 -0
  47. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon/response.rb +234 -0
  48. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon/socket.rb +297 -0
  49. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon/ssl_socket.rb +194 -0
  50. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon/test/plugin/server/exec.rb +26 -0
  51. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon/test/plugin/server/puma.rb +23 -0
  52. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon/test/plugin/server/unicorn.rb +40 -0
  53. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon/test/plugin/server/webrick.rb +26 -0
  54. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon/test/server.rb +106 -0
  55. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon/unix_socket.rb +42 -0
  56. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon/utils.rb +143 -0
  57. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon/version.rb +4 -0
  58. data/vendor/bundle/ruby/3.0.0/gems/excon-0.89.0/lib/excon.rb +255 -0
  59. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/MIT-LICENSE +20 -0
  60. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/README.md +122 -0
  61. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/backend/base.rb +289 -0
  62. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/backend/cache.rb +113 -0
  63. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/backend/cache_file.rb +36 -0
  64. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/backend/cascade.rb +56 -0
  65. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/backend/chain.rb +130 -0
  66. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/backend/fallbacks.rb +97 -0
  67. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/backend/flatten.rb +118 -0
  68. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/backend/gettext.rb +85 -0
  69. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/backend/interpolation_compiler.rb +123 -0
  70. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/backend/key_value.rb +206 -0
  71. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/backend/memoize.rb +54 -0
  72. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/backend/metadata.rb +71 -0
  73. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/backend/pluralization.rb +55 -0
  74. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/backend/simple.rb +108 -0
  75. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/backend/transliterator.rb +108 -0
  76. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/backend.rb +21 -0
  77. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/config.rb +165 -0
  78. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/core_ext/hash.rb +59 -0
  79. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/exceptions.rb +111 -0
  80. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/gettext/helpers.rb +75 -0
  81. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/gettext/po_parser.rb +329 -0
  82. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/gettext.rb +28 -0
  83. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/interpolate/ruby.rb +39 -0
  84. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/locale/fallbacks.rb +99 -0
  85. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/locale/tag/parents.rb +24 -0
  86. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/locale/tag/rfc4646.rb +74 -0
  87. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/locale/tag/simple.rb +39 -0
  88. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/locale/tag.rb +28 -0
  89. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/locale.rb +8 -0
  90. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/middleware.rb +17 -0
  91. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/tests/basics.rb +60 -0
  92. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/tests/defaults.rb +52 -0
  93. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/tests/interpolation.rb +163 -0
  94. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/tests/link.rb +66 -0
  95. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/tests/localization/date.rb +117 -0
  96. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/tests/localization/date_time.rb +103 -0
  97. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/tests/localization/procs.rb +117 -0
  98. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/tests/localization/time.rb +103 -0
  99. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/tests/localization.rb +19 -0
  100. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/tests/lookup.rb +81 -0
  101. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/tests/pluralization.rb +35 -0
  102. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/tests/procs.rb +60 -0
  103. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/tests.rb +14 -0
  104. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n/version.rb +5 -0
  105. data/vendor/bundle/ruby/3.0.0/gems/i18n-1.8.11/lib/i18n.rb +415 -0
  106. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/Code-of-Conduct.md +73 -0
  107. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/Contributing.md +132 -0
  108. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/History.md +269 -0
  109. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/Licence.md +25 -0
  110. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/Manifest.txt +31 -0
  111. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/README.rdoc +194 -0
  112. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/Rakefile +270 -0
  113. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/lib/mime/type/columnar.rb +57 -0
  114. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/lib/mime/type.rb +634 -0
  115. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/lib/mime/types/_columnar.rb +137 -0
  116. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/lib/mime/types/cache.rb +58 -0
  117. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/lib/mime/types/columnar.rb +3 -0
  118. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/lib/mime/types/container.rb +96 -0
  119. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/lib/mime/types/deprecations.rb +36 -0
  120. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/lib/mime/types/full.rb +19 -0
  121. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/lib/mime/types/loader.rb +159 -0
  122. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/lib/mime/types/logger.rb +37 -0
  123. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/lib/mime/types/registry.rb +90 -0
  124. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/lib/mime/types.rb +233 -0
  125. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/lib/mime-types.rb +3 -0
  126. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/test/bad-fixtures/malformed +9 -0
  127. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/test/fixture/json.json +1 -0
  128. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/test/fixture/old-data +9 -0
  129. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/test/fixture/yaml.yaml +55 -0
  130. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/test/minitest_helper.rb +11 -0
  131. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/test/test_mime_type.rb +621 -0
  132. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/test/test_mime_types.rb +169 -0
  133. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/test/test_mime_types_cache.rb +118 -0
  134. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/test/test_mime_types_class.rb +159 -0
  135. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/test/test_mime_types_lazy.rb +49 -0
  136. data/vendor/bundle/ruby/3.0.0/gems/mime-types-3.4.1/test/test_mime_types_loader.rb +32 -0
  137. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/Code-of-Conduct.md +75 -0
  138. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/Contributing.md +241 -0
  139. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/History.md +494 -0
  140. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/Licence.md +24 -0
  141. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/Manifest.txt +34 -0
  142. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/README.md +73 -0
  143. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/Rakefile +155 -0
  144. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/data/content_type_mime.db +878 -0
  145. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/data/ext_mime.db +1198 -0
  146. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/data/mime-types.json +1 -0
  147. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/data/mime.content_type.column +2376 -0
  148. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/data/mime.docs.column +2376 -0
  149. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/data/mime.encoding.column +2376 -0
  150. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/data/mime.flags.column +2376 -0
  151. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/data/mime.friendly.column +2376 -0
  152. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/data/mime.pext.column +2376 -0
  153. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/data/mime.use_instead.column +2376 -0
  154. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/data/mime.xrefs.column +2376 -0
  155. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/lib/mime/types/data.rb +21 -0
  156. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/lib/mime-types-data.rb +3 -0
  157. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/types/application.yaml +17254 -0
  158. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/types/audio.yaml +1716 -0
  159. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/types/chemical.yaml +71 -0
  160. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/types/conference.yaml +9 -0
  161. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/types/drawing.yaml +15 -0
  162. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/types/font.yaml +65 -0
  163. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/types/image.yaml +1251 -0
  164. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/types/message.yaml +200 -0
  165. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/types/model.yaml +390 -0
  166. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/types/multipart.yaml +179 -0
  167. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/types/provisional-standard-types.yaml +129 -0
  168. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/types/text.yaml +1166 -0
  169. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/types/video.yaml +1121 -0
  170. data/vendor/bundle/ruby/3.0.0/gems/mime-types-data-3.2021.1115/types/world.yaml +8 -0
  171. data/vendor/bundle/ruby/3.0.0/specifications/excon-0.89.0.gemspec +58 -0
  172. data/vendor/bundle/ruby/3.0.0/specifications/i18n-1.8.11.gemspec +32 -0
  173. data/vendor/bundle/ruby/3.0.0/specifications/mime-types-3.4.1.gemspec +63 -0
  174. data/vendor/bundle/ruby/3.0.0/specifications/mime-types-data-3.2021.1115.gemspec +54 -0
  175. data/version.txt +1 -1
  176. metadata +157 -4
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+ module Excon
3
+ module Middleware
4
+ class Decompress < Excon::Middleware::Base
5
+
6
+ INFLATE_ZLIB_OR_GZIP = 47 # Zlib::MAX_WBITS + 32
7
+ INFLATE_RAW = -15 # Zlib::MAX_WBITS * -1
8
+
9
+ def request_call(datum)
10
+ unless datum.has_key?(:response_block)
11
+ key = datum[:headers].keys.detect {|k| k.to_s.casecmp('Accept-Encoding') == 0 } || 'Accept-Encoding'
12
+ if datum[:headers][key].to_s.empty?
13
+ datum[:headers][key] = 'deflate, gzip'
14
+ end
15
+ end
16
+ @stack.request_call(datum)
17
+ end
18
+
19
+ def response_call(datum)
20
+ body = datum[:response][:body]
21
+ unless datum.has_key?(:response_block) || body.nil? || body.empty?
22
+ if (key = datum[:response][:headers].keys.detect {|k| k.casecmp('Content-Encoding') == 0 })
23
+ encodings = Utils.split_header_value(datum[:response][:headers][key])
24
+ if (encoding = encodings.last)
25
+ if encoding.casecmp('deflate') == 0
26
+ datum[:response][:body] = begin
27
+ Zlib::Inflate.new(INFLATE_ZLIB_OR_GZIP).inflate(body)
28
+ rescue Zlib::DataError # fallback to raw on error
29
+ Zlib::Inflate.new(INFLATE_RAW).inflate(body)
30
+ end
31
+ encodings.pop
32
+ elsif encoding.casecmp('gzip') == 0 || encoding.casecmp('x-gzip') == 0
33
+ datum[:response][:body] = Zlib::GzipReader.new(StringIO.new(body)).read
34
+ encodings.pop
35
+ end
36
+ datum[:response][:headers][key] = encodings.join(', ')
37
+ end
38
+ end
39
+ end
40
+ @stack.response_call(datum)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+ module Excon
3
+ module Middleware
4
+ class EscapePath < Excon::Middleware::Base
5
+ def request_call(datum)
6
+ # make sure path is encoded, prevent double encoding
7
+ datum[:path] = Excon::Utils.escape_uri(Excon::Utils.unescape_uri(datum[:path]))
8
+ @stack.request_call(datum)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+ module Excon
3
+ module Middleware
4
+ class Expects < Excon::Middleware::Base
5
+ def self.valid_parameter_keys
6
+ [
7
+ :expects
8
+ ]
9
+ end
10
+
11
+ def response_call(datum)
12
+ if datum.has_key?(:expects) && ![*datum[:expects]].include?(datum[:response][:status])
13
+ raise(
14
+ Excon::Errors.status_error(
15
+ datum.reject {|key,_| key == :response},
16
+ Excon::Response.new(datum[:response])
17
+ )
18
+ )
19
+ else
20
+ @stack.response_call(datum)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+ require 'set'
3
+
4
+ module Excon
5
+ module Middleware
6
+ class Idempotent < Excon::Middleware::Base
7
+ def self.valid_parameter_keys
8
+ [
9
+ :idempotent,
10
+ :retries_remaining,
11
+ :retry_errors,
12
+ :retry_interval,
13
+ :retry_limit
14
+ ]
15
+ end
16
+
17
+ def request_call(datum)
18
+ datum[:retries_remaining] ||= datum[:retry_limit]
19
+ @stack.request_call(datum)
20
+ end
21
+
22
+ def error_call(datum)
23
+ if datum[:idempotent]
24
+ if datum.has_key?(:request_block)
25
+ if datum[:request_block].respond_to?(:rewind)
26
+ datum[:request_block].rewind
27
+ else
28
+ Excon.display_warning('Excon requests with a :request_block must implement #rewind in order to be :idempotent.')
29
+ datum[:idempotent] = false
30
+ end
31
+ end
32
+ if datum.has_key?(:response_block) && datum[:response_block].respond_to?(:rewind)
33
+ datum[:response_block].rewind
34
+ end
35
+ if datum.has_key?(:pipeline)
36
+ Excon.display_warning("Excon requests can not be :idempotent when pipelining.")
37
+ datum[:idempotent] = false
38
+ end
39
+ end
40
+
41
+ if datum[:idempotent] && datum[:retry_errors].any? {|ex| datum[:error].kind_of?(ex) } && datum[:retries_remaining] > 1
42
+
43
+ sleep(datum[:retry_interval]) if datum[:retry_interval]
44
+
45
+ # reduces remaining retries, reset connection, and restart request_call
46
+ datum[:retries_remaining] -= 1
47
+ connection = datum.delete(:connection)
48
+ valid_keys = Set.new(connection.valid_request_keys(datum[:middlewares]))
49
+ datum.select! {|key, _| valid_keys.include?(key) }
50
+ connection.request(datum)
51
+ else
52
+ @stack.error_call(datum)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+ module Excon
3
+ module Middleware
4
+ class Instrumentor < Excon::Middleware::Base
5
+ def self.valid_parameter_keys
6
+ [
7
+ :logger,
8
+ :instrumentor,
9
+ :instrumentor_name
10
+ ]
11
+ end
12
+
13
+ def error_call(datum)
14
+ if datum.has_key?(:instrumentor)
15
+ datum[:instrumentor].instrument("#{datum[:instrumentor_name]}.error", :error => datum[:error]) do
16
+ @stack.error_call(datum)
17
+ end
18
+ else
19
+ @stack.error_call(datum)
20
+ end
21
+ end
22
+
23
+ def request_call(datum)
24
+ if datum.has_key?(:instrumentor)
25
+ if datum[:retries_remaining] < datum[:retry_limit]
26
+ event_name = "#{datum[:instrumentor_name]}.retry"
27
+ else
28
+ event_name = "#{datum[:instrumentor_name]}.request"
29
+ end
30
+ datum[:instrumentor].instrument(event_name, datum) do
31
+ @stack.request_call(datum)
32
+ end
33
+ else
34
+ @stack.request_call(datum)
35
+ end
36
+ end
37
+
38
+ def response_call(datum)
39
+ if datum.has_key?(:instrumentor)
40
+ datum[:instrumentor].instrument("#{datum[:instrumentor_name]}.response", datum[:response]) do
41
+ @stack.response_call(datum)
42
+ end
43
+ else
44
+ @stack.response_call(datum)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+ module Excon
3
+ module Middleware
4
+ class Mock < Excon::Middleware::Base
5
+ def self.valid_parameter_keys
6
+ [
7
+ :allow_unstubbed_requests,
8
+ :captures,
9
+ :mock
10
+ ]
11
+ end
12
+
13
+ def request_call(datum)
14
+ if datum[:mock]
15
+ # convert File/Tempfile body to string before matching:
16
+ if datum[:body].respond_to?(:read)
17
+ if datum[:body].respond_to?(:binmode)
18
+ datum[:body].binmode
19
+ end
20
+ if datum[:body].respond_to?(:rewind)
21
+ datum[:body].rewind
22
+ end
23
+ datum[:body] = datum[:body].read
24
+ elsif !datum[:body].nil? && !datum[:body].is_a?(String)
25
+ raise Excon::Errors::InvalidStub.new("Request body should be a string or an IO object. #{datum[:body].class} provided")
26
+ end
27
+
28
+ if (stub = Excon.stub_for(datum))
29
+ datum[:remote_ip] ||= '127.0.0.1'
30
+ datum[:response] = {
31
+ :body => '',
32
+ :headers => {},
33
+ :status => 200,
34
+ :remote_ip => datum[:remote_ip]
35
+ }
36
+
37
+ stub_datum = case stub.last
38
+ when Proc
39
+ stub.last.call(datum)
40
+ else
41
+ stub.last
42
+ end
43
+
44
+ datum[:response].merge!(stub_datum.reject {|key,_| key == :headers})
45
+ if stub_datum.has_key?(:headers)
46
+ datum[:response][:headers].merge!(stub_datum[:headers])
47
+ end
48
+ elsif datum[:allow_unstubbed_requests] != true
49
+ # if we reach here no stubs matched
50
+ message = StringIO.new
51
+ message.puts('no stubs matched')
52
+ Excon::PrettyPrinter.pp(message, datum)
53
+ raise(Excon::Errors::StubNotFound.new(message.string))
54
+ end
55
+ end
56
+
57
+ @stack.request_call(datum)
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+ module Excon
3
+ module Middleware
4
+ class RedirectFollower < Excon::Middleware::Base
5
+ def self.valid_parameter_keys
6
+ [
7
+ :redirects_remaining,
8
+ :redirect_limit
9
+ ]
10
+ end
11
+
12
+ def request_call(datum)
13
+ datum[:redirects_remaining] ||= datum[:redirect_limit] ||
14
+ Excon::DEFAULT_REDIRECT_LIMIT
15
+ @stack.request_call(datum)
16
+ end
17
+
18
+ def get_header(datum, header)
19
+ _, header_value = datum[:response][:headers].detect do |key, _|
20
+ key.casecmp(header) == 0
21
+ end
22
+ header_value
23
+ end
24
+
25
+ def response_call(datum)
26
+ if datum.has_key?(:response)
27
+ case datum[:response][:status]
28
+ when 301, 302, 303, 307, 308
29
+ if datum[:redirects_remaining] <= 0
30
+ raise Excon::Errors::TooManyRedirects
31
+ end
32
+
33
+ datum[:redirects_remaining] -= 1
34
+
35
+ uri_parser = datum[:uri_parser] || Excon.defaults[:uri_parser]
36
+
37
+ location = get_header(datum, 'Location')
38
+ base_uri = Excon::Utils.request_uri(datum)
39
+ uri = uri_parser.join(base_uri, location)
40
+
41
+ # delete old/redirect response and remote_ip
42
+ response = datum.delete(:response)
43
+ datum.delete(:remote_ip)
44
+
45
+ params = datum.dup
46
+ params.delete(:connection)
47
+ params.delete(:password)
48
+ params.delete(:stack)
49
+ params.delete(:user)
50
+
51
+ if [301, 302, 303].include?(response[:status])
52
+ params[:method] = :get
53
+ params.delete(:body)
54
+ params[:headers].delete('Content-Length')
55
+ end
56
+ params[:headers] = datum[:headers].dup
57
+ params[:headers].delete('Authorization')
58
+ params[:headers].delete('Proxy-Connection')
59
+ params[:headers].delete('Proxy-Authorization')
60
+ params[:headers].delete('Host')
61
+ params.merge!(
62
+ :scheme => uri.scheme || datum[:scheme],
63
+ :host => uri.host || datum[:host],
64
+ :hostname => uri.hostname || datum[:hostname],
65
+ :port => uri.port || datum[:port],
66
+ :path => uri.path,
67
+ :query => uri.query
68
+ )
69
+
70
+ params.merge!(:user => Utils.unescape_uri(uri.user)) if uri.user
71
+ params.merge!(:password => Utils.unescape_uri(uri.password)) if uri.password
72
+
73
+ response = Excon::Connection.new(params).request
74
+ datum.merge!({
75
+ :remote_ip => response.remote_ip,
76
+ :response => response.data
77
+ })
78
+ else
79
+ @stack.response_call(datum)
80
+ end
81
+ else
82
+ @stack.response_call(datum)
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+ module Excon
3
+ module Middleware
4
+ class ResponseParser < Excon::Middleware::Base
5
+ def response_call(datum)
6
+ unless datum.has_key?(:response)
7
+ datum = Excon::Response.parse(datum[:connection].send(:socket), datum)
8
+ end
9
+ if datum.has_key?(:logger)
10
+ datum[:response][:logger] = datum[:logger]
11
+ end
12
+ @stack.response_call(datum)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+ module Excon
3
+ class PrettyPrinter
4
+ def self.pp(io, datum, indent=0)
5
+ datum = datum.dup
6
+
7
+ # reduce duplication/noise of output
8
+ unless datum.is_a?(Excon::Headers)
9
+ datum.delete(:connection)
10
+ datum.delete(:stack)
11
+
12
+ datum = Utils.redact(datum)
13
+ end
14
+
15
+ indent += 2
16
+ max_key_length = datum.keys.map {|key| key.inspect.length}.max
17
+ datum.keys.sort_by {|key| key.to_s}.each do |key|
18
+ value = datum[key]
19
+ io.write("#{' ' * indent}#{key.inspect.ljust(max_key_length)} => ")
20
+ case value
21
+ when Array
22
+ io.puts("[")
23
+ value.each do |v|
24
+ io.puts("#{' ' * indent} #{v.inspect}")
25
+ end
26
+ io.write("#{' ' * indent}]")
27
+ when Hash
28
+ io.puts("{")
29
+ self.pp(io, value, indent)
30
+ io.write("#{' ' * indent}}")
31
+ else
32
+ io.write("#{value.inspect}")
33
+ end
34
+ io.puts
35
+ end
36
+ indent -= 2
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,234 @@
1
+ # frozen_string_literal: true
2
+ module Excon
3
+ class Response
4
+
5
+ attr_accessor :data
6
+
7
+ # backwards compatability reader/writers
8
+ def body=(new_body)
9
+ @data[:body] = new_body
10
+ end
11
+ def body
12
+ @data[:body]
13
+ end
14
+ def headers=(new_headers)
15
+ @data[:headers] = new_headers
16
+ end
17
+ def headers
18
+ @data[:headers]
19
+ end
20
+ def host
21
+ @data[:host]
22
+ end
23
+ def local_address
24
+ @data[:local_address]
25
+ end
26
+ def local_port
27
+ @data[:local_port]
28
+ end
29
+ def path
30
+ @data[:path]
31
+ end
32
+ def port
33
+ @data[:port]
34
+ end
35
+ def reason_phrase=(new_reason_phrase)
36
+ @data[:reason_phrase] = new_reason_phrase
37
+ end
38
+ def reason_phrase
39
+ @data[:reason_phrase]
40
+ end
41
+ def remote_ip=(new_remote_ip)
42
+ @data[:remote_ip] = new_remote_ip
43
+ end
44
+ def remote_ip
45
+ @data[:remote_ip]
46
+ end
47
+ def status=(new_status)
48
+ @data[:status] = new_status
49
+ end
50
+ def status
51
+ @data[:status]
52
+ end
53
+ def status_line
54
+ @data[:status_line]
55
+ end
56
+ def status_line=(new_status_line)
57
+ @data[:status_line] = new_status_line
58
+ end
59
+
60
+ def self.parse(socket, datum)
61
+ # this will discard any trailing lines from the previous response if any.
62
+ line = nil
63
+ loop do
64
+ line = socket.readline
65
+ break if line[9,3].to_i != 0
66
+ end
67
+
68
+ status = line[9, 3].to_i
69
+ reason_phrase = line[13..-3] # -3 strips the trailing "\r\n"
70
+
71
+ datum[:response] = {
72
+ :body => String.new,
73
+ :cookies => [],
74
+ :host => datum[:host],
75
+ :headers => Excon::Headers.new,
76
+ :path => datum[:path],
77
+ :port => datum[:port],
78
+ :status => status,
79
+ :status_line => line,
80
+ :reason_phrase => reason_phrase
81
+ }
82
+
83
+ unix_proxy = datum[:proxy] ? datum[:proxy][:scheme] == UNIX : false
84
+ unless datum[:scheme] == UNIX || unix_proxy
85
+ datum[:response].merge!(
86
+ :remote_ip => socket.remote_ip,
87
+ :local_port => socket.local_port,
88
+ :local_address => socket.local_address
89
+ )
90
+ end
91
+
92
+ parse_headers(socket, datum)
93
+
94
+ unless (['HEAD', 'CONNECT'].include?(datum[:method].to_s.upcase)) || NO_ENTITY.include?(datum[:response][:status])
95
+
96
+ if (key = datum[:response][:headers].keys.detect {|k| k.casecmp('Transfer-Encoding') == 0 })
97
+ encodings = Utils.split_header_value(datum[:response][:headers][key])
98
+ if (encoding = encodings.last) && encoding.casecmp('chunked') == 0
99
+ transfer_encoding_chunked = true
100
+ if encodings.length == 1
101
+ datum[:response][:headers].delete(key)
102
+ else
103
+ datum[:response][:headers][key] = encodings[0...-1].join(', ')
104
+ end
105
+ end
106
+ end
107
+
108
+ # use :response_block unless :expects would fail
109
+ if (response_block = datum[:response_block])
110
+ if datum[:middlewares].include?(Excon::Middleware::Expects) && datum[:expects] &&
111
+ !Array(datum[:expects]).include?(datum[:response][:status])
112
+ response_block = nil
113
+ end
114
+ end
115
+
116
+ if transfer_encoding_chunked
117
+ if response_block
118
+ while (chunk_size = socket.readline.chomp!.to_i(16)) > 0
119
+ while chunk_size > 0
120
+ chunk = socket.read(chunk_size) || raise(EOFError)
121
+ chunk_size -= chunk.bytesize
122
+ response_block.call(chunk, nil, nil)
123
+ end
124
+ new_line_size = 2 # 2 == "\r\n".length
125
+ while new_line_size > 0
126
+ chunk = socket.read(new_line_size) || raise(EOFError)
127
+ new_line_size -= chunk.length
128
+ end
129
+ end
130
+ else
131
+ while (chunk_size = socket.readline.chomp!.to_i(16)) > 0
132
+ while chunk_size > 0
133
+ chunk = socket.read(chunk_size) || raise(EOFError)
134
+ chunk_size -= chunk.bytesize
135
+ datum[:response][:body] << chunk
136
+ end
137
+ new_line_size = 2 # 2 == "\r\n".length
138
+ while new_line_size > 0
139
+ chunk = socket.read(new_line_size) || raise(EOFError)
140
+ new_line_size -= chunk.length
141
+ end
142
+ end
143
+ end
144
+ parse_headers(socket, datum) # merge trailers into headers
145
+ else
146
+ if (key = datum[:response][:headers].keys.detect {|k| k.casecmp('Content-Length') == 0 })
147
+ content_length = datum[:response][:headers][key].to_i
148
+ end
149
+
150
+ if (remaining = content_length)
151
+ if response_block
152
+ while remaining > 0
153
+ chunk = socket.read([datum[:chunk_size], remaining].min) || raise(EOFError)
154
+ response_block.call(chunk, [remaining - chunk.bytesize, 0].max, content_length)
155
+ remaining -= chunk.bytesize
156
+ end
157
+ else
158
+ while remaining > 0
159
+ chunk = socket.read([datum[:chunk_size], remaining].min) || raise(EOFError)
160
+ datum[:response][:body] << chunk
161
+ remaining -= chunk.bytesize
162
+ end
163
+ end
164
+ else
165
+ if response_block
166
+ while (chunk = socket.read(datum[:chunk_size]))
167
+ response_block.call(chunk, nil, nil)
168
+ end
169
+ else
170
+ while (chunk = socket.read(datum[:chunk_size]))
171
+ datum[:response][:body] << chunk
172
+ end
173
+ end
174
+ end
175
+ end
176
+ end
177
+ datum
178
+ end
179
+
180
+ def self.parse_headers(socket, datum)
181
+ last_key = nil
182
+ until (data = socket.readline.chomp).empty?
183
+ if !data.lstrip!.nil?
184
+ raise Excon::Error::ResponseParse, 'malformed header' unless last_key
185
+ # append to last_key's last value
186
+ datum[:response][:headers][last_key] << ' ' << data.rstrip
187
+ else
188
+ key, value = data.split(':', 2)
189
+ raise Excon::Error::ResponseParse, 'malformed header' unless value
190
+ # add key/value or append value to existing values
191
+ datum[:response][:headers][key] = ([datum[:response][:headers][key]] << value.strip).compact.join(', ')
192
+ if key.casecmp('Set-Cookie') == 0
193
+ datum[:response][:cookies] << value.strip
194
+ end
195
+ last_key = key
196
+ end
197
+ end
198
+ end
199
+
200
+ def initialize(params={})
201
+ @data = {
202
+ :body => ''
203
+ }.merge(params)
204
+ @data[:headers] = Excon::Headers.new.merge!(params[:headers] || {})
205
+
206
+ @body = @data[:body]
207
+ @headers = @data[:headers]
208
+ @status = @data[:status]
209
+ @remote_ip = @data[:remote_ip]
210
+ @local_port = @data[:local_port]
211
+ @local_address = @data[:local_address]
212
+ end
213
+
214
+ def [](key)
215
+ @data[key]
216
+ end
217
+
218
+ def params
219
+ Excon.display_warning('Excon::Response#params is deprecated use Excon::Response#data instead.')
220
+ data
221
+ end
222
+
223
+ def pp
224
+ Excon::PrettyPrinter.pp($stdout, @data)
225
+ end
226
+
227
+ # Retrieve a specific header value. Header names are treated case-insensitively.
228
+ # @param [String] name Header name
229
+ def get_header(name)
230
+ headers[name]
231
+ end
232
+
233
+ end # class Response
234
+ end # module Excon