bundler 2.0.2

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

Potentially problematic release.


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

Files changed (303) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +3111 -0
  3. data/LICENSE.md +23 -0
  4. data/README.md +63 -0
  5. data/bundler.gemspec +65 -0
  6. data/exe/bundle +31 -0
  7. data/exe/bundle_ruby +60 -0
  8. data/exe/bundler +4 -0
  9. data/lib/bundler.rb +567 -0
  10. data/lib/bundler/build_metadata.rb +53 -0
  11. data/lib/bundler/capistrano.rb +22 -0
  12. data/lib/bundler/cli.rb +792 -0
  13. data/lib/bundler/cli/add.rb +35 -0
  14. data/lib/bundler/cli/binstubs.rb +49 -0
  15. data/lib/bundler/cli/cache.rb +36 -0
  16. data/lib/bundler/cli/check.rb +38 -0
  17. data/lib/bundler/cli/clean.rb +25 -0
  18. data/lib/bundler/cli/common.rb +102 -0
  19. data/lib/bundler/cli/config.rb +119 -0
  20. data/lib/bundler/cli/console.rb +43 -0
  21. data/lib/bundler/cli/doctor.rb +140 -0
  22. data/lib/bundler/cli/exec.rb +105 -0
  23. data/lib/bundler/cli/gem.rb +252 -0
  24. data/lib/bundler/cli/info.rb +50 -0
  25. data/lib/bundler/cli/init.rb +47 -0
  26. data/lib/bundler/cli/inject.rb +60 -0
  27. data/lib/bundler/cli/install.rb +218 -0
  28. data/lib/bundler/cli/issue.rb +40 -0
  29. data/lib/bundler/cli/list.rb +58 -0
  30. data/lib/bundler/cli/lock.rb +63 -0
  31. data/lib/bundler/cli/open.rb +26 -0
  32. data/lib/bundler/cli/outdated.rb +266 -0
  33. data/lib/bundler/cli/package.rb +49 -0
  34. data/lib/bundler/cli/platform.rb +46 -0
  35. data/lib/bundler/cli/plugin.rb +24 -0
  36. data/lib/bundler/cli/pristine.rb +47 -0
  37. data/lib/bundler/cli/remove.rb +18 -0
  38. data/lib/bundler/cli/show.rb +75 -0
  39. data/lib/bundler/cli/update.rb +91 -0
  40. data/lib/bundler/cli/viz.rb +31 -0
  41. data/lib/bundler/compact_index_client.rb +109 -0
  42. data/lib/bundler/compact_index_client/cache.rb +118 -0
  43. data/lib/bundler/compact_index_client/updater.rb +116 -0
  44. data/lib/bundler/compatibility_guard.rb +13 -0
  45. data/lib/bundler/constants.rb +7 -0
  46. data/lib/bundler/current_ruby.rb +94 -0
  47. data/lib/bundler/definition.rb +995 -0
  48. data/lib/bundler/dep_proxy.rb +48 -0
  49. data/lib/bundler/dependency.rb +139 -0
  50. data/lib/bundler/deployment.rb +69 -0
  51. data/lib/bundler/deprecate.rb +44 -0
  52. data/lib/bundler/dsl.rb +615 -0
  53. data/lib/bundler/endpoint_specification.rb +141 -0
  54. data/lib/bundler/env.rb +149 -0
  55. data/lib/bundler/environment_preserver.rb +59 -0
  56. data/lib/bundler/errors.rb +158 -0
  57. data/lib/bundler/feature_flag.rb +75 -0
  58. data/lib/bundler/fetcher.rb +312 -0
  59. data/lib/bundler/fetcher/base.rb +52 -0
  60. data/lib/bundler/fetcher/compact_index.rb +126 -0
  61. data/lib/bundler/fetcher/dependency.rb +82 -0
  62. data/lib/bundler/fetcher/downloader.rb +84 -0
  63. data/lib/bundler/fetcher/index.rb +52 -0
  64. data/lib/bundler/friendly_errors.rb +131 -0
  65. data/lib/bundler/gem_helper.rb +217 -0
  66. data/lib/bundler/gem_helpers.rb +101 -0
  67. data/lib/bundler/gem_remote_fetcher.rb +43 -0
  68. data/lib/bundler/gem_tasks.rb +7 -0
  69. data/lib/bundler/gem_version_promoter.rb +190 -0
  70. data/lib/bundler/gemdeps.rb +29 -0
  71. data/lib/bundler/graph.rb +152 -0
  72. data/lib/bundler/index.rb +213 -0
  73. data/lib/bundler/injector.rb +253 -0
  74. data/lib/bundler/inline.rb +74 -0
  75. data/lib/bundler/installer.rb +318 -0
  76. data/lib/bundler/installer/gem_installer.rb +85 -0
  77. data/lib/bundler/installer/parallel_installer.rb +229 -0
  78. data/lib/bundler/installer/standalone.rb +53 -0
  79. data/lib/bundler/lazy_specification.rb +123 -0
  80. data/lib/bundler/lockfile_generator.rb +95 -0
  81. data/lib/bundler/lockfile_parser.rb +256 -0
  82. data/lib/bundler/match_platform.rb +24 -0
  83. data/lib/bundler/mirror.rb +223 -0
  84. data/lib/bundler/plugin.rb +294 -0
  85. data/lib/bundler/plugin/api.rb +81 -0
  86. data/lib/bundler/plugin/api/source.rb +306 -0
  87. data/lib/bundler/plugin/dsl.rb +53 -0
  88. data/lib/bundler/plugin/events.rb +61 -0
  89. data/lib/bundler/plugin/index.rb +165 -0
  90. data/lib/bundler/plugin/installer.rb +96 -0
  91. data/lib/bundler/plugin/installer/git.rb +38 -0
  92. data/lib/bundler/plugin/installer/rubygems.rb +27 -0
  93. data/lib/bundler/plugin/source_list.rb +27 -0
  94. data/lib/bundler/process_lock.rb +24 -0
  95. data/lib/bundler/psyched_yaml.rb +37 -0
  96. data/lib/bundler/remote_specification.rb +114 -0
  97. data/lib/bundler/resolver.rb +373 -0
  98. data/lib/bundler/resolver/spec_group.rb +106 -0
  99. data/lib/bundler/retry.rb +66 -0
  100. data/lib/bundler/ruby_dsl.rb +18 -0
  101. data/lib/bundler/ruby_version.rb +152 -0
  102. data/lib/bundler/rubygems_ext.rb +209 -0
  103. data/lib/bundler/rubygems_gem_installer.rb +99 -0
  104. data/lib/bundler/rubygems_integration.rb +915 -0
  105. data/lib/bundler/runtime.rb +322 -0
  106. data/lib/bundler/settings.rb +464 -0
  107. data/lib/bundler/settings/validator.rb +102 -0
  108. data/lib/bundler/setup.rb +28 -0
  109. data/lib/bundler/shared_helpers.rb +386 -0
  110. data/lib/bundler/similarity_detector.rb +63 -0
  111. data/lib/bundler/source.rb +94 -0
  112. data/lib/bundler/source/gemspec.rb +18 -0
  113. data/lib/bundler/source/git.rb +329 -0
  114. data/lib/bundler/source/git/git_proxy.rb +262 -0
  115. data/lib/bundler/source/metadata.rb +62 -0
  116. data/lib/bundler/source/path.rb +249 -0
  117. data/lib/bundler/source/path/installer.rb +74 -0
  118. data/lib/bundler/source/rubygems.rb +539 -0
  119. data/lib/bundler/source/rubygems/remote.rb +69 -0
  120. data/lib/bundler/source_list.rb +186 -0
  121. data/lib/bundler/spec_set.rb +208 -0
  122. data/lib/bundler/ssl_certs/.document +1 -0
  123. data/lib/bundler/ssl_certs/certificate_manager.rb +66 -0
  124. data/lib/bundler/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem +21 -0
  125. data/lib/bundler/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem +23 -0
  126. data/lib/bundler/ssl_certs/rubygems.org/AddTrustExternalCARoot.pem +25 -0
  127. data/lib/bundler/stub_specification.rb +108 -0
  128. data/lib/bundler/templates/.document +1 -0
  129. data/lib/bundler/templates/Executable +29 -0
  130. data/lib/bundler/templates/Executable.bundler +105 -0
  131. data/lib/bundler/templates/Executable.standalone +14 -0
  132. data/lib/bundler/templates/Gemfile +7 -0
  133. data/lib/bundler/templates/gems.rb +8 -0
  134. data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +74 -0
  135. data/lib/bundler/templates/newgem/Gemfile.tt +4 -0
  136. data/lib/bundler/templates/newgem/LICENSE.txt.tt +21 -0
  137. data/lib/bundler/templates/newgem/README.md.tt +47 -0
  138. data/lib/bundler/templates/newgem/Rakefile.tt +29 -0
  139. data/lib/bundler/templates/newgem/bin/console.tt +14 -0
  140. data/lib/bundler/templates/newgem/bin/setup.tt +8 -0
  141. data/lib/bundler/templates/newgem/exe/newgem.tt +3 -0
  142. data/lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt +3 -0
  143. data/lib/bundler/templates/newgem/ext/newgem/newgem.c.tt +9 -0
  144. data/lib/bundler/templates/newgem/ext/newgem/newgem.h.tt +6 -0
  145. data/lib/bundler/templates/newgem/gitignore.tt +20 -0
  146. data/lib/bundler/templates/newgem/lib/newgem.rb.tt +13 -0
  147. data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +7 -0
  148. data/lib/bundler/templates/newgem/newgem.gemspec.tt +50 -0
  149. data/lib/bundler/templates/newgem/rspec.tt +3 -0
  150. data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +9 -0
  151. data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +14 -0
  152. data/lib/bundler/templates/newgem/test/newgem_test.rb.tt +11 -0
  153. data/lib/bundler/templates/newgem/test/test_helper.rb.tt +8 -0
  154. data/lib/bundler/templates/newgem/travis.yml.tt +7 -0
  155. data/lib/bundler/ui.rb +9 -0
  156. data/lib/bundler/ui/rg_proxy.rb +19 -0
  157. data/lib/bundler/ui/shell.rb +146 -0
  158. data/lib/bundler/ui/silent.rb +69 -0
  159. data/lib/bundler/uri_credentials_filter.rb +37 -0
  160. data/lib/bundler/vendor/fileutils/lib/fileutils.rb +1741 -0
  161. data/lib/bundler/vendor/fileutils/lib/fileutils/version.rb +5 -0
  162. data/lib/bundler/vendor/molinillo/lib/molinillo.rb +12 -0
  163. data/lib/bundler/vendor/molinillo/lib/molinillo/compatibility.rb +26 -0
  164. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/resolution_state.rb +57 -0
  165. data/lib/bundler/vendor/molinillo/lib/molinillo/delegates/specification_provider.rb +81 -0
  166. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +223 -0
  167. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/action.rb +36 -0
  168. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb +66 -0
  169. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/add_vertex.rb +62 -0
  170. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/delete_edge.rb +63 -0
  171. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb +61 -0
  172. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/log.rb +126 -0
  173. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/set_payload.rb +46 -0
  174. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/tag.rb +36 -0
  175. data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph/vertex.rb +136 -0
  176. data/lib/bundler/vendor/molinillo/lib/molinillo/errors.rb +143 -0
  177. data/lib/bundler/vendor/molinillo/lib/molinillo/gem_metadata.rb +6 -0
  178. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +101 -0
  179. data/lib/bundler/vendor/molinillo/lib/molinillo/modules/ui.rb +67 -0
  180. data/lib/bundler/vendor/molinillo/lib/molinillo/resolution.rb +837 -0
  181. data/lib/bundler/vendor/molinillo/lib/molinillo/resolver.rb +46 -0
  182. data/lib/bundler/vendor/molinillo/lib/molinillo/state.rb +58 -0
  183. data/lib/bundler/vendor/net-http-persistent/lib/net/http/faster.rb +27 -0
  184. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +1233 -0
  185. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/ssl_reuse.rb +129 -0
  186. data/lib/bundler/vendor/thor/lib/thor.rb +509 -0
  187. data/lib/bundler/vendor/thor/lib/thor/actions.rb +331 -0
  188. data/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +104 -0
  189. data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +60 -0
  190. data/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +118 -0
  191. data/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb +143 -0
  192. data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +373 -0
  193. data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +109 -0
  194. data/lib/bundler/vendor/thor/lib/thor/base.rb +678 -0
  195. data/lib/bundler/vendor/thor/lib/thor/command.rb +135 -0
  196. data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +97 -0
  197. data/lib/bundler/vendor/thor/lib/thor/core_ext/io_binary_read.rb +12 -0
  198. data/lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb +129 -0
  199. data/lib/bundler/vendor/thor/lib/thor/error.rb +114 -0
  200. data/lib/bundler/vendor/thor/lib/thor/group.rb +281 -0
  201. data/lib/bundler/vendor/thor/lib/thor/invocation.rb +177 -0
  202. data/lib/bundler/vendor/thor/lib/thor/line_editor.rb +17 -0
  203. data/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb +37 -0
  204. data/lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb +88 -0
  205. data/lib/bundler/vendor/thor/lib/thor/parser.rb +4 -0
  206. data/lib/bundler/vendor/thor/lib/thor/parser/argument.rb +70 -0
  207. data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +175 -0
  208. data/lib/bundler/vendor/thor/lib/thor/parser/option.rb +146 -0
  209. data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +226 -0
  210. data/lib/bundler/vendor/thor/lib/thor/rake_compat.rb +71 -0
  211. data/lib/bundler/vendor/thor/lib/thor/runner.rb +324 -0
  212. data/lib/bundler/vendor/thor/lib/thor/shell.rb +81 -0
  213. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +482 -0
  214. data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +149 -0
  215. data/lib/bundler/vendor/thor/lib/thor/shell/html.rb +126 -0
  216. data/lib/bundler/vendor/thor/lib/thor/util.rb +268 -0
  217. data/lib/bundler/vendor/thor/lib/thor/version.rb +3 -0
  218. data/lib/bundler/vendored_fileutils.rb +9 -0
  219. data/lib/bundler/vendored_molinillo.rb +4 -0
  220. data/lib/bundler/vendored_persistent.rb +52 -0
  221. data/lib/bundler/vendored_thor.rb +8 -0
  222. data/lib/bundler/version.rb +28 -0
  223. data/lib/bundler/version_ranges.rb +76 -0
  224. data/lib/bundler/vlad.rb +17 -0
  225. data/lib/bundler/worker.rb +106 -0
  226. data/lib/bundler/yaml_serializer.rb +90 -0
  227. data/man/bundle-add.1 +58 -0
  228. data/man/bundle-add.1.txt +52 -0
  229. data/man/bundle-add.ronn +40 -0
  230. data/man/bundle-binstubs.1 +40 -0
  231. data/man/bundle-binstubs.1.txt +48 -0
  232. data/man/bundle-binstubs.ronn +43 -0
  233. data/man/bundle-check.1 +31 -0
  234. data/man/bundle-check.1.txt +33 -0
  235. data/man/bundle-check.ronn +26 -0
  236. data/man/bundle-clean.1 +24 -0
  237. data/man/bundle-clean.1.txt +26 -0
  238. data/man/bundle-clean.ronn +18 -0
  239. data/man/bundle-config.1 +497 -0
  240. data/man/bundle-config.1.txt +529 -0
  241. data/man/bundle-config.ronn +397 -0
  242. data/man/bundle-doctor.1 +44 -0
  243. data/man/bundle-doctor.1.txt +44 -0
  244. data/man/bundle-doctor.ronn +33 -0
  245. data/man/bundle-exec.1 +165 -0
  246. data/man/bundle-exec.1.txt +178 -0
  247. data/man/bundle-exec.ronn +152 -0
  248. data/man/bundle-gem.1 +80 -0
  249. data/man/bundle-gem.1.txt +91 -0
  250. data/man/bundle-gem.ronn +78 -0
  251. data/man/bundle-info.1 +20 -0
  252. data/man/bundle-info.1.txt +21 -0
  253. data/man/bundle-info.ronn +17 -0
  254. data/man/bundle-init.1 +25 -0
  255. data/man/bundle-init.1.txt +34 -0
  256. data/man/bundle-init.ronn +29 -0
  257. data/man/bundle-inject.1 +33 -0
  258. data/man/bundle-inject.1.txt +32 -0
  259. data/man/bundle-inject.ronn +22 -0
  260. data/man/bundle-install.1 +308 -0
  261. data/man/bundle-install.1.txt +396 -0
  262. data/man/bundle-install.ronn +378 -0
  263. data/man/bundle-list.1 +50 -0
  264. data/man/bundle-list.1.txt +43 -0
  265. data/man/bundle-list.ronn +33 -0
  266. data/man/bundle-lock.1 +84 -0
  267. data/man/bundle-lock.1.txt +93 -0
  268. data/man/bundle-lock.ronn +94 -0
  269. data/man/bundle-open.1 +32 -0
  270. data/man/bundle-open.1.txt +29 -0
  271. data/man/bundle-open.ronn +19 -0
  272. data/man/bundle-outdated.1 +155 -0
  273. data/man/bundle-outdated.1.txt +131 -0
  274. data/man/bundle-outdated.ronn +111 -0
  275. data/man/bundle-package.1 +55 -0
  276. data/man/bundle-package.1.txt +79 -0
  277. data/man/bundle-package.ronn +72 -0
  278. data/man/bundle-platform.1 +61 -0
  279. data/man/bundle-platform.1.txt +57 -0
  280. data/man/bundle-platform.ronn +42 -0
  281. data/man/bundle-pristine.1 +34 -0
  282. data/man/bundle-pristine.1.txt +44 -0
  283. data/man/bundle-pristine.ronn +34 -0
  284. data/man/bundle-remove.1 +31 -0
  285. data/man/bundle-remove.1.txt +34 -0
  286. data/man/bundle-remove.ronn +23 -0
  287. data/man/bundle-show.1 +23 -0
  288. data/man/bundle-show.1.txt +27 -0
  289. data/man/bundle-show.ronn +21 -0
  290. data/man/bundle-update.1 +394 -0
  291. data/man/bundle-update.1.txt +391 -0
  292. data/man/bundle-update.ronn +350 -0
  293. data/man/bundle-viz.1 +39 -0
  294. data/man/bundle-viz.1.txt +39 -0
  295. data/man/bundle-viz.ronn +30 -0
  296. data/man/bundle.1 +136 -0
  297. data/man/bundle.1.txt +116 -0
  298. data/man/bundle.ronn +111 -0
  299. data/man/gemfile.5 +689 -0
  300. data/man/gemfile.5.ronn +521 -0
  301. data/man/gemfile.5.txt +653 -0
  302. data/man/index.txt +25 -0
  303. metadata +463 -0
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/vendor/molinillo/lib/molinillo/dependency_graph'
4
+
5
+ module Bundler::Molinillo
6
+ # This class encapsulates a dependency resolver.
7
+ # The resolver is responsible for determining which set of dependencies to
8
+ # activate, with feedback from the {#specification_provider}
9
+ #
10
+ #
11
+ class Resolver
12
+ require 'bundler/vendor/molinillo/lib/molinillo/resolution'
13
+
14
+ # @return [SpecificationProvider] the specification provider used
15
+ # in the resolution process
16
+ attr_reader :specification_provider
17
+
18
+ # @return [UI] the UI module used to communicate back to the user
19
+ # during the resolution process
20
+ attr_reader :resolver_ui
21
+
22
+ # Initializes a new resolver.
23
+ # @param [SpecificationProvider] specification_provider
24
+ # see {#specification_provider}
25
+ # @param [UI] resolver_ui
26
+ # see {#resolver_ui}
27
+ def initialize(specification_provider, resolver_ui)
28
+ @specification_provider = specification_provider
29
+ @resolver_ui = resolver_ui
30
+ end
31
+
32
+ # Resolves the requested dependencies into a {DependencyGraph},
33
+ # locking to the base dependency graph (if specified)
34
+ # @param [Array] requested an array of 'requested' dependencies that the
35
+ # {#specification_provider} can understand
36
+ # @param [DependencyGraph,nil] base the base dependency graph to which
37
+ # dependencies should be 'locked'
38
+ def resolve(requested, base = DependencyGraph.new)
39
+ Resolution.new(specification_provider,
40
+ resolver_ui,
41
+ requested,
42
+ base).
43
+ resolve
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bundler::Molinillo
4
+ # A state that a {Resolution} can be in
5
+ # @attr [String] name the name of the current requirement
6
+ # @attr [Array<Object>] requirements currently unsatisfied requirements
7
+ # @attr [DependencyGraph] activated the graph of activated dependencies
8
+ # @attr [Object] requirement the current requirement
9
+ # @attr [Object] possibilities the possibilities to satisfy the current requirement
10
+ # @attr [Integer] depth the depth of the resolution
11
+ # @attr [Hash] conflicts unresolved conflicts, indexed by dependency name
12
+ # @attr [Array<UnwindDetails>] unused_unwind_options unwinds for previous conflicts that weren't explored
13
+ ResolutionState = Struct.new(
14
+ :name,
15
+ :requirements,
16
+ :activated,
17
+ :requirement,
18
+ :possibilities,
19
+ :depth,
20
+ :conflicts,
21
+ :unused_unwind_options
22
+ )
23
+
24
+ class ResolutionState
25
+ # Returns an empty resolution state
26
+ # @return [ResolutionState] an empty state
27
+ def self.empty
28
+ new(nil, [], DependencyGraph.new, nil, nil, 0, {}, [])
29
+ end
30
+ end
31
+
32
+ # A state that encapsulates a set of {#requirements} with an {Array} of
33
+ # possibilities
34
+ class DependencyState < ResolutionState
35
+ # Removes a possibility from `self`
36
+ # @return [PossibilityState] a state with a single possibility,
37
+ # the possibility that was removed from `self`
38
+ def pop_possibility_state
39
+ PossibilityState.new(
40
+ name,
41
+ requirements.dup,
42
+ activated,
43
+ requirement,
44
+ [possibilities.pop],
45
+ depth + 1,
46
+ conflicts.dup,
47
+ unused_unwind_options.dup
48
+ ).tap do |state|
49
+ state.activated.tag(state)
50
+ end
51
+ end
52
+ end
53
+
54
+ # A state that encapsulates a single possibility to fulfill the given
55
+ # {#requirement}
56
+ class PossibilityState < ResolutionState
57
+ end
58
+ end
@@ -0,0 +1,27 @@
1
+ require 'net/protocol'
2
+
3
+ ##
4
+ # Aaron Patterson's monkeypatch (accepted into 1.9.1) to fix Net::HTTP's speed
5
+ # problems.
6
+ #
7
+ # http://gist.github.com/251244
8
+
9
+ class Net::BufferedIO #:nodoc:
10
+ alias :old_rbuf_fill :rbuf_fill
11
+
12
+ def rbuf_fill
13
+ if @io.respond_to? :read_nonblock then
14
+ begin
15
+ @rbuf << @io.read_nonblock(65536)
16
+ rescue Errno::EWOULDBLOCK, Errno::EAGAIN => e
17
+ retry if IO.select [@io], nil, nil, @read_timeout
18
+ raise Timeout::Error, e.message
19
+ end
20
+ else # SSL sockets do not have read_nonblock
21
+ timeout @read_timeout do
22
+ @rbuf << @io.sysread(65536)
23
+ end
24
+ end
25
+ end
26
+ end if RUBY_VERSION < '1.9'
27
+
@@ -0,0 +1,1233 @@
1
+ require 'net/http'
2
+ begin
3
+ require 'net/https'
4
+ rescue LoadError
5
+ # net/https or openssl
6
+ end if RUBY_VERSION < '1.9' # but only for 1.8
7
+ require 'bundler/vendor/net-http-persistent/lib/net/http/faster'
8
+ require 'uri'
9
+ require 'cgi' # for escaping
10
+
11
+ begin
12
+ require 'net/http/pipeline'
13
+ rescue LoadError
14
+ end
15
+
16
+ autoload :OpenSSL, 'openssl'
17
+
18
+ ##
19
+ # Persistent connections for Net::HTTP
20
+ #
21
+ # Bundler::Persistent::Net::HTTP::Persistent maintains persistent connections across all the
22
+ # servers you wish to talk to. For each host:port you communicate with a
23
+ # single persistent connection is created.
24
+ #
25
+ # Multiple Bundler::Persistent::Net::HTTP::Persistent objects will share the same set of
26
+ # connections.
27
+ #
28
+ # For each thread you start a new connection will be created. A
29
+ # Bundler::Persistent::Net::HTTP::Persistent connection will not be shared across threads.
30
+ #
31
+ # You can shut down the HTTP connections when done by calling #shutdown. You
32
+ # should name your Bundler::Persistent::Net::HTTP::Persistent object if you intend to call this
33
+ # method.
34
+ #
35
+ # Example:
36
+ #
37
+ # require 'bundler/vendor/net-http-persistent/lib/net/http/persistent'
38
+ #
39
+ # uri = URI 'http://example.com/awesome/web/service'
40
+ #
41
+ # http = Bundler::Persistent::Net::HTTP::Persistent.new 'my_app_name'
42
+ #
43
+ # # perform a GET
44
+ # response = http.request uri
45
+ #
46
+ # # or
47
+ #
48
+ # get = Net::HTTP::Get.new uri.request_uri
49
+ # response = http.request get
50
+ #
51
+ # # create a POST
52
+ # post_uri = uri + 'create'
53
+ # post = Net::HTTP::Post.new post_uri.path
54
+ # post.set_form_data 'some' => 'cool data'
55
+ #
56
+ # # perform the POST, the URI is always required
57
+ # response http.request post_uri, post
58
+ #
59
+ # Note that for GET, HEAD and other requests that do not have a body you want
60
+ # to use URI#request_uri not URI#path. The request_uri contains the query
61
+ # params which are sent in the body for other requests.
62
+ #
63
+ # == SSL
64
+ #
65
+ # SSL connections are automatically created depending upon the scheme of the
66
+ # URI. SSL connections are automatically verified against the default
67
+ # certificate store for your computer. You can override this by changing
68
+ # verify_mode or by specifying an alternate cert_store.
69
+ #
70
+ # Here are the SSL settings, see the individual methods for documentation:
71
+ #
72
+ # #certificate :: This client's certificate
73
+ # #ca_file :: The certificate-authority
74
+ # #cert_store :: An SSL certificate store
75
+ # #private_key :: The client's SSL private key
76
+ # #reuse_ssl_sessions :: Reuse a previously opened SSL session for a new
77
+ # connection
78
+ # #ssl_version :: Which specific SSL version to use
79
+ # #verify_callback :: For server certificate verification
80
+ # #verify_mode :: How connections should be verified
81
+ #
82
+ # == Proxies
83
+ #
84
+ # A proxy can be set through #proxy= or at initialization time by providing a
85
+ # second argument to ::new. The proxy may be the URI of the proxy server or
86
+ # <code>:ENV</code> which will consult environment variables.
87
+ #
88
+ # See #proxy= and #proxy_from_env for details.
89
+ #
90
+ # == Headers
91
+ #
92
+ # Headers may be specified for use in every request. #headers are appended to
93
+ # any headers on the request. #override_headers replace existing headers on
94
+ # the request.
95
+ #
96
+ # The difference between the two can be seen in setting the User-Agent. Using
97
+ # <code>http.headers['User-Agent'] = 'MyUserAgent'</code> will send "Ruby,
98
+ # MyUserAgent" while <code>http.override_headers['User-Agent'] =
99
+ # 'MyUserAgent'</code> will send "MyUserAgent".
100
+ #
101
+ # == Tuning
102
+ #
103
+ # === Segregation
104
+ #
105
+ # By providing an application name to ::new you can separate your connections
106
+ # from the connections of other applications.
107
+ #
108
+ # === Idle Timeout
109
+ #
110
+ # If a connection hasn't been used for this number of seconds it will automatically be
111
+ # reset upon the next use to avoid attempting to send to a closed connection.
112
+ # The default value is 5 seconds. nil means no timeout. Set through #idle_timeout.
113
+ #
114
+ # Reducing this value may help avoid the "too many connection resets" error
115
+ # when sending non-idempotent requests while increasing this value will cause
116
+ # fewer round-trips.
117
+ #
118
+ # === Read Timeout
119
+ #
120
+ # The amount of time allowed between reading two chunks from the socket. Set
121
+ # through #read_timeout
122
+ #
123
+ # === Max Requests
124
+ #
125
+ # The number of requests that should be made before opening a new connection.
126
+ # Typically many keep-alive capable servers tune this to 100 or less, so the
127
+ # 101st request will fail with ECONNRESET. If unset (default), this value has no
128
+ # effect, if set, connections will be reset on the request after max_requests.
129
+ #
130
+ # === Open Timeout
131
+ #
132
+ # The amount of time to wait for a connection to be opened. Set through
133
+ # #open_timeout.
134
+ #
135
+ # === Socket Options
136
+ #
137
+ # Socket options may be set on newly-created connections. See #socket_options
138
+ # for details.
139
+ #
140
+ # === Non-Idempotent Requests
141
+ #
142
+ # By default non-idempotent requests will not be retried per RFC 2616. By
143
+ # setting retry_change_requests to true requests will automatically be retried
144
+ # once.
145
+ #
146
+ # Only do this when you know that retrying a POST or other non-idempotent
147
+ # request is safe for your application and will not create duplicate
148
+ # resources.
149
+ #
150
+ # The recommended way to handle non-idempotent requests is the following:
151
+ #
152
+ # require 'bundler/vendor/net-http-persistent/lib/net/http/persistent'
153
+ #
154
+ # uri = URI 'http://example.com/awesome/web/service'
155
+ # post_uri = uri + 'create'
156
+ #
157
+ # http = Bundler::Persistent::Net::HTTP::Persistent.new 'my_app_name'
158
+ #
159
+ # post = Net::HTTP::Post.new post_uri.path
160
+ # # ... fill in POST request
161
+ #
162
+ # begin
163
+ # response = http.request post_uri, post
164
+ # rescue Bundler::Persistent::Net::HTTP::Persistent::Error
165
+ #
166
+ # # POST failed, make a new request to verify the server did not process
167
+ # # the request
168
+ # exists_uri = uri + '...'
169
+ # response = http.get exists_uri
170
+ #
171
+ # # Retry if it failed
172
+ # retry if response.code == '404'
173
+ # end
174
+ #
175
+ # The method of determining if the resource was created or not is unique to
176
+ # the particular service you are using. Of course, you will want to add
177
+ # protection from infinite looping.
178
+ #
179
+ # === Connection Termination
180
+ #
181
+ # If you are done using the Bundler::Persistent::Net::HTTP::Persistent instance you may shut down
182
+ # all the connections in the current thread with #shutdown. This is not
183
+ # recommended for normal use, it should only be used when it will be several
184
+ # minutes before you make another HTTP request.
185
+ #
186
+ # If you are using multiple threads, call #shutdown in each thread when the
187
+ # thread is done making requests. If you don't call shutdown, that's OK.
188
+ # Ruby will automatically garbage collect and shutdown your HTTP connections
189
+ # when the thread terminates.
190
+
191
+ class Bundler::Persistent::Net::HTTP::Persistent
192
+
193
+ ##
194
+ # The beginning of Time
195
+
196
+ EPOCH = Time.at 0 # :nodoc:
197
+
198
+ ##
199
+ # Is OpenSSL available? This test works with autoload
200
+
201
+ HAVE_OPENSSL = defined? OpenSSL::SSL # :nodoc:
202
+
203
+ ##
204
+ # The version of Bundler::Persistent::Net::HTTP::Persistent you are using
205
+
206
+ VERSION = '2.9.4'
207
+
208
+ ##
209
+ # Exceptions rescued for automatic retry on ruby 2.0.0. This overlaps with
210
+ # the exception list for ruby 1.x.
211
+
212
+ RETRIED_EXCEPTIONS = [ # :nodoc:
213
+ (Net::ReadTimeout if Net.const_defined? :ReadTimeout),
214
+ IOError,
215
+ EOFError,
216
+ Errno::ECONNRESET,
217
+ Errno::ECONNABORTED,
218
+ Errno::EPIPE,
219
+ (OpenSSL::SSL::SSLError if HAVE_OPENSSL),
220
+ Timeout::Error,
221
+ ].compact
222
+
223
+ ##
224
+ # Error class for errors raised by Bundler::Persistent::Net::HTTP::Persistent. Various
225
+ # SystemCallErrors are re-raised with a human-readable message under this
226
+ # class.
227
+
228
+ class Error < StandardError; end
229
+
230
+ ##
231
+ # Use this method to detect the idle timeout of the host at +uri+. The
232
+ # value returned can be used to configure #idle_timeout. +max+ controls the
233
+ # maximum idle timeout to detect.
234
+ #
235
+ # After
236
+ #
237
+ # Idle timeout detection is performed by creating a connection then
238
+ # performing a HEAD request in a loop until the connection terminates
239
+ # waiting one additional second per loop.
240
+ #
241
+ # NOTE: This may not work on ruby > 1.9.
242
+
243
+ def self.detect_idle_timeout uri, max = 10
244
+ uri = URI uri unless URI::Generic === uri
245
+ uri += '/'
246
+
247
+ req = Net::HTTP::Head.new uri.request_uri
248
+
249
+ http = new 'net-http-persistent detect_idle_timeout'
250
+
251
+ connection = http.connection_for uri
252
+
253
+ sleep_time = 0
254
+
255
+ loop do
256
+ response = connection.request req
257
+
258
+ $stderr.puts "HEAD #{uri} => #{response.code}" if $DEBUG
259
+
260
+ unless Net::HTTPOK === response then
261
+ raise Error, "bad response code #{response.code} detecting idle timeout"
262
+ end
263
+
264
+ break if sleep_time >= max
265
+
266
+ sleep_time += 1
267
+
268
+ $stderr.puts "sleeping #{sleep_time}" if $DEBUG
269
+ sleep sleep_time
270
+ end
271
+ rescue
272
+ # ignore StandardErrors, we've probably found the idle timeout.
273
+ ensure
274
+ http.shutdown
275
+
276
+ return sleep_time unless $!
277
+ end
278
+
279
+ ##
280
+ # This client's OpenSSL::X509::Certificate
281
+
282
+ attr_reader :certificate
283
+
284
+ # For Net::HTTP parity
285
+ alias cert certificate
286
+
287
+ ##
288
+ # An SSL certificate authority. Setting this will set verify_mode to
289
+ # VERIFY_PEER.
290
+
291
+ attr_reader :ca_file
292
+
293
+ ##
294
+ # An SSL certificate store. Setting this will override the default
295
+ # certificate store. See verify_mode for more information.
296
+
297
+ attr_reader :cert_store
298
+
299
+ ##
300
+ # Sends debug_output to this IO via Net::HTTP#set_debug_output.
301
+ #
302
+ # Never use this method in production code, it causes a serious security
303
+ # hole.
304
+
305
+ attr_accessor :debug_output
306
+
307
+ ##
308
+ # Current connection generation
309
+
310
+ attr_reader :generation # :nodoc:
311
+
312
+ ##
313
+ # Where this instance's connections live in the thread local variables
314
+
315
+ attr_reader :generation_key # :nodoc:
316
+
317
+ ##
318
+ # Headers that are added to every request using Net::HTTP#add_field
319
+
320
+ attr_reader :headers
321
+
322
+ ##
323
+ # Maps host:port to an HTTP version. This allows us to enable version
324
+ # specific features.
325
+
326
+ attr_reader :http_versions
327
+
328
+ ##
329
+ # Maximum time an unused connection can remain idle before being
330
+ # automatically closed.
331
+
332
+ attr_accessor :idle_timeout
333
+
334
+ ##
335
+ # Maximum number of requests on a connection before it is considered expired
336
+ # and automatically closed.
337
+
338
+ attr_accessor :max_requests
339
+
340
+ ##
341
+ # The value sent in the Keep-Alive header. Defaults to 30. Not needed for
342
+ # HTTP/1.1 servers.
343
+ #
344
+ # This may not work correctly for HTTP/1.0 servers
345
+ #
346
+ # This method may be removed in a future version as RFC 2616 does not
347
+ # require this header.
348
+
349
+ attr_accessor :keep_alive
350
+
351
+ ##
352
+ # A name for this connection. Allows you to keep your connections apart
353
+ # from everybody else's.
354
+
355
+ attr_reader :name
356
+
357
+ ##
358
+ # Seconds to wait until a connection is opened. See Net::HTTP#open_timeout
359
+
360
+ attr_accessor :open_timeout
361
+
362
+ ##
363
+ # Headers that are added to every request using Net::HTTP#[]=
364
+
365
+ attr_reader :override_headers
366
+
367
+ ##
368
+ # This client's SSL private key
369
+
370
+ attr_reader :private_key
371
+
372
+ # For Net::HTTP parity
373
+ alias key private_key
374
+
375
+ ##
376
+ # The URL through which requests will be proxied
377
+
378
+ attr_reader :proxy_uri
379
+
380
+ ##
381
+ # List of host suffixes which will not be proxied
382
+
383
+ attr_reader :no_proxy
384
+
385
+ ##
386
+ # Seconds to wait until reading one block. See Net::HTTP#read_timeout
387
+
388
+ attr_accessor :read_timeout
389
+
390
+ ##
391
+ # Where this instance's request counts live in the thread local variables
392
+
393
+ attr_reader :request_key # :nodoc:
394
+
395
+ ##
396
+ # By default SSL sessions are reused to avoid extra SSL handshakes. Set
397
+ # this to false if you have problems communicating with an HTTPS server
398
+ # like:
399
+ #
400
+ # SSL_connect [...] read finished A: unexpected message (OpenSSL::SSL::SSLError)
401
+
402
+ attr_accessor :reuse_ssl_sessions
403
+
404
+ ##
405
+ # An array of options for Socket#setsockopt.
406
+ #
407
+ # By default the TCP_NODELAY option is set on sockets.
408
+ #
409
+ # To set additional options append them to this array:
410
+ #
411
+ # http.socket_options << [Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1]
412
+
413
+ attr_reader :socket_options
414
+
415
+ ##
416
+ # Current SSL connection generation
417
+
418
+ attr_reader :ssl_generation # :nodoc:
419
+
420
+ ##
421
+ # Where this instance's SSL connections live in the thread local variables
422
+
423
+ attr_reader :ssl_generation_key # :nodoc:
424
+
425
+ ##
426
+ # SSL version to use.
427
+ #
428
+ # By default, the version will be negotiated automatically between client
429
+ # and server. Ruby 1.9 and newer only.
430
+
431
+ attr_reader :ssl_version if RUBY_VERSION > '1.9'
432
+
433
+ ##
434
+ # Where this instance's last-use times live in the thread local variables
435
+
436
+ attr_reader :timeout_key # :nodoc:
437
+
438
+ ##
439
+ # SSL verification callback. Used when ca_file is set.
440
+
441
+ attr_reader :verify_callback
442
+
443
+ ##
444
+ # HTTPS verify mode. Defaults to OpenSSL::SSL::VERIFY_PEER which verifies
445
+ # the server certificate.
446
+ #
447
+ # If no ca_file or cert_store is set the default system certificate store is
448
+ # used.
449
+ #
450
+ # You can use +verify_mode+ to override any default values.
451
+
452
+ attr_reader :verify_mode
453
+
454
+ ##
455
+ # Enable retries of non-idempotent requests that change data (e.g. POST
456
+ # requests) when the server has disconnected.
457
+ #
458
+ # This will in the worst case lead to multiple requests with the same data,
459
+ # but it may be useful for some applications. Take care when enabling
460
+ # this option to ensure it is safe to POST or perform other non-idempotent
461
+ # requests to the server.
462
+
463
+ attr_accessor :retry_change_requests
464
+
465
+ ##
466
+ # Creates a new Bundler::Persistent::Net::HTTP::Persistent.
467
+ #
468
+ # Set +name+ to keep your connections apart from everybody else's. Not
469
+ # required currently, but highly recommended. Your library name should be
470
+ # good enough. This parameter will be required in a future version.
471
+ #
472
+ # +proxy+ may be set to a URI::HTTP or :ENV to pick up proxy options from
473
+ # the environment. See proxy_from_env for details.
474
+ #
475
+ # In order to use a URI for the proxy you may need to do some extra work
476
+ # beyond URI parsing if the proxy requires a password:
477
+ #
478
+ # proxy = URI 'http://proxy.example'
479
+ # proxy.user = 'AzureDiamond'
480
+ # proxy.password = 'hunter2'
481
+
482
+ def initialize name = nil, proxy = nil
483
+ @name = name
484
+
485
+ @debug_output = nil
486
+ @proxy_uri = nil
487
+ @no_proxy = []
488
+ @headers = {}
489
+ @override_headers = {}
490
+ @http_versions = {}
491
+ @keep_alive = 30
492
+ @open_timeout = nil
493
+ @read_timeout = nil
494
+ @idle_timeout = 5
495
+ @max_requests = nil
496
+ @socket_options = []
497
+
498
+ @socket_options << [Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1] if
499
+ Socket.const_defined? :TCP_NODELAY
500
+
501
+ key = ['net_http_persistent', name].compact
502
+ @generation_key = [key, 'generations' ].join('_').intern
503
+ @ssl_generation_key = [key, 'ssl_generations'].join('_').intern
504
+ @request_key = [key, 'requests' ].join('_').intern
505
+ @timeout_key = [key, 'timeouts' ].join('_').intern
506
+
507
+ @certificate = nil
508
+ @ca_file = nil
509
+ @private_key = nil
510
+ @ssl_version = nil
511
+ @verify_callback = nil
512
+ @verify_mode = nil
513
+ @cert_store = nil
514
+
515
+ @generation = 0 # incremented when proxy URI changes
516
+ @ssl_generation = 0 # incremented when SSL session variables change
517
+
518
+ if HAVE_OPENSSL then
519
+ @verify_mode = OpenSSL::SSL::VERIFY_PEER
520
+ @reuse_ssl_sessions = OpenSSL::SSL.const_defined? :Session
521
+ end
522
+
523
+ @retry_change_requests = false
524
+
525
+ @ruby_1 = RUBY_VERSION < '2'
526
+ @retried_on_ruby_2 = !@ruby_1
527
+
528
+ self.proxy = proxy if proxy
529
+ end
530
+
531
+ ##
532
+ # Sets this client's OpenSSL::X509::Certificate
533
+
534
+ def certificate= certificate
535
+ @certificate = certificate
536
+
537
+ reconnect_ssl
538
+ end
539
+
540
+ # For Net::HTTP parity
541
+ alias cert= certificate=
542
+
543
+ ##
544
+ # Sets the SSL certificate authority file.
545
+
546
+ def ca_file= file
547
+ @ca_file = file
548
+
549
+ reconnect_ssl
550
+ end
551
+
552
+ ##
553
+ # Overrides the default SSL certificate store used for verifying
554
+ # connections.
555
+
556
+ def cert_store= store
557
+ @cert_store = store
558
+
559
+ reconnect_ssl
560
+ end
561
+
562
+ ##
563
+ # Finishes all connections on the given +thread+ that were created before
564
+ # the given +generation+ in the threads +generation_key+ list.
565
+ #
566
+ # See #shutdown for a bunch of scary warning about misusing this method.
567
+
568
+ def cleanup(generation, thread = Thread.current,
569
+ generation_key = @generation_key) # :nodoc:
570
+ timeouts = thread[@timeout_key]
571
+
572
+ (0...generation).each do |old_generation|
573
+ next unless thread[generation_key]
574
+
575
+ conns = thread[generation_key].delete old_generation
576
+
577
+ conns.each_value do |conn|
578
+ finish conn, thread
579
+
580
+ timeouts.delete conn.object_id if timeouts
581
+ end if conns
582
+ end
583
+ end
584
+
585
+ ##
586
+ # Creates a new connection for +uri+
587
+
588
+ def connection_for uri
589
+ Thread.current[@generation_key] ||= Hash.new { |h,k| h[k] = {} }
590
+ Thread.current[@ssl_generation_key] ||= Hash.new { |h,k| h[k] = {} }
591
+ Thread.current[@request_key] ||= Hash.new 0
592
+ Thread.current[@timeout_key] ||= Hash.new EPOCH
593
+
594
+ use_ssl = uri.scheme.downcase == 'https'
595
+
596
+ if use_ssl then
597
+ raise Bundler::Persistent::Net::HTTP::Persistent::Error, 'OpenSSL is not available' unless
598
+ HAVE_OPENSSL
599
+
600
+ ssl_generation = @ssl_generation
601
+
602
+ ssl_cleanup ssl_generation
603
+
604
+ connections = Thread.current[@ssl_generation_key][ssl_generation]
605
+ else
606
+ generation = @generation
607
+
608
+ cleanup generation
609
+
610
+ connections = Thread.current[@generation_key][generation]
611
+ end
612
+
613
+ net_http_args = [uri.host, uri.port]
614
+ connection_id = net_http_args.join ':'
615
+
616
+ if @proxy_uri and not proxy_bypass? uri.host, uri.port then
617
+ connection_id << @proxy_connection_id
618
+ net_http_args.concat @proxy_args
619
+ else
620
+ net_http_args.concat [nil, nil, nil, nil]
621
+ end
622
+
623
+ connection = connections[connection_id]
624
+
625
+ unless connection = connections[connection_id] then
626
+ connections[connection_id] = http_class.new(*net_http_args)
627
+ connection = connections[connection_id]
628
+ ssl connection if use_ssl
629
+ else
630
+ reset connection if expired? connection
631
+ end
632
+
633
+ start connection unless connection.started?
634
+
635
+ connection.read_timeout = @read_timeout if @read_timeout
636
+ connection.keep_alive_timeout = @idle_timeout if @idle_timeout && connection.respond_to?(:keep_alive_timeout=)
637
+
638
+ connection
639
+ rescue Errno::ECONNREFUSED
640
+ address = connection.proxy_address || connection.address
641
+ port = connection.proxy_port || connection.port
642
+
643
+ raise Error, "connection refused: #{address}:#{port}"
644
+ rescue Errno::EHOSTDOWN
645
+ address = connection.proxy_address || connection.address
646
+ port = connection.proxy_port || connection.port
647
+
648
+ raise Error, "host down: #{address}:#{port}"
649
+ end
650
+
651
+ ##
652
+ # Returns an error message containing the number of requests performed on
653
+ # this connection
654
+
655
+ def error_message connection
656
+ requests = Thread.current[@request_key][connection.object_id] - 1 # fixup
657
+ last_use = Thread.current[@timeout_key][connection.object_id]
658
+
659
+ age = Time.now - last_use
660
+
661
+ "after #{requests} requests on #{connection.object_id}, " \
662
+ "last used #{age} seconds ago"
663
+ end
664
+
665
+ ##
666
+ # URI::escape wrapper
667
+
668
+ def escape str
669
+ CGI.escape str if str
670
+ end
671
+
672
+ ##
673
+ # URI::unescape wrapper
674
+
675
+ def unescape str
676
+ CGI.unescape str if str
677
+ end
678
+
679
+
680
+ ##
681
+ # Returns true if the connection should be reset due to an idle timeout, or
682
+ # maximum request count, false otherwise.
683
+
684
+ def expired? connection
685
+ requests = Thread.current[@request_key][connection.object_id]
686
+ return true if @max_requests && requests >= @max_requests
687
+ return false unless @idle_timeout
688
+ return true if @idle_timeout.zero?
689
+
690
+ last_used = Thread.current[@timeout_key][connection.object_id]
691
+
692
+ Time.now - last_used > @idle_timeout
693
+ end
694
+
695
+ ##
696
+ # Starts the Net::HTTP +connection+
697
+
698
+ def start connection
699
+ connection.set_debug_output @debug_output if @debug_output
700
+ connection.open_timeout = @open_timeout if @open_timeout
701
+
702
+ connection.start
703
+
704
+ socket = connection.instance_variable_get :@socket
705
+
706
+ if socket then # for fakeweb
707
+ @socket_options.each do |option|
708
+ socket.io.setsockopt(*option)
709
+ end
710
+ end
711
+ end
712
+
713
+ ##
714
+ # Finishes the Net::HTTP +connection+
715
+
716
+ def finish connection, thread = Thread.current
717
+ if requests = thread[@request_key] then
718
+ requests.delete connection.object_id
719
+ end
720
+
721
+ connection.finish
722
+ rescue IOError
723
+ end
724
+
725
+ def http_class # :nodoc:
726
+ if RUBY_VERSION > '2.0' then
727
+ Net::HTTP
728
+ elsif [:Artifice, :FakeWeb, :WebMock].any? { |klass|
729
+ Object.const_defined?(klass)
730
+ } or not @reuse_ssl_sessions then
731
+ Net::HTTP
732
+ else
733
+ Bundler::Persistent::Net::HTTP::Persistent::SSLReuse
734
+ end
735
+ end
736
+
737
+ ##
738
+ # Returns the HTTP protocol version for +uri+
739
+
740
+ def http_version uri
741
+ @http_versions["#{uri.host}:#{uri.port}"]
742
+ end
743
+
744
+ ##
745
+ # Is +req+ idempotent according to RFC 2616?
746
+
747
+ def idempotent? req
748
+ case req
749
+ when Net::HTTP::Delete, Net::HTTP::Get, Net::HTTP::Head,
750
+ Net::HTTP::Options, Net::HTTP::Put, Net::HTTP::Trace then
751
+ true
752
+ end
753
+ end
754
+
755
+ ##
756
+ # Is the request +req+ idempotent or is retry_change_requests allowed.
757
+ #
758
+ # If +retried_on_ruby_2+ is true, true will be returned if we are on ruby,
759
+ # retry_change_requests is allowed and the request is not idempotent.
760
+
761
+ def can_retry? req, retried_on_ruby_2 = false
762
+ return @retry_change_requests && !idempotent?(req) if retried_on_ruby_2
763
+
764
+ @retry_change_requests || idempotent?(req)
765
+ end
766
+
767
+ if RUBY_VERSION > '1.9' then
768
+ ##
769
+ # Workaround for missing Net::HTTPHeader#connection_close? on Ruby 1.8
770
+
771
+ def connection_close? header
772
+ header.connection_close?
773
+ end
774
+
775
+ ##
776
+ # Workaround for missing Net::HTTPHeader#connection_keep_alive? on Ruby 1.8
777
+
778
+ def connection_keep_alive? header
779
+ header.connection_keep_alive?
780
+ end
781
+ else
782
+ ##
783
+ # Workaround for missing Net::HTTPRequest#connection_close? on Ruby 1.8
784
+
785
+ def connection_close? header
786
+ header['connection'] =~ /close/ or header['proxy-connection'] =~ /close/
787
+ end
788
+
789
+ ##
790
+ # Workaround for missing Net::HTTPRequest#connection_keep_alive? on Ruby
791
+ # 1.8
792
+
793
+ def connection_keep_alive? header
794
+ header['connection'] =~ /keep-alive/ or
795
+ header['proxy-connection'] =~ /keep-alive/
796
+ end
797
+ end
798
+
799
+ ##
800
+ # Deprecated in favor of #expired?
801
+
802
+ def max_age # :nodoc:
803
+ return Time.now + 1 unless @idle_timeout
804
+
805
+ Time.now - @idle_timeout
806
+ end
807
+
808
+ ##
809
+ # Adds "http://" to the String +uri+ if it is missing.
810
+
811
+ def normalize_uri uri
812
+ (uri =~ /^https?:/) ? uri : "http://#{uri}"
813
+ end
814
+
815
+ ##
816
+ # Pipelines +requests+ to the HTTP server at +uri+ yielding responses if a
817
+ # block is given. Returns all responses received.
818
+ #
819
+ # See
820
+ # Net::HTTP::Pipeline[http://docs.seattlerb.org/net-http-pipeline/Net/HTTP/Pipeline.html]
821
+ # for further details.
822
+ #
823
+ # Only if <tt>net-http-pipeline</tt> was required before
824
+ # <tt>net-http-persistent</tt> #pipeline will be present.
825
+
826
+ def pipeline uri, requests, &block # :yields: responses
827
+ connection = connection_for uri
828
+
829
+ connection.pipeline requests, &block
830
+ end
831
+
832
+ ##
833
+ # Sets this client's SSL private key
834
+
835
+ def private_key= key
836
+ @private_key = key
837
+
838
+ reconnect_ssl
839
+ end
840
+
841
+ # For Net::HTTP parity
842
+ alias key= private_key=
843
+
844
+ ##
845
+ # Sets the proxy server. The +proxy+ may be the URI of the proxy server,
846
+ # the symbol +:ENV+ which will read the proxy from the environment or nil to
847
+ # disable use of a proxy. See #proxy_from_env for details on setting the
848
+ # proxy from the environment.
849
+ #
850
+ # If the proxy URI is set after requests have been made, the next request
851
+ # will shut-down and re-open all connections.
852
+ #
853
+ # The +no_proxy+ query parameter can be used to specify hosts which shouldn't
854
+ # be reached via proxy; if set it should be a comma separated list of
855
+ # hostname suffixes, optionally with +:port+ appended, for example
856
+ # <tt>example.com,some.host:8080</tt>.
857
+
858
+ def proxy= proxy
859
+ @proxy_uri = case proxy
860
+ when :ENV then proxy_from_env
861
+ when URI::HTTP then proxy
862
+ when nil then # ignore
863
+ else raise ArgumentError, 'proxy must be :ENV or a URI::HTTP'
864
+ end
865
+
866
+ @no_proxy.clear
867
+
868
+ if @proxy_uri then
869
+ @proxy_args = [
870
+ @proxy_uri.host,
871
+ @proxy_uri.port,
872
+ unescape(@proxy_uri.user),
873
+ unescape(@proxy_uri.password),
874
+ ]
875
+
876
+ @proxy_connection_id = [nil, *@proxy_args].join ':'
877
+
878
+ if @proxy_uri.query then
879
+ @no_proxy = CGI.parse(@proxy_uri.query)['no_proxy'].join(',').downcase.split(',').map { |x| x.strip }.reject { |x| x.empty? }
880
+ end
881
+ end
882
+
883
+ reconnect
884
+ reconnect_ssl
885
+ end
886
+
887
+ ##
888
+ # Creates a URI for an HTTP proxy server from ENV variables.
889
+ #
890
+ # If +HTTP_PROXY+ is set a proxy will be returned.
891
+ #
892
+ # If +HTTP_PROXY_USER+ or +HTTP_PROXY_PASS+ are set the URI is given the
893
+ # indicated user and password unless HTTP_PROXY contains either of these in
894
+ # the URI.
895
+ #
896
+ # The +NO_PROXY+ ENV variable can be used to specify hosts which shouldn't
897
+ # be reached via proxy; if set it should be a comma separated list of
898
+ # hostname suffixes, optionally with +:port+ appended, for example
899
+ # <tt>example.com,some.host:8080</tt>. When set to <tt>*</tt> no proxy will
900
+ # be returned.
901
+ #
902
+ # For Windows users, lowercase ENV variables are preferred over uppercase ENV
903
+ # variables.
904
+
905
+ def proxy_from_env
906
+ env_proxy = ENV['http_proxy'] || ENV['HTTP_PROXY']
907
+
908
+ return nil if env_proxy.nil? or env_proxy.empty?
909
+
910
+ uri = URI normalize_uri env_proxy
911
+
912
+ env_no_proxy = ENV['no_proxy'] || ENV['NO_PROXY']
913
+
914
+ # '*' is special case for always bypass
915
+ return nil if env_no_proxy == '*'
916
+
917
+ if env_no_proxy then
918
+ uri.query = "no_proxy=#{escape(env_no_proxy)}"
919
+ end
920
+
921
+ unless uri.user or uri.password then
922
+ uri.user = escape ENV['http_proxy_user'] || ENV['HTTP_PROXY_USER']
923
+ uri.password = escape ENV['http_proxy_pass'] || ENV['HTTP_PROXY_PASS']
924
+ end
925
+
926
+ uri
927
+ end
928
+
929
+ ##
930
+ # Returns true when proxy should by bypassed for host.
931
+
932
+ def proxy_bypass? host, port
933
+ host = host.downcase
934
+ host_port = [host, port].join ':'
935
+
936
+ @no_proxy.each do |name|
937
+ return true if host[-name.length, name.length] == name or
938
+ host_port[-name.length, name.length] == name
939
+ end
940
+
941
+ false
942
+ end
943
+
944
+ ##
945
+ # Forces reconnection of HTTP connections.
946
+
947
+ def reconnect
948
+ @generation += 1
949
+ end
950
+
951
+ ##
952
+ # Forces reconnection of SSL connections.
953
+
954
+ def reconnect_ssl
955
+ @ssl_generation += 1
956
+ end
957
+
958
+ ##
959
+ # Finishes then restarts the Net::HTTP +connection+
960
+
961
+ def reset connection
962
+ Thread.current[@request_key].delete connection.object_id
963
+ Thread.current[@timeout_key].delete connection.object_id
964
+
965
+ finish connection
966
+
967
+ start connection
968
+ rescue Errno::ECONNREFUSED
969
+ e = Error.new "connection refused: #{connection.address}:#{connection.port}"
970
+ e.set_backtrace $@
971
+ raise e
972
+ rescue Errno::EHOSTDOWN
973
+ e = Error.new "host down: #{connection.address}:#{connection.port}"
974
+ e.set_backtrace $@
975
+ raise e
976
+ end
977
+
978
+ ##
979
+ # Makes a request on +uri+. If +req+ is nil a Net::HTTP::Get is performed
980
+ # against +uri+.
981
+ #
982
+ # If a block is passed #request behaves like Net::HTTP#request (the body of
983
+ # the response will not have been read).
984
+ #
985
+ # +req+ must be a Net::HTTPRequest subclass (see Net::HTTP for a list).
986
+ #
987
+ # If there is an error and the request is idempotent according to RFC 2616
988
+ # it will be retried automatically.
989
+
990
+ def request uri, req = nil, &block
991
+ retried = false
992
+ bad_response = false
993
+
994
+ req = request_setup req || uri
995
+
996
+ connection = connection_for uri
997
+ connection_id = connection.object_id
998
+
999
+ begin
1000
+ Thread.current[@request_key][connection_id] += 1
1001
+ response = connection.request req, &block
1002
+
1003
+ if connection_close?(req) or
1004
+ (response.http_version <= '1.0' and
1005
+ not connection_keep_alive?(response)) or
1006
+ connection_close?(response) then
1007
+ connection.finish
1008
+ end
1009
+ rescue Net::HTTPBadResponse => e
1010
+ message = error_message connection
1011
+
1012
+ finish connection
1013
+
1014
+ raise Error, "too many bad responses #{message}" if
1015
+ bad_response or not can_retry? req
1016
+
1017
+ bad_response = true
1018
+ retry
1019
+ rescue *RETRIED_EXCEPTIONS => e # retried on ruby 2
1020
+ request_failed e, req, connection if
1021
+ retried or not can_retry? req, @retried_on_ruby_2
1022
+
1023
+ reset connection
1024
+
1025
+ retried = true
1026
+ retry
1027
+ rescue Errno::EINVAL, Errno::ETIMEDOUT => e # not retried on ruby 2
1028
+ request_failed e, req, connection if retried or not can_retry? req
1029
+
1030
+ reset connection
1031
+
1032
+ retried = true
1033
+ retry
1034
+ rescue Exception => e
1035
+ finish connection
1036
+
1037
+ raise
1038
+ ensure
1039
+ Thread.current[@timeout_key][connection_id] = Time.now
1040
+ end
1041
+
1042
+ @http_versions["#{uri.host}:#{uri.port}"] ||= response.http_version
1043
+
1044
+ response
1045
+ end
1046
+
1047
+ ##
1048
+ # Raises an Error for +exception+ which resulted from attempting the request
1049
+ # +req+ on the +connection+.
1050
+ #
1051
+ # Finishes the +connection+.
1052
+
1053
+ def request_failed exception, req, connection # :nodoc:
1054
+ due_to = "(due to #{exception.message} - #{exception.class})"
1055
+ message = "too many connection resets #{due_to} #{error_message connection}"
1056
+
1057
+ finish connection
1058
+
1059
+
1060
+ raise Error, message, exception.backtrace
1061
+ end
1062
+
1063
+ ##
1064
+ # Creates a GET request if +req_or_uri+ is a URI and adds headers to the
1065
+ # request.
1066
+ #
1067
+ # Returns the request.
1068
+
1069
+ def request_setup req_or_uri # :nodoc:
1070
+ req = if URI === req_or_uri then
1071
+ Net::HTTP::Get.new req_or_uri.request_uri
1072
+ else
1073
+ req_or_uri
1074
+ end
1075
+
1076
+ @headers.each do |pair|
1077
+ req.add_field(*pair)
1078
+ end
1079
+
1080
+ @override_headers.each do |name, value|
1081
+ req[name] = value
1082
+ end
1083
+
1084
+ unless req['Connection'] then
1085
+ req.add_field 'Connection', 'keep-alive'
1086
+ req.add_field 'Keep-Alive', @keep_alive
1087
+ end
1088
+
1089
+ req
1090
+ end
1091
+
1092
+ ##
1093
+ # Shuts down all connections for +thread+.
1094
+ #
1095
+ # Uses the current thread by default.
1096
+ #
1097
+ # If you've used Bundler::Persistent::Net::HTTP::Persistent across multiple threads you should
1098
+ # call this in each thread when you're done making HTTP requests.
1099
+ #
1100
+ # *NOTE*: Calling shutdown for another thread can be dangerous!
1101
+ #
1102
+ # If the thread is still using the connection it may cause an error! It is
1103
+ # best to call #shutdown in the thread at the appropriate time instead!
1104
+
1105
+ def shutdown thread = Thread.current
1106
+ generation = reconnect
1107
+ cleanup generation, thread, @generation_key
1108
+
1109
+ ssl_generation = reconnect_ssl
1110
+ cleanup ssl_generation, thread, @ssl_generation_key
1111
+
1112
+ thread[@request_key] = nil
1113
+ thread[@timeout_key] = nil
1114
+ end
1115
+
1116
+ ##
1117
+ # Shuts down all connections in all threads
1118
+ #
1119
+ # *NOTE*: THIS METHOD IS VERY DANGEROUS!
1120
+ #
1121
+ # Do not call this method if other threads are still using their
1122
+ # connections! Call #shutdown at the appropriate time instead!
1123
+ #
1124
+ # Use this method only as a last resort!
1125
+
1126
+ def shutdown_in_all_threads
1127
+ Thread.list.each do |thread|
1128
+ shutdown thread
1129
+ end
1130
+
1131
+ nil
1132
+ end
1133
+
1134
+ ##
1135
+ # Enables SSL on +connection+
1136
+
1137
+ def ssl connection
1138
+ connection.use_ssl = true
1139
+
1140
+ connection.ssl_version = @ssl_version if @ssl_version
1141
+
1142
+ connection.verify_mode = @verify_mode
1143
+
1144
+ if OpenSSL::SSL::VERIFY_PEER == OpenSSL::SSL::VERIFY_NONE and
1145
+ not Object.const_defined?(:I_KNOW_THAT_OPENSSL_VERIFY_PEER_EQUALS_VERIFY_NONE_IS_WRONG) then
1146
+ warn <<-WARNING
1147
+ !!!SECURITY WARNING!!!
1148
+
1149
+ The SSL HTTP connection to:
1150
+
1151
+ #{connection.address}:#{connection.port}
1152
+
1153
+ !!!MAY NOT BE VERIFIED!!!
1154
+
1155
+ On your platform your OpenSSL implementation is broken.
1156
+
1157
+ There is no difference between the values of VERIFY_NONE and VERIFY_PEER.
1158
+
1159
+ This means that attempting to verify the security of SSL connections may not
1160
+ work. This exposes you to man-in-the-middle exploits, snooping on the
1161
+ contents of your connection and other dangers to the security of your data.
1162
+
1163
+ To disable this warning define the following constant at top-level in your
1164
+ application:
1165
+
1166
+ I_KNOW_THAT_OPENSSL_VERIFY_PEER_EQUALS_VERIFY_NONE_IS_WRONG = nil
1167
+
1168
+ WARNING
1169
+ end
1170
+
1171
+ if @ca_file then
1172
+ connection.ca_file = @ca_file
1173
+ connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
1174
+ connection.verify_callback = @verify_callback if @verify_callback
1175
+ end
1176
+
1177
+ if @certificate and @private_key then
1178
+ connection.cert = @certificate
1179
+ connection.key = @private_key
1180
+ end
1181
+
1182
+ connection.cert_store = if @cert_store then
1183
+ @cert_store
1184
+ else
1185
+ store = OpenSSL::X509::Store.new
1186
+ store.set_default_paths
1187
+ store
1188
+ end
1189
+ end
1190
+
1191
+ ##
1192
+ # Finishes all connections that existed before the given SSL parameter
1193
+ # +generation+.
1194
+
1195
+ def ssl_cleanup generation # :nodoc:
1196
+ cleanup generation, Thread.current, @ssl_generation_key
1197
+ end
1198
+
1199
+ ##
1200
+ # SSL version to use
1201
+
1202
+ def ssl_version= ssl_version
1203
+ @ssl_version = ssl_version
1204
+
1205
+ reconnect_ssl
1206
+ end if RUBY_VERSION > '1.9'
1207
+
1208
+ ##
1209
+ # Sets the HTTPS verify mode. Defaults to OpenSSL::SSL::VERIFY_PEER.
1210
+ #
1211
+ # Setting this to VERIFY_NONE is a VERY BAD IDEA and should NEVER be used.
1212
+ # Securely transfer the correct certificate and update the default
1213
+ # certificate store or set the ca file instead.
1214
+
1215
+ def verify_mode= verify_mode
1216
+ @verify_mode = verify_mode
1217
+
1218
+ reconnect_ssl
1219
+ end
1220
+
1221
+ ##
1222
+ # SSL verification callback.
1223
+
1224
+ def verify_callback= callback
1225
+ @verify_callback = callback
1226
+
1227
+ reconnect_ssl
1228
+ end
1229
+
1230
+ end
1231
+
1232
+ require 'bundler/vendor/net-http-persistent/lib/net/http/persistent/ssl_reuse'
1233
+