rubygems-update 3.4.22 → 3.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (540) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +105 -2
  3. data/Manifest.txt +46 -221
  4. data/README.md +1 -3
  5. data/bundler/CHANGELOG.md +63 -0
  6. data/bundler/bundler.gemspec +4 -2
  7. data/bundler/exe/bundle +1 -10
  8. data/bundler/lib/bundler/build_metadata.rb +3 -3
  9. data/bundler/lib/bundler/capistrano.rb +1 -1
  10. data/bundler/lib/bundler/checksum.rb +254 -0
  11. data/bundler/lib/bundler/ci_detector.rb +75 -0
  12. data/bundler/lib/bundler/cli/add.rb +3 -3
  13. data/bundler/lib/bundler/cli/binstubs.rb +4 -4
  14. data/bundler/lib/bundler/cli/cache.rb +1 -1
  15. data/bundler/lib/bundler/cli/check.rb +1 -1
  16. data/bundler/lib/bundler/cli/common.rb +9 -1
  17. data/bundler/lib/bundler/cli/config.rb +8 -7
  18. data/bundler/lib/bundler/cli/console.rb +3 -2
  19. data/bundler/lib/bundler/cli/doctor.rb +2 -2
  20. data/bundler/lib/bundler/cli/exec.rb +1 -1
  21. data/bundler/lib/bundler/cli/gem.rb +28 -23
  22. data/bundler/lib/bundler/cli/info.rb +2 -13
  23. data/bundler/lib/bundler/cli/install.rb +5 -4
  24. data/bundler/lib/bundler/cli/issue.rb +1 -1
  25. data/bundler/lib/bundler/cli/lock.rb +4 -4
  26. data/bundler/lib/bundler/cli/open.rb +1 -1
  27. data/bundler/lib/bundler/cli/outdated.rb +6 -6
  28. data/bundler/lib/bundler/cli/plugin.rb +7 -14
  29. data/bundler/lib/bundler/cli/pristine.rb +38 -30
  30. data/bundler/lib/bundler/cli/show.rb +2 -2
  31. data/bundler/lib/bundler/cli/update.rb +5 -5
  32. data/bundler/lib/bundler/cli.rb +215 -263
  33. data/bundler/lib/bundler/compact_index_client/cache.rb +29 -9
  34. data/bundler/lib/bundler/compact_index_client/cache_file.rb +153 -0
  35. data/bundler/lib/bundler/compact_index_client/gem_parser.rb +7 -3
  36. data/bundler/lib/bundler/compact_index_client/updater.rb +79 -81
  37. data/bundler/lib/bundler/compact_index_client.rb +14 -7
  38. data/bundler/lib/bundler/constants.rb +1 -1
  39. data/bundler/lib/bundler/current_ruby.rb +5 -21
  40. data/bundler/lib/bundler/definition.rb +42 -15
  41. data/bundler/lib/bundler/dependency.rb +16 -12
  42. data/bundler/lib/bundler/digest.rb +2 -2
  43. data/bundler/lib/bundler/dsl.rb +46 -30
  44. data/bundler/lib/bundler/endpoint_specification.rb +5 -1
  45. data/bundler/lib/bundler/env.rb +1 -3
  46. data/bundler/lib/bundler/errors.rb +43 -0
  47. data/bundler/lib/bundler/fetcher/base.rb +3 -1
  48. data/bundler/lib/bundler/fetcher/compact_index.rb +4 -4
  49. data/bundler/lib/bundler/fetcher/downloader.rb +13 -11
  50. data/bundler/lib/bundler/fetcher/gem_remote_fetcher.rb +16 -0
  51. data/bundler/lib/bundler/fetcher/index.rb +1 -1
  52. data/bundler/lib/bundler/fetcher.rb +28 -25
  53. data/bundler/lib/bundler/friendly_errors.rb +5 -5
  54. data/bundler/lib/bundler/gem_helper.rb +1 -1
  55. data/bundler/lib/bundler/gem_helpers.rb +5 -2
  56. data/bundler/lib/bundler/graph.rb +9 -9
  57. data/bundler/lib/bundler/index.rb +1 -2
  58. data/bundler/lib/bundler/injector.rb +1 -1
  59. data/bundler/lib/bundler/inline.rb +3 -3
  60. data/bundler/lib/bundler/installer/gem_installer.rb +5 -5
  61. data/bundler/lib/bundler/installer/parallel_installer.rb +16 -8
  62. data/bundler/lib/bundler/installer/standalone.rb +2 -3
  63. data/bundler/lib/bundler/installer.rb +9 -9
  64. data/bundler/lib/bundler/lazy_specification.rb +24 -17
  65. data/bundler/lib/bundler/lockfile_generator.rb +9 -0
  66. data/bundler/lib/bundler/lockfile_parser.rb +81 -10
  67. data/bundler/lib/bundler/man/bundle-add.1 +3 -26
  68. data/bundler/lib/bundler/man/bundle-binstubs.1 +4 -16
  69. data/bundler/lib/bundler/man/bundle-cache.1 +3 -24
  70. data/bundler/lib/bundler/man/bundle-check.1 +3 -12
  71. data/bundler/lib/bundler/man/bundle-clean.1 +3 -10
  72. data/bundler/lib/bundler/man/bundle-config.1 +20 -211
  73. data/bundler/lib/bundler/man/bundle-config.1.ronn +6 -0
  74. data/bundler/lib/bundler/man/bundle-console.1 +4 -22
  75. data/bundler/lib/bundler/man/bundle-doctor.1 +4 -18
  76. data/bundler/lib/bundler/man/bundle-exec.1 +12 -73
  77. data/bundler/lib/bundler/man/bundle-gem.1 +13 -49
  78. data/bundler/lib/bundler/man/bundle-help.1 +3 -7
  79. data/bundler/lib/bundler/man/bundle-info.1 +3 -9
  80. data/bundler/lib/bundler/man/bundle-init.1 +3 -12
  81. data/bundler/lib/bundler/man/bundle-inject.1 +6 -19
  82. data/bundler/lib/bundler/man/bundle-install.1 +27 -125
  83. data/bundler/lib/bundler/man/bundle-install.1.ronn +1 -0
  84. data/bundler/lib/bundler/man/bundle-list.1 +4 -19
  85. data/bundler/lib/bundler/man/bundle-lock.1 +5 -29
  86. data/bundler/lib/bundler/man/bundle-open.1 +7 -27
  87. data/bundler/lib/bundler/man/bundle-outdated.1 +3 -55
  88. data/bundler/lib/bundler/man/bundle-outdated.1.ronn +1 -0
  89. data/bundler/lib/bundler/man/bundle-platform.1 +5 -27
  90. data/bundler/lib/bundler/man/bundle-plugin.1 +3 -29
  91. data/bundler/lib/bundler/man/bundle-pristine.1 +5 -16
  92. data/bundler/lib/bundler/man/bundle-remove.1 +4 -14
  93. data/bundler/lib/bundler/man/bundle-show.1 +3 -10
  94. data/bundler/lib/bundler/man/bundle-update.1 +18 -137
  95. data/bundler/lib/bundler/man/bundle-version.1 +3 -16
  96. data/bundler/lib/bundler/man/bundle-viz.1 +4 -16
  97. data/bundler/lib/bundler/man/bundle.1 +5 -44
  98. data/bundler/lib/bundler/man/gemfile.5 +24 -301
  99. data/bundler/lib/bundler/man/gemfile.5.ronn +4 -0
  100. data/bundler/lib/bundler/match_metadata.rb +4 -0
  101. data/bundler/lib/bundler/match_platform.rb +1 -1
  102. data/bundler/lib/bundler/plugin/api/source.rb +3 -2
  103. data/bundler/lib/bundler/plugin/installer.rb +1 -1
  104. data/bundler/lib/bundler/plugin.rb +3 -3
  105. data/bundler/lib/bundler/resolver/base.rb +1 -1
  106. data/bundler/lib/bundler/resolver/incompatibility.rb +1 -1
  107. data/bundler/lib/bundler/resolver/spec_group.rb +1 -4
  108. data/bundler/lib/bundler/resolver.rb +16 -16
  109. data/bundler/lib/bundler/ruby_dsl.rb +20 -12
  110. data/bundler/lib/bundler/ruby_version.rb +1 -1
  111. data/bundler/lib/bundler/rubygems_ext.rb +24 -50
  112. data/bundler/lib/bundler/rubygems_gem_installer.rb +6 -56
  113. data/bundler/lib/bundler/rubygems_integration.rb +25 -94
  114. data/bundler/lib/bundler/runtime.rb +2 -2
  115. data/bundler/lib/bundler/self_manager.rb +23 -7
  116. data/bundler/lib/bundler/settings.rb +27 -7
  117. data/bundler/lib/bundler/setup.rb +4 -1
  118. data/bundler/lib/bundler/shared_helpers.rb +35 -13
  119. data/bundler/lib/bundler/source/git/git_proxy.rb +15 -15
  120. data/bundler/lib/bundler/source/git.rb +4 -3
  121. data/bundler/lib/bundler/source/metadata.rb +15 -15
  122. data/bundler/lib/bundler/source/path.rb +7 -6
  123. data/bundler/lib/bundler/source/rubygems.rb +21 -14
  124. data/bundler/lib/bundler/source.rb +2 -0
  125. data/bundler/lib/bundler/spec_set.rb +38 -10
  126. data/bundler/lib/bundler/stub_specification.rb +1 -0
  127. data/bundler/lib/bundler/templates/Executable.bundler +1 -1
  128. data/bundler/lib/bundler/templates/newgem/README.md.tt +3 -3
  129. data/bundler/lib/bundler/templates/newgem/Rakefile.tt +2 -6
  130. data/bundler/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt +1 -1
  131. data/bundler/lib/bundler/templates/newgem/standard.yml.tt +1 -1
  132. data/bundler/lib/bundler/ui/shell.rb +1 -1
  133. data/bundler/lib/bundler/vendor/connection_pool/.document +1 -0
  134. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
  135. data/bundler/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +53 -6
  136. data/bundler/lib/bundler/vendor/fileutils/.document +1 -0
  137. data/bundler/lib/bundler/vendor/fileutils/lib/fileutils.rb +8 -20
  138. data/bundler/lib/bundler/vendor/net-http-persistent/.document +1 -0
  139. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb +3 -3
  140. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +2 -2
  141. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +1 -1
  142. data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +34 -34
  143. data/bundler/lib/bundler/vendor/pub_grub/.document +1 -0
  144. data/bundler/lib/bundler/vendor/thor/.document +1 -0
  145. data/bundler/lib/bundler/vendor/tsort/.document +1 -0
  146. data/bundler/lib/bundler/vendor/tsort/lib/tsort.rb +3 -0
  147. data/bundler/lib/bundler/vendor/uri/.document +1 -0
  148. data/bundler/lib/bundler/vendor/uri/lib/uri/common.rb +256 -132
  149. data/bundler/lib/bundler/vendor/uri/lib/uri/generic.rb +1 -0
  150. data/bundler/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +95 -31
  151. data/bundler/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
  152. data/bundler/lib/bundler/vendored_net_http.rb +8 -0
  153. data/bundler/lib/bundler/vendored_persistent.rb +0 -4
  154. data/bundler/lib/bundler/vendored_timeout.rb +8 -0
  155. data/bundler/lib/bundler/version.rb +1 -1
  156. data/bundler/lib/bundler/vlad.rb +1 -1
  157. data/bundler/lib/bundler/yaml_serializer.rb +3 -3
  158. data/bundler/lib/bundler.rb +41 -32
  159. data/lib/rubygems/available_set.rb +4 -4
  160. data/lib/rubygems/basic_specification.rb +35 -37
  161. data/lib/rubygems/bundler_version_finder.rb +4 -4
  162. data/lib/rubygems/ci_detector.rb +75 -0
  163. data/lib/rubygems/command.rb +13 -15
  164. data/lib/rubygems/command_manager.rb +5 -4
  165. data/lib/rubygems/commands/build_command.rb +2 -2
  166. data/lib/rubygems/commands/cert_command.rb +1 -2
  167. data/lib/rubygems/commands/check_command.rb +4 -4
  168. data/lib/rubygems/commands/cleanup_command.rb +12 -14
  169. data/lib/rubygems/commands/contents_command.rb +4 -4
  170. data/lib/rubygems/commands/dependency_command.rb +4 -5
  171. data/lib/rubygems/commands/environment_command.rb +1 -3
  172. data/lib/rubygems/commands/exec_command.rb +1 -1
  173. data/lib/rubygems/commands/fetch_command.rb +2 -2
  174. data/lib/rubygems/commands/generate_index_command.rb +39 -74
  175. data/lib/rubygems/commands/help_command.rb +3 -3
  176. data/lib/rubygems/commands/info_command.rb +2 -2
  177. data/lib/rubygems/commands/install_command.rb +8 -16
  178. data/lib/rubygems/commands/list_command.rb +2 -2
  179. data/lib/rubygems/commands/lock_command.rb +1 -1
  180. data/lib/rubygems/commands/open_command.rb +1 -1
  181. data/lib/rubygems/commands/owner_command.rb +1 -1
  182. data/lib/rubygems/commands/pristine_command.rb +13 -15
  183. data/lib/rubygems/commands/push_command.rb +2 -2
  184. data/lib/rubygems/commands/query_command.rb +4 -5
  185. data/lib/rubygems/commands/rdoc_command.rb +2 -2
  186. data/lib/rubygems/commands/search_command.rb +2 -2
  187. data/lib/rubygems/commands/setup_command.rb +31 -34
  188. data/lib/rubygems/commands/sources_command.rb +12 -12
  189. data/lib/rubygems/commands/specification_command.rb +10 -10
  190. data/lib/rubygems/commands/stale_command.rb +1 -1
  191. data/lib/rubygems/commands/uninstall_command.rb +9 -10
  192. data/lib/rubygems/commands/unpack_command.rb +4 -4
  193. data/lib/rubygems/commands/update_command.rb +10 -12
  194. data/lib/rubygems/commands/which_command.rb +1 -1
  195. data/lib/rubygems/commands/yank_command.rb +1 -1
  196. data/lib/rubygems/compatibility.rb +5 -6
  197. data/lib/rubygems/config_file.rb +4 -4
  198. data/lib/rubygems/core_ext/kernel_gem.rb +0 -2
  199. data/lib/rubygems/core_ext/kernel_require.rb +19 -48
  200. data/lib/rubygems/core_ext/kernel_warn.rb +1 -1
  201. data/lib/rubygems/core_ext/tcpsocket_init.rb +1 -1
  202. data/lib/rubygems/defaults.rb +15 -3
  203. data/lib/rubygems/dependency.rb +12 -14
  204. data/lib/rubygems/dependency_installer.rb +29 -30
  205. data/lib/rubygems/dependency_list.rb +1 -1
  206. data/lib/rubygems/deprecate.rb +16 -15
  207. data/lib/rubygems/doctor.rb +5 -5
  208. data/lib/rubygems/errors.rb +2 -6
  209. data/lib/rubygems/exceptions.rb +2 -1
  210. data/lib/rubygems/ext/builder.rb +15 -10
  211. data/lib/rubygems/ext/cargo_builder.rb +5 -5
  212. data/lib/rubygems/ext/ext_conf_builder.rb +1 -3
  213. data/lib/rubygems/gem_runner.rb +4 -4
  214. data/lib/rubygems/gemcutter_utilities/webauthn_listener/response.rb +3 -3
  215. data/lib/rubygems/gemcutter_utilities/webauthn_poller.rb +3 -3
  216. data/lib/rubygems/gemcutter_utilities.rb +18 -19
  217. data/lib/rubygems/install_update_options.rb +18 -19
  218. data/lib/rubygems/installer.rb +59 -33
  219. data/lib/rubygems/installer_uninstaller_utils.rb +0 -2
  220. data/lib/rubygems/local_remote_options.rb +7 -10
  221. data/lib/rubygems/name_tuple.rb +7 -9
  222. data/lib/rubygems/net/http.rb +3 -0
  223. data/lib/rubygems/net-http/.document +1 -0
  224. data/lib/rubygems/net-http/LICENSE.txt +22 -0
  225. data/lib/rubygems/net-http/lib/net/http/backward.rb +40 -0
  226. data/lib/rubygems/net-http/lib/net/http/exceptions.rb +34 -0
  227. data/lib/rubygems/net-http/lib/net/http/generic_request.rb +414 -0
  228. data/lib/rubygems/net-http/lib/net/http/header.rb +981 -0
  229. data/lib/rubygems/net-http/lib/net/http/proxy_delta.rb +17 -0
  230. data/lib/rubygems/net-http/lib/net/http/request.rb +88 -0
  231. data/lib/rubygems/net-http/lib/net/http/requests.rb +425 -0
  232. data/lib/rubygems/net-http/lib/net/http/response.rb +738 -0
  233. data/lib/rubygems/net-http/lib/net/http/responses.rb +1174 -0
  234. data/lib/rubygems/net-http/lib/net/http/status.rb +84 -0
  235. data/lib/rubygems/net-http/lib/net/http.rb +2496 -0
  236. data/lib/rubygems/net-http/lib/net/https.rb +23 -0
  237. data/lib/rubygems/net-protocol/.document +1 -0
  238. data/lib/rubygems/net-protocol/LICENSE.txt +22 -0
  239. data/lib/rubygems/net-protocol/lib/net/protocol.rb +544 -0
  240. data/lib/rubygems/optparse/lib/optparse.rb +39 -17
  241. data/lib/rubygems/package/old.rb +2 -2
  242. data/lib/rubygems/package/tar_header.rb +45 -39
  243. data/lib/rubygems/package/tar_reader/entry.rb +5 -4
  244. data/lib/rubygems/package/tar_reader.rb +5 -3
  245. data/lib/rubygems/package/tar_writer.rb +19 -17
  246. data/lib/rubygems/package.rb +27 -26
  247. data/lib/rubygems/package_task.rb +2 -2
  248. data/lib/rubygems/path_support.rb +9 -10
  249. data/lib/rubygems/platform.rb +60 -45
  250. data/lib/rubygems/query_utils.rb +7 -9
  251. data/lib/rubygems/remote_fetcher.rb +15 -15
  252. data/lib/rubygems/request/connection_pools.rb +3 -3
  253. data/lib/rubygems/request.rb +20 -17
  254. data/lib/rubygems/request_set/gem_dependency_api.rb +119 -122
  255. data/lib/rubygems/request_set/lockfile/parser.rb +9 -9
  256. data/lib/rubygems/request_set/lockfile/tokenizer.rb +20 -12
  257. data/lib/rubygems/request_set/lockfile.rb +6 -11
  258. data/lib/rubygems/request_set.rb +5 -5
  259. data/lib/rubygems/requirement.rb +7 -7
  260. data/lib/rubygems/resolv/.document +1 -0
  261. data/lib/rubygems/resolv/LICENSE.txt +22 -0
  262. data/lib/rubygems/resolv/lib/resolv.rb +3387 -0
  263. data/lib/rubygems/resolver/activation_request.rb +1 -3
  264. data/lib/rubygems/resolver/api_set/gem_parser.rb +7 -3
  265. data/lib/rubygems/resolver/best_set.rb +1 -1
  266. data/lib/rubygems/resolver/composed_set.rb +1 -1
  267. data/lib/rubygems/resolver/conflict.rb +4 -12
  268. data/lib/rubygems/resolver/index_set.rb +4 -4
  269. data/lib/rubygems/resolver/index_specification.rb +2 -2
  270. data/lib/rubygems/resolver/installer_set.rb +5 -6
  271. data/lib/rubygems/resolver/lock_set.rb +1 -1
  272. data/lib/rubygems/resolver/molinillo/.document +1 -0
  273. data/lib/rubygems/resolver.rb +3 -10
  274. data/lib/rubygems/s3_uri_signer.rb +6 -6
  275. data/lib/rubygems/safe_marshal/elements.rb +138 -0
  276. data/lib/rubygems/safe_marshal/reader.rb +306 -0
  277. data/lib/rubygems/safe_marshal/visitors/stream_printer.rb +31 -0
  278. data/lib/rubygems/safe_marshal/visitors/to_ruby.rb +385 -0
  279. data/lib/rubygems/safe_marshal/visitors/visitor.rb +74 -0
  280. data/lib/rubygems/safe_marshal.rb +74 -0
  281. data/lib/rubygems/safe_yaml.rb +5 -28
  282. data/lib/rubygems/security/policies.rb +36 -38
  283. data/lib/rubygems/security/policy.rb +7 -11
  284. data/lib/rubygems/security/signer.rb +1 -1
  285. data/lib/rubygems/security/trust_dir.rb +3 -3
  286. data/lib/rubygems/security.rb +8 -22
  287. data/lib/rubygems/source/git.rb +1 -3
  288. data/lib/rubygems/source/installed.rb +0 -2
  289. data/lib/rubygems/source/local.rb +5 -8
  290. data/lib/rubygems/source/lock.rb +1 -3
  291. data/lib/rubygems/source/specific_file.rb +0 -1
  292. data/lib/rubygems/source/vendor.rb +0 -2
  293. data/lib/rubygems/source.rb +12 -12
  294. data/lib/rubygems/source_list.rb +4 -4
  295. data/lib/rubygems/spec_fetcher.rb +29 -29
  296. data/lib/rubygems/specification.rb +125 -138
  297. data/lib/rubygems/specification_policy.rb +55 -25
  298. data/lib/rubygems/stub_specification.rb +4 -5
  299. data/lib/rubygems/text.rb +1 -2
  300. data/lib/rubygems/timeout/.document +1 -0
  301. data/lib/rubygems/timeout/LICENSE.txt +22 -0
  302. data/lib/rubygems/timeout/lib/timeout.rb +199 -0
  303. data/lib/rubygems/timeout.rb +3 -0
  304. data/lib/rubygems/tsort/lib/tsort.rb +3 -0
  305. data/lib/rubygems/uninstaller.rb +7 -9
  306. data/lib/rubygems/update_suggestion.rb +5 -18
  307. data/lib/rubygems/uri_formatter.rb +1 -1
  308. data/lib/rubygems/user_interaction.rb +15 -21
  309. data/lib/rubygems/util/licenses.rb +65 -35
  310. data/lib/rubygems/util/list.rb +3 -1
  311. data/lib/rubygems/util.rb +2 -4
  312. data/lib/rubygems/validator.rb +5 -3
  313. data/lib/rubygems/version.rb +34 -28
  314. data/lib/rubygems/version_option.rb +2 -5
  315. data/lib/rubygems/yaml_serializer.rb +3 -3
  316. data/lib/rubygems.rb +37 -37
  317. data/rubygems-update.gemspec +4 -4
  318. data/setup.rb +2 -2
  319. metadata +50 -225
  320. data/lib/rubygems/indexer.rb +0 -428
  321. data/lib/rubygems/mock_gem_ui.rb +0 -86
  322. data/test/rubygems/alternate_cert.pem +0 -19
  323. data/test/rubygems/alternate_cert_32.pem +0 -19
  324. data/test/rubygems/alternate_key.pem +0 -27
  325. data/test/rubygems/bad_rake.rb +0 -3
  326. data/test/rubygems/bundler_test_gem.rb +0 -424
  327. data/test/rubygems/ca_cert.pem +0 -77
  328. data/test/rubygems/child_cert.pem +0 -19
  329. data/test/rubygems/child_cert_32.pem +0 -19
  330. data/test/rubygems/child_key.pem +0 -27
  331. data/test/rubygems/client.pem +0 -107
  332. data/test/rubygems/data/excon-0.7.7.gemspec.rz +0 -0
  333. data/test/rubygems/data/gem-private_key.pem +0 -27
  334. data/test/rubygems/data/gem-public_cert.pem +0 -20
  335. data/test/rubygems/data/null-required-ruby-version.gemspec.rz +0 -0
  336. data/test/rubygems/data/null-required-rubygems-version.gemspec.rz +0 -0
  337. data/test/rubygems/data/pry-0.4.7.gemspec.rz +0 -0
  338. data/test/rubygems/encrypted_private_key.pem +0 -30
  339. data/test/rubygems/expired_cert.pem +0 -19
  340. data/test/rubygems/fake_certlib/openssl.rb +0 -9
  341. data/test/rubygems/foo/discover.rb +0 -1
  342. data/test/rubygems/future_cert.pem +0 -19
  343. data/test/rubygems/future_cert_32.pem +0 -19
  344. data/test/rubygems/good_rake.rb +0 -3
  345. data/test/rubygems/grandchild_cert.pem +0 -19
  346. data/test/rubygems/grandchild_cert_32.pem +0 -19
  347. data/test/rubygems/grandchild_key.pem +0 -27
  348. data/test/rubygems/helper.rb +0 -1649
  349. data/test/rubygems/installer_test_case.rb +0 -248
  350. data/test/rubygems/invalid_client.pem +0 -49
  351. data/test/rubygems/invalid_issuer_cert.pem +0 -20
  352. data/test/rubygems/invalid_issuer_cert_32.pem +0 -20
  353. data/test/rubygems/invalid_key.pem +0 -27
  354. data/test/rubygems/invalid_signer_cert.pem +0 -19
  355. data/test/rubygems/invalid_signer_cert_32.pem +0 -19
  356. data/test/rubygems/invalidchild_cert.pem +0 -19
  357. data/test/rubygems/invalidchild_cert_32.pem +0 -19
  358. data/test/rubygems/invalidchild_key.pem +0 -27
  359. data/test/rubygems/multifactor_auth_utilities.rb +0 -111
  360. data/test/rubygems/package/tar_test_case.rb +0 -175
  361. data/test/rubygems/packages/Bluebie-legs-0.6.2.gem +0 -0
  362. data/test/rubygems/packages/ascii_binder-0.1.10.1.gem +0 -0
  363. data/test/rubygems/packages/ill-formatted-platform-1.0.0.10.gem +0 -0
  364. data/test/rubygems/plugin/exception/rubygems_plugin.rb +0 -4
  365. data/test/rubygems/plugin/load/rubygems_plugin.rb +0 -5
  366. data/test/rubygems/plugin/standarderror/rubygems_plugin.rb +0 -4
  367. data/test/rubygems/private3072_key.pem +0 -40
  368. data/test/rubygems/private_ec_key.pem +0 -9
  369. data/test/rubygems/private_key.pem +0 -27
  370. data/test/rubygems/public3072_cert.pem +0 -25
  371. data/test/rubygems/public_cert.pem +0 -20
  372. data/test/rubygems/public_cert_32.pem +0 -19
  373. data/test/rubygems/public_key.pem +0 -9
  374. data/test/rubygems/rubygems/commands/crash_command.rb +0 -5
  375. data/test/rubygems/rubygems_plugin.rb +0 -24
  376. data/test/rubygems/sff/discover.rb +0 -1
  377. data/test/rubygems/simple_gem.rb +0 -68
  378. data/test/rubygems/specifications/bar-0.0.2.gemspec +0 -9
  379. data/test/rubygems/specifications/foo-0.0.1-x86-mswin32.gemspec +0 -0
  380. data/test/rubygems/specifications/rubyforge-0.0.1.gemspec +0 -14
  381. data/test/rubygems/ssl_cert.pem +0 -80
  382. data/test/rubygems/ssl_key.pem +0 -27
  383. data/test/rubygems/test_bundled_ca.rb +0 -61
  384. data/test/rubygems/test_config.rb +0 -28
  385. data/test/rubygems/test_deprecate.rb +0 -158
  386. data/test/rubygems/test_exit.rb +0 -17
  387. data/test/rubygems/test_gem.rb +0 -1799
  388. data/test/rubygems/test_gem_available_set.rb +0 -130
  389. data/test/rubygems/test_gem_bundler_version_finder.rb +0 -127
  390. data/test/rubygems/test_gem_command.rb +0 -403
  391. data/test/rubygems/test_gem_command_manager.rb +0 -400
  392. data/test/rubygems/test_gem_commands_build_command.rb +0 -739
  393. data/test/rubygems/test_gem_commands_cert_command.rb +0 -866
  394. data/test/rubygems/test_gem_commands_check_command.rb +0 -68
  395. data/test/rubygems/test_gem_commands_cleanup_command.rb +0 -292
  396. data/test/rubygems/test_gem_commands_contents_command.rb +0 -271
  397. data/test/rubygems/test_gem_commands_dependency_command.rb +0 -228
  398. data/test/rubygems/test_gem_commands_environment_command.rb +0 -169
  399. data/test/rubygems/test_gem_commands_exec_command.rb +0 -857
  400. data/test/rubygems/test_gem_commands_fetch_command.rb +0 -258
  401. data/test/rubygems/test_gem_commands_generate_index_command.rb +0 -81
  402. data/test/rubygems/test_gem_commands_help_command.rb +0 -94
  403. data/test/rubygems/test_gem_commands_info_command.rb +0 -70
  404. data/test/rubygems/test_gem_commands_install_command.rb +0 -1573
  405. data/test/rubygems/test_gem_commands_list_command.rb +0 -33
  406. data/test/rubygems/test_gem_commands_lock_command.rb +0 -67
  407. data/test/rubygems/test_gem_commands_mirror.rb +0 -20
  408. data/test/rubygems/test_gem_commands_open_command.rb +0 -101
  409. data/test/rubygems/test_gem_commands_outdated_command.rb +0 -50
  410. data/test/rubygems/test_gem_commands_owner_command.rb +0 -503
  411. data/test/rubygems/test_gem_commands_pristine_command.rb +0 -708
  412. data/test/rubygems/test_gem_commands_push_command.rb +0 -603
  413. data/test/rubygems/test_gem_commands_query_command.rb +0 -858
  414. data/test/rubygems/test_gem_commands_search_command.rb +0 -16
  415. data/test/rubygems/test_gem_commands_server_command.rb +0 -20
  416. data/test/rubygems/test_gem_commands_setup_command.rb +0 -474
  417. data/test/rubygems/test_gem_commands_signin_command.rb +0 -259
  418. data/test/rubygems/test_gem_commands_signout_command.rb +0 -30
  419. data/test/rubygems/test_gem_commands_sources_command.rb +0 -534
  420. data/test/rubygems/test_gem_commands_specification_command.rb +0 -277
  421. data/test/rubygems/test_gem_commands_stale_command.rb +0 -43
  422. data/test/rubygems/test_gem_commands_uninstall_command.rb +0 -542
  423. data/test/rubygems/test_gem_commands_unpack_command.rb +0 -224
  424. data/test/rubygems/test_gem_commands_update_command.rb +0 -836
  425. data/test/rubygems/test_gem_commands_which_command.rb +0 -85
  426. data/test/rubygems/test_gem_commands_yank_command.rb +0 -299
  427. data/test/rubygems/test_gem_config_file.rb +0 -551
  428. data/test/rubygems/test_gem_dependency.rb +0 -398
  429. data/test/rubygems/test_gem_dependency_installer.rb +0 -1190
  430. data/test/rubygems/test_gem_dependency_list.rb +0 -265
  431. data/test/rubygems/test_gem_dependency_resolution_error.rb +0 -27
  432. data/test/rubygems/test_gem_doctor.rb +0 -195
  433. data/test/rubygems/test_gem_ext_builder.rb +0 -337
  434. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/.gitignore +0 -1
  435. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/custom_name.gemspec +0 -10
  436. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.lock +0 -249
  437. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.toml +0 -10
  438. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/src/lib.rs +0 -27
  439. data/test/rubygems/test_gem_ext_cargo_builder/custom_name/lib/custom_name.rb +0 -3
  440. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/.gitignore +0 -1
  441. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock +0 -249
  442. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml +0 -10
  443. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/rust_ruby_example.gemspec +0 -10
  444. data/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs +0 -51
  445. data/test/rubygems/test_gem_ext_cargo_builder.rb +0 -167
  446. data/test/rubygems/test_gem_ext_cargo_builder_link_flag_converter.rb +0 -34
  447. data/test/rubygems/test_gem_ext_cargo_builder_unit.rb +0 -60
  448. data/test/rubygems/test_gem_ext_cmake_builder.rb +0 -84
  449. data/test/rubygems/test_gem_ext_configure_builder.rb +0 -80
  450. data/test/rubygems/test_gem_ext_ext_conf_builder.rb +0 -229
  451. data/test/rubygems/test_gem_ext_rake_builder.rb +0 -113
  452. data/test/rubygems/test_gem_gem_runner.rb +0 -119
  453. data/test/rubygems/test_gem_gemcutter_utilities.rb +0 -361
  454. data/test/rubygems/test_gem_impossible_dependencies_error.rb +0 -60
  455. data/test/rubygems/test_gem_indexer.rb +0 -381
  456. data/test/rubygems/test_gem_install_update_options.rb +0 -208
  457. data/test/rubygems/test_gem_installer.rb +0 -2512
  458. data/test/rubygems/test_gem_local_remote_options.rb +0 -133
  459. data/test/rubygems/test_gem_name_tuple.rb +0 -43
  460. data/test/rubygems/test_gem_package.rb +0 -1306
  461. data/test/rubygems/test_gem_package_old.rb +0 -91
  462. data/test/rubygems/test_gem_package_tar_header.rb +0 -226
  463. data/test/rubygems/test_gem_package_tar_reader.rb +0 -150
  464. data/test/rubygems/test_gem_package_tar_reader_entry.rb +0 -350
  465. data/test/rubygems/test_gem_package_tar_writer.rb +0 -331
  466. data/test/rubygems/test_gem_package_task.rb +0 -118
  467. data/test/rubygems/test_gem_path_support.rb +0 -139
  468. data/test/rubygems/test_gem_platform.rb +0 -497
  469. data/test/rubygems/test_gem_rdoc.rb +0 -137
  470. data/test/rubygems/test_gem_remote_fetcher.rb +0 -1227
  471. data/test/rubygems/test_gem_request.rb +0 -547
  472. data/test/rubygems/test_gem_request_connection_pools.rb +0 -152
  473. data/test/rubygems/test_gem_request_set.rb +0 -672
  474. data/test/rubygems/test_gem_request_set_gem_dependency_api.rb +0 -853
  475. data/test/rubygems/test_gem_request_set_lockfile.rb +0 -469
  476. data/test/rubygems/test_gem_request_set_lockfile_parser.rb +0 -544
  477. data/test/rubygems/test_gem_request_set_lockfile_tokenizer.rb +0 -307
  478. data/test/rubygems/test_gem_requirement.rb +0 -505
  479. data/test/rubygems/test_gem_resolver.rb +0 -859
  480. data/test/rubygems/test_gem_resolver_activation_request.rb +0 -43
  481. data/test/rubygems/test_gem_resolver_api_set.rb +0 -210
  482. data/test/rubygems/test_gem_resolver_api_specification.rb +0 -167
  483. data/test/rubygems/test_gem_resolver_best_set.rb +0 -159
  484. data/test/rubygems/test_gem_resolver_composed_set.rb +0 -44
  485. data/test/rubygems/test_gem_resolver_conflict.rb +0 -82
  486. data/test/rubygems/test_gem_resolver_dependency_request.rb +0 -83
  487. data/test/rubygems/test_gem_resolver_git_set.rb +0 -188
  488. data/test/rubygems/test_gem_resolver_git_specification.rb +0 -114
  489. data/test/rubygems/test_gem_resolver_index_set.rb +0 -88
  490. data/test/rubygems/test_gem_resolver_index_specification.rb +0 -93
  491. data/test/rubygems/test_gem_resolver_installed_specification.rb +0 -47
  492. data/test/rubygems/test_gem_resolver_installer_set.rb +0 -320
  493. data/test/rubygems/test_gem_resolver_local_specification.rb +0 -44
  494. data/test/rubygems/test_gem_resolver_lock_set.rb +0 -62
  495. data/test/rubygems/test_gem_resolver_lock_specification.rb +0 -98
  496. data/test/rubygems/test_gem_resolver_requirement_list.rb +0 -19
  497. data/test/rubygems/test_gem_resolver_specification.rb +0 -63
  498. data/test/rubygems/test_gem_resolver_vendor_set.rb +0 -82
  499. data/test/rubygems/test_gem_resolver_vendor_specification.rb +0 -82
  500. data/test/rubygems/test_gem_security.rb +0 -341
  501. data/test/rubygems/test_gem_security_policy.rb +0 -535
  502. data/test/rubygems/test_gem_security_signer.rb +0 -218
  503. data/test/rubygems/test_gem_security_trust_dir.rb +0 -99
  504. data/test/rubygems/test_gem_silent_ui.rb +0 -123
  505. data/test/rubygems/test_gem_source.rb +0 -254
  506. data/test/rubygems/test_gem_source_fetch_problem.rb +0 -37
  507. data/test/rubygems/test_gem_source_git.rb +0 -310
  508. data/test/rubygems/test_gem_source_installed.rb +0 -35
  509. data/test/rubygems/test_gem_source_list.rb +0 -119
  510. data/test/rubygems/test_gem_source_local.rb +0 -107
  511. data/test/rubygems/test_gem_source_lock.rb +0 -113
  512. data/test/rubygems/test_gem_source_specific_file.rb +0 -76
  513. data/test/rubygems/test_gem_source_subpath_problem.rb +0 -50
  514. data/test/rubygems/test_gem_source_vendor.rb +0 -30
  515. data/test/rubygems/test_gem_spec_fetcher.rb +0 -338
  516. data/test/rubygems/test_gem_specification.rb +0 -3856
  517. data/test/rubygems/test_gem_stream_ui.rb +0 -255
  518. data/test/rubygems/test_gem_stub_specification.rb +0 -278
  519. data/test/rubygems/test_gem_text.rb +0 -103
  520. data/test/rubygems/test_gem_uninstaller.rb +0 -675
  521. data/test/rubygems/test_gem_unsatisfiable_dependency_error.rb +0 -31
  522. data/test/rubygems/test_gem_update_suggestion.rb +0 -209
  523. data/test/rubygems/test_gem_uri.rb +0 -41
  524. data/test/rubygems/test_gem_uri_formatter.rb +0 -27
  525. data/test/rubygems/test_gem_util.rb +0 -91
  526. data/test/rubygems/test_gem_validator.rb +0 -42
  527. data/test/rubygems/test_gem_version.rb +0 -305
  528. data/test/rubygems/test_gem_version_option.rb +0 -165
  529. data/test/rubygems/test_kernel.rb +0 -124
  530. data/test/rubygems/test_project_sanity.rb +0 -49
  531. data/test/rubygems/test_remote_fetch_error.rb +0 -20
  532. data/test/rubygems/test_require.rb +0 -732
  533. data/test/rubygems/test_rubygems.rb +0 -76
  534. data/test/rubygems/test_webauthn_listener.rb +0 -143
  535. data/test/rubygems/test_webauthn_listener_response.rb +0 -93
  536. data/test/rubygems/test_webauthn_poller.rb +0 -124
  537. data/test/rubygems/utilities.rb +0 -436
  538. data/test/rubygems/wrong_key_cert.pem +0 -19
  539. data/test/rubygems/wrong_key_cert_32.pem +0 -19
  540. data/test/test_changelog_generator.rb +0 -17
@@ -0,0 +1,2496 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # = net/http.rb
4
+ #
5
+ # Copyright (c) 1999-2007 Yukihiro Matsumoto
6
+ # Copyright (c) 1999-2007 Minero Aoki
7
+ # Copyright (c) 2001 GOTOU Yuuzou
8
+ #
9
+ # Written and maintained by Minero Aoki <aamine@loveruby.net>.
10
+ # HTTPS support added by GOTOU Yuuzou <gotoyuzo@notwork.org>.
11
+ #
12
+ # This file is derived from "http-access.rb".
13
+ #
14
+ # Documented by Minero Aoki; converted to RDoc by William Webber.
15
+ #
16
+ # This program is free software. You can re-distribute and/or
17
+ # modify this program under the same terms of ruby itself ---
18
+ # Ruby Distribution License or GNU General Public License.
19
+ #
20
+ # See Gem::Net::HTTP for an overview and examples.
21
+ #
22
+
23
+ require_relative '../../../net-protocol/lib/net/protocol'
24
+ require 'uri'
25
+ require_relative '../../../resolv/lib/resolv'
26
+ autoload :OpenSSL, 'openssl'
27
+
28
+ module Gem::Net #:nodoc:
29
+
30
+ # :stopdoc:
31
+ class HTTPBadResponse < StandardError; end
32
+ class HTTPHeaderSyntaxError < StandardError; end
33
+ # :startdoc:
34
+
35
+ # \Class \Gem::Net::HTTP provides a rich library that implements the client
36
+ # in a client-server model that uses the \HTTP request-response protocol.
37
+ # For information about \HTTP, see:
38
+ #
39
+ # - {Hypertext Transfer Protocol}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol].
40
+ # - {Technical overview}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Technical_overview].
41
+ #
42
+ # == About the Examples
43
+ #
44
+ # :include: doc/net-http/examples.rdoc
45
+ #
46
+ # == Strategies
47
+ #
48
+ # - If you will make only a few GET requests,
49
+ # consider using {OpenURI}[https://docs.ruby-lang.org/en/master/OpenURI.html].
50
+ # - If you will make only a few requests of all kinds,
51
+ # consider using the various singleton convenience methods in this class.
52
+ # Each of the following methods automatically starts and finishes
53
+ # a {session}[rdoc-ref:Gem::Net::HTTP@Sessions] that sends a single request:
54
+ #
55
+ # # Return string response body.
56
+ # Gem::Net::HTTP.get(hostname, path)
57
+ # Gem::Net::HTTP.get(uri)
58
+ #
59
+ # # Write string response body to $stdout.
60
+ # Gem::Net::HTTP.get_print(hostname, path)
61
+ # Gem::Net::HTTP.get_print(uri)
62
+ #
63
+ # # Return response as Gem::Net::HTTPResponse object.
64
+ # Gem::Net::HTTP.get_response(hostname, path)
65
+ # Gem::Net::HTTP.get_response(uri)
66
+ # data = '{"title": "foo", "body": "bar", "userId": 1}'
67
+ # Gem::Net::HTTP.post(uri, data)
68
+ # params = {title: 'foo', body: 'bar', userId: 1}
69
+ # Gem::Net::HTTP.post_form(uri, params)
70
+ #
71
+ # - If performance is important, consider using sessions, which lower request overhead.
72
+ # This {session}[rdoc-ref:Gem::Net::HTTP@Sessions] has multiple requests for
73
+ # {HTTP methods}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods]
74
+ # and {WebDAV methods}[https://en.wikipedia.org/wiki/WebDAV#Implementation]:
75
+ #
76
+ # Gem::Net::HTTP.start(hostname) do |http|
77
+ # # Session started automatically before block execution.
78
+ # http.get(path)
79
+ # http.head(path)
80
+ # body = 'Some text'
81
+ # http.post(path, body) # Can also have a block.
82
+ # http.put(path, body)
83
+ # http.delete(path)
84
+ # http.options(path)
85
+ # http.trace(path)
86
+ # http.patch(path, body) # Can also have a block.
87
+ # http.copy(path)
88
+ # http.lock(path, body)
89
+ # http.mkcol(path, body)
90
+ # http.move(path)
91
+ # http.propfind(path, body)
92
+ # http.proppatch(path, body)
93
+ # http.unlock(path, body)
94
+ # # Session finished automatically at block exit.
95
+ # end
96
+ #
97
+ # The methods cited above are convenience methods that, via their few arguments,
98
+ # allow minimal control over the requests.
99
+ # For greater control, consider using {request objects}[rdoc-ref:Gem::Net::HTTPRequest].
100
+ #
101
+ # == URIs
102
+ #
103
+ # On the internet, a URI
104
+ # ({Universal Resource Identifier}[https://en.wikipedia.org/wiki/Uniform_Resource_Identifier])
105
+ # is a string that identifies a particular resource.
106
+ # It consists of some or all of: scheme, hostname, path, query, and fragment;
107
+ # see {URI syntax}[https://en.wikipedia.org/wiki/Uniform_Resource_Identifier#Syntax].
108
+ #
109
+ # A Ruby {URI::Generic}[https://docs.ruby-lang.org/en/master/URI/Generic.html] object
110
+ # represents an internet URI.
111
+ # It provides, among others, methods
112
+ # +scheme+, +hostname+, +path+, +query+, and +fragment+.
113
+ #
114
+ # === Schemes
115
+ #
116
+ # An internet \URI has
117
+ # a {scheme}[https://en.wikipedia.org/wiki/List_of_URI_schemes].
118
+ #
119
+ # The two schemes supported in \Gem::Net::HTTP are <tt>'https'</tt> and <tt>'http'</tt>:
120
+ #
121
+ # uri.scheme # => "https"
122
+ # URI('http://example.com').scheme # => "http"
123
+ #
124
+ # === Hostnames
125
+ #
126
+ # A hostname identifies a server (host) to which requests may be sent:
127
+ #
128
+ # hostname = uri.hostname # => "jsonplaceholder.typicode.com"
129
+ # Gem::Net::HTTP.start(hostname) do |http|
130
+ # # Some HTTP stuff.
131
+ # end
132
+ #
133
+ # === Paths
134
+ #
135
+ # A host-specific path identifies a resource on the host:
136
+ #
137
+ # _uri = uri.dup
138
+ # _uri.path = '/todos/1'
139
+ # hostname = _uri.hostname
140
+ # path = _uri.path
141
+ # Gem::Net::HTTP.get(hostname, path)
142
+ #
143
+ # === Queries
144
+ #
145
+ # A host-specific query adds name/value pairs to the URI:
146
+ #
147
+ # _uri = uri.dup
148
+ # params = {userId: 1, completed: false}
149
+ # _uri.query = URI.encode_www_form(params)
150
+ # _uri # => #<URI::HTTPS https://jsonplaceholder.typicode.com?userId=1&completed=false>
151
+ # Gem::Net::HTTP.get(_uri)
152
+ #
153
+ # === Fragments
154
+ #
155
+ # A {URI fragment}[https://en.wikipedia.org/wiki/URI_fragment] has no effect
156
+ # in \Gem::Net::HTTP;
157
+ # the same data is returned, regardless of whether a fragment is included.
158
+ #
159
+ # == Request Headers
160
+ #
161
+ # Request headers may be used to pass additional information to the host,
162
+ # similar to arguments passed in a method call;
163
+ # each header is a name/value pair.
164
+ #
165
+ # Each of the \Gem::Net::HTTP methods that sends a request to the host
166
+ # has optional argument +headers+,
167
+ # where the headers are expressed as a hash of field-name/value pairs:
168
+ #
169
+ # headers = {Accept: 'application/json', Connection: 'Keep-Alive'}
170
+ # Gem::Net::HTTP.get(uri, headers)
171
+ #
172
+ # See lists of both standard request fields and common request fields at
173
+ # {Request Fields}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Request_fields].
174
+ # A host may also accept other custom fields.
175
+ #
176
+ # == \HTTP Sessions
177
+ #
178
+ # A _session_ is a connection between a server (host) and a client that:
179
+ #
180
+ # - Is begun by instance method Gem::Net::HTTP#start.
181
+ # - May contain any number of requests.
182
+ # - Is ended by instance method Gem::Net::HTTP#finish.
183
+ #
184
+ # See example sessions at {Strategies}[rdoc-ref:Gem::Net::HTTP@Strategies].
185
+ #
186
+ # === Session Using \Gem::Net::HTTP.start
187
+ #
188
+ # If you have many requests to make to a single host (and port),
189
+ # consider using singleton method Gem::Net::HTTP.start with a block;
190
+ # the method handles the session automatically by:
191
+ #
192
+ # - Calling #start before block execution.
193
+ # - Executing the block.
194
+ # - Calling #finish after block execution.
195
+ #
196
+ # In the block, you can use these instance methods,
197
+ # each of which that sends a single request:
198
+ #
199
+ # - {HTTP methods}[https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods]:
200
+ #
201
+ # - #get, #request_get: GET.
202
+ # - #head, #request_head: HEAD.
203
+ # - #post, #request_post: POST.
204
+ # - #delete: DELETE.
205
+ # - #options: OPTIONS.
206
+ # - #trace: TRACE.
207
+ # - #patch: PATCH.
208
+ #
209
+ # - {WebDAV methods}[https://en.wikipedia.org/wiki/WebDAV#Implementation]:
210
+ #
211
+ # - #copy: COPY.
212
+ # - #lock: LOCK.
213
+ # - #mkcol: MKCOL.
214
+ # - #move: MOVE.
215
+ # - #propfind: PROPFIND.
216
+ # - #proppatch: PROPPATCH.
217
+ # - #unlock: UNLOCK.
218
+ #
219
+ # === Session Using \Gem::Net::HTTP.start and \Gem::Net::HTTP.finish
220
+ #
221
+ # You can manage a session manually using methods #start and #finish:
222
+ #
223
+ # http = Gem::Net::HTTP.new(hostname)
224
+ # http.start
225
+ # http.get('/todos/1')
226
+ # http.get('/todos/2')
227
+ # http.delete('/posts/1')
228
+ # http.finish # Needed to free resources.
229
+ #
230
+ # === Single-Request Session
231
+ #
232
+ # Certain convenience methods automatically handle a session by:
233
+ #
234
+ # - Creating an \HTTP object
235
+ # - Starting a session.
236
+ # - Sending a single request.
237
+ # - Finishing the session.
238
+ # - Destroying the object.
239
+ #
240
+ # Such methods that send GET requests:
241
+ #
242
+ # - ::get: Returns the string response body.
243
+ # - ::get_print: Writes the string response body to $stdout.
244
+ # - ::get_response: Returns a Gem::Net::HTTPResponse object.
245
+ #
246
+ # Such methods that send POST requests:
247
+ #
248
+ # - ::post: Posts data to the host.
249
+ # - ::post_form: Posts form data to the host.
250
+ #
251
+ # == \HTTP Requests and Responses
252
+ #
253
+ # Many of the methods above are convenience methods,
254
+ # each of which sends a request and returns a string
255
+ # without directly using \Gem::Net::HTTPRequest and \Gem::Net::HTTPResponse objects.
256
+ #
257
+ # You can, however, directly create a request object, send the request,
258
+ # and retrieve the response object; see:
259
+ #
260
+ # - Gem::Net::HTTPRequest.
261
+ # - Gem::Net::HTTPResponse.
262
+ #
263
+ # == Following Redirection
264
+ #
265
+ # Each returned response is an instance of a subclass of Gem::Net::HTTPResponse.
266
+ # See the {response class hierarchy}[rdoc-ref:Gem::Net::HTTPResponse@Response+Subclasses].
267
+ #
268
+ # In particular, class Gem::Net::HTTPRedirection is the parent
269
+ # of all redirection classes.
270
+ # This allows you to craft a case statement to handle redirections properly:
271
+ #
272
+ # def fetch(uri, limit = 10)
273
+ # # You should choose a better exception.
274
+ # raise ArgumentError, 'Too many HTTP redirects' if limit == 0
275
+ #
276
+ # res = Gem::Net::HTTP.get_response(URI(uri))
277
+ # case res
278
+ # when Gem::Net::HTTPSuccess # Any success class.
279
+ # res
280
+ # when Gem::Net::HTTPRedirection # Any redirection class.
281
+ # location = res['Location']
282
+ # warn "Redirected to #{location}"
283
+ # fetch(location, limit - 1)
284
+ # else # Any other class.
285
+ # res.value
286
+ # end
287
+ # end
288
+ #
289
+ # fetch(uri)
290
+ #
291
+ # == Basic Authentication
292
+ #
293
+ # Basic authentication is performed according to
294
+ # {RFC2617}[http://www.ietf.org/rfc/rfc2617.txt]:
295
+ #
296
+ # req = Gem::Net::HTTP::Get.new(uri)
297
+ # req.basic_auth('user', 'pass')
298
+ # res = Gem::Net::HTTP.start(hostname) do |http|
299
+ # http.request(req)
300
+ # end
301
+ #
302
+ # == Streaming Response Bodies
303
+ #
304
+ # By default \Gem::Net::HTTP reads an entire response into memory. If you are
305
+ # handling large files or wish to implement a progress bar you can instead
306
+ # stream the body directly to an IO.
307
+ #
308
+ # Gem::Net::HTTP.start(hostname) do |http|
309
+ # req = Gem::Net::HTTP::Get.new(uri)
310
+ # http.request(req) do |res|
311
+ # open('t.tmp', 'w') do |f|
312
+ # res.read_body do |chunk|
313
+ # f.write chunk
314
+ # end
315
+ # end
316
+ # end
317
+ # end
318
+ #
319
+ # == HTTPS
320
+ #
321
+ # HTTPS is enabled for an \HTTP connection by Gem::Net::HTTP#use_ssl=:
322
+ #
323
+ # Gem::Net::HTTP.start(hostname, :use_ssl => true) do |http|
324
+ # req = Gem::Net::HTTP::Get.new(uri)
325
+ # res = http.request(req)
326
+ # end
327
+ #
328
+ # Or if you simply want to make a GET request, you may pass in a URI
329
+ # object that has an \HTTPS URL. \Gem::Net::HTTP automatically turns on TLS
330
+ # verification if the URI object has a 'https' URI scheme:
331
+ #
332
+ # uri # => #<URI::HTTPS https://jsonplaceholder.typicode.com/>
333
+ # Gem::Net::HTTP.get(uri)
334
+ #
335
+ # == Proxy Server
336
+ #
337
+ # An \HTTP object can have
338
+ # a {proxy server}[https://en.wikipedia.org/wiki/Proxy_server].
339
+ #
340
+ # You can create an \HTTP object with a proxy server
341
+ # using method Gem::Net::HTTP.new or method Gem::Net::HTTP.start.
342
+ #
343
+ # The proxy may be defined either by argument +p_addr+
344
+ # or by environment variable <tt>'http_proxy'</tt>.
345
+ #
346
+ # === Proxy Using Argument +p_addr+ as a \String
347
+ #
348
+ # When argument +p_addr+ is a string hostname,
349
+ # the returned +http+ has the given host as its proxy:
350
+ #
351
+ # http = Gem::Net::HTTP.new(hostname, nil, 'proxy.example')
352
+ # http.proxy? # => true
353
+ # http.proxy_from_env? # => false
354
+ # http.proxy_address # => "proxy.example"
355
+ # # These use default values.
356
+ # http.proxy_port # => 80
357
+ # http.proxy_user # => nil
358
+ # http.proxy_pass # => nil
359
+ #
360
+ # The port, username, and password for the proxy may also be given:
361
+ #
362
+ # http = Gem::Net::HTTP.new(hostname, nil, 'proxy.example', 8000, 'pname', 'ppass')
363
+ # # => #<Gem::Net::HTTP jsonplaceholder.typicode.com:80 open=false>
364
+ # http.proxy? # => true
365
+ # http.proxy_from_env? # => false
366
+ # http.proxy_address # => "proxy.example"
367
+ # http.proxy_port # => 8000
368
+ # http.proxy_user # => "pname"
369
+ # http.proxy_pass # => "ppass"
370
+ #
371
+ # === Proxy Using '<tt>ENV['http_proxy']</tt>'
372
+ #
373
+ # When environment variable <tt>'http_proxy'</tt>
374
+ # is set to a \URI string,
375
+ # the returned +http+ will have the server at that URI as its proxy;
376
+ # note that the \URI string must have a protocol
377
+ # such as <tt>'http'</tt> or <tt>'https'</tt>:
378
+ #
379
+ # ENV['http_proxy'] = 'http://example.com'
380
+ # http = Gem::Net::HTTP.new(hostname)
381
+ # http.proxy? # => true
382
+ # http.proxy_from_env? # => true
383
+ # http.proxy_address # => "example.com"
384
+ # # These use default values.
385
+ # http.proxy_port # => 80
386
+ # http.proxy_user # => nil
387
+ # http.proxy_pass # => nil
388
+ #
389
+ # The \URI string may include proxy username, password, and port number:
390
+ #
391
+ # ENV['http_proxy'] = 'http://pname:ppass@example.com:8000'
392
+ # http = Gem::Net::HTTP.new(hostname)
393
+ # http.proxy? # => true
394
+ # http.proxy_from_env? # => true
395
+ # http.proxy_address # => "example.com"
396
+ # http.proxy_port # => 8000
397
+ # http.proxy_user # => "pname"
398
+ # http.proxy_pass # => "ppass"
399
+ #
400
+ # === Filtering Proxies
401
+ #
402
+ # With method Gem::Net::HTTP.new (but not Gem::Net::HTTP.start),
403
+ # you can use argument +p_no_proxy+ to filter proxies:
404
+ #
405
+ # - Reject a certain address:
406
+ #
407
+ # http = Gem::Net::HTTP.new('example.com', nil, 'proxy.example', 8000, 'pname', 'ppass', 'proxy.example')
408
+ # http.proxy_address # => nil
409
+ #
410
+ # - Reject certain domains or subdomains:
411
+ #
412
+ # http = Gem::Net::HTTP.new('example.com', nil, 'my.proxy.example', 8000, 'pname', 'ppass', 'proxy.example')
413
+ # http.proxy_address # => nil
414
+ #
415
+ # - Reject certain addresses and port combinations:
416
+ #
417
+ # http = Gem::Net::HTTP.new('example.com', nil, 'proxy.example', 8000, 'pname', 'ppass', 'proxy.example:1234')
418
+ # http.proxy_address # => "proxy.example"
419
+ #
420
+ # http = Gem::Net::HTTP.new('example.com', nil, 'proxy.example', 8000, 'pname', 'ppass', 'proxy.example:8000')
421
+ # http.proxy_address # => nil
422
+ #
423
+ # - Reject a list of the types above delimited using a comma:
424
+ #
425
+ # http = Gem::Net::HTTP.new('example.com', nil, 'proxy.example', 8000, 'pname', 'ppass', 'my.proxy,proxy.example:8000')
426
+ # http.proxy_address # => nil
427
+ #
428
+ # http = Gem::Net::HTTP.new('example.com', nil, 'my.proxy', 8000, 'pname', 'ppass', 'my.proxy,proxy.example:8000')
429
+ # http.proxy_address # => nil
430
+ #
431
+ # == Compression and Decompression
432
+ #
433
+ # \Gem::Net::HTTP does not compress the body of a request before sending.
434
+ #
435
+ # By default, \Gem::Net::HTTP adds header <tt>'Accept-Encoding'</tt>
436
+ # to a new {request object}[rdoc-ref:Gem::Net::HTTPRequest]:
437
+ #
438
+ # Gem::Net::HTTP::Get.new(uri)['Accept-Encoding']
439
+ # # => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3"
440
+ #
441
+ # This requests the server to zip-encode the response body if there is one;
442
+ # the server is not required to do so.
443
+ #
444
+ # \Gem::Net::HTTP does not automatically decompress a response body
445
+ # if the response has header <tt>'Content-Range'</tt>.
446
+ #
447
+ # Otherwise decompression (or not) depends on the value of header
448
+ # {Content-Encoding}[https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#content-encoding-response-header]:
449
+ #
450
+ # - <tt>'deflate'</tt>, <tt>'gzip'</tt>, or <tt>'x-gzip'</tt>:
451
+ # decompresses the body and deletes the header.
452
+ # - <tt>'none'</tt> or <tt>'identity'</tt>:
453
+ # does not decompress the body, but deletes the header.
454
+ # - Any other value:
455
+ # leaves the body and header unchanged.
456
+ #
457
+ # == What's Here
458
+ #
459
+ # This is a categorized summary of methods and attributes.
460
+ #
461
+ # === \Gem::Net::HTTP Objects
462
+ #
463
+ # - {::new}[rdoc-ref:Gem::Net::HTTP.new]:
464
+ # Creates a new instance.
465
+ # - {#inspect}[rdoc-ref:Gem::Net::HTTP#inspect]:
466
+ # Returns a string representation of +self+.
467
+ #
468
+ # === Sessions
469
+ #
470
+ # - {::start}[rdoc-ref:Gem::Net::HTTP.start]:
471
+ # Begins a new session in a new \Gem::Net::HTTP object.
472
+ # - {#started?}[rdoc-ref:Gem::Net::HTTP#started?]
473
+ # (aliased as {#active?}[rdoc-ref:Gem::Net::HTTP#active?]):
474
+ # Returns whether in a session.
475
+ # - {#finish}[rdoc-ref:Gem::Net::HTTP#finish]:
476
+ # Ends an active session.
477
+ # - {#start}[rdoc-ref:Gem::Net::HTTP#start]:
478
+ # Begins a new session in an existing \Gem::Net::HTTP object (+self+).
479
+ #
480
+ # === Connections
481
+ #
482
+ # - {:continue_timeout}[rdoc-ref:Gem::Net::HTTP#continue_timeout]:
483
+ # Returns the continue timeout.
484
+ # - {#continue_timeout=}[rdoc-ref:Gem::Net::HTTP#continue_timeout=]:
485
+ # Sets the continue timeout seconds.
486
+ # - {:keep_alive_timeout}[rdoc-ref:Gem::Net::HTTP#keep_alive_timeout]:
487
+ # Returns the keep-alive timeout.
488
+ # - {:keep_alive_timeout=}[rdoc-ref:Gem::Net::HTTP#keep_alive_timeout=]:
489
+ # Sets the keep-alive timeout.
490
+ # - {:max_retries}[rdoc-ref:Gem::Net::HTTP#max_retries]:
491
+ # Returns the maximum retries.
492
+ # - {#max_retries=}[rdoc-ref:Gem::Net::HTTP#max_retries=]:
493
+ # Sets the maximum retries.
494
+ # - {:open_timeout}[rdoc-ref:Gem::Net::HTTP#open_timeout]:
495
+ # Returns the open timeout.
496
+ # - {:open_timeout=}[rdoc-ref:Gem::Net::HTTP#open_timeout=]:
497
+ # Sets the open timeout.
498
+ # - {:read_timeout}[rdoc-ref:Gem::Net::HTTP#read_timeout]:
499
+ # Returns the open timeout.
500
+ # - {:read_timeout=}[rdoc-ref:Gem::Net::HTTP#read_timeout=]:
501
+ # Sets the read timeout.
502
+ # - {:ssl_timeout}[rdoc-ref:Gem::Net::HTTP#ssl_timeout]:
503
+ # Returns the ssl timeout.
504
+ # - {:ssl_timeout=}[rdoc-ref:Gem::Net::HTTP#ssl_timeout=]:
505
+ # Sets the ssl timeout.
506
+ # - {:write_timeout}[rdoc-ref:Gem::Net::HTTP#write_timeout]:
507
+ # Returns the write timeout.
508
+ # - {write_timeout=}[rdoc-ref:Gem::Net::HTTP#write_timeout=]:
509
+ # Sets the write timeout.
510
+ #
511
+ # === Requests
512
+ #
513
+ # - {::get}[rdoc-ref:Gem::Net::HTTP.get]:
514
+ # Sends a GET request and returns the string response body.
515
+ # - {::get_print}[rdoc-ref:Gem::Net::HTTP.get_print]:
516
+ # Sends a GET request and write the string response body to $stdout.
517
+ # - {::get_response}[rdoc-ref:Gem::Net::HTTP.get_response]:
518
+ # Sends a GET request and returns a response object.
519
+ # - {::post_form}[rdoc-ref:Gem::Net::HTTP.post_form]:
520
+ # Sends a POST request with form data and returns a response object.
521
+ # - {::post}[rdoc-ref:Gem::Net::HTTP.post]:
522
+ # Sends a POST request with data and returns a response object.
523
+ # - {#copy}[rdoc-ref:Gem::Net::HTTP#copy]:
524
+ # Sends a COPY request and returns a response object.
525
+ # - {#delete}[rdoc-ref:Gem::Net::HTTP#delete]:
526
+ # Sends a DELETE request and returns a response object.
527
+ # - {#get}[rdoc-ref:Gem::Net::HTTP#get]:
528
+ # Sends a GET request and returns a response object.
529
+ # - {#head}[rdoc-ref:Gem::Net::HTTP#head]:
530
+ # Sends a HEAD request and returns a response object.
531
+ # - {#lock}[rdoc-ref:Gem::Net::HTTP#lock]:
532
+ # Sends a LOCK request and returns a response object.
533
+ # - {#mkcol}[rdoc-ref:Gem::Net::HTTP#mkcol]:
534
+ # Sends a MKCOL request and returns a response object.
535
+ # - {#move}[rdoc-ref:Gem::Net::HTTP#move]:
536
+ # Sends a MOVE request and returns a response object.
537
+ # - {#options}[rdoc-ref:Gem::Net::HTTP#options]:
538
+ # Sends a OPTIONS request and returns a response object.
539
+ # - {#patch}[rdoc-ref:Gem::Net::HTTP#patch]:
540
+ # Sends a PATCH request and returns a response object.
541
+ # - {#post}[rdoc-ref:Gem::Net::HTTP#post]:
542
+ # Sends a POST request and returns a response object.
543
+ # - {#propfind}[rdoc-ref:Gem::Net::HTTP#propfind]:
544
+ # Sends a PROPFIND request and returns a response object.
545
+ # - {#proppatch}[rdoc-ref:Gem::Net::HTTP#proppatch]:
546
+ # Sends a PROPPATCH request and returns a response object.
547
+ # - {#put}[rdoc-ref:Gem::Net::HTTP#put]:
548
+ # Sends a PUT request and returns a response object.
549
+ # - {#request}[rdoc-ref:Gem::Net::HTTP#request]:
550
+ # Sends a request and returns a response object.
551
+ # - {#request_get}[rdoc-ref:Gem::Net::HTTP#request_get]
552
+ # (aliased as {#get2}[rdoc-ref:Gem::Net::HTTP#get2]):
553
+ # Sends a GET request and forms a response object;
554
+ # if a block given, calls the block with the object,
555
+ # otherwise returns the object.
556
+ # - {#request_head}[rdoc-ref:Gem::Net::HTTP#request_head]
557
+ # (aliased as {#head2}[rdoc-ref:Gem::Net::HTTP#head2]):
558
+ # Sends a HEAD request and forms a response object;
559
+ # if a block given, calls the block with the object,
560
+ # otherwise returns the object.
561
+ # - {#request_post}[rdoc-ref:Gem::Net::HTTP#request_post]
562
+ # (aliased as {#post2}[rdoc-ref:Gem::Net::HTTP#post2]):
563
+ # Sends a POST request and forms a response object;
564
+ # if a block given, calls the block with the object,
565
+ # otherwise returns the object.
566
+ # - {#send_request}[rdoc-ref:Gem::Net::HTTP#send_request]:
567
+ # Sends a request and returns a response object.
568
+ # - {#trace}[rdoc-ref:Gem::Net::HTTP#trace]:
569
+ # Sends a TRACE request and returns a response object.
570
+ # - {#unlock}[rdoc-ref:Gem::Net::HTTP#unlock]:
571
+ # Sends an UNLOCK request and returns a response object.
572
+ #
573
+ # === Responses
574
+ #
575
+ # - {:close_on_empty_response}[rdoc-ref:Gem::Net::HTTP#close_on_empty_response]:
576
+ # Returns whether to close connection on empty response.
577
+ # - {:close_on_empty_response=}[rdoc-ref:Gem::Net::HTTP#close_on_empty_response=]:
578
+ # Sets whether to close connection on empty response.
579
+ # - {:ignore_eof}[rdoc-ref:Gem::Net::HTTP#ignore_eof]:
580
+ # Returns whether to ignore end-of-file when reading a response body
581
+ # with <tt>Content-Length</tt> headers.
582
+ # - {:ignore_eof=}[rdoc-ref:Gem::Net::HTTP#ignore_eof=]:
583
+ # Sets whether to ignore end-of-file when reading a response body
584
+ # with <tt>Content-Length</tt> headers.
585
+ # - {:response_body_encoding}[rdoc-ref:Gem::Net::HTTP#response_body_encoding]:
586
+ # Returns the encoding to use for the response body.
587
+ # - {#response_body_encoding=}[rdoc-ref:Gem::Net::HTTP#response_body_encoding=]:
588
+ # Sets the response body encoding.
589
+ #
590
+ # === Proxies
591
+ #
592
+ # - {:proxy_address}[rdoc-ref:Gem::Net::HTTP#proxy_address]:
593
+ # Returns the proxy address.
594
+ # - {:proxy_address=}[rdoc-ref:Gem::Net::HTTP#proxy_address=]:
595
+ # Sets the proxy address.
596
+ # - {::proxy_class?}[rdoc-ref:Gem::Net::HTTP.proxy_class?]:
597
+ # Returns whether +self+ is a proxy class.
598
+ # - {#proxy?}[rdoc-ref:Gem::Net::HTTP#proxy?]:
599
+ # Returns whether +self+ has a proxy.
600
+ # - {#proxy_address}[rdoc-ref:Gem::Net::HTTP#proxy_address]
601
+ # (aliased as {#proxyaddr}[rdoc-ref:Gem::Net::HTTP#proxyaddr]):
602
+ # Returns the proxy address.
603
+ # - {#proxy_from_env?}[rdoc-ref:Gem::Net::HTTP#proxy_from_env?]:
604
+ # Returns whether the proxy is taken from an environment variable.
605
+ # - {:proxy_from_env=}[rdoc-ref:Gem::Net::HTTP#proxy_from_env=]:
606
+ # Sets whether the proxy is to be taken from an environment variable.
607
+ # - {:proxy_pass}[rdoc-ref:Gem::Net::HTTP#proxy_pass]:
608
+ # Returns the proxy password.
609
+ # - {:proxy_pass=}[rdoc-ref:Gem::Net::HTTP#proxy_pass=]:
610
+ # Sets the proxy password.
611
+ # - {:proxy_port}[rdoc-ref:Gem::Net::HTTP#proxy_port]:
612
+ # Returns the proxy port.
613
+ # - {:proxy_port=}[rdoc-ref:Gem::Net::HTTP#proxy_port=]:
614
+ # Sets the proxy port.
615
+ # - {#proxy_user}[rdoc-ref:Gem::Net::HTTP#proxy_user]:
616
+ # Returns the proxy user name.
617
+ # - {:proxy_user=}[rdoc-ref:Gem::Net::HTTP#proxy_user=]:
618
+ # Sets the proxy user.
619
+ #
620
+ # === Security
621
+ #
622
+ # - {:ca_file}[rdoc-ref:Gem::Net::HTTP#ca_file]:
623
+ # Returns the path to a CA certification file.
624
+ # - {:ca_file=}[rdoc-ref:Gem::Net::HTTP#ca_file=]:
625
+ # Sets the path to a CA certification file.
626
+ # - {:ca_path}[rdoc-ref:Gem::Net::HTTP#ca_path]:
627
+ # Returns the path of to CA directory containing certification files.
628
+ # - {:ca_path=}[rdoc-ref:Gem::Net::HTTP#ca_path=]:
629
+ # Sets the path of to CA directory containing certification files.
630
+ # - {:cert}[rdoc-ref:Gem::Net::HTTP#cert]:
631
+ # Returns the OpenSSL::X509::Certificate object to be used for client certification.
632
+ # - {:cert=}[rdoc-ref:Gem::Net::HTTP#cert=]:
633
+ # Sets the OpenSSL::X509::Certificate object to be used for client certification.
634
+ # - {:cert_store}[rdoc-ref:Gem::Net::HTTP#cert_store]:
635
+ # Returns the X509::Store to be used for verifying peer certificate.
636
+ # - {:cert_store=}[rdoc-ref:Gem::Net::HTTP#cert_store=]:
637
+ # Sets the X509::Store to be used for verifying peer certificate.
638
+ # - {:ciphers}[rdoc-ref:Gem::Net::HTTP#ciphers]:
639
+ # Returns the available SSL ciphers.
640
+ # - {:ciphers=}[rdoc-ref:Gem::Net::HTTP#ciphers=]:
641
+ # Sets the available SSL ciphers.
642
+ # - {:extra_chain_cert}[rdoc-ref:Gem::Net::HTTP#extra_chain_cert]:
643
+ # Returns the extra X509 certificates to be added to the certificate chain.
644
+ # - {:extra_chain_cert=}[rdoc-ref:Gem::Net::HTTP#extra_chain_cert=]:
645
+ # Sets the extra X509 certificates to be added to the certificate chain.
646
+ # - {:key}[rdoc-ref:Gem::Net::HTTP#key]:
647
+ # Returns the OpenSSL::PKey::RSA or OpenSSL::PKey::DSA object.
648
+ # - {:key=}[rdoc-ref:Gem::Net::HTTP#key=]:
649
+ # Sets the OpenSSL::PKey::RSA or OpenSSL::PKey::DSA object.
650
+ # - {:max_version}[rdoc-ref:Gem::Net::HTTP#max_version]:
651
+ # Returns the maximum SSL version.
652
+ # - {:max_version=}[rdoc-ref:Gem::Net::HTTP#max_version=]:
653
+ # Sets the maximum SSL version.
654
+ # - {:min_version}[rdoc-ref:Gem::Net::HTTP#min_version]:
655
+ # Returns the minimum SSL version.
656
+ # - {:min_version=}[rdoc-ref:Gem::Net::HTTP#min_version=]:
657
+ # Sets the minimum SSL version.
658
+ # - {#peer_cert}[rdoc-ref:Gem::Net::HTTP#peer_cert]:
659
+ # Returns the X509 certificate chain for the session's socket peer.
660
+ # - {:ssl_version}[rdoc-ref:Gem::Net::HTTP#ssl_version]:
661
+ # Returns the SSL version.
662
+ # - {:ssl_version=}[rdoc-ref:Gem::Net::HTTP#ssl_version=]:
663
+ # Sets the SSL version.
664
+ # - {#use_ssl=}[rdoc-ref:Gem::Net::HTTP#use_ssl=]:
665
+ # Sets whether a new session is to use Transport Layer Security.
666
+ # - {#use_ssl?}[rdoc-ref:Gem::Net::HTTP#use_ssl?]:
667
+ # Returns whether +self+ uses SSL.
668
+ # - {:verify_callback}[rdoc-ref:Gem::Net::HTTP#verify_callback]:
669
+ # Returns the callback for the server certification verification.
670
+ # - {:verify_callback=}[rdoc-ref:Gem::Net::HTTP#verify_callback=]:
671
+ # Sets the callback for the server certification verification.
672
+ # - {:verify_depth}[rdoc-ref:Gem::Net::HTTP#verify_depth]:
673
+ # Returns the maximum depth for the certificate chain verification.
674
+ # - {:verify_depth=}[rdoc-ref:Gem::Net::HTTP#verify_depth=]:
675
+ # Sets the maximum depth for the certificate chain verification.
676
+ # - {:verify_hostname}[rdoc-ref:Gem::Net::HTTP#verify_hostname]:
677
+ # Returns the flags for server the certification verification at the beginning of the SSL/TLS session.
678
+ # - {:verify_hostname=}[rdoc-ref:Gem::Net::HTTP#verify_hostname=]:
679
+ # Sets he flags for server the certification verification at the beginning of the SSL/TLS session.
680
+ # - {:verify_mode}[rdoc-ref:Gem::Net::HTTP#verify_mode]:
681
+ # Returns the flags for server the certification verification at the beginning of the SSL/TLS session.
682
+ # - {:verify_mode=}[rdoc-ref:Gem::Net::HTTP#verify_mode=]:
683
+ # Sets the flags for server the certification verification at the beginning of the SSL/TLS session.
684
+ #
685
+ # === Addresses and Ports
686
+ #
687
+ # - {:address}[rdoc-ref:Gem::Net::HTTP#address]:
688
+ # Returns the string host name or host IP.
689
+ # - {::default_port}[rdoc-ref:Gem::Net::HTTP.default_port]:
690
+ # Returns integer 80, the default port to use for HTTP requests.
691
+ # - {::http_default_port}[rdoc-ref:Gem::Net::HTTP.http_default_port]:
692
+ # Returns integer 80, the default port to use for HTTP requests.
693
+ # - {::https_default_port}[rdoc-ref:Gem::Net::HTTP.https_default_port]:
694
+ # Returns integer 443, the default port to use for HTTPS requests.
695
+ # - {#ipaddr}[rdoc-ref:Gem::Net::HTTP#ipaddr]:
696
+ # Returns the IP address for the connection.
697
+ # - {#ipaddr=}[rdoc-ref:Gem::Net::HTTP#ipaddr=]:
698
+ # Sets the IP address for the connection.
699
+ # - {:local_host}[rdoc-ref:Gem::Net::HTTP#local_host]:
700
+ # Returns the string local host used to establish the connection.
701
+ # - {:local_host=}[rdoc-ref:Gem::Net::HTTP#local_host=]:
702
+ # Sets the string local host used to establish the connection.
703
+ # - {:local_port}[rdoc-ref:Gem::Net::HTTP#local_port]:
704
+ # Returns the integer local port used to establish the connection.
705
+ # - {:local_port=}[rdoc-ref:Gem::Net::HTTP#local_port=]:
706
+ # Sets the integer local port used to establish the connection.
707
+ # - {:port}[rdoc-ref:Gem::Net::HTTP#port]:
708
+ # Returns the integer port number.
709
+ #
710
+ # === \HTTP Version
711
+ #
712
+ # - {::version_1_2?}[rdoc-ref:Gem::Net::HTTP.version_1_2?]
713
+ # (aliased as {::is_version_1_2?}[rdoc-ref:Gem::Net::HTTP.is_version_1_2?]
714
+ # and {::version_1_2}[rdoc-ref:Gem::Net::HTTP.version_1_2]):
715
+ # Returns true; retained for compatibility.
716
+ #
717
+ # === Debugging
718
+ #
719
+ # - {#set_debug_output}[rdoc-ref:Gem::Net::HTTP#set_debug_output]:
720
+ # Sets the output stream for debugging.
721
+ #
722
+ class HTTP < Protocol
723
+
724
+ # :stopdoc:
725
+ VERSION = "0.4.0"
726
+ HTTPVersion = '1.1'
727
+ begin
728
+ require 'zlib'
729
+ HAVE_ZLIB=true
730
+ rescue LoadError
731
+ HAVE_ZLIB=false
732
+ end
733
+ # :startdoc:
734
+
735
+ # Returns +true+; retained for compatibility.
736
+ def HTTP.version_1_2
737
+ true
738
+ end
739
+
740
+ # Returns +true+; retained for compatibility.
741
+ def HTTP.version_1_2?
742
+ true
743
+ end
744
+
745
+ # Returns +false+; retained for compatibility.
746
+ def HTTP.version_1_1? #:nodoc:
747
+ false
748
+ end
749
+
750
+ class << HTTP
751
+ alias is_version_1_1? version_1_1? #:nodoc:
752
+ alias is_version_1_2? version_1_2? #:nodoc:
753
+ end
754
+
755
+ # :call-seq:
756
+ # Gem::Net::HTTP.get_print(hostname, path, port = 80) -> nil
757
+ # Gem::Net::HTTP:get_print(uri, headers = {}, port = uri.port) -> nil
758
+ #
759
+ # Like Gem::Net::HTTP.get, but writes the returned body to $stdout;
760
+ # returns +nil+.
761
+ def HTTP.get_print(uri_or_host, path_or_headers = nil, port = nil)
762
+ get_response(uri_or_host, path_or_headers, port) {|res|
763
+ res.read_body do |chunk|
764
+ $stdout.print chunk
765
+ end
766
+ }
767
+ nil
768
+ end
769
+
770
+ # :call-seq:
771
+ # Gem::Net::HTTP.get(hostname, path, port = 80) -> body
772
+ # Gem::Net::HTTP:get(uri, headers = {}, port = uri.port) -> body
773
+ #
774
+ # Sends a GET request and returns the \HTTP response body as a string.
775
+ #
776
+ # With string arguments +hostname+ and +path+:
777
+ #
778
+ # hostname = 'jsonplaceholder.typicode.com'
779
+ # path = '/todos/1'
780
+ # puts Gem::Net::HTTP.get(hostname, path)
781
+ #
782
+ # Output:
783
+ #
784
+ # {
785
+ # "userId": 1,
786
+ # "id": 1,
787
+ # "title": "delectus aut autem",
788
+ # "completed": false
789
+ # }
790
+ #
791
+ # With URI object +uri+ and optional hash argument +headers+:
792
+ #
793
+ # uri = URI('https://jsonplaceholder.typicode.com/todos/1')
794
+ # headers = {'Content-type' => 'application/json; charset=UTF-8'}
795
+ # Gem::Net::HTTP.get(uri, headers)
796
+ #
797
+ # Related:
798
+ #
799
+ # - Gem::Net::HTTP::Get: request class for \HTTP method +GET+.
800
+ # - Gem::Net::HTTP#get: convenience method for \HTTP method +GET+.
801
+ #
802
+ def HTTP.get(uri_or_host, path_or_headers = nil, port = nil)
803
+ get_response(uri_or_host, path_or_headers, port).body
804
+ end
805
+
806
+ # :call-seq:
807
+ # Gem::Net::HTTP.get_response(hostname, path, port = 80) -> http_response
808
+ # Gem::Net::HTTP:get_response(uri, headers = {}, port = uri.port) -> http_response
809
+ #
810
+ # Like Gem::Net::HTTP.get, but returns a Gem::Net::HTTPResponse object
811
+ # instead of the body string.
812
+ def HTTP.get_response(uri_or_host, path_or_headers = nil, port = nil, &block)
813
+ if path_or_headers && !path_or_headers.is_a?(Hash)
814
+ host = uri_or_host
815
+ path = path_or_headers
816
+ new(host, port || HTTP.default_port).start {|http|
817
+ return http.request_get(path, &block)
818
+ }
819
+ else
820
+ uri = uri_or_host
821
+ headers = path_or_headers
822
+ start(uri.hostname, uri.port,
823
+ :use_ssl => uri.scheme == 'https') {|http|
824
+ return http.request_get(uri, headers, &block)
825
+ }
826
+ end
827
+ end
828
+
829
+ # Posts data to a host; returns a Gem::Net::HTTPResponse object.
830
+ #
831
+ # Argument +url+ must be a URL;
832
+ # argument +data+ must be a string:
833
+ #
834
+ # _uri = uri.dup
835
+ # _uri.path = '/posts'
836
+ # data = '{"title": "foo", "body": "bar", "userId": 1}'
837
+ # headers = {'content-type': 'application/json'}
838
+ # res = Gem::Net::HTTP.post(_uri, data, headers) # => #<Gem::Net::HTTPCreated 201 Created readbody=true>
839
+ # puts res.body
840
+ #
841
+ # Output:
842
+ #
843
+ # {
844
+ # "title": "foo",
845
+ # "body": "bar",
846
+ # "userId": 1,
847
+ # "id": 101
848
+ # }
849
+ #
850
+ # Related:
851
+ #
852
+ # - Gem::Net::HTTP::Post: request class for \HTTP method +POST+.
853
+ # - Gem::Net::HTTP#post: convenience method for \HTTP method +POST+.
854
+ #
855
+ def HTTP.post(url, data, header = nil)
856
+ start(url.hostname, url.port,
857
+ :use_ssl => url.scheme == 'https' ) {|http|
858
+ http.post(url, data, header)
859
+ }
860
+ end
861
+
862
+ # Posts data to a host; returns a Gem::Net::HTTPResponse object.
863
+ #
864
+ # Argument +url+ must be a URI;
865
+ # argument +data+ must be a hash:
866
+ #
867
+ # _uri = uri.dup
868
+ # _uri.path = '/posts'
869
+ # data = {title: 'foo', body: 'bar', userId: 1}
870
+ # res = Gem::Net::HTTP.post_form(_uri, data) # => #<Gem::Net::HTTPCreated 201 Created readbody=true>
871
+ # puts res.body
872
+ #
873
+ # Output:
874
+ #
875
+ # {
876
+ # "title": "foo",
877
+ # "body": "bar",
878
+ # "userId": "1",
879
+ # "id": 101
880
+ # }
881
+ #
882
+ def HTTP.post_form(url, params)
883
+ req = Post.new(url)
884
+ req.form_data = params
885
+ req.basic_auth url.user, url.password if url.user
886
+ start(url.hostname, url.port,
887
+ :use_ssl => url.scheme == 'https' ) {|http|
888
+ http.request(req)
889
+ }
890
+ end
891
+
892
+ #
893
+ # \HTTP session management
894
+ #
895
+
896
+ # Returns integer +80+, the default port to use for \HTTP requests:
897
+ #
898
+ # Gem::Net::HTTP.default_port # => 80
899
+ #
900
+ def HTTP.default_port
901
+ http_default_port()
902
+ end
903
+
904
+ # Returns integer +80+, the default port to use for \HTTP requests:
905
+ #
906
+ # Gem::Net::HTTP.http_default_port # => 80
907
+ #
908
+ def HTTP.http_default_port
909
+ 80
910
+ end
911
+
912
+ # Returns integer +443+, the default port to use for HTTPS requests:
913
+ #
914
+ # Gem::Net::HTTP.https_default_port # => 443
915
+ #
916
+ def HTTP.https_default_port
917
+ 443
918
+ end
919
+
920
+ def HTTP.socket_type #:nodoc: obsolete
921
+ BufferedIO
922
+ end
923
+
924
+ # :call-seq:
925
+ # HTTP.start(address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil, opts) -> http
926
+ # HTTP.start(address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil, opts) {|http| ... } -> object
927
+ #
928
+ # Creates a new \Gem::Net::HTTP object, +http+, via \Gem::Net::HTTP.new:
929
+ #
930
+ # - For arguments +address+ and +port+, see Gem::Net::HTTP.new.
931
+ # - For proxy-defining arguments +p_addr+ through +p_pass+,
932
+ # see {Proxy Server}[rdoc-ref:Gem::Net::HTTP@Proxy+Server].
933
+ # - For argument +opts+, see below.
934
+ #
935
+ # With no block given:
936
+ #
937
+ # - Calls <tt>http.start</tt> with no block (see #start),
938
+ # which opens a TCP connection and \HTTP session.
939
+ # - Returns +http+.
940
+ # - The caller should call #finish to close the session:
941
+ #
942
+ # http = Gem::Net::HTTP.start(hostname)
943
+ # http.started? # => true
944
+ # http.finish
945
+ # http.started? # => false
946
+ #
947
+ # With a block given:
948
+ #
949
+ # - Calls <tt>http.start</tt> with the block (see #start), which:
950
+ #
951
+ # - Opens a TCP connection and \HTTP session.
952
+ # - Calls the block,
953
+ # which may make any number of requests to the host.
954
+ # - Closes the \HTTP session and TCP connection on block exit.
955
+ # - Returns the block's value +object+.
956
+ #
957
+ # - Returns +object+.
958
+ #
959
+ # Example:
960
+ #
961
+ # hostname = 'jsonplaceholder.typicode.com'
962
+ # Gem::Net::HTTP.start(hostname) do |http|
963
+ # puts http.get('/todos/1').body
964
+ # puts http.get('/todos/2').body
965
+ # end
966
+ #
967
+ # Output:
968
+ #
969
+ # {
970
+ # "userId": 1,
971
+ # "id": 1,
972
+ # "title": "delectus aut autem",
973
+ # "completed": false
974
+ # }
975
+ # {
976
+ # "userId": 1,
977
+ # "id": 2,
978
+ # "title": "quis ut nam facilis et officia qui",
979
+ # "completed": false
980
+ # }
981
+ #
982
+ # If the last argument given is a hash, it is the +opts+ hash,
983
+ # where each key is a method or accessor to be called,
984
+ # and its value is the value to be set.
985
+ #
986
+ # The keys may include:
987
+ #
988
+ # - #ca_file
989
+ # - #ca_path
990
+ # - #cert
991
+ # - #cert_store
992
+ # - #ciphers
993
+ # - #close_on_empty_response
994
+ # - +ipaddr+ (calls #ipaddr=)
995
+ # - #keep_alive_timeout
996
+ # - #key
997
+ # - #open_timeout
998
+ # - #read_timeout
999
+ # - #ssl_timeout
1000
+ # - #ssl_version
1001
+ # - +use_ssl+ (calls #use_ssl=)
1002
+ # - #verify_callback
1003
+ # - #verify_depth
1004
+ # - #verify_mode
1005
+ # - #write_timeout
1006
+ #
1007
+ # Note: If +port+ is +nil+ and <tt>opts[:use_ssl]</tt> is a truthy value,
1008
+ # the value passed to +new+ is Gem::Net::HTTP.https_default_port, not +port+.
1009
+ #
1010
+ def HTTP.start(address, *arg, &block) # :yield: +http+
1011
+ arg.pop if opt = Hash.try_convert(arg[-1])
1012
+ port, p_addr, p_port, p_user, p_pass = *arg
1013
+ p_addr = :ENV if arg.size < 2
1014
+ port = https_default_port if !port && opt && opt[:use_ssl]
1015
+ http = new(address, port, p_addr, p_port, p_user, p_pass)
1016
+ http.ipaddr = opt[:ipaddr] if opt && opt[:ipaddr]
1017
+
1018
+ if opt
1019
+ if opt[:use_ssl]
1020
+ opt = {verify_mode: OpenSSL::SSL::VERIFY_PEER}.update(opt)
1021
+ end
1022
+ http.methods.grep(/\A(\w+)=\z/) do |meth|
1023
+ key = $1.to_sym
1024
+ opt.key?(key) or next
1025
+ http.__send__(meth, opt[key])
1026
+ end
1027
+ end
1028
+
1029
+ http.start(&block)
1030
+ end
1031
+
1032
+ class << HTTP
1033
+ alias newobj new # :nodoc:
1034
+ end
1035
+
1036
+ # Returns a new \Gem::Net::HTTP object +http+
1037
+ # (but does not open a TCP connection or \HTTP session).
1038
+ #
1039
+ # With only string argument +address+ given
1040
+ # (and <tt>ENV['http_proxy']</tt> undefined or +nil+),
1041
+ # the returned +http+:
1042
+ #
1043
+ # - Has the given address.
1044
+ # - Has the default port number, Gem::Net::HTTP.default_port (80).
1045
+ # - Has no proxy.
1046
+ #
1047
+ # Example:
1048
+ #
1049
+ # http = Gem::Net::HTTP.new(hostname)
1050
+ # # => #<Gem::Net::HTTP jsonplaceholder.typicode.com:80 open=false>
1051
+ # http.address # => "jsonplaceholder.typicode.com"
1052
+ # http.port # => 80
1053
+ # http.proxy? # => false
1054
+ #
1055
+ # With integer argument +port+ also given,
1056
+ # the returned +http+ has the given port:
1057
+ #
1058
+ # http = Gem::Net::HTTP.new(hostname, 8000)
1059
+ # # => #<Gem::Net::HTTP jsonplaceholder.typicode.com:8000 open=false>
1060
+ # http.port # => 8000
1061
+ #
1062
+ # For proxy-defining arguments +p_addr+ through +p_no_proxy+,
1063
+ # see {Proxy Server}[rdoc-ref:Gem::Net::HTTP@Proxy+Server].
1064
+ #
1065
+ def HTTP.new(address, port = nil, p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil, p_no_proxy = nil)
1066
+ http = super address, port
1067
+
1068
+ if proxy_class? then # from Gem::Net::HTTP::Proxy()
1069
+ http.proxy_from_env = @proxy_from_env
1070
+ http.proxy_address = @proxy_address
1071
+ http.proxy_port = @proxy_port
1072
+ http.proxy_user = @proxy_user
1073
+ http.proxy_pass = @proxy_pass
1074
+ elsif p_addr == :ENV then
1075
+ http.proxy_from_env = true
1076
+ else
1077
+ if p_addr && p_no_proxy && !URI::Generic.use_proxy?(address, address, port, p_no_proxy)
1078
+ p_addr = nil
1079
+ p_port = nil
1080
+ end
1081
+ http.proxy_address = p_addr
1082
+ http.proxy_port = p_port || default_port
1083
+ http.proxy_user = p_user
1084
+ http.proxy_pass = p_pass
1085
+ end
1086
+
1087
+ http
1088
+ end
1089
+
1090
+ # Creates a new \Gem::Net::HTTP object for the specified server address,
1091
+ # without opening the TCP connection or initializing the \HTTP session.
1092
+ # The +address+ should be a DNS hostname or IP address.
1093
+ def initialize(address, port = nil) # :nodoc:
1094
+ @address = address
1095
+ @port = (port || HTTP.default_port)
1096
+ @ipaddr = nil
1097
+ @local_host = nil
1098
+ @local_port = nil
1099
+ @curr_http_version = HTTPVersion
1100
+ @keep_alive_timeout = 2
1101
+ @last_communicated = nil
1102
+ @close_on_empty_response = false
1103
+ @socket = nil
1104
+ @started = false
1105
+ @open_timeout = 60
1106
+ @read_timeout = 60
1107
+ @write_timeout = 60
1108
+ @continue_timeout = nil
1109
+ @max_retries = 1
1110
+ @debug_output = nil
1111
+ @response_body_encoding = false
1112
+ @ignore_eof = true
1113
+
1114
+ @proxy_from_env = false
1115
+ @proxy_uri = nil
1116
+ @proxy_address = nil
1117
+ @proxy_port = nil
1118
+ @proxy_user = nil
1119
+ @proxy_pass = nil
1120
+
1121
+ @use_ssl = false
1122
+ @ssl_context = nil
1123
+ @ssl_session = nil
1124
+ @sspi_enabled = false
1125
+ SSL_IVNAMES.each do |ivname|
1126
+ instance_variable_set ivname, nil
1127
+ end
1128
+ end
1129
+
1130
+ # Returns a string representation of +self+:
1131
+ #
1132
+ # Gem::Net::HTTP.new(hostname).inspect
1133
+ # # => "#<Gem::Net::HTTP jsonplaceholder.typicode.com:80 open=false>"
1134
+ #
1135
+ def inspect
1136
+ "#<#{self.class} #{@address}:#{@port} open=#{started?}>"
1137
+ end
1138
+
1139
+ # *WARNING* This method opens a serious security hole.
1140
+ # Never use this method in production code.
1141
+ #
1142
+ # Sets the output stream for debugging:
1143
+ #
1144
+ # http = Gem::Net::HTTP.new(hostname)
1145
+ # File.open('t.tmp', 'w') do |file|
1146
+ # http.set_debug_output(file)
1147
+ # http.start
1148
+ # http.get('/nosuch/1')
1149
+ # http.finish
1150
+ # end
1151
+ # puts File.read('t.tmp')
1152
+ #
1153
+ # Output:
1154
+ #
1155
+ # opening connection to jsonplaceholder.typicode.com:80...
1156
+ # opened
1157
+ # <- "GET /nosuch/1 HTTP/1.1\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: */*\r\nUser-Agent: Ruby\r\nHost: jsonplaceholder.typicode.com\r\n\r\n"
1158
+ # -> "HTTP/1.1 404 Not Found\r\n"
1159
+ # -> "Date: Mon, 12 Dec 2022 21:14:11 GMT\r\n"
1160
+ # -> "Content-Type: application/json; charset=utf-8\r\n"
1161
+ # -> "Content-Length: 2\r\n"
1162
+ # -> "Connection: keep-alive\r\n"
1163
+ # -> "X-Powered-By: Express\r\n"
1164
+ # -> "X-Ratelimit-Limit: 1000\r\n"
1165
+ # -> "X-Ratelimit-Remaining: 999\r\n"
1166
+ # -> "X-Ratelimit-Reset: 1670879660\r\n"
1167
+ # -> "Vary: Origin, Accept-Encoding\r\n"
1168
+ # -> "Access-Control-Allow-Credentials: true\r\n"
1169
+ # -> "Cache-Control: max-age=43200\r\n"
1170
+ # -> "Pragma: no-cache\r\n"
1171
+ # -> "Expires: -1\r\n"
1172
+ # -> "X-Content-Type-Options: nosniff\r\n"
1173
+ # -> "Etag: W/\"2-vyGp6PvFo4RvsFtPoIWeCReyIC8\"\r\n"
1174
+ # -> "Via: 1.1 vegur\r\n"
1175
+ # -> "CF-Cache-Status: MISS\r\n"
1176
+ # -> "Server-Timing: cf-q-config;dur=1.3000000762986e-05\r\n"
1177
+ # -> "Report-To: {\"endpoints\":[{\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v3?s=yOr40jo%2BwS1KHzhTlVpl54beJ5Wx2FcG4gGV0XVrh3X9OlR5q4drUn2dkt5DGO4GDcE%2BVXT7CNgJvGs%2BZleIyMu8CLieFiDIvOviOY3EhHg94m0ZNZgrEdpKD0S85S507l1vsEwEHkoTm%2Ff19SiO\"}],\"group\":\"cf-nel\",\"max_age\":604800}\r\n"
1178
+ # -> "NEL: {\"success_fraction\":0,\"report_to\":\"cf-nel\",\"max_age\":604800}\r\n"
1179
+ # -> "Server: cloudflare\r\n"
1180
+ # -> "CF-RAY: 778977dc484ce591-DFW\r\n"
1181
+ # -> "alt-svc: h3=\":443\"; ma=86400, h3-29=\":443\"; ma=86400\r\n"
1182
+ # -> "\r\n"
1183
+ # reading 2 bytes...
1184
+ # -> "{}"
1185
+ # read 2 bytes
1186
+ # Conn keep-alive
1187
+ #
1188
+ def set_debug_output(output)
1189
+ warn 'Gem::Net::HTTP#set_debug_output called after HTTP started', uplevel: 1 if started?
1190
+ @debug_output = output
1191
+ end
1192
+
1193
+ # Returns the string host name or host IP given as argument +address+ in ::new.
1194
+ attr_reader :address
1195
+
1196
+ # Returns the integer port number given as argument +port+ in ::new.
1197
+ attr_reader :port
1198
+
1199
+ # Sets or returns the string local host used to establish the connection;
1200
+ # initially +nil+.
1201
+ attr_accessor :local_host
1202
+
1203
+ # Sets or returns the integer local port used to establish the connection;
1204
+ # initially +nil+.
1205
+ attr_accessor :local_port
1206
+
1207
+ # Returns the encoding to use for the response body;
1208
+ # see #response_body_encoding=.
1209
+ attr_reader :response_body_encoding
1210
+
1211
+ # Sets the encoding to be used for the response body;
1212
+ # returns the encoding.
1213
+ #
1214
+ # The given +value+ may be:
1215
+ #
1216
+ # - An Encoding object.
1217
+ # - The name of an encoding.
1218
+ # - An alias for an encoding name.
1219
+ #
1220
+ # See {Encoding}[https://docs.ruby-lang.org/en/master/Encoding.html].
1221
+ #
1222
+ # Examples:
1223
+ #
1224
+ # http = Gem::Net::HTTP.new(hostname)
1225
+ # http.response_body_encoding = Encoding::US_ASCII # => #<Encoding:US-ASCII>
1226
+ # http.response_body_encoding = 'US-ASCII' # => "US-ASCII"
1227
+ # http.response_body_encoding = 'ASCII' # => "ASCII"
1228
+ #
1229
+ def response_body_encoding=(value)
1230
+ value = Encoding.find(value) if value.is_a?(String)
1231
+ @response_body_encoding = value
1232
+ end
1233
+
1234
+ # Sets whether to determine the proxy from environment variable
1235
+ # '<tt>ENV['http_proxy']</tt>';
1236
+ # see {Proxy Using ENV['http_proxy']}[rdoc-ref:Gem::Net::HTTP@Proxy+Using+-27ENV-5B-27http_proxy-27-5D-27].
1237
+ attr_writer :proxy_from_env
1238
+
1239
+ # Sets the proxy address;
1240
+ # see {Proxy Server}[rdoc-ref:Gem::Net::HTTP@Proxy+Server].
1241
+ attr_writer :proxy_address
1242
+
1243
+ # Sets the proxy port;
1244
+ # see {Proxy Server}[rdoc-ref:Gem::Net::HTTP@Proxy+Server].
1245
+ attr_writer :proxy_port
1246
+
1247
+ # Sets the proxy user;
1248
+ # see {Proxy Server}[rdoc-ref:Gem::Net::HTTP@Proxy+Server].
1249
+ attr_writer :proxy_user
1250
+
1251
+ # Sets the proxy password;
1252
+ # see {Proxy Server}[rdoc-ref:Gem::Net::HTTP@Proxy+Server].
1253
+ attr_writer :proxy_pass
1254
+
1255
+ # Returns the IP address for the connection.
1256
+ #
1257
+ # If the session has not been started,
1258
+ # returns the value set by #ipaddr=,
1259
+ # or +nil+ if it has not been set:
1260
+ #
1261
+ # http = Gem::Net::HTTP.new(hostname)
1262
+ # http.ipaddr # => nil
1263
+ # http.ipaddr = '172.67.155.76'
1264
+ # http.ipaddr # => "172.67.155.76"
1265
+ #
1266
+ # If the session has been started,
1267
+ # returns the IP address from the socket:
1268
+ #
1269
+ # http = Gem::Net::HTTP.new(hostname)
1270
+ # http.start
1271
+ # http.ipaddr # => "172.67.155.76"
1272
+ # http.finish
1273
+ #
1274
+ def ipaddr
1275
+ started? ? @socket.io.peeraddr[3] : @ipaddr
1276
+ end
1277
+
1278
+ # Sets the IP address for the connection:
1279
+ #
1280
+ # http = Gem::Net::HTTP.new(hostname)
1281
+ # http.ipaddr # => nil
1282
+ # http.ipaddr = '172.67.155.76'
1283
+ # http.ipaddr # => "172.67.155.76"
1284
+ #
1285
+ # The IP address may not be set if the session has been started.
1286
+ def ipaddr=(addr)
1287
+ raise IOError, "ipaddr value changed, but session already started" if started?
1288
+ @ipaddr = addr
1289
+ end
1290
+
1291
+ # Sets or returns the numeric (\Integer or \Float) number of seconds
1292
+ # to wait for a connection to open;
1293
+ # initially 60.
1294
+ # If the connection is not made in the given interval,
1295
+ # an exception is raised.
1296
+ attr_accessor :open_timeout
1297
+
1298
+ # Returns the numeric (\Integer or \Float) number of seconds
1299
+ # to wait for one block to be read (via one read(2) call);
1300
+ # see #read_timeout=.
1301
+ attr_reader :read_timeout
1302
+
1303
+ # Returns the numeric (\Integer or \Float) number of seconds
1304
+ # to wait for one block to be written (via one write(2) call);
1305
+ # see #write_timeout=.
1306
+ attr_reader :write_timeout
1307
+
1308
+ # Sets the maximum number of times to retry an idempotent request in case of
1309
+ # \Gem::Net::ReadTimeout, IOError, EOFError, Errno::ECONNRESET,
1310
+ # Errno::ECONNABORTED, Errno::EPIPE, OpenSSL::SSL::SSLError,
1311
+ # Gem::Timeout::Error.
1312
+ # The initial value is 1.
1313
+ #
1314
+ # Argument +retries+ must be a non-negative numeric value:
1315
+ #
1316
+ # http = Gem::Net::HTTP.new(hostname)
1317
+ # http.max_retries = 2 # => 2
1318
+ # http.max_retries # => 2
1319
+ #
1320
+ def max_retries=(retries)
1321
+ retries = retries.to_int
1322
+ if retries < 0
1323
+ raise ArgumentError, 'max_retries should be non-negative integer number'
1324
+ end
1325
+ @max_retries = retries
1326
+ end
1327
+
1328
+ # Returns the maximum number of times to retry an idempotent request;
1329
+ # see #max_retries=.
1330
+ attr_reader :max_retries
1331
+
1332
+ # Sets the read timeout, in seconds, for +self+ to integer +sec+;
1333
+ # the initial value is 60.
1334
+ #
1335
+ # Argument +sec+ must be a non-negative numeric value:
1336
+ #
1337
+ # http = Gem::Net::HTTP.new(hostname)
1338
+ # http.read_timeout # => 60
1339
+ # http.get('/todos/1') # => #<Gem::Net::HTTPOK 200 OK readbody=true>
1340
+ # http.read_timeout = 0
1341
+ # http.get('/todos/1') # Raises Gem::Net::ReadTimeout.
1342
+ #
1343
+ def read_timeout=(sec)
1344
+ @socket.read_timeout = sec if @socket
1345
+ @read_timeout = sec
1346
+ end
1347
+
1348
+ # Sets the write timeout, in seconds, for +self+ to integer +sec+;
1349
+ # the initial value is 60.
1350
+ #
1351
+ # Argument +sec+ must be a non-negative numeric value:
1352
+ #
1353
+ # _uri = uri.dup
1354
+ # _uri.path = '/posts'
1355
+ # body = 'bar' * 200000
1356
+ # data = <<EOF
1357
+ # {"title": "foo", "body": "#{body}", "userId": "1"}
1358
+ # EOF
1359
+ # headers = {'content-type': 'application/json'}
1360
+ # http = Gem::Net::HTTP.new(hostname)
1361
+ # http.write_timeout # => 60
1362
+ # http.post(_uri.path, data, headers)
1363
+ # # => #<Gem::Net::HTTPCreated 201 Created readbody=true>
1364
+ # http.write_timeout = 0
1365
+ # http.post(_uri.path, data, headers) # Raises Gem::Net::WriteTimeout.
1366
+ #
1367
+ def write_timeout=(sec)
1368
+ @socket.write_timeout = sec if @socket
1369
+ @write_timeout = sec
1370
+ end
1371
+
1372
+ # Returns the continue timeout value;
1373
+ # see continue_timeout=.
1374
+ attr_reader :continue_timeout
1375
+
1376
+ # Sets the continue timeout value,
1377
+ # which is the number of seconds to wait for an expected 100 Continue response.
1378
+ # If the \HTTP object does not receive a response in this many seconds
1379
+ # it sends the request body.
1380
+ def continue_timeout=(sec)
1381
+ @socket.continue_timeout = sec if @socket
1382
+ @continue_timeout = sec
1383
+ end
1384
+
1385
+ # Sets or returns the numeric (\Integer or \Float) number of seconds
1386
+ # to keep the connection open after a request is sent;
1387
+ # initially 2.
1388
+ # If a new request is made during the given interval,
1389
+ # the still-open connection is used;
1390
+ # otherwise the connection will have been closed
1391
+ # and a new connection is opened.
1392
+ attr_accessor :keep_alive_timeout
1393
+
1394
+ # Sets or returns whether to ignore end-of-file when reading a response body
1395
+ # with <tt>Content-Length</tt> headers;
1396
+ # initially +true+.
1397
+ attr_accessor :ignore_eof
1398
+
1399
+ # Returns +true+ if the \HTTP session has been started:
1400
+ #
1401
+ # http = Gem::Net::HTTP.new(hostname)
1402
+ # http.started? # => false
1403
+ # http.start
1404
+ # http.started? # => true
1405
+ # http.finish # => nil
1406
+ # http.started? # => false
1407
+ #
1408
+ # Gem::Net::HTTP.start(hostname) do |http|
1409
+ # http.started?
1410
+ # end # => true
1411
+ # http.started? # => false
1412
+ #
1413
+ def started?
1414
+ @started
1415
+ end
1416
+
1417
+ alias active? started? #:nodoc: obsolete
1418
+
1419
+ # Sets or returns whether to close the connection when the response is empty;
1420
+ # initially +false+.
1421
+ attr_accessor :close_on_empty_response
1422
+
1423
+ # Returns +true+ if +self+ uses SSL, +false+ otherwise.
1424
+ # See Gem::Net::HTTP#use_ssl=.
1425
+ def use_ssl?
1426
+ @use_ssl
1427
+ end
1428
+
1429
+ # Sets whether a new session is to use
1430
+ # {Transport Layer Security}[https://en.wikipedia.org/wiki/Transport_Layer_Security]:
1431
+ #
1432
+ # Raises IOError if attempting to change during a session.
1433
+ #
1434
+ # Raises OpenSSL::SSL::SSLError if the port is not an HTTPS port.
1435
+ def use_ssl=(flag)
1436
+ flag = flag ? true : false
1437
+ if started? and @use_ssl != flag
1438
+ raise IOError, "use_ssl value changed, but session already started"
1439
+ end
1440
+ @use_ssl = flag
1441
+ end
1442
+
1443
+ SSL_IVNAMES = [
1444
+ :@ca_file,
1445
+ :@ca_path,
1446
+ :@cert,
1447
+ :@cert_store,
1448
+ :@ciphers,
1449
+ :@extra_chain_cert,
1450
+ :@key,
1451
+ :@ssl_timeout,
1452
+ :@ssl_version,
1453
+ :@min_version,
1454
+ :@max_version,
1455
+ :@verify_callback,
1456
+ :@verify_depth,
1457
+ :@verify_mode,
1458
+ :@verify_hostname,
1459
+ ] # :nodoc:
1460
+ SSL_ATTRIBUTES = [
1461
+ :ca_file,
1462
+ :ca_path,
1463
+ :cert,
1464
+ :cert_store,
1465
+ :ciphers,
1466
+ :extra_chain_cert,
1467
+ :key,
1468
+ :ssl_timeout,
1469
+ :ssl_version,
1470
+ :min_version,
1471
+ :max_version,
1472
+ :verify_callback,
1473
+ :verify_depth,
1474
+ :verify_mode,
1475
+ :verify_hostname,
1476
+ ] # :nodoc:
1477
+
1478
+ # Sets or returns the path to a CA certification file in PEM format.
1479
+ attr_accessor :ca_file
1480
+
1481
+ # Sets or returns the path of to CA directory
1482
+ # containing certification files in PEM format.
1483
+ attr_accessor :ca_path
1484
+
1485
+ # Sets or returns the OpenSSL::X509::Certificate object
1486
+ # to be used for client certification.
1487
+ attr_accessor :cert
1488
+
1489
+ # Sets or returns the X509::Store to be used for verifying peer certificate.
1490
+ attr_accessor :cert_store
1491
+
1492
+ # Sets or returns the available SSL ciphers.
1493
+ # See {OpenSSL::SSL::SSLContext#ciphers=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-ciphers-3D].
1494
+ attr_accessor :ciphers
1495
+
1496
+ # Sets or returns the extra X509 certificates to be added to the certificate chain.
1497
+ # See {OpenSSL::SSL::SSLContext#add_certificate}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-add_certificate].
1498
+ attr_accessor :extra_chain_cert
1499
+
1500
+ # Sets or returns the OpenSSL::PKey::RSA or OpenSSL::PKey::DSA object.
1501
+ attr_accessor :key
1502
+
1503
+ # Sets or returns the SSL timeout seconds.
1504
+ attr_accessor :ssl_timeout
1505
+
1506
+ # Sets or returns the SSL version.
1507
+ # See {OpenSSL::SSL::SSLContext#ssl_version=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-ssl_version-3D].
1508
+ attr_accessor :ssl_version
1509
+
1510
+ # Sets or returns the minimum SSL version.
1511
+ # See {OpenSSL::SSL::SSLContext#min_version=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-min_version-3D].
1512
+ attr_accessor :min_version
1513
+
1514
+ # Sets or returns the maximum SSL version.
1515
+ # See {OpenSSL::SSL::SSLContext#max_version=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#method-i-max_version-3D].
1516
+ attr_accessor :max_version
1517
+
1518
+ # Sets or returns the callback for the server certification verification.
1519
+ attr_accessor :verify_callback
1520
+
1521
+ # Sets or returns the maximum depth for the certificate chain verification.
1522
+ attr_accessor :verify_depth
1523
+
1524
+ # Sets or returns the flags for server the certification verification
1525
+ # at the beginning of the SSL/TLS session.
1526
+ # OpenSSL::SSL::VERIFY_NONE or OpenSSL::SSL::VERIFY_PEER are acceptable.
1527
+ attr_accessor :verify_mode
1528
+
1529
+ # Sets or returns whether to verify that the server certificate is valid
1530
+ # for the hostname.
1531
+ # See {OpenSSL::SSL::SSLContext#verify_hostname=}[https://docs.ruby-lang.org/en/master/OpenSSL/SSL/SSLContext.html#attribute-i-verify_mode].
1532
+ attr_accessor :verify_hostname
1533
+
1534
+ # Returns the X509 certificate chain (an array of strings)
1535
+ # for the session's socket peer,
1536
+ # or +nil+ if none.
1537
+ def peer_cert
1538
+ if not use_ssl? or not @socket
1539
+ return nil
1540
+ end
1541
+ @socket.io.peer_cert
1542
+ end
1543
+
1544
+ # Starts an \HTTP session.
1545
+ #
1546
+ # Without a block, returns +self+:
1547
+ #
1548
+ # http = Gem::Net::HTTP.new(hostname)
1549
+ # # => #<Gem::Net::HTTP jsonplaceholder.typicode.com:80 open=false>
1550
+ # http.start
1551
+ # # => #<Gem::Net::HTTP jsonplaceholder.typicode.com:80 open=true>
1552
+ # http.started? # => true
1553
+ # http.finish
1554
+ #
1555
+ # With a block, calls the block with +self+,
1556
+ # finishes the session when the block exits,
1557
+ # and returns the block's value:
1558
+ #
1559
+ # http.start do |http|
1560
+ # http
1561
+ # end
1562
+ # # => #<Gem::Net::HTTP jsonplaceholder.typicode.com:80 open=false>
1563
+ # http.started? # => false
1564
+ #
1565
+ def start # :yield: http
1566
+ raise IOError, 'HTTP session already opened' if @started
1567
+ if block_given?
1568
+ begin
1569
+ do_start
1570
+ return yield(self)
1571
+ ensure
1572
+ do_finish
1573
+ end
1574
+ end
1575
+ do_start
1576
+ self
1577
+ end
1578
+
1579
+ def do_start
1580
+ connect
1581
+ @started = true
1582
+ end
1583
+ private :do_start
1584
+
1585
+ def connect
1586
+ if use_ssl?
1587
+ # reference early to load OpenSSL before connecting,
1588
+ # as OpenSSL may take time to load.
1589
+ @ssl_context = OpenSSL::SSL::SSLContext.new
1590
+ end
1591
+
1592
+ if proxy? then
1593
+ conn_addr = proxy_address
1594
+ conn_port = proxy_port
1595
+ else
1596
+ conn_addr = conn_address
1597
+ conn_port = port
1598
+ end
1599
+
1600
+ debug "opening connection to #{conn_addr}:#{conn_port}..."
1601
+ s = Gem::Timeout.timeout(@open_timeout, Gem::Net::OpenTimeout) {
1602
+ begin
1603
+ TCPSocket.open(conn_addr, conn_port, @local_host, @local_port)
1604
+ rescue => e
1605
+ raise e, "Failed to open TCP connection to " +
1606
+ "#{conn_addr}:#{conn_port} (#{e.message})"
1607
+ end
1608
+ }
1609
+ s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
1610
+ debug "opened"
1611
+ if use_ssl?
1612
+ if proxy?
1613
+ plain_sock = BufferedIO.new(s, read_timeout: @read_timeout,
1614
+ write_timeout: @write_timeout,
1615
+ continue_timeout: @continue_timeout,
1616
+ debug_output: @debug_output)
1617
+ buf = +"CONNECT #{conn_address}:#{@port} HTTP/#{HTTPVersion}\r\n" \
1618
+ "Host: #{@address}:#{@port}\r\n"
1619
+ if proxy_user
1620
+ credential = ["#{proxy_user}:#{proxy_pass}"].pack('m0')
1621
+ buf << "Proxy-Authorization: Basic #{credential}\r\n"
1622
+ end
1623
+ buf << "\r\n"
1624
+ plain_sock.write(buf)
1625
+ HTTPResponse.read_new(plain_sock).value
1626
+ # assuming nothing left in buffers after successful CONNECT response
1627
+ end
1628
+
1629
+ ssl_parameters = Hash.new
1630
+ iv_list = instance_variables
1631
+ SSL_IVNAMES.each_with_index do |ivname, i|
1632
+ if iv_list.include?(ivname)
1633
+ value = instance_variable_get(ivname)
1634
+ unless value.nil?
1635
+ ssl_parameters[SSL_ATTRIBUTES[i]] = value
1636
+ end
1637
+ end
1638
+ end
1639
+ @ssl_context.set_params(ssl_parameters)
1640
+ unless @ssl_context.session_cache_mode.nil? # a dummy method on JRuby
1641
+ @ssl_context.session_cache_mode =
1642
+ OpenSSL::SSL::SSLContext::SESSION_CACHE_CLIENT |
1643
+ OpenSSL::SSL::SSLContext::SESSION_CACHE_NO_INTERNAL_STORE
1644
+ end
1645
+ if @ssl_context.respond_to?(:session_new_cb) # not implemented under JRuby
1646
+ @ssl_context.session_new_cb = proc {|sock, sess| @ssl_session = sess }
1647
+ end
1648
+
1649
+ # Still do the post_connection_check below even if connecting
1650
+ # to IP address
1651
+ verify_hostname = @ssl_context.verify_hostname
1652
+
1653
+ # Server Name Indication (SNI) RFC 3546/6066
1654
+ case @address
1655
+ when Gem::Resolv::IPv4::Regex, Gem::Resolv::IPv6::Regex
1656
+ # don't set SNI, as IP addresses in SNI is not valid
1657
+ # per RFC 6066, section 3.
1658
+
1659
+ # Avoid openssl warning
1660
+ @ssl_context.verify_hostname = false
1661
+ else
1662
+ ssl_host_address = @address
1663
+ end
1664
+
1665
+ debug "starting SSL for #{conn_addr}:#{conn_port}..."
1666
+ s = OpenSSL::SSL::SSLSocket.new(s, @ssl_context)
1667
+ s.sync_close = true
1668
+ s.hostname = ssl_host_address if s.respond_to?(:hostname=) && ssl_host_address
1669
+
1670
+ if @ssl_session and
1671
+ Process.clock_gettime(Process::CLOCK_REALTIME) < @ssl_session.time.to_f + @ssl_session.timeout
1672
+ s.session = @ssl_session
1673
+ end
1674
+ ssl_socket_connect(s, @open_timeout)
1675
+ if (@ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE) && verify_hostname
1676
+ s.post_connection_check(@address)
1677
+ end
1678
+ debug "SSL established, protocol: #{s.ssl_version}, cipher: #{s.cipher[0]}"
1679
+ end
1680
+ @socket = BufferedIO.new(s, read_timeout: @read_timeout,
1681
+ write_timeout: @write_timeout,
1682
+ continue_timeout: @continue_timeout,
1683
+ debug_output: @debug_output)
1684
+ @last_communicated = nil
1685
+ on_connect
1686
+ rescue => exception
1687
+ if s
1688
+ debug "Conn close because of connect error #{exception}"
1689
+ s.close
1690
+ end
1691
+ raise
1692
+ end
1693
+ private :connect
1694
+
1695
+ def on_connect
1696
+ end
1697
+ private :on_connect
1698
+
1699
+ # Finishes the \HTTP session:
1700
+ #
1701
+ # http = Gem::Net::HTTP.new(hostname)
1702
+ # http.start
1703
+ # http.started? # => true
1704
+ # http.finish # => nil
1705
+ # http.started? # => false
1706
+ #
1707
+ # Raises IOError if not in a session.
1708
+ def finish
1709
+ raise IOError, 'HTTP session not yet started' unless started?
1710
+ do_finish
1711
+ end
1712
+
1713
+ def do_finish
1714
+ @started = false
1715
+ @socket.close if @socket
1716
+ @socket = nil
1717
+ end
1718
+ private :do_finish
1719
+
1720
+ #
1721
+ # proxy
1722
+ #
1723
+
1724
+ public
1725
+
1726
+ # no proxy
1727
+ @is_proxy_class = false
1728
+ @proxy_from_env = false
1729
+ @proxy_addr = nil
1730
+ @proxy_port = nil
1731
+ @proxy_user = nil
1732
+ @proxy_pass = nil
1733
+
1734
+ # Creates an \HTTP proxy class which behaves like \Gem::Net::HTTP, but
1735
+ # performs all access via the specified proxy.
1736
+ #
1737
+ # This class is obsolete. You may pass these same parameters directly to
1738
+ # \Gem::Net::HTTP.new. See Gem::Net::HTTP.new for details of the arguments.
1739
+ def HTTP.Proxy(p_addr = :ENV, p_port = nil, p_user = nil, p_pass = nil) #:nodoc:
1740
+ return self unless p_addr
1741
+
1742
+ Class.new(self) {
1743
+ @is_proxy_class = true
1744
+
1745
+ if p_addr == :ENV then
1746
+ @proxy_from_env = true
1747
+ @proxy_address = nil
1748
+ @proxy_port = nil
1749
+ else
1750
+ @proxy_from_env = false
1751
+ @proxy_address = p_addr
1752
+ @proxy_port = p_port || default_port
1753
+ end
1754
+
1755
+ @proxy_user = p_user
1756
+ @proxy_pass = p_pass
1757
+ }
1758
+ end
1759
+
1760
+ class << HTTP
1761
+ # Returns true if self is a class which was created by HTTP::Proxy.
1762
+ def proxy_class?
1763
+ defined?(@is_proxy_class) ? @is_proxy_class : false
1764
+ end
1765
+
1766
+ # Returns the address of the proxy host, or +nil+ if none;
1767
+ # see Gem::Net::HTTP@Proxy+Server.
1768
+ attr_reader :proxy_address
1769
+
1770
+ # Returns the port number of the proxy host, or +nil+ if none;
1771
+ # see Gem::Net::HTTP@Proxy+Server.
1772
+ attr_reader :proxy_port
1773
+
1774
+ # Returns the user name for accessing the proxy, or +nil+ if none;
1775
+ # see Gem::Net::HTTP@Proxy+Server.
1776
+ attr_reader :proxy_user
1777
+
1778
+ # Returns the password for accessing the proxy, or +nil+ if none;
1779
+ # see Gem::Net::HTTP@Proxy+Server.
1780
+ attr_reader :proxy_pass
1781
+ end
1782
+
1783
+ # Returns +true+ if a proxy server is defined, +false+ otherwise;
1784
+ # see {Proxy Server}[rdoc-ref:Gem::Net::HTTP@Proxy+Server].
1785
+ def proxy?
1786
+ !!(@proxy_from_env ? proxy_uri : @proxy_address)
1787
+ end
1788
+
1789
+ # Returns +true+ if the proxy server is defined in the environment,
1790
+ # +false+ otherwise;
1791
+ # see {Proxy Server}[rdoc-ref:Gem::Net::HTTP@Proxy+Server].
1792
+ def proxy_from_env?
1793
+ @proxy_from_env
1794
+ end
1795
+
1796
+ # The proxy URI determined from the environment for this connection.
1797
+ def proxy_uri # :nodoc:
1798
+ return if @proxy_uri == false
1799
+ @proxy_uri ||= URI::HTTP.new(
1800
+ "http", nil, address, port, nil, nil, nil, nil, nil
1801
+ ).find_proxy || false
1802
+ @proxy_uri || nil
1803
+ end
1804
+
1805
+ # Returns the address of the proxy server, if defined, +nil+ otherwise;
1806
+ # see {Proxy Server}[rdoc-ref:Gem::Net::HTTP@Proxy+Server].
1807
+ def proxy_address
1808
+ if @proxy_from_env then
1809
+ proxy_uri&.hostname
1810
+ else
1811
+ @proxy_address
1812
+ end
1813
+ end
1814
+
1815
+ # Returns the port number of the proxy server, if defined, +nil+ otherwise;
1816
+ # see {Proxy Server}[rdoc-ref:Gem::Net::HTTP@Proxy+Server].
1817
+ def proxy_port
1818
+ if @proxy_from_env then
1819
+ proxy_uri&.port
1820
+ else
1821
+ @proxy_port
1822
+ end
1823
+ end
1824
+
1825
+ # Returns the user name of the proxy server, if defined, +nil+ otherwise;
1826
+ # see {Proxy Server}[rdoc-ref:Gem::Net::HTTP@Proxy+Server].
1827
+ def proxy_user
1828
+ if @proxy_from_env
1829
+ user = proxy_uri&.user
1830
+ unescape(user) if user
1831
+ else
1832
+ @proxy_user
1833
+ end
1834
+ end
1835
+
1836
+ # Returns the password of the proxy server, if defined, +nil+ otherwise;
1837
+ # see {Proxy Server}[rdoc-ref:Gem::Net::HTTP@Proxy+Server].
1838
+ def proxy_pass
1839
+ if @proxy_from_env
1840
+ pass = proxy_uri&.password
1841
+ unescape(pass) if pass
1842
+ else
1843
+ @proxy_pass
1844
+ end
1845
+ end
1846
+
1847
+ alias proxyaddr proxy_address #:nodoc: obsolete
1848
+ alias proxyport proxy_port #:nodoc: obsolete
1849
+
1850
+ private
1851
+
1852
+ def unescape(value)
1853
+ require 'cgi/util'
1854
+ CGI.unescape(value)
1855
+ end
1856
+
1857
+ # without proxy, obsolete
1858
+
1859
+ def conn_address # :nodoc:
1860
+ @ipaddr || address()
1861
+ end
1862
+
1863
+ def conn_port # :nodoc:
1864
+ port()
1865
+ end
1866
+
1867
+ def edit_path(path)
1868
+ if proxy?
1869
+ if path.start_with?("ftp://") || use_ssl?
1870
+ path
1871
+ else
1872
+ "http://#{addr_port}#{path}"
1873
+ end
1874
+ else
1875
+ path
1876
+ end
1877
+ end
1878
+
1879
+ #
1880
+ # HTTP operations
1881
+ #
1882
+
1883
+ public
1884
+
1885
+ # :call-seq:
1886
+ # get(path, initheader = nil) {|res| ... }
1887
+ #
1888
+ # Sends a GET request to the server;
1889
+ # returns an instance of a subclass of Gem::Net::HTTPResponse.
1890
+ #
1891
+ # The request is based on the Gem::Net::HTTP::Get object
1892
+ # created from string +path+ and initial headers hash +initheader+.
1893
+ #
1894
+ # With a block given, calls the block with the response body:
1895
+ #
1896
+ # http = Gem::Net::HTTP.new(hostname)
1897
+ # http.get('/todos/1') do |res|
1898
+ # p res
1899
+ # end # => #<Gem::Net::HTTPOK 200 OK readbody=true>
1900
+ #
1901
+ # Output:
1902
+ #
1903
+ # "{\n \"userId\": 1,\n \"id\": 1,\n \"title\": \"delectus aut autem\",\n \"completed\": false\n}"
1904
+ #
1905
+ # With no block given, simply returns the response object:
1906
+ #
1907
+ # http.get('/') # => #<Gem::Net::HTTPOK 200 OK readbody=true>
1908
+ #
1909
+ # Related:
1910
+ #
1911
+ # - Gem::Net::HTTP::Get: request class for \HTTP method GET.
1912
+ # - Gem::Net::HTTP.get: sends GET request, returns response body.
1913
+ #
1914
+ def get(path, initheader = nil, dest = nil, &block) # :yield: +body_segment+
1915
+ res = nil
1916
+
1917
+ request(Get.new(path, initheader)) {|r|
1918
+ r.read_body dest, &block
1919
+ res = r
1920
+ }
1921
+ res
1922
+ end
1923
+
1924
+ # Sends a HEAD request to the server;
1925
+ # returns an instance of a subclass of Gem::Net::HTTPResponse.
1926
+ #
1927
+ # The request is based on the Gem::Net::HTTP::Head object
1928
+ # created from string +path+ and initial headers hash +initheader+:
1929
+ #
1930
+ # res = http.head('/todos/1') # => #<Gem::Net::HTTPOK 200 OK readbody=true>
1931
+ # res.body # => nil
1932
+ # res.to_hash.take(3)
1933
+ # # =>
1934
+ # [["date", ["Wed, 15 Feb 2023 15:25:42 GMT"]],
1935
+ # ["content-type", ["application/json; charset=utf-8"]],
1936
+ # ["connection", ["close"]]]
1937
+ #
1938
+ def head(path, initheader = nil)
1939
+ request(Head.new(path, initheader))
1940
+ end
1941
+
1942
+ # :call-seq:
1943
+ # post(path, data, initheader = nil) {|res| ... }
1944
+ #
1945
+ # Sends a POST request to the server;
1946
+ # returns an instance of a subclass of Gem::Net::HTTPResponse.
1947
+ #
1948
+ # The request is based on the Gem::Net::HTTP::Post object
1949
+ # created from string +path+, string +data+, and initial headers hash +initheader+.
1950
+ #
1951
+ # With a block given, calls the block with the response body:
1952
+ #
1953
+ # data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
1954
+ # http = Gem::Net::HTTP.new(hostname)
1955
+ # http.post('/todos', data) do |res|
1956
+ # p res
1957
+ # end # => #<Gem::Net::HTTPCreated 201 Created readbody=true>
1958
+ #
1959
+ # Output:
1960
+ #
1961
+ # "{\n \"{\\\"userId\\\": 1, \\\"id\\\": 1, \\\"title\\\": \\\"delectus aut autem\\\", \\\"completed\\\": false}\": \"\",\n \"id\": 201\n}"
1962
+ #
1963
+ # With no block given, simply returns the response object:
1964
+ #
1965
+ # http.post('/todos', data) # => #<Gem::Net::HTTPCreated 201 Created readbody=true>
1966
+ #
1967
+ # Related:
1968
+ #
1969
+ # - Gem::Net::HTTP::Post: request class for \HTTP method POST.
1970
+ # - Gem::Net::HTTP.post: sends POST request, returns response body.
1971
+ #
1972
+ def post(path, data, initheader = nil, dest = nil, &block) # :yield: +body_segment+
1973
+ send_entity(path, data, initheader, dest, Post, &block)
1974
+ end
1975
+
1976
+ # :call-seq:
1977
+ # patch(path, data, initheader = nil) {|res| ... }
1978
+ #
1979
+ # Sends a PATCH request to the server;
1980
+ # returns an instance of a subclass of Gem::Net::HTTPResponse.
1981
+ #
1982
+ # The request is based on the Gem::Net::HTTP::Patch object
1983
+ # created from string +path+, string +data+, and initial headers hash +initheader+.
1984
+ #
1985
+ # With a block given, calls the block with the response body:
1986
+ #
1987
+ # data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
1988
+ # http = Gem::Net::HTTP.new(hostname)
1989
+ # http.patch('/todos/1', data) do |res|
1990
+ # p res
1991
+ # end # => #<Gem::Net::HTTPOK 200 OK readbody=true>
1992
+ #
1993
+ # Output:
1994
+ #
1995
+ # "{\n \"userId\": 1,\n \"id\": 1,\n \"title\": \"delectus aut autem\",\n \"completed\": false,\n \"{\\\"userId\\\": 1, \\\"id\\\": 1, \\\"title\\\": \\\"delectus aut autem\\\", \\\"completed\\\": false}\": \"\"\n}"
1996
+ #
1997
+ # With no block given, simply returns the response object:
1998
+ #
1999
+ # http.patch('/todos/1', data) # => #<Gem::Net::HTTPCreated 201 Created readbody=true>
2000
+ #
2001
+ def patch(path, data, initheader = nil, dest = nil, &block) # :yield: +body_segment+
2002
+ send_entity(path, data, initheader, dest, Patch, &block)
2003
+ end
2004
+
2005
+ # Sends a PUT request to the server;
2006
+ # returns an instance of a subclass of Gem::Net::HTTPResponse.
2007
+ #
2008
+ # The request is based on the Gem::Net::HTTP::Put object
2009
+ # created from string +path+, string +data+, and initial headers hash +initheader+.
2010
+ #
2011
+ # data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
2012
+ # http = Gem::Net::HTTP.new(hostname)
2013
+ # http.put('/todos/1', data) # => #<Gem::Net::HTTPOK 200 OK readbody=true>
2014
+ #
2015
+ def put(path, data, initheader = nil)
2016
+ request(Put.new(path, initheader), data)
2017
+ end
2018
+
2019
+ # Sends a PROPPATCH request to the server;
2020
+ # returns an instance of a subclass of Gem::Net::HTTPResponse.
2021
+ #
2022
+ # The request is based on the Gem::Net::HTTP::Proppatch object
2023
+ # created from string +path+, string +body+, and initial headers hash +initheader+.
2024
+ #
2025
+ # data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
2026
+ # http = Gem::Net::HTTP.new(hostname)
2027
+ # http.proppatch('/todos/1', data)
2028
+ #
2029
+ def proppatch(path, body, initheader = nil)
2030
+ request(Proppatch.new(path, initheader), body)
2031
+ end
2032
+
2033
+ # Sends a LOCK request to the server;
2034
+ # returns an instance of a subclass of Gem::Net::HTTPResponse.
2035
+ #
2036
+ # The request is based on the Gem::Net::HTTP::Lock object
2037
+ # created from string +path+, string +body+, and initial headers hash +initheader+.
2038
+ #
2039
+ # data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
2040
+ # http = Gem::Net::HTTP.new(hostname)
2041
+ # http.lock('/todos/1', data)
2042
+ #
2043
+ def lock(path, body, initheader = nil)
2044
+ request(Lock.new(path, initheader), body)
2045
+ end
2046
+
2047
+ # Sends an UNLOCK request to the server;
2048
+ # returns an instance of a subclass of Gem::Net::HTTPResponse.
2049
+ #
2050
+ # The request is based on the Gem::Net::HTTP::Unlock object
2051
+ # created from string +path+, string +body+, and initial headers hash +initheader+.
2052
+ #
2053
+ # data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
2054
+ # http = Gem::Net::HTTP.new(hostname)
2055
+ # http.unlock('/todos/1', data)
2056
+ #
2057
+ def unlock(path, body, initheader = nil)
2058
+ request(Unlock.new(path, initheader), body)
2059
+ end
2060
+
2061
+ # Sends an Options request to the server;
2062
+ # returns an instance of a subclass of Gem::Net::HTTPResponse.
2063
+ #
2064
+ # The request is based on the Gem::Net::HTTP::Options object
2065
+ # created from string +path+ and initial headers hash +initheader+.
2066
+ #
2067
+ # http = Gem::Net::HTTP.new(hostname)
2068
+ # http.options('/')
2069
+ #
2070
+ def options(path, initheader = nil)
2071
+ request(Options.new(path, initheader))
2072
+ end
2073
+
2074
+ # Sends a PROPFIND request to the server;
2075
+ # returns an instance of a subclass of Gem::Net::HTTPResponse.
2076
+ #
2077
+ # The request is based on the Gem::Net::HTTP::Propfind object
2078
+ # created from string +path+, string +body+, and initial headers hash +initheader+.
2079
+ #
2080
+ # data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
2081
+ # http = Gem::Net::HTTP.new(hostname)
2082
+ # http.propfind('/todos/1', data)
2083
+ #
2084
+ def propfind(path, body = nil, initheader = {'Depth' => '0'})
2085
+ request(Propfind.new(path, initheader), body)
2086
+ end
2087
+
2088
+ # Sends a DELETE request to the server;
2089
+ # returns an instance of a subclass of Gem::Net::HTTPResponse.
2090
+ #
2091
+ # The request is based on the Gem::Net::HTTP::Delete object
2092
+ # created from string +path+ and initial headers hash +initheader+.
2093
+ #
2094
+ # http = Gem::Net::HTTP.new(hostname)
2095
+ # http.delete('/todos/1')
2096
+ #
2097
+ def delete(path, initheader = {'Depth' => 'Infinity'})
2098
+ request(Delete.new(path, initheader))
2099
+ end
2100
+
2101
+ # Sends a MOVE request to the server;
2102
+ # returns an instance of a subclass of Gem::Net::HTTPResponse.
2103
+ #
2104
+ # The request is based on the Gem::Net::HTTP::Move object
2105
+ # created from string +path+ and initial headers hash +initheader+.
2106
+ #
2107
+ # http = Gem::Net::HTTP.new(hostname)
2108
+ # http.move('/todos/1')
2109
+ #
2110
+ def move(path, initheader = nil)
2111
+ request(Move.new(path, initheader))
2112
+ end
2113
+
2114
+ # Sends a COPY request to the server;
2115
+ # returns an instance of a subclass of Gem::Net::HTTPResponse.
2116
+ #
2117
+ # The request is based on the Gem::Net::HTTP::Copy object
2118
+ # created from string +path+ and initial headers hash +initheader+.
2119
+ #
2120
+ # http = Gem::Net::HTTP.new(hostname)
2121
+ # http.copy('/todos/1')
2122
+ #
2123
+ def copy(path, initheader = nil)
2124
+ request(Copy.new(path, initheader))
2125
+ end
2126
+
2127
+ # Sends a MKCOL request to the server;
2128
+ # returns an instance of a subclass of Gem::Net::HTTPResponse.
2129
+ #
2130
+ # The request is based on the Gem::Net::HTTP::Mkcol object
2131
+ # created from string +path+, string +body+, and initial headers hash +initheader+.
2132
+ #
2133
+ # data = '{"userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}'
2134
+ # http.mkcol('/todos/1', data)
2135
+ # http = Gem::Net::HTTP.new(hostname)
2136
+ #
2137
+ def mkcol(path, body = nil, initheader = nil)
2138
+ request(Mkcol.new(path, initheader), body)
2139
+ end
2140
+
2141
+ # Sends a TRACE request to the server;
2142
+ # returns an instance of a subclass of Gem::Net::HTTPResponse.
2143
+ #
2144
+ # The request is based on the Gem::Net::HTTP::Trace object
2145
+ # created from string +path+ and initial headers hash +initheader+.
2146
+ #
2147
+ # http = Gem::Net::HTTP.new(hostname)
2148
+ # http.trace('/todos/1')
2149
+ #
2150
+ def trace(path, initheader = nil)
2151
+ request(Trace.new(path, initheader))
2152
+ end
2153
+
2154
+ # Sends a GET request to the server;
2155
+ # forms the response into a Gem::Net::HTTPResponse object.
2156
+ #
2157
+ # The request is based on the Gem::Net::HTTP::Get object
2158
+ # created from string +path+ and initial headers hash +initheader+.
2159
+ #
2160
+ # With no block given, returns the response object:
2161
+ #
2162
+ # http = Gem::Net::HTTP.new(hostname)
2163
+ # http.request_get('/todos') # => #<Gem::Net::HTTPOK 200 OK readbody=true>
2164
+ #
2165
+ # With a block given, calls the block with the response object
2166
+ # and returns the response object:
2167
+ #
2168
+ # http.request_get('/todos') do |res|
2169
+ # p res
2170
+ # end # => #<Gem::Net::HTTPOK 200 OK readbody=true>
2171
+ #
2172
+ # Output:
2173
+ #
2174
+ # #<Gem::Net::HTTPOK 200 OK readbody=false>
2175
+ #
2176
+ def request_get(path, initheader = nil, &block) # :yield: +response+
2177
+ request(Get.new(path, initheader), &block)
2178
+ end
2179
+
2180
+ # Sends a HEAD request to the server;
2181
+ # returns an instance of a subclass of Gem::Net::HTTPResponse.
2182
+ #
2183
+ # The request is based on the Gem::Net::HTTP::Head object
2184
+ # created from string +path+ and initial headers hash +initheader+.
2185
+ #
2186
+ # http = Gem::Net::HTTP.new(hostname)
2187
+ # http.head('/todos/1') # => #<Gem::Net::HTTPOK 200 OK readbody=true>
2188
+ #
2189
+ def request_head(path, initheader = nil, &block)
2190
+ request(Head.new(path, initheader), &block)
2191
+ end
2192
+
2193
+ # Sends a POST request to the server;
2194
+ # forms the response into a Gem::Net::HTTPResponse object.
2195
+ #
2196
+ # The request is based on the Gem::Net::HTTP::Post object
2197
+ # created from string +path+, string +data+, and initial headers hash +initheader+.
2198
+ #
2199
+ # With no block given, returns the response object:
2200
+ #
2201
+ # http = Gem::Net::HTTP.new(hostname)
2202
+ # http.post('/todos', 'xyzzy')
2203
+ # # => #<Gem::Net::HTTPCreated 201 Created readbody=true>
2204
+ #
2205
+ # With a block given, calls the block with the response body
2206
+ # and returns the response object:
2207
+ #
2208
+ # http.post('/todos', 'xyzzy') do |res|
2209
+ # p res
2210
+ # end # => #<Gem::Net::HTTPCreated 201 Created readbody=true>
2211
+ #
2212
+ # Output:
2213
+ #
2214
+ # "{\n \"xyzzy\": \"\",\n \"id\": 201\n}"
2215
+ #
2216
+ def request_post(path, data, initheader = nil, &block) # :yield: +response+
2217
+ request Post.new(path, initheader), data, &block
2218
+ end
2219
+
2220
+ # Sends a PUT request to the server;
2221
+ # returns an instance of a subclass of Gem::Net::HTTPResponse.
2222
+ #
2223
+ # The request is based on the Gem::Net::HTTP::Put object
2224
+ # created from string +path+, string +data+, and initial headers hash +initheader+.
2225
+ #
2226
+ # http = Gem::Net::HTTP.new(hostname)
2227
+ # http.put('/todos/1', 'xyzzy')
2228
+ # # => #<Gem::Net::HTTPOK 200 OK readbody=true>
2229
+ #
2230
+ def request_put(path, data, initheader = nil, &block) #:nodoc:
2231
+ request Put.new(path, initheader), data, &block
2232
+ end
2233
+
2234
+ alias get2 request_get #:nodoc: obsolete
2235
+ alias head2 request_head #:nodoc: obsolete
2236
+ alias post2 request_post #:nodoc: obsolete
2237
+ alias put2 request_put #:nodoc: obsolete
2238
+
2239
+ # Sends an \HTTP request to the server;
2240
+ # returns an instance of a subclass of Gem::Net::HTTPResponse.
2241
+ #
2242
+ # The request is based on the Gem::Net::HTTPRequest object
2243
+ # created from string +path+, string +data+, and initial headers hash +header+.
2244
+ # That object is an instance of the
2245
+ # {subclass of Gem::Net::HTTPRequest}[rdoc-ref:Gem::Net::HTTPRequest@Request+Subclasses],
2246
+ # that corresponds to the given uppercase string +name+,
2247
+ # which must be
2248
+ # an {HTTP request method}[https://en.wikipedia.org/wiki/HTTP#Request_methods]
2249
+ # or a {WebDAV request method}[https://en.wikipedia.org/wiki/WebDAV#Implementation].
2250
+ #
2251
+ # Examples:
2252
+ #
2253
+ # http = Gem::Net::HTTP.new(hostname)
2254
+ # http.send_request('GET', '/todos/1')
2255
+ # # => #<Gem::Net::HTTPOK 200 OK readbody=true>
2256
+ # http.send_request('POST', '/todos', 'xyzzy')
2257
+ # # => #<Gem::Net::HTTPCreated 201 Created readbody=true>
2258
+ #
2259
+ def send_request(name, path, data = nil, header = nil)
2260
+ has_response_body = name != 'HEAD'
2261
+ r = HTTPGenericRequest.new(name,(data ? true : false),has_response_body,path,header)
2262
+ request r, data
2263
+ end
2264
+
2265
+ # Sends the given request +req+ to the server;
2266
+ # forms the response into a Gem::Net::HTTPResponse object.
2267
+ #
2268
+ # The given +req+ must be an instance of a
2269
+ # {subclass of Gem::Net::HTTPRequest}[rdoc-ref:Gem::Net::HTTPRequest@Request+Subclasses].
2270
+ # Argument +body+ should be given only if needed for the request.
2271
+ #
2272
+ # With no block given, returns the response object:
2273
+ #
2274
+ # http = Gem::Net::HTTP.new(hostname)
2275
+ #
2276
+ # req = Gem::Net::HTTP::Get.new('/todos/1')
2277
+ # http.request(req)
2278
+ # # => #<Gem::Net::HTTPOK 200 OK readbody=true>
2279
+ #
2280
+ # req = Gem::Net::HTTP::Post.new('/todos')
2281
+ # http.request(req, 'xyzzy')
2282
+ # # => #<Gem::Net::HTTPCreated 201 Created readbody=true>
2283
+ #
2284
+ # With a block given, calls the block with the response and returns the response:
2285
+ #
2286
+ # req = Gem::Net::HTTP::Get.new('/todos/1')
2287
+ # http.request(req) do |res|
2288
+ # p res
2289
+ # end # => #<Gem::Net::HTTPOK 200 OK readbody=true>
2290
+ #
2291
+ # Output:
2292
+ #
2293
+ # #<Gem::Net::HTTPOK 200 OK readbody=false>
2294
+ #
2295
+ def request(req, body = nil, &block) # :yield: +response+
2296
+ unless started?
2297
+ start {
2298
+ req['connection'] ||= 'close'
2299
+ return request(req, body, &block)
2300
+ }
2301
+ end
2302
+ if proxy_user()
2303
+ req.proxy_basic_auth proxy_user(), proxy_pass() unless use_ssl?
2304
+ end
2305
+ req.set_body_internal body
2306
+ res = transport_request(req, &block)
2307
+ if sspi_auth?(res)
2308
+ sspi_auth(req)
2309
+ res = transport_request(req, &block)
2310
+ end
2311
+ res
2312
+ end
2313
+
2314
+ private
2315
+
2316
+ # Executes a request which uses a representation
2317
+ # and returns its body.
2318
+ def send_entity(path, data, initheader, dest, type, &block)
2319
+ res = nil
2320
+ request(type.new(path, initheader), data) {|r|
2321
+ r.read_body dest, &block
2322
+ res = r
2323
+ }
2324
+ res
2325
+ end
2326
+
2327
+ IDEMPOTENT_METHODS_ = %w/GET HEAD PUT DELETE OPTIONS TRACE/ # :nodoc:
2328
+
2329
+ def transport_request(req)
2330
+ count = 0
2331
+ begin
2332
+ begin_transport req
2333
+ res = catch(:response) {
2334
+ begin
2335
+ req.exec @socket, @curr_http_version, edit_path(req.path)
2336
+ rescue Errno::EPIPE
2337
+ # Failure when writing full request, but we can probably
2338
+ # still read the received response.
2339
+ end
2340
+
2341
+ begin
2342
+ res = HTTPResponse.read_new(@socket)
2343
+ res.decode_content = req.decode_content
2344
+ res.body_encoding = @response_body_encoding
2345
+ res.ignore_eof = @ignore_eof
2346
+ end while res.kind_of?(HTTPInformation)
2347
+
2348
+ res.uri = req.uri
2349
+
2350
+ res
2351
+ }
2352
+ res.reading_body(@socket, req.response_body_permitted?) {
2353
+ yield res if block_given?
2354
+ }
2355
+ rescue Gem::Net::OpenTimeout
2356
+ raise
2357
+ rescue Gem::Net::ReadTimeout, IOError, EOFError,
2358
+ Errno::ECONNRESET, Errno::ECONNABORTED, Errno::EPIPE, Errno::ETIMEDOUT,
2359
+ # avoid a dependency on OpenSSL
2360
+ defined?(OpenSSL::SSL) ? OpenSSL::SSL::SSLError : IOError,
2361
+ Gem::Timeout::Error => exception
2362
+ if count < max_retries && IDEMPOTENT_METHODS_.include?(req.method)
2363
+ count += 1
2364
+ @socket.close if @socket
2365
+ debug "Conn close because of error #{exception}, and retry"
2366
+ retry
2367
+ end
2368
+ debug "Conn close because of error #{exception}"
2369
+ @socket.close if @socket
2370
+ raise
2371
+ end
2372
+
2373
+ end_transport req, res
2374
+ res
2375
+ rescue => exception
2376
+ debug "Conn close because of error #{exception}"
2377
+ @socket.close if @socket
2378
+ raise exception
2379
+ end
2380
+
2381
+ def begin_transport(req)
2382
+ if @socket.closed?
2383
+ connect
2384
+ elsif @last_communicated
2385
+ if @last_communicated + @keep_alive_timeout < Process.clock_gettime(Process::CLOCK_MONOTONIC)
2386
+ debug 'Conn close because of keep_alive_timeout'
2387
+ @socket.close
2388
+ connect
2389
+ elsif @socket.io.to_io.wait_readable(0) && @socket.eof?
2390
+ debug "Conn close because of EOF"
2391
+ @socket.close
2392
+ connect
2393
+ end
2394
+ end
2395
+
2396
+ if not req.response_body_permitted? and @close_on_empty_response
2397
+ req['connection'] ||= 'close'
2398
+ end
2399
+
2400
+ req.update_uri address, port, use_ssl?
2401
+ req['host'] ||= addr_port()
2402
+ end
2403
+
2404
+ def end_transport(req, res)
2405
+ @curr_http_version = res.http_version
2406
+ @last_communicated = nil
2407
+ if @socket.closed?
2408
+ debug 'Conn socket closed'
2409
+ elsif not res.body and @close_on_empty_response
2410
+ debug 'Conn close'
2411
+ @socket.close
2412
+ elsif keep_alive?(req, res)
2413
+ debug 'Conn keep-alive'
2414
+ @last_communicated = Process.clock_gettime(Process::CLOCK_MONOTONIC)
2415
+ else
2416
+ debug 'Conn close'
2417
+ @socket.close
2418
+ end
2419
+ end
2420
+
2421
+ def keep_alive?(req, res)
2422
+ return false if req.connection_close?
2423
+ if @curr_http_version <= '1.0'
2424
+ res.connection_keep_alive?
2425
+ else # HTTP/1.1 or later
2426
+ not res.connection_close?
2427
+ end
2428
+ end
2429
+
2430
+ def sspi_auth?(res)
2431
+ return false unless @sspi_enabled
2432
+ if res.kind_of?(HTTPProxyAuthenticationRequired) and
2433
+ proxy? and res["Proxy-Authenticate"].include?("Negotiate")
2434
+ begin
2435
+ require 'win32/sspi'
2436
+ true
2437
+ rescue LoadError
2438
+ false
2439
+ end
2440
+ else
2441
+ false
2442
+ end
2443
+ end
2444
+
2445
+ def sspi_auth(req)
2446
+ n = Win32::SSPI::NegotiateAuth.new
2447
+ req["Proxy-Authorization"] = "Negotiate #{n.get_initial_token}"
2448
+ # Some versions of ISA will close the connection if this isn't present.
2449
+ req["Connection"] = "Keep-Alive"
2450
+ req["Proxy-Connection"] = "Keep-Alive"
2451
+ res = transport_request(req)
2452
+ authphrase = res["Proxy-Authenticate"] or return res
2453
+ req["Proxy-Authorization"] = "Negotiate #{n.complete_authentication(authphrase)}"
2454
+ rescue => err
2455
+ raise HTTPAuthenticationError.new('HTTP authentication failed', err)
2456
+ end
2457
+
2458
+ #
2459
+ # utils
2460
+ #
2461
+
2462
+ private
2463
+
2464
+ def addr_port
2465
+ addr = address
2466
+ addr = "[#{addr}]" if addr.include?(":")
2467
+ default_port = use_ssl? ? HTTP.https_default_port : HTTP.http_default_port
2468
+ default_port == port ? addr : "#{addr}:#{port}"
2469
+ end
2470
+
2471
+ # Adds a message to debugging output
2472
+ def debug(msg)
2473
+ return unless @debug_output
2474
+ @debug_output << msg
2475
+ @debug_output << "\n"
2476
+ end
2477
+
2478
+ alias_method :D, :debug
2479
+ end
2480
+
2481
+ end
2482
+
2483
+ require_relative 'http/exceptions'
2484
+
2485
+ require_relative 'http/header'
2486
+
2487
+ require_relative 'http/generic_request'
2488
+ require_relative 'http/request'
2489
+ require_relative 'http/requests'
2490
+
2491
+ require_relative 'http/response'
2492
+ require_relative 'http/responses'
2493
+
2494
+ require_relative 'http/proxy_delta'
2495
+
2496
+ require_relative 'http/backward'