logstash-output-scalyr 0.1.6 → 0.1.11.beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (357) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -0
  3. data/Gemfile +6 -0
  4. data/README.md +57 -4
  5. data/lib/logstash/outputs/scalyr.rb +284 -107
  6. data/lib/scalyr/common/client.rb +117 -43
  7. data/lib/scalyr/constants.rb +2 -0
  8. data/logstash-output-scalyr.gemspec +2 -1
  9. data/spec/benchmarks/flattening_and_serialization.rb +125 -0
  10. data/spec/benchmarks/metrics_overhead.rb +48 -0
  11. data/spec/logstash/outputs/scalyr_integration_spec.rb +188 -0
  12. data/spec/logstash/outputs/scalyr_spec.rb +141 -71
  13. data/vendor/bundle/jruby/2.5.0/cache/addressable-2.7.0.gem +0 -0
  14. data/vendor/bundle/jruby/2.5.0/cache/connection_pool-2.2.5.gem +0 -0
  15. data/vendor/bundle/jruby/2.5.0/cache/crack-0.4.5.gem +0 -0
  16. data/vendor/bundle/jruby/2.5.0/cache/hashdiff-1.0.1.gem +0 -0
  17. data/vendor/bundle/jruby/2.5.0/cache/net-http-persistent-4.0.1.gem +0 -0
  18. data/vendor/bundle/jruby/2.5.0/cache/public_suffix-4.0.6.gem +0 -0
  19. data/vendor/bundle/jruby/2.5.0/cache/quantile-0.2.1.gem +0 -0
  20. data/vendor/bundle/jruby/2.5.0/cache/rexml-3.2.5.gem +0 -0
  21. data/vendor/bundle/jruby/2.5.0/cache/webmock-3.13.0.gem +0 -0
  22. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/CHANGELOG.md +235 -0
  23. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/Gemfile +32 -0
  24. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/LICENSE.txt +202 -0
  25. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/README.md +121 -0
  26. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/Rakefile +34 -0
  27. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/data/unicode.data +0 -0
  28. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/lib/addressable.rb +4 -0
  29. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/lib/addressable/idna.rb +27 -0
  30. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/lib/addressable/idna/native.rb +61 -0
  31. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/lib/addressable/idna/pure.rb +676 -0
  32. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/lib/addressable/template.rb +1045 -0
  33. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/lib/addressable/uri.rb +2529 -0
  34. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/lib/addressable/version.rb +32 -0
  35. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/spec/addressable/idna_spec.rb +300 -0
  36. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/spec/addressable/net_http_compat_spec.rb +30 -0
  37. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/spec/addressable/rack_mount_compat_spec.rb +106 -0
  38. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/spec/addressable/security_spec.rb +59 -0
  39. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/spec/addressable/template_spec.rb +1451 -0
  40. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/spec/addressable/uri_spec.rb +6603 -0
  41. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/spec/spec_helper.rb +24 -0
  42. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/tasks/clobber.rake +4 -0
  43. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/tasks/gem.rake +93 -0
  44. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/tasks/git.rake +47 -0
  45. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/tasks/metrics.rake +24 -0
  46. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/tasks/rspec.rake +23 -0
  47. data/vendor/bundle/jruby/2.5.0/gems/addressable-2.7.0/tasks/yard.rake +29 -0
  48. data/vendor/bundle/jruby/2.5.0/gems/{connection_pool-2.2.3 → connection_pool-2.2.5}/Changes.md +11 -0
  49. data/vendor/bundle/jruby/2.5.0/gems/{connection_pool-2.2.3 → connection_pool-2.2.5}/Gemfile +0 -2
  50. data/vendor/bundle/jruby/2.5.0/gems/{connection_pool-2.2.3 → connection_pool-2.2.5}/LICENSE +0 -0
  51. data/vendor/bundle/jruby/2.5.0/gems/{connection_pool-2.2.3 → connection_pool-2.2.5}/README.md +29 -5
  52. data/vendor/bundle/jruby/2.5.0/gems/{connection_pool-2.2.3 → connection_pool-2.2.5}/Rakefile +0 -1
  53. data/vendor/bundle/jruby/2.5.0/gems/{connection_pool-2.2.3 → connection_pool-2.2.5}/connection_pool.gemspec +1 -0
  54. data/vendor/bundle/jruby/2.5.0/gems/{connection_pool-2.2.3 → connection_pool-2.2.5}/lib/connection_pool.rb +16 -0
  55. data/vendor/bundle/jruby/2.5.0/gems/{connection_pool-2.2.3 → connection_pool-2.2.5}/lib/connection_pool/timed_stack.rb +9 -5
  56. data/vendor/bundle/jruby/2.5.0/gems/{connection_pool-2.2.3 → connection_pool-2.2.5}/lib/connection_pool/version.rb +1 -1
  57. data/vendor/bundle/jruby/2.5.0/gems/{connection_pool-2.2.3 → connection_pool-2.2.5}/lib/connection_pool/wrapper.rb +17 -3
  58. data/vendor/bundle/jruby/2.5.0/gems/{connection_pool-2.2.3 → connection_pool-2.2.5}/test/helper.rb +0 -0
  59. data/vendor/bundle/jruby/2.5.0/gems/{connection_pool-2.2.3 → connection_pool-2.2.5}/test/test_connection_pool.rb +16 -2
  60. data/vendor/bundle/jruby/2.5.0/gems/{connection_pool-2.2.3 → connection_pool-2.2.5}/test/test_connection_pool_timed_stack.rb +10 -0
  61. data/vendor/bundle/jruby/2.5.0/gems/crack-0.4.5/lib/crack.rb +7 -0
  62. data/vendor/bundle/jruby/2.5.0/gems/crack-0.4.5/lib/crack/json.rb +98 -0
  63. data/vendor/bundle/jruby/2.5.0/gems/crack-0.4.5/lib/crack/util.rb +17 -0
  64. data/vendor/bundle/jruby/2.5.0/gems/crack-0.4.5/lib/crack/version.rb +3 -0
  65. data/vendor/bundle/jruby/2.5.0/gems/crack-0.4.5/lib/crack/xml.rb +238 -0
  66. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/Gemfile +8 -0
  67. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/LICENSE +19 -0
  68. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/README.md +276 -0
  69. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/Rakefile +18 -0
  70. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/changelog.md +100 -0
  71. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/hashdiff.gemspec +39 -0
  72. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff.rb +10 -0
  73. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/compare_hashes.rb +69 -0
  74. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/diff.rb +177 -0
  75. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/lcs.rb +66 -0
  76. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/lcs_compare_arrays.rb +32 -0
  77. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/linear_compare_array.rb +159 -0
  78. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/patch.rb +88 -0
  79. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/util.rb +155 -0
  80. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/lib/hashdiff/version.rb +5 -0
  81. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/best_diff_spec.rb +75 -0
  82. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/diff_array_spec.rb +60 -0
  83. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/diff_spec.rb +360 -0
  84. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/lcs_spec.rb +76 -0
  85. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/linear_compare_array_spec.rb +50 -0
  86. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/patch_spec.rb +185 -0
  87. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/readme_spec.rb +15 -0
  88. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/hashdiff/util_spec.rb +116 -0
  89. data/vendor/bundle/jruby/2.5.0/gems/hashdiff-1.0.1/spec/spec_helper.rb +15 -0
  90. data/vendor/bundle/jruby/2.5.0/gems/{net-http-persistent-4.0.0 → net-http-persistent-4.0.1}/Gemfile +0 -0
  91. data/vendor/bundle/jruby/2.5.0/gems/{net-http-persistent-4.0.0 → net-http-persistent-4.0.1}/History.txt +6 -0
  92. data/vendor/bundle/jruby/2.5.0/gems/{net-http-persistent-4.0.0 → net-http-persistent-4.0.1}/Manifest.txt +0 -0
  93. data/vendor/bundle/jruby/2.5.0/gems/{net-http-persistent-4.0.0 → net-http-persistent-4.0.1}/README.rdoc +0 -0
  94. data/vendor/bundle/jruby/2.5.0/gems/{net-http-persistent-4.0.0 → net-http-persistent-4.0.1}/Rakefile +1 -1
  95. data/vendor/bundle/jruby/2.5.0/gems/{net-http-persistent-4.0.0 → net-http-persistent-4.0.1}/lib/net/http/persistent.rb +1 -1
  96. data/vendor/bundle/jruby/2.5.0/gems/{net-http-persistent-4.0.0 → net-http-persistent-4.0.1}/lib/net/http/persistent/connection.rb +0 -0
  97. data/vendor/bundle/jruby/2.5.0/gems/{net-http-persistent-4.0.0 → net-http-persistent-4.0.1}/lib/net/http/persistent/pool.rb +0 -0
  98. data/vendor/bundle/jruby/2.5.0/gems/{net-http-persistent-4.0.0 → net-http-persistent-4.0.1}/lib/net/http/persistent/timed_stack_multi.rb +0 -0
  99. data/vendor/bundle/jruby/2.5.0/gems/{net-http-persistent-4.0.0 → net-http-persistent-4.0.1}/test/test_net_http_persistent.rb +0 -0
  100. data/vendor/bundle/jruby/2.5.0/gems/{net-http-persistent-4.0.0 → net-http-persistent-4.0.1}/test/test_net_http_persistent_timed_stack_multi.rb +0 -0
  101. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/2.0-Upgrade.md +52 -0
  102. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/CHANGELOG.md +406 -0
  103. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/Gemfile +15 -0
  104. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/LICENSE.txt +22 -0
  105. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/README.md +207 -0
  106. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/Rakefile +51 -0
  107. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/SECURITY.md +104 -0
  108. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/bin/console +15 -0
  109. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/codecov.yml +12 -0
  110. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/data/list.txt +13380 -0
  111. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/lib/public_suffix.rb +179 -0
  112. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/lib/public_suffix/domain.rb +235 -0
  113. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/lib/public_suffix/errors.rb +41 -0
  114. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/lib/public_suffix/list.rb +247 -0
  115. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/lib/public_suffix/rule.rb +350 -0
  116. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/lib/public_suffix/version.rb +13 -0
  117. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/public_suffix.gemspec +29 -0
  118. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/acceptance_test.rb +131 -0
  119. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/benchmarks/bm_find.rb +66 -0
  120. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/benchmarks/bm_find_all.rb +102 -0
  121. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/benchmarks/bm_names.rb +91 -0
  122. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/benchmarks/bm_select.rb +26 -0
  123. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/benchmarks/bm_select_incremental.rb +25 -0
  124. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/benchmarks/bm_valid.rb +101 -0
  125. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/profilers/domain_profiler.rb +12 -0
  126. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/profilers/find_profiler.rb +12 -0
  127. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/profilers/find_profiler_jp.rb +12 -0
  128. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/profilers/initialization_profiler.rb +11 -0
  129. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/profilers/list_profsize.rb +11 -0
  130. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/profilers/object_binsize.rb +57 -0
  131. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/psl_test.rb +52 -0
  132. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/test_helper.rb +18 -0
  133. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/tests.txt +98 -0
  134. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/unit/domain_test.rb +106 -0
  135. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/unit/errors_test.rb +25 -0
  136. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/unit/list_test.rb +241 -0
  137. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/unit/public_suffix_test.rb +188 -0
  138. data/vendor/bundle/jruby/2.5.0/gems/public_suffix-4.0.6/test/unit/rule_test.rb +222 -0
  139. data/vendor/bundle/jruby/2.5.0/gems/quantile-0.2.1/LICENSE +191 -0
  140. data/vendor/bundle/jruby/2.5.0/gems/quantile-0.2.1/README.md +55 -0
  141. data/vendor/bundle/jruby/2.5.0/gems/quantile-0.2.1/lib/quantile.rb +17 -0
  142. data/vendor/bundle/jruby/2.5.0/gems/quantile-0.2.1/lib/quantile/estimator.rb +186 -0
  143. data/vendor/bundle/jruby/2.5.0/gems/quantile-0.2.1/lib/quantile/quantile.rb +66 -0
  144. data/vendor/bundle/jruby/2.5.0/gems/quantile-0.2.1/lib/quantile/version.rb +16 -0
  145. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/LICENSE.txt +22 -0
  146. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/NEWS.md +178 -0
  147. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/README.md +48 -0
  148. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/context.rdoc +143 -0
  149. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/rdoc/child.rdoc +87 -0
  150. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/rdoc/document.rdoc +276 -0
  151. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/rdoc/element.rdoc +602 -0
  152. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/rdoc/node.rdoc +97 -0
  153. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/rdoc/parent.rdoc +267 -0
  154. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/tocs/child_toc.rdoc +12 -0
  155. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/tocs/document_toc.rdoc +30 -0
  156. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/tocs/element_toc.rdoc +55 -0
  157. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/tocs/master_toc.rdoc +135 -0
  158. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/tocs/node_toc.rdoc +16 -0
  159. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/doc/rexml/tasks/tocs/parent_toc.rdoc +25 -0
  160. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml.rb +3 -0
  161. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/attlistdecl.rb +63 -0
  162. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/attribute.rb +205 -0
  163. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/cdata.rb +68 -0
  164. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/child.rb +97 -0
  165. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/comment.rb +80 -0
  166. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/doctype.rb +311 -0
  167. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/document.rb +451 -0
  168. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/dtd/attlistdecl.rb +11 -0
  169. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/dtd/dtd.rb +47 -0
  170. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/dtd/elementdecl.rb +18 -0
  171. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/dtd/entitydecl.rb +57 -0
  172. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/dtd/notationdecl.rb +40 -0
  173. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/element.rb +2599 -0
  174. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/encoding.rb +51 -0
  175. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/entity.rb +171 -0
  176. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/formatters/default.rb +116 -0
  177. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/formatters/pretty.rb +142 -0
  178. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/formatters/transitive.rb +58 -0
  179. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/functions.rb +447 -0
  180. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/instruction.rb +79 -0
  181. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/light/node.rb +188 -0
  182. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/namespace.rb +59 -0
  183. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/node.rb +76 -0
  184. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/output.rb +30 -0
  185. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parent.rb +166 -0
  186. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parseexception.rb +52 -0
  187. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/baseparser.rb +694 -0
  188. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/lightparser.rb +59 -0
  189. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/pullparser.rb +197 -0
  190. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/sax2parser.rb +273 -0
  191. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/streamparser.rb +61 -0
  192. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/treeparser.rb +101 -0
  193. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/ultralightparser.rb +57 -0
  194. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/parsers/xpathparser.rb +689 -0
  195. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/quickpath.rb +266 -0
  196. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/rexml.rb +37 -0
  197. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/sax2listener.rb +98 -0
  198. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/security.rb +28 -0
  199. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/source.rb +298 -0
  200. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/streamlistener.rb +93 -0
  201. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/text.rb +424 -0
  202. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/undefinednamespaceexception.rb +9 -0
  203. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/validation/relaxng.rb +539 -0
  204. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/validation/validation.rb +144 -0
  205. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/validation/validationexception.rb +10 -0
  206. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/xmldecl.rb +130 -0
  207. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/xmltokens.rb +85 -0
  208. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/xpath.rb +81 -0
  209. data/vendor/bundle/jruby/2.5.0/gems/rexml-3.2.5/lib/rexml/xpath_parser.rb +974 -0
  210. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/CHANGELOG.md +1894 -0
  211. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/Gemfile +9 -0
  212. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/LICENSE +20 -0
  213. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/README.md +1176 -0
  214. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/Rakefile +38 -0
  215. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock.rb +59 -0
  216. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/api.rb +109 -0
  217. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/assertion_failure.rb +11 -0
  218. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/callback_registry.rb +35 -0
  219. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/config.rb +18 -0
  220. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/cucumber.rb +10 -0
  221. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/deprecation.rb +9 -0
  222. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/errors.rb +17 -0
  223. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/async_http_client_adapter.rb +216 -0
  224. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/curb_adapter.rb +351 -0
  225. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +231 -0
  226. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/excon_adapter.rb +165 -0
  227. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_lib_adapter.rb +7 -0
  228. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_lib_adapter_registry.rb +19 -0
  229. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_rb/client.rb +17 -0
  230. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_rb/request.rb +16 -0
  231. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_rb/response.rb +64 -0
  232. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_rb/streamer.rb +29 -0
  233. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_rb/webmock.rb +68 -0
  234. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/http_rb_adapter.rb +37 -0
  235. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/httpclient_adapter.rb +259 -0
  236. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/manticore_adapter.rb +145 -0
  237. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/net_http.rb +385 -0
  238. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/net_http_response.rb +34 -0
  239. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/patron_adapter.rb +130 -0
  240. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb +174 -0
  241. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/matchers/any_arg_matcher.rb +13 -0
  242. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/matchers/hash_argument_matcher.rb +21 -0
  243. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/matchers/hash_excluding_matcher.rb +15 -0
  244. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/matchers/hash_including_matcher.rb +17 -0
  245. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/minitest.rb +41 -0
  246. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/rack_response.rb +69 -0
  247. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/request_body_diff.rb +64 -0
  248. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/request_execution_verifier.rb +77 -0
  249. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/request_pattern.rb +405 -0
  250. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/request_registry.rb +35 -0
  251. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/request_signature.rb +54 -0
  252. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/request_signature_snippet.rb +61 -0
  253. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/request_stub.rb +100 -0
  254. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/response.rb +159 -0
  255. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/responses_sequence.rb +40 -0
  256. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/rspec.rb +42 -0
  257. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/rspec/matchers.rb +27 -0
  258. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/rspec/matchers/request_pattern_matcher.rb +78 -0
  259. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/rspec/matchers/webmock_matcher.rb +67 -0
  260. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/stub_registry.rb +82 -0
  261. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/stub_request_snippet.rb +38 -0
  262. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/test_unit.rb +20 -0
  263. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/hash_counter.rb +39 -0
  264. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/hash_keys_stringifier.rb +25 -0
  265. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/hash_validator.rb +17 -0
  266. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/headers.rb +64 -0
  267. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/json.rb +67 -0
  268. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/query_mapper.rb +281 -0
  269. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/uri.rb +111 -0
  270. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/values_stringifier.rb +20 -0
  271. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/util/version_checker.rb +111 -0
  272. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/version.rb +3 -0
  273. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/lib/webmock/webmock.rb +163 -0
  274. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/minitest/test_helper.rb +34 -0
  275. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/minitest/test_webmock.rb +9 -0
  276. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/minitest/webmock_spec.rb +60 -0
  277. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/async_http_client/async_http_client_spec.rb +375 -0
  278. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/async_http_client/async_http_client_spec_helper.rb +73 -0
  279. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/curb/curb_spec.rb +499 -0
  280. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/curb/curb_spec_helper.rb +147 -0
  281. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/em_http_request/em_http_request_spec.rb +462 -0
  282. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/em_http_request/em_http_request_spec_helper.rb +77 -0
  283. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/excon/excon_spec.rb +77 -0
  284. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/excon/excon_spec_helper.rb +52 -0
  285. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/http_rb/http_rb_spec.rb +93 -0
  286. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/http_rb/http_rb_spec_helper.rb +54 -0
  287. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/httpclient/httpclient_spec.rb +217 -0
  288. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/httpclient/httpclient_spec_helper.rb +57 -0
  289. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/manticore/manticore_spec.rb +107 -0
  290. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/manticore/manticore_spec_helper.rb +35 -0
  291. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/net_http/net_http_shared.rb +153 -0
  292. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/net_http/net_http_spec.rb +369 -0
  293. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/net_http/net_http_spec_helper.rb +64 -0
  294. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/net_http/real_net_http_spec.rb +20 -0
  295. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/patron/patron_spec.rb +125 -0
  296. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/patron/patron_spec_helper.rb +54 -0
  297. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/allowing_and_disabling_net_connect.rb +313 -0
  298. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/callbacks.rb +148 -0
  299. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/complex_cross_concern_behaviors.rb +36 -0
  300. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/enabling_and_disabling_webmock.rb +95 -0
  301. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/precedence_of_stubs.rb +15 -0
  302. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/request_expectations.rb +930 -0
  303. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/returning_declared_responses.rb +409 -0
  304. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/shared/stubbing_requests.rb +678 -0
  305. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/typhoeus/typhoeus_hydra_spec.rb +135 -0
  306. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/typhoeus/typhoeus_hydra_spec_helper.rb +60 -0
  307. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/acceptance/webmock_shared.rb +41 -0
  308. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/fixtures/test.txt +1 -0
  309. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/quality_spec.rb +84 -0
  310. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/spec_helper.rb +48 -0
  311. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/support/example_curl_output.txt +22 -0
  312. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/support/failures.rb +9 -0
  313. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/support/my_rack_app.rb +53 -0
  314. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/support/network_connection.rb +19 -0
  315. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/support/webmock_server.rb +70 -0
  316. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/api_spec.rb +175 -0
  317. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/errors_spec.rb +129 -0
  318. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/http_lib_adapters/http_lib_adapter_registry_spec.rb +17 -0
  319. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/http_lib_adapters/http_lib_adapter_spec.rb +12 -0
  320. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/matchers/hash_excluding_matcher_spec.rb +61 -0
  321. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/matchers/hash_including_matcher_spec.rb +87 -0
  322. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/rack_response_spec.rb +112 -0
  323. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/request_body_diff_spec.rb +90 -0
  324. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/request_execution_verifier_spec.rb +208 -0
  325. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/request_pattern_spec.rb +736 -0
  326. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/request_registry_spec.rb +95 -0
  327. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/request_signature_snippet_spec.rb +89 -0
  328. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/request_signature_spec.rb +155 -0
  329. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/request_stub_spec.rb +199 -0
  330. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/response_spec.rb +286 -0
  331. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/stub_registry_spec.rb +103 -0
  332. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/stub_request_snippet_spec.rb +115 -0
  333. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/util/hash_counter_spec.rb +39 -0
  334. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/util/hash_keys_stringifier_spec.rb +27 -0
  335. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/util/headers_spec.rb +28 -0
  336. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/util/json_spec.rb +33 -0
  337. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/util/query_mapper_spec.rb +157 -0
  338. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/util/uri_spec.rb +371 -0
  339. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/util/version_checker_spec.rb +65 -0
  340. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/spec/unit/webmock_spec.rb +60 -0
  341. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/test/http_request.rb +24 -0
  342. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/test/shared_test.rb +108 -0
  343. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/test/test_helper.rb +23 -0
  344. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/test/test_webmock.rb +12 -0
  345. data/vendor/bundle/jruby/2.5.0/gems/webmock-3.13.0/webmock.gemspec +54 -0
  346. data/vendor/bundle/jruby/2.5.0/specifications/addressable-2.7.0.gemspec +39 -0
  347. data/vendor/bundle/jruby/2.5.0/specifications/{connection_pool-2.2.3.gemspec → connection_pool-2.2.5.gemspec} +4 -3
  348. data/vendor/bundle/jruby/2.5.0/specifications/crack-0.4.5.gemspec +32 -0
  349. data/vendor/bundle/jruby/2.5.0/specifications/hashdiff-1.0.1.gemspec +46 -0
  350. data/vendor/bundle/jruby/2.5.0/specifications/{net-http-persistent-4.0.0.gemspec → net-http-persistent-4.0.1.gemspec} +4 -5
  351. data/vendor/bundle/jruby/2.5.0/specifications/public_suffix-4.0.6.gemspec +24 -0
  352. data/vendor/bundle/jruby/2.5.0/specifications/quantile-0.2.1.gemspec +20 -0
  353. data/vendor/bundle/jruby/2.5.0/specifications/rexml-3.2.5.gemspec +42 -0
  354. data/vendor/bundle/jruby/2.5.0/specifications/webmock-3.13.0.gemspec +85 -0
  355. metadata +367 -32
  356. data/vendor/bundle/jruby/2.5.0/cache/connection_pool-2.2.3.gem +0 -0
  357. data/vendor/bundle/jruby/2.5.0/cache/net-http-persistent-4.0.0.gem +0 -0
@@ -0,0 +1,2529 @@
1
+ # frozen_string_literal: true
2
+
3
+ # encoding:utf-8
4
+ #--
5
+ # Copyright (C) Bob Aman
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #++
19
+
20
+
21
+ require "addressable/version"
22
+ require "addressable/idna"
23
+ require "public_suffix"
24
+
25
+ ##
26
+ # Addressable is a library for processing links and URIs.
27
+ module Addressable
28
+ ##
29
+ # This is an implementation of a URI parser based on
30
+ # <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>,
31
+ # <a href="http://www.ietf.org/rfc/rfc3987.txt">RFC 3987</a>.
32
+ class URI
33
+ ##
34
+ # Raised if something other than a uri is supplied.
35
+ class InvalidURIError < StandardError
36
+ end
37
+
38
+ ##
39
+ # Container for the character classes specified in
40
+ # <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>.
41
+ module CharacterClasses
42
+ ALPHA = "a-zA-Z"
43
+ DIGIT = "0-9"
44
+ GEN_DELIMS = "\\:\\/\\?\\#\\[\\]\\@"
45
+ SUB_DELIMS = "\\!\\$\\&\\'\\(\\)\\*\\+\\,\\;\\="
46
+ RESERVED = GEN_DELIMS + SUB_DELIMS
47
+ UNRESERVED = ALPHA + DIGIT + "\\-\\.\\_\\~"
48
+ PCHAR = UNRESERVED + SUB_DELIMS + "\\:\\@"
49
+ SCHEME = ALPHA + DIGIT + "\\-\\+\\."
50
+ HOST = UNRESERVED + SUB_DELIMS + "\\[\\:\\]"
51
+ AUTHORITY = PCHAR
52
+ PATH = PCHAR + "\\/"
53
+ QUERY = PCHAR + "\\/\\?"
54
+ FRAGMENT = PCHAR + "\\/\\?"
55
+ end
56
+
57
+ SLASH = '/'
58
+ EMPTY_STR = ''
59
+
60
+ URIREGEX = /^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/
61
+
62
+ PORT_MAPPING = {
63
+ "http" => 80,
64
+ "https" => 443,
65
+ "ftp" => 21,
66
+ "tftp" => 69,
67
+ "sftp" => 22,
68
+ "ssh" => 22,
69
+ "svn+ssh" => 22,
70
+ "telnet" => 23,
71
+ "nntp" => 119,
72
+ "gopher" => 70,
73
+ "wais" => 210,
74
+ "ldap" => 389,
75
+ "prospero" => 1525
76
+ }
77
+
78
+ ##
79
+ # Returns a URI object based on the parsed string.
80
+ #
81
+ # @param [String, Addressable::URI, #to_str] uri
82
+ # The URI string to parse.
83
+ # No parsing is performed if the object is already an
84
+ # <code>Addressable::URI</code>.
85
+ #
86
+ # @return [Addressable::URI] The parsed URI.
87
+ def self.parse(uri)
88
+ # If we were given nil, return nil.
89
+ return nil unless uri
90
+ # If a URI object is passed, just return itself.
91
+ return uri.dup if uri.kind_of?(self)
92
+
93
+ # If a URI object of the Ruby standard library variety is passed,
94
+ # convert it to a string, then parse the string.
95
+ # We do the check this way because we don't want to accidentally
96
+ # cause a missing constant exception to be thrown.
97
+ if uri.class.name =~ /^URI\b/
98
+ uri = uri.to_s
99
+ end
100
+
101
+ # Otherwise, convert to a String
102
+ begin
103
+ uri = uri.to_str
104
+ rescue TypeError, NoMethodError
105
+ raise TypeError, "Can't convert #{uri.class} into String."
106
+ end if not uri.is_a? String
107
+
108
+ # This Regexp supplied as an example in RFC 3986, and it works great.
109
+ scan = uri.scan(URIREGEX)
110
+ fragments = scan[0]
111
+ scheme = fragments[1]
112
+ authority = fragments[3]
113
+ path = fragments[4]
114
+ query = fragments[6]
115
+ fragment = fragments[8]
116
+ user = nil
117
+ password = nil
118
+ host = nil
119
+ port = nil
120
+ if authority != nil
121
+ # The Regexp above doesn't split apart the authority.
122
+ userinfo = authority[/^([^\[\]]*)@/, 1]
123
+ if userinfo != nil
124
+ user = userinfo.strip[/^([^:]*):?/, 1]
125
+ password = userinfo.strip[/:(.*)$/, 1]
126
+ end
127
+ host = authority.sub(
128
+ /^([^\[\]]*)@/, EMPTY_STR
129
+ ).sub(
130
+ /:([^:@\[\]]*?)$/, EMPTY_STR
131
+ )
132
+ port = authority[/:([^:@\[\]]*?)$/, 1]
133
+ end
134
+ if port == EMPTY_STR
135
+ port = nil
136
+ end
137
+
138
+ return new(
139
+ :scheme => scheme,
140
+ :user => user,
141
+ :password => password,
142
+ :host => host,
143
+ :port => port,
144
+ :path => path,
145
+ :query => query,
146
+ :fragment => fragment
147
+ )
148
+ end
149
+
150
+ ##
151
+ # Converts an input to a URI. The input does not have to be a valid
152
+ # URI — the method will use heuristics to guess what URI was intended.
153
+ # This is not standards-compliant, merely user-friendly.
154
+ #
155
+ # @param [String, Addressable::URI, #to_str] uri
156
+ # The URI string to parse.
157
+ # No parsing is performed if the object is already an
158
+ # <code>Addressable::URI</code>.
159
+ # @param [Hash] hints
160
+ # A <code>Hash</code> of hints to the heuristic parser.
161
+ # Defaults to <code>{:scheme => "http"}</code>.
162
+ #
163
+ # @return [Addressable::URI] The parsed URI.
164
+ def self.heuristic_parse(uri, hints={})
165
+ # If we were given nil, return nil.
166
+ return nil unless uri
167
+ # If a URI object is passed, just return itself.
168
+ return uri.dup if uri.kind_of?(self)
169
+
170
+ # If a URI object of the Ruby standard library variety is passed,
171
+ # convert it to a string, then parse the string.
172
+ # We do the check this way because we don't want to accidentally
173
+ # cause a missing constant exception to be thrown.
174
+ if uri.class.name =~ /^URI\b/
175
+ uri = uri.to_s
176
+ end
177
+
178
+ if !uri.respond_to?(:to_str)
179
+ raise TypeError, "Can't convert #{uri.class} into String."
180
+ end
181
+ # Otherwise, convert to a String
182
+ uri = uri.to_str.dup.strip
183
+ hints = {
184
+ :scheme => "http"
185
+ }.merge(hints)
186
+ case uri
187
+ when /^http:\//i
188
+ uri.sub!(/^http:\/+/i, "http://")
189
+ when /^https:\//i
190
+ uri.sub!(/^https:\/+/i, "https://")
191
+ when /^feed:\/+http:\//i
192
+ uri.sub!(/^feed:\/+http:\/+/i, "feed:http://")
193
+ when /^feed:\//i
194
+ uri.sub!(/^feed:\/+/i, "feed://")
195
+ when %r[^file:/{4}]i
196
+ uri.sub!(%r[^file:/+]i, "file:////")
197
+ when %r[^file://localhost/]i
198
+ uri.sub!(%r[^file://localhost/+]i, "file:///")
199
+ when %r[^file:/+]i
200
+ uri.sub!(%r[^file:/+]i, "file:///")
201
+ when /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/
202
+ uri.sub!(/^/, hints[:scheme] + "://")
203
+ when /\A\d+\..*:\d+\z/
204
+ uri = "#{hints[:scheme]}://#{uri}"
205
+ end
206
+ match = uri.match(URIREGEX)
207
+ fragments = match.captures
208
+ authority = fragments[3]
209
+ if authority && authority.length > 0
210
+ new_authority = authority.tr("\\", "/").gsub(" ", "%20")
211
+ # NOTE: We want offset 4, not 3!
212
+ offset = match.offset(4)
213
+ uri = uri.dup
214
+ uri[offset[0]...offset[1]] = new_authority
215
+ end
216
+ parsed = self.parse(uri)
217
+ if parsed.scheme =~ /^[^\/?#\.]+\.[^\/?#]+$/
218
+ parsed = self.parse(hints[:scheme] + "://" + uri)
219
+ end
220
+ if parsed.path.include?(".")
221
+ if parsed.path[/\b@\b/]
222
+ parsed.scheme = "mailto" unless parsed.scheme
223
+ elsif new_host = parsed.path[/^([^\/]+\.[^\/]*)/, 1]
224
+ parsed.defer_validation do
225
+ new_path = parsed.path.sub(
226
+ Regexp.new("^" + Regexp.escape(new_host)), EMPTY_STR)
227
+ parsed.host = new_host
228
+ parsed.path = new_path
229
+ parsed.scheme = hints[:scheme] unless parsed.scheme
230
+ end
231
+ end
232
+ end
233
+ return parsed
234
+ end
235
+
236
+ ##
237
+ # Converts a path to a file scheme URI. If the path supplied is
238
+ # relative, it will be returned as a relative URI. If the path supplied
239
+ # is actually a non-file URI, it will parse the URI as if it had been
240
+ # parsed with <code>Addressable::URI.parse</code>. Handles all of the
241
+ # various Microsoft-specific formats for specifying paths.
242
+ #
243
+ # @param [String, Addressable::URI, #to_str] path
244
+ # Typically a <code>String</code> path to a file or directory, but
245
+ # will return a sensible return value if an absolute URI is supplied
246
+ # instead.
247
+ #
248
+ # @return [Addressable::URI]
249
+ # The parsed file scheme URI or the original URI if some other URI
250
+ # scheme was provided.
251
+ #
252
+ # @example
253
+ # base = Addressable::URI.convert_path("/absolute/path/")
254
+ # uri = Addressable::URI.convert_path("relative/path")
255
+ # (base + uri).to_s
256
+ # #=> "file:///absolute/path/relative/path"
257
+ #
258
+ # Addressable::URI.convert_path(
259
+ # "c:\\windows\\My Documents 100%20\\foo.txt"
260
+ # ).to_s
261
+ # #=> "file:///c:/windows/My%20Documents%20100%20/foo.txt"
262
+ #
263
+ # Addressable::URI.convert_path("http://example.com/").to_s
264
+ # #=> "http://example.com/"
265
+ def self.convert_path(path)
266
+ # If we were given nil, return nil.
267
+ return nil unless path
268
+ # If a URI object is passed, just return itself.
269
+ return path if path.kind_of?(self)
270
+ if !path.respond_to?(:to_str)
271
+ raise TypeError, "Can't convert #{path.class} into String."
272
+ end
273
+ # Otherwise, convert to a String
274
+ path = path.to_str.strip
275
+
276
+ path.sub!(/^file:\/?\/?/, EMPTY_STR) if path =~ /^file:\/?\/?/
277
+ path = SLASH + path if path =~ /^([a-zA-Z])[\|:]/
278
+ uri = self.parse(path)
279
+
280
+ if uri.scheme == nil
281
+ # Adjust windows-style uris
282
+ uri.path.sub!(/^\/?([a-zA-Z])[\|:][\\\/]/) do
283
+ "/#{$1.downcase}:/"
284
+ end
285
+ uri.path.tr!("\\", SLASH)
286
+ if File.exist?(uri.path) &&
287
+ File.stat(uri.path).directory?
288
+ uri.path.chomp!(SLASH)
289
+ uri.path = uri.path + '/'
290
+ end
291
+
292
+ # If the path is absolute, set the scheme and host.
293
+ if uri.path.start_with?(SLASH)
294
+ uri.scheme = "file"
295
+ uri.host = EMPTY_STR
296
+ end
297
+ uri.normalize!
298
+ end
299
+
300
+ return uri
301
+ end
302
+
303
+ ##
304
+ # Joins several URIs together.
305
+ #
306
+ # @param [String, Addressable::URI, #to_str] *uris
307
+ # The URIs to join.
308
+ #
309
+ # @return [Addressable::URI] The joined URI.
310
+ #
311
+ # @example
312
+ # base = "http://example.com/"
313
+ # uri = Addressable::URI.parse("relative/path")
314
+ # Addressable::URI.join(base, uri)
315
+ # #=> #<Addressable::URI:0xcab390 URI:http://example.com/relative/path>
316
+ def self.join(*uris)
317
+ uri_objects = uris.collect do |uri|
318
+ if !uri.respond_to?(:to_str)
319
+ raise TypeError, "Can't convert #{uri.class} into String."
320
+ end
321
+ uri.kind_of?(self) ? uri : self.parse(uri.to_str)
322
+ end
323
+ result = uri_objects.shift.dup
324
+ for uri in uri_objects
325
+ result.join!(uri)
326
+ end
327
+ return result
328
+ end
329
+
330
+ ##
331
+ # Tables used to optimize encoding operations in `self.encode_component`
332
+ # and `self.normalize_component`
333
+ SEQUENCE_ENCODING_TABLE = Hash.new do |hash, sequence|
334
+ hash[sequence] = sequence.unpack("C*").map do |c|
335
+ format("%02x", c)
336
+ end.join
337
+ end
338
+
339
+ SEQUENCE_UPCASED_PERCENT_ENCODING_TABLE = Hash.new do |hash, sequence|
340
+ hash[sequence] = sequence.unpack("C*").map do |c|
341
+ format("%%%02X", c)
342
+ end.join
343
+ end
344
+
345
+ ##
346
+ # Percent encodes a URI component.
347
+ #
348
+ # @param [String, #to_str] component The URI component to encode.
349
+ #
350
+ # @param [String, Regexp] character_class
351
+ # The characters which are not percent encoded. If a <code>String</code>
352
+ # is passed, the <code>String</code> must be formatted as a regular
353
+ # expression character class. (Do not include the surrounding square
354
+ # brackets.) For example, <code>"b-zB-Z0-9"</code> would cause
355
+ # everything but the letters 'b' through 'z' and the numbers '0' through
356
+ # '9' to be percent encoded. If a <code>Regexp</code> is passed, the
357
+ # value <code>/[^b-zB-Z0-9]/</code> would have the same effect. A set of
358
+ # useful <code>String</code> values may be found in the
359
+ # <code>Addressable::URI::CharacterClasses</code> module. The default
360
+ # value is the reserved plus unreserved character classes specified in
361
+ # <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>.
362
+ #
363
+ # @param [Regexp] upcase_encoded
364
+ # A string of characters that may already be percent encoded, and whose
365
+ # encodings should be upcased. This allows normalization of percent
366
+ # encodings for characters not included in the
367
+ # <code>character_class</code>.
368
+ #
369
+ # @return [String] The encoded component.
370
+ #
371
+ # @example
372
+ # Addressable::URI.encode_component("simple/example", "b-zB-Z0-9")
373
+ # => "simple%2Fex%61mple"
374
+ # Addressable::URI.encode_component("simple/example", /[^b-zB-Z0-9]/)
375
+ # => "simple%2Fex%61mple"
376
+ # Addressable::URI.encode_component(
377
+ # "simple/example", Addressable::URI::CharacterClasses::UNRESERVED
378
+ # )
379
+ # => "simple%2Fexample"
380
+ def self.encode_component(component, character_class=
381
+ CharacterClasses::RESERVED + CharacterClasses::UNRESERVED,
382
+ upcase_encoded='')
383
+ return nil if component.nil?
384
+
385
+ begin
386
+ if component.kind_of?(Symbol) ||
387
+ component.kind_of?(Numeric) ||
388
+ component.kind_of?(TrueClass) ||
389
+ component.kind_of?(FalseClass)
390
+ component = component.to_s
391
+ else
392
+ component = component.to_str
393
+ end
394
+ rescue TypeError, NoMethodError
395
+ raise TypeError, "Can't convert #{component.class} into String."
396
+ end if !component.is_a? String
397
+
398
+ if ![String, Regexp].include?(character_class.class)
399
+ raise TypeError,
400
+ "Expected String or Regexp, got #{character_class.inspect}"
401
+ end
402
+ if character_class.kind_of?(String)
403
+ character_class = /[^#{character_class}]/
404
+ end
405
+ # We can't perform regexps on invalid UTF sequences, but
406
+ # here we need to, so switch to ASCII.
407
+ component = component.dup
408
+ component.force_encoding(Encoding::ASCII_8BIT)
409
+ # Avoiding gsub! because there are edge cases with frozen strings
410
+ component = component.gsub(character_class) do |sequence|
411
+ SEQUENCE_UPCASED_PERCENT_ENCODING_TABLE[sequence]
412
+ end
413
+ if upcase_encoded.length > 0
414
+ upcase_encoded_chars = upcase_encoded.chars.map do |char|
415
+ SEQUENCE_ENCODING_TABLE[char]
416
+ end
417
+ component = component.gsub(/%(#{upcase_encoded_chars.join('|')})/,
418
+ &:upcase)
419
+ end
420
+ return component
421
+ end
422
+
423
+ class << self
424
+ alias_method :encode_component, :encode_component
425
+ end
426
+
427
+ ##
428
+ # Unencodes any percent encoded characters within a URI component.
429
+ # This method may be used for unencoding either components or full URIs,
430
+ # however, it is recommended to use the <code>unencode_component</code>
431
+ # alias when unencoding components.
432
+ #
433
+ # @param [String, Addressable::URI, #to_str] uri
434
+ # The URI or component to unencode.
435
+ #
436
+ # @param [Class] return_type
437
+ # The type of object to return.
438
+ # This value may only be set to <code>String</code> or
439
+ # <code>Addressable::URI</code>. All other values are invalid. Defaults
440
+ # to <code>String</code>.
441
+ #
442
+ # @param [String] leave_encoded
443
+ # A string of characters to leave encoded. If a percent encoded character
444
+ # in this list is encountered then it will remain percent encoded.
445
+ #
446
+ # @return [String, Addressable::URI]
447
+ # The unencoded component or URI.
448
+ # The return type is determined by the <code>return_type</code>
449
+ # parameter.
450
+ def self.unencode(uri, return_type=String, leave_encoded='')
451
+ return nil if uri.nil?
452
+
453
+ begin
454
+ uri = uri.to_str
455
+ rescue NoMethodError, TypeError
456
+ raise TypeError, "Can't convert #{uri.class} into String."
457
+ end if !uri.is_a? String
458
+ if ![String, ::Addressable::URI].include?(return_type)
459
+ raise TypeError,
460
+ "Expected Class (String or Addressable::URI), " +
461
+ "got #{return_type.inspect}"
462
+ end
463
+ uri = uri.dup
464
+ # Seriously, only use UTF-8. I'm really not kidding!
465
+ uri.force_encoding("utf-8")
466
+ leave_encoded = leave_encoded.dup.force_encoding("utf-8")
467
+ result = uri.gsub(/%[0-9a-f]{2}/iu) do |sequence|
468
+ c = sequence[1..3].to_i(16).chr
469
+ c.force_encoding("utf-8")
470
+ leave_encoded.include?(c) ? sequence : c
471
+ end
472
+ result.force_encoding("utf-8")
473
+ if return_type == String
474
+ return result
475
+ elsif return_type == ::Addressable::URI
476
+ return ::Addressable::URI.parse(result)
477
+ end
478
+ end
479
+
480
+ class << self
481
+ alias_method :unescape, :unencode
482
+ alias_method :unencode_component, :unencode
483
+ alias_method :unescape_component, :unencode
484
+ end
485
+
486
+
487
+ ##
488
+ # Normalizes the encoding of a URI component.
489
+ #
490
+ # @param [String, #to_str] component The URI component to encode.
491
+ #
492
+ # @param [String, Regexp] character_class
493
+ # The characters which are not percent encoded. If a <code>String</code>
494
+ # is passed, the <code>String</code> must be formatted as a regular
495
+ # expression character class. (Do not include the surrounding square
496
+ # brackets.) For example, <code>"b-zB-Z0-9"</code> would cause
497
+ # everything but the letters 'b' through 'z' and the numbers '0'
498
+ # through '9' to be percent encoded. If a <code>Regexp</code> is passed,
499
+ # the value <code>/[^b-zB-Z0-9]/</code> would have the same effect. A
500
+ # set of useful <code>String</code> values may be found in the
501
+ # <code>Addressable::URI::CharacterClasses</code> module. The default
502
+ # value is the reserved plus unreserved character classes specified in
503
+ # <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>.
504
+ #
505
+ # @param [String] leave_encoded
506
+ # When <code>character_class</code> is a <code>String</code> then
507
+ # <code>leave_encoded</code> is a string of characters that should remain
508
+ # percent encoded while normalizing the component; if they appear percent
509
+ # encoded in the original component, then they will be upcased ("%2f"
510
+ # normalized to "%2F") but otherwise left alone.
511
+ #
512
+ # @return [String] The normalized component.
513
+ #
514
+ # @example
515
+ # Addressable::URI.normalize_component("simpl%65/%65xampl%65", "b-zB-Z")
516
+ # => "simple%2Fex%61mple"
517
+ # Addressable::URI.normalize_component(
518
+ # "simpl%65/%65xampl%65", /[^b-zB-Z]/
519
+ # )
520
+ # => "simple%2Fex%61mple"
521
+ # Addressable::URI.normalize_component(
522
+ # "simpl%65/%65xampl%65",
523
+ # Addressable::URI::CharacterClasses::UNRESERVED
524
+ # )
525
+ # => "simple%2Fexample"
526
+ # Addressable::URI.normalize_component(
527
+ # "one%20two%2fthree%26four",
528
+ # "0-9a-zA-Z &/",
529
+ # "/"
530
+ # )
531
+ # => "one two%2Fthree&four"
532
+ def self.normalize_component(component, character_class=
533
+ CharacterClasses::RESERVED + CharacterClasses::UNRESERVED,
534
+ leave_encoded='')
535
+ return nil if component.nil?
536
+
537
+ begin
538
+ component = component.to_str
539
+ rescue NoMethodError, TypeError
540
+ raise TypeError, "Can't convert #{component.class} into String."
541
+ end if !component.is_a? String
542
+
543
+ if ![String, Regexp].include?(character_class.class)
544
+ raise TypeError,
545
+ "Expected String or Regexp, got #{character_class.inspect}"
546
+ end
547
+ if character_class.kind_of?(String)
548
+ leave_re = if leave_encoded.length > 0
549
+ character_class = "#{character_class}%" unless character_class.include?('%')
550
+
551
+ "|%(?!#{leave_encoded.chars.map do |char|
552
+ seq = SEQUENCE_ENCODING_TABLE[char]
553
+ [seq.upcase, seq.downcase]
554
+ end.flatten.join('|')})"
555
+ end
556
+
557
+ character_class = /[^#{character_class}]#{leave_re}/
558
+ end
559
+ # We can't perform regexps on invalid UTF sequences, but
560
+ # here we need to, so switch to ASCII.
561
+ component = component.dup
562
+ component.force_encoding(Encoding::ASCII_8BIT)
563
+ unencoded = self.unencode_component(component, String, leave_encoded)
564
+ begin
565
+ encoded = self.encode_component(
566
+ Addressable::IDNA.unicode_normalize_kc(unencoded),
567
+ character_class,
568
+ leave_encoded
569
+ )
570
+ rescue ArgumentError
571
+ encoded = self.encode_component(unencoded)
572
+ end
573
+ encoded.force_encoding(Encoding::UTF_8)
574
+ return encoded
575
+ end
576
+
577
+ ##
578
+ # Percent encodes any special characters in the URI.
579
+ #
580
+ # @param [String, Addressable::URI, #to_str] uri
581
+ # The URI to encode.
582
+ #
583
+ # @param [Class] return_type
584
+ # The type of object to return.
585
+ # This value may only be set to <code>String</code> or
586
+ # <code>Addressable::URI</code>. All other values are invalid. Defaults
587
+ # to <code>String</code>.
588
+ #
589
+ # @return [String, Addressable::URI]
590
+ # The encoded URI.
591
+ # The return type is determined by the <code>return_type</code>
592
+ # parameter.
593
+ def self.encode(uri, return_type=String)
594
+ return nil if uri.nil?
595
+
596
+ begin
597
+ uri = uri.to_str
598
+ rescue NoMethodError, TypeError
599
+ raise TypeError, "Can't convert #{uri.class} into String."
600
+ end if !uri.is_a? String
601
+
602
+ if ![String, ::Addressable::URI].include?(return_type)
603
+ raise TypeError,
604
+ "Expected Class (String or Addressable::URI), " +
605
+ "got #{return_type.inspect}"
606
+ end
607
+ uri_object = uri.kind_of?(self) ? uri : self.parse(uri)
608
+ encoded_uri = Addressable::URI.new(
609
+ :scheme => self.encode_component(uri_object.scheme,
610
+ Addressable::URI::CharacterClasses::SCHEME),
611
+ :authority => self.encode_component(uri_object.authority,
612
+ Addressable::URI::CharacterClasses::AUTHORITY),
613
+ :path => self.encode_component(uri_object.path,
614
+ Addressable::URI::CharacterClasses::PATH),
615
+ :query => self.encode_component(uri_object.query,
616
+ Addressable::URI::CharacterClasses::QUERY),
617
+ :fragment => self.encode_component(uri_object.fragment,
618
+ Addressable::URI::CharacterClasses::FRAGMENT)
619
+ )
620
+ if return_type == String
621
+ return encoded_uri.to_s
622
+ elsif return_type == ::Addressable::URI
623
+ return encoded_uri
624
+ end
625
+ end
626
+
627
+ class << self
628
+ alias_method :escape, :encode
629
+ end
630
+
631
+ ##
632
+ # Normalizes the encoding of a URI. Characters within a hostname are
633
+ # not percent encoded to allow for internationalized domain names.
634
+ #
635
+ # @param [String, Addressable::URI, #to_str] uri
636
+ # The URI to encode.
637
+ #
638
+ # @param [Class] return_type
639
+ # The type of object to return.
640
+ # This value may only be set to <code>String</code> or
641
+ # <code>Addressable::URI</code>. All other values are invalid. Defaults
642
+ # to <code>String</code>.
643
+ #
644
+ # @return [String, Addressable::URI]
645
+ # The encoded URI.
646
+ # The return type is determined by the <code>return_type</code>
647
+ # parameter.
648
+ def self.normalized_encode(uri, return_type=String)
649
+ begin
650
+ uri = uri.to_str
651
+ rescue NoMethodError, TypeError
652
+ raise TypeError, "Can't convert #{uri.class} into String."
653
+ end if !uri.is_a? String
654
+
655
+ if ![String, ::Addressable::URI].include?(return_type)
656
+ raise TypeError,
657
+ "Expected Class (String or Addressable::URI), " +
658
+ "got #{return_type.inspect}"
659
+ end
660
+ uri_object = uri.kind_of?(self) ? uri : self.parse(uri)
661
+ components = {
662
+ :scheme => self.unencode_component(uri_object.scheme),
663
+ :user => self.unencode_component(uri_object.user),
664
+ :password => self.unencode_component(uri_object.password),
665
+ :host => self.unencode_component(uri_object.host),
666
+ :port => (uri_object.port.nil? ? nil : uri_object.port.to_s),
667
+ :path => self.unencode_component(uri_object.path),
668
+ :query => self.unencode_component(uri_object.query),
669
+ :fragment => self.unencode_component(uri_object.fragment)
670
+ }
671
+ components.each do |key, value|
672
+ if value != nil
673
+ begin
674
+ components[key] =
675
+ Addressable::IDNA.unicode_normalize_kc(value.to_str)
676
+ rescue ArgumentError
677
+ # Likely a malformed UTF-8 character, skip unicode normalization
678
+ components[key] = value.to_str
679
+ end
680
+ end
681
+ end
682
+ encoded_uri = Addressable::URI.new(
683
+ :scheme => self.encode_component(components[:scheme],
684
+ Addressable::URI::CharacterClasses::SCHEME),
685
+ :user => self.encode_component(components[:user],
686
+ Addressable::URI::CharacterClasses::UNRESERVED),
687
+ :password => self.encode_component(components[:password],
688
+ Addressable::URI::CharacterClasses::UNRESERVED),
689
+ :host => components[:host],
690
+ :port => components[:port],
691
+ :path => self.encode_component(components[:path],
692
+ Addressable::URI::CharacterClasses::PATH),
693
+ :query => self.encode_component(components[:query],
694
+ Addressable::URI::CharacterClasses::QUERY),
695
+ :fragment => self.encode_component(components[:fragment],
696
+ Addressable::URI::CharacterClasses::FRAGMENT)
697
+ )
698
+ if return_type == String
699
+ return encoded_uri.to_s
700
+ elsif return_type == ::Addressable::URI
701
+ return encoded_uri
702
+ end
703
+ end
704
+
705
+ ##
706
+ # Encodes a set of key/value pairs according to the rules for the
707
+ # <code>application/x-www-form-urlencoded</code> MIME type.
708
+ #
709
+ # @param [#to_hash, #to_ary] form_values
710
+ # The form values to encode.
711
+ #
712
+ # @param [TrueClass, FalseClass] sort
713
+ # Sort the key/value pairs prior to encoding.
714
+ # Defaults to <code>false</code>.
715
+ #
716
+ # @return [String]
717
+ # The encoded value.
718
+ def self.form_encode(form_values, sort=false)
719
+ if form_values.respond_to?(:to_hash)
720
+ form_values = form_values.to_hash.to_a
721
+ elsif form_values.respond_to?(:to_ary)
722
+ form_values = form_values.to_ary
723
+ else
724
+ raise TypeError, "Can't convert #{form_values.class} into Array."
725
+ end
726
+
727
+ form_values = form_values.inject([]) do |accu, (key, value)|
728
+ if value.kind_of?(Array)
729
+ value.each do |v|
730
+ accu << [key.to_s, v.to_s]
731
+ end
732
+ else
733
+ accu << [key.to_s, value.to_s]
734
+ end
735
+ accu
736
+ end
737
+
738
+ if sort
739
+ # Useful for OAuth and optimizing caching systems
740
+ form_values = form_values.sort
741
+ end
742
+ escaped_form_values = form_values.map do |(key, value)|
743
+ # Line breaks are CRLF pairs
744
+ [
745
+ self.encode_component(
746
+ key.gsub(/(\r\n|\n|\r)/, "\r\n"),
747
+ CharacterClasses::UNRESERVED
748
+ ).gsub("%20", "+"),
749
+ self.encode_component(
750
+ value.gsub(/(\r\n|\n|\r)/, "\r\n"),
751
+ CharacterClasses::UNRESERVED
752
+ ).gsub("%20", "+")
753
+ ]
754
+ end
755
+ return escaped_form_values.map do |(key, value)|
756
+ "#{key}=#{value}"
757
+ end.join("&")
758
+ end
759
+
760
+ ##
761
+ # Decodes a <code>String</code> according to the rules for the
762
+ # <code>application/x-www-form-urlencoded</code> MIME type.
763
+ #
764
+ # @param [String, #to_str] encoded_value
765
+ # The form values to decode.
766
+ #
767
+ # @return [Array]
768
+ # The decoded values.
769
+ # This is not a <code>Hash</code> because of the possibility for
770
+ # duplicate keys.
771
+ def self.form_unencode(encoded_value)
772
+ if !encoded_value.respond_to?(:to_str)
773
+ raise TypeError, "Can't convert #{encoded_value.class} into String."
774
+ end
775
+ encoded_value = encoded_value.to_str
776
+ split_values = encoded_value.split("&").map do |pair|
777
+ pair.split("=", 2)
778
+ end
779
+ return split_values.map do |(key, value)|
780
+ [
781
+ key ? self.unencode_component(
782
+ key.gsub("+", "%20")).gsub(/(\r\n|\n|\r)/, "\n") : nil,
783
+ value ? (self.unencode_component(
784
+ value.gsub("+", "%20")).gsub(/(\r\n|\n|\r)/, "\n")) : nil
785
+ ]
786
+ end
787
+ end
788
+
789
+ ##
790
+ # Creates a new uri object from component parts.
791
+ #
792
+ # @option [String, #to_str] scheme The scheme component.
793
+ # @option [String, #to_str] user The user component.
794
+ # @option [String, #to_str] password The password component.
795
+ # @option [String, #to_str] userinfo
796
+ # The userinfo component. If this is supplied, the user and password
797
+ # components must be omitted.
798
+ # @option [String, #to_str] host The host component.
799
+ # @option [String, #to_str] port The port component.
800
+ # @option [String, #to_str] authority
801
+ # The authority component. If this is supplied, the user, password,
802
+ # userinfo, host, and port components must be omitted.
803
+ # @option [String, #to_str] path The path component.
804
+ # @option [String, #to_str] query The query component.
805
+ # @option [String, #to_str] fragment The fragment component.
806
+ #
807
+ # @return [Addressable::URI] The constructed URI object.
808
+ def initialize(options={})
809
+ if options.has_key?(:authority)
810
+ if (options.keys & [:userinfo, :user, :password, :host, :port]).any?
811
+ raise ArgumentError,
812
+ "Cannot specify both an authority and any of the components " +
813
+ "within the authority."
814
+ end
815
+ end
816
+ if options.has_key?(:userinfo)
817
+ if (options.keys & [:user, :password]).any?
818
+ raise ArgumentError,
819
+ "Cannot specify both a userinfo and either the user or password."
820
+ end
821
+ end
822
+
823
+ self.defer_validation do
824
+ # Bunch of crazy logic required because of the composite components
825
+ # like userinfo and authority.
826
+ self.scheme = options[:scheme] if options[:scheme]
827
+ self.user = options[:user] if options[:user]
828
+ self.password = options[:password] if options[:password]
829
+ self.userinfo = options[:userinfo] if options[:userinfo]
830
+ self.host = options[:host] if options[:host]
831
+ self.port = options[:port] if options[:port]
832
+ self.authority = options[:authority] if options[:authority]
833
+ self.path = options[:path] if options[:path]
834
+ self.query = options[:query] if options[:query]
835
+ self.query_values = options[:query_values] if options[:query_values]
836
+ self.fragment = options[:fragment] if options[:fragment]
837
+ end
838
+ self.to_s
839
+ end
840
+
841
+ ##
842
+ # Freeze URI, initializing instance variables.
843
+ #
844
+ # @return [Addressable::URI] The frozen URI object.
845
+ def freeze
846
+ self.normalized_scheme
847
+ self.normalized_user
848
+ self.normalized_password
849
+ self.normalized_userinfo
850
+ self.normalized_host
851
+ self.normalized_port
852
+ self.normalized_authority
853
+ self.normalized_site
854
+ self.normalized_path
855
+ self.normalized_query
856
+ self.normalized_fragment
857
+ self.hash
858
+ super
859
+ end
860
+
861
+ ##
862
+ # The scheme component for this URI.
863
+ #
864
+ # @return [String] The scheme component.
865
+ def scheme
866
+ return defined?(@scheme) ? @scheme : nil
867
+ end
868
+
869
+ ##
870
+ # The scheme component for this URI, normalized.
871
+ #
872
+ # @return [String] The scheme component, normalized.
873
+ def normalized_scheme
874
+ return nil unless self.scheme
875
+ @normalized_scheme ||= begin
876
+ if self.scheme =~ /^\s*ssh\+svn\s*$/i
877
+ "svn+ssh".dup
878
+ else
879
+ Addressable::URI.normalize_component(
880
+ self.scheme.strip.downcase,
881
+ Addressable::URI::CharacterClasses::SCHEME
882
+ )
883
+ end
884
+ end
885
+ # All normalized values should be UTF-8
886
+ @normalized_scheme.force_encoding(Encoding::UTF_8) if @normalized_scheme
887
+ @normalized_scheme
888
+ end
889
+
890
+ ##
891
+ # Sets the scheme component for this URI.
892
+ #
893
+ # @param [String, #to_str] new_scheme The new scheme component.
894
+ def scheme=(new_scheme)
895
+ if new_scheme && !new_scheme.respond_to?(:to_str)
896
+ raise TypeError, "Can't convert #{new_scheme.class} into String."
897
+ elsif new_scheme
898
+ new_scheme = new_scheme.to_str
899
+ end
900
+ if new_scheme && new_scheme !~ /\A[a-z][a-z0-9\.\+\-]*\z/i
901
+ raise InvalidURIError, "Invalid scheme format: #{new_scheme}"
902
+ end
903
+ @scheme = new_scheme
904
+ @scheme = nil if @scheme.to_s.strip.empty?
905
+
906
+ # Reset dependent values
907
+ remove_instance_variable(:@normalized_scheme) if defined?(@normalized_scheme)
908
+ remove_composite_values
909
+
910
+ # Ensure we haven't created an invalid URI
911
+ validate()
912
+ end
913
+
914
+ ##
915
+ # The user component for this URI.
916
+ #
917
+ # @return [String] The user component.
918
+ def user
919
+ return defined?(@user) ? @user : nil
920
+ end
921
+
922
+ ##
923
+ # The user component for this URI, normalized.
924
+ #
925
+ # @return [String] The user component, normalized.
926
+ def normalized_user
927
+ return nil unless self.user
928
+ return @normalized_user if defined?(@normalized_user)
929
+ @normalized_user ||= begin
930
+ if normalized_scheme =~ /https?/ && self.user.strip.empty? &&
931
+ (!self.password || self.password.strip.empty?)
932
+ nil
933
+ else
934
+ Addressable::URI.normalize_component(
935
+ self.user.strip,
936
+ Addressable::URI::CharacterClasses::UNRESERVED
937
+ )
938
+ end
939
+ end
940
+ # All normalized values should be UTF-8
941
+ @normalized_user.force_encoding(Encoding::UTF_8) if @normalized_user
942
+ @normalized_user
943
+ end
944
+
945
+ ##
946
+ # Sets the user component for this URI.
947
+ #
948
+ # @param [String, #to_str] new_user The new user component.
949
+ def user=(new_user)
950
+ if new_user && !new_user.respond_to?(:to_str)
951
+ raise TypeError, "Can't convert #{new_user.class} into String."
952
+ end
953
+ @user = new_user ? new_user.to_str : nil
954
+
955
+ # You can't have a nil user with a non-nil password
956
+ if password != nil
957
+ @user = EMPTY_STR if @user.nil?
958
+ end
959
+
960
+ # Reset dependent values
961
+ remove_instance_variable(:@userinfo) if defined?(@userinfo)
962
+ remove_instance_variable(:@normalized_userinfo) if defined?(@normalized_userinfo)
963
+ remove_instance_variable(:@authority) if defined?(@authority)
964
+ remove_instance_variable(:@normalized_user) if defined?(@normalized_user)
965
+ remove_composite_values
966
+
967
+ # Ensure we haven't created an invalid URI
968
+ validate()
969
+ end
970
+
971
+ ##
972
+ # The password component for this URI.
973
+ #
974
+ # @return [String] The password component.
975
+ def password
976
+ return defined?(@password) ? @password : nil
977
+ end
978
+
979
+ ##
980
+ # The password component for this URI, normalized.
981
+ #
982
+ # @return [String] The password component, normalized.
983
+ def normalized_password
984
+ return nil unless self.password
985
+ return @normalized_password if defined?(@normalized_password)
986
+ @normalized_password ||= begin
987
+ if self.normalized_scheme =~ /https?/ && self.password.strip.empty? &&
988
+ (!self.user || self.user.strip.empty?)
989
+ nil
990
+ else
991
+ Addressable::URI.normalize_component(
992
+ self.password.strip,
993
+ Addressable::URI::CharacterClasses::UNRESERVED
994
+ )
995
+ end
996
+ end
997
+ # All normalized values should be UTF-8
998
+ if @normalized_password
999
+ @normalized_password.force_encoding(Encoding::UTF_8)
1000
+ end
1001
+ @normalized_password
1002
+ end
1003
+
1004
+ ##
1005
+ # Sets the password component for this URI.
1006
+ #
1007
+ # @param [String, #to_str] new_password The new password component.
1008
+ def password=(new_password)
1009
+ if new_password && !new_password.respond_to?(:to_str)
1010
+ raise TypeError, "Can't convert #{new_password.class} into String."
1011
+ end
1012
+ @password = new_password ? new_password.to_str : nil
1013
+
1014
+ # You can't have a nil user with a non-nil password
1015
+ @password ||= nil
1016
+ @user ||= nil
1017
+ if @password != nil
1018
+ @user = EMPTY_STR if @user.nil?
1019
+ end
1020
+
1021
+ # Reset dependent values
1022
+ remove_instance_variable(:@userinfo) if defined?(@userinfo)
1023
+ remove_instance_variable(:@normalized_userinfo) if defined?(@normalized_userinfo)
1024
+ remove_instance_variable(:@authority) if defined?(@authority)
1025
+ remove_instance_variable(:@normalized_password) if defined?(@normalized_password)
1026
+ remove_composite_values
1027
+
1028
+ # Ensure we haven't created an invalid URI
1029
+ validate()
1030
+ end
1031
+
1032
+ ##
1033
+ # The userinfo component for this URI.
1034
+ # Combines the user and password components.
1035
+ #
1036
+ # @return [String] The userinfo component.
1037
+ def userinfo
1038
+ current_user = self.user
1039
+ current_password = self.password
1040
+ (current_user || current_password) && @userinfo ||= begin
1041
+ if current_user && current_password
1042
+ "#{current_user}:#{current_password}"
1043
+ elsif current_user && !current_password
1044
+ "#{current_user}"
1045
+ end
1046
+ end
1047
+ end
1048
+
1049
+ ##
1050
+ # The userinfo component for this URI, normalized.
1051
+ #
1052
+ # @return [String] The userinfo component, normalized.
1053
+ def normalized_userinfo
1054
+ return nil unless self.userinfo
1055
+ return @normalized_userinfo if defined?(@normalized_userinfo)
1056
+ @normalized_userinfo ||= begin
1057
+ current_user = self.normalized_user
1058
+ current_password = self.normalized_password
1059
+ if !current_user && !current_password
1060
+ nil
1061
+ elsif current_user && current_password
1062
+ "#{current_user}:#{current_password}".dup
1063
+ elsif current_user && !current_password
1064
+ "#{current_user}".dup
1065
+ end
1066
+ end
1067
+ # All normalized values should be UTF-8
1068
+ if @normalized_userinfo
1069
+ @normalized_userinfo.force_encoding(Encoding::UTF_8)
1070
+ end
1071
+ @normalized_userinfo
1072
+ end
1073
+
1074
+ ##
1075
+ # Sets the userinfo component for this URI.
1076
+ #
1077
+ # @param [String, #to_str] new_userinfo The new userinfo component.
1078
+ def userinfo=(new_userinfo)
1079
+ if new_userinfo && !new_userinfo.respond_to?(:to_str)
1080
+ raise TypeError, "Can't convert #{new_userinfo.class} into String."
1081
+ end
1082
+ new_user, new_password = if new_userinfo
1083
+ [
1084
+ new_userinfo.to_str.strip[/^(.*):/, 1],
1085
+ new_userinfo.to_str.strip[/:(.*)$/, 1]
1086
+ ]
1087
+ else
1088
+ [nil, nil]
1089
+ end
1090
+
1091
+ # Password assigned first to ensure validity in case of nil
1092
+ self.password = new_password
1093
+ self.user = new_user
1094
+
1095
+ # Reset dependent values
1096
+ remove_instance_variable(:@authority) if defined?(@authority)
1097
+ remove_composite_values
1098
+
1099
+ # Ensure we haven't created an invalid URI
1100
+ validate()
1101
+ end
1102
+
1103
+ ##
1104
+ # The host component for this URI.
1105
+ #
1106
+ # @return [String] The host component.
1107
+ def host
1108
+ return defined?(@host) ? @host : nil
1109
+ end
1110
+
1111
+ ##
1112
+ # The host component for this URI, normalized.
1113
+ #
1114
+ # @return [String] The host component, normalized.
1115
+ def normalized_host
1116
+ return nil unless self.host
1117
+ @normalized_host ||= begin
1118
+ if !self.host.strip.empty?
1119
+ result = ::Addressable::IDNA.to_ascii(
1120
+ URI.unencode_component(self.host.strip.downcase)
1121
+ )
1122
+ if result =~ /[^\.]\.$/
1123
+ # Single trailing dots are unnecessary.
1124
+ result = result[0...-1]
1125
+ end
1126
+ result = Addressable::URI.normalize_component(
1127
+ result,
1128
+ CharacterClasses::HOST)
1129
+ result
1130
+ else
1131
+ EMPTY_STR.dup
1132
+ end
1133
+ end
1134
+ # All normalized values should be UTF-8
1135
+ @normalized_host.force_encoding(Encoding::UTF_8) if @normalized_host
1136
+ @normalized_host
1137
+ end
1138
+
1139
+ ##
1140
+ # Sets the host component for this URI.
1141
+ #
1142
+ # @param [String, #to_str] new_host The new host component.
1143
+ def host=(new_host)
1144
+ if new_host && !new_host.respond_to?(:to_str)
1145
+ raise TypeError, "Can't convert #{new_host.class} into String."
1146
+ end
1147
+ @host = new_host ? new_host.to_str : nil
1148
+
1149
+ # Reset dependent values
1150
+ remove_instance_variable(:@authority) if defined?(@authority)
1151
+ remove_instance_variable(:@normalized_host) if defined?(@normalized_host)
1152
+ remove_composite_values
1153
+
1154
+ # Ensure we haven't created an invalid URI
1155
+ validate()
1156
+ end
1157
+
1158
+ ##
1159
+ # This method is same as URI::Generic#host except
1160
+ # brackets for IPv6 (and 'IPvFuture') addresses are removed.
1161
+ #
1162
+ # @see Addressable::URI#host
1163
+ #
1164
+ # @return [String] The hostname for this URI.
1165
+ def hostname
1166
+ v = self.host
1167
+ /\A\[(.*)\]\z/ =~ v ? $1 : v
1168
+ end
1169
+
1170
+ ##
1171
+ # This method is same as URI::Generic#host= except
1172
+ # the argument can be a bare IPv6 address (or 'IPvFuture').
1173
+ #
1174
+ # @see Addressable::URI#host=
1175
+ #
1176
+ # @param [String, #to_str] new_hostname The new hostname for this URI.
1177
+ def hostname=(new_hostname)
1178
+ if new_hostname &&
1179
+ (new_hostname.respond_to?(:ipv4?) || new_hostname.respond_to?(:ipv6?))
1180
+ new_hostname = new_hostname.to_s
1181
+ elsif new_hostname && !new_hostname.respond_to?(:to_str)
1182
+ raise TypeError, "Can't convert #{new_hostname.class} into String."
1183
+ end
1184
+ v = new_hostname ? new_hostname.to_str : nil
1185
+ v = "[#{v}]" if /\A\[.*\]\z/ !~ v && /:/ =~ v
1186
+ self.host = v
1187
+ end
1188
+
1189
+ ##
1190
+ # Returns the top-level domain for this host.
1191
+ #
1192
+ # @example
1193
+ # Addressable::URI.parse("http://www.example.co.uk").tld # => "co.uk"
1194
+ def tld
1195
+ PublicSuffix.parse(self.host, ignore_private: true).tld
1196
+ end
1197
+
1198
+ ##
1199
+ # Sets the top-level domain for this URI.
1200
+ #
1201
+ # @param [String, #to_str] new_tld The new top-level domain.
1202
+ def tld=(new_tld)
1203
+ replaced_tld = host.sub(/#{tld}\z/, new_tld)
1204
+ self.host = PublicSuffix::Domain.new(replaced_tld).to_s
1205
+ end
1206
+
1207
+ ##
1208
+ # Returns the public suffix domain for this host.
1209
+ #
1210
+ # @example
1211
+ # Addressable::URI.parse("http://www.example.co.uk").domain # => "example.co.uk"
1212
+ def domain
1213
+ PublicSuffix.domain(self.host, ignore_private: true)
1214
+ end
1215
+
1216
+ ##
1217
+ # The authority component for this URI.
1218
+ # Combines the user, password, host, and port components.
1219
+ #
1220
+ # @return [String] The authority component.
1221
+ def authority
1222
+ self.host && @authority ||= begin
1223
+ authority = String.new
1224
+ if self.userinfo != nil
1225
+ authority << "#{self.userinfo}@"
1226
+ end
1227
+ authority << self.host
1228
+ if self.port != nil
1229
+ authority << ":#{self.port}"
1230
+ end
1231
+ authority
1232
+ end
1233
+ end
1234
+
1235
+ ##
1236
+ # The authority component for this URI, normalized.
1237
+ #
1238
+ # @return [String] The authority component, normalized.
1239
+ def normalized_authority
1240
+ return nil unless self.authority
1241
+ @normalized_authority ||= begin
1242
+ authority = String.new
1243
+ if self.normalized_userinfo != nil
1244
+ authority << "#{self.normalized_userinfo}@"
1245
+ end
1246
+ authority << self.normalized_host
1247
+ if self.normalized_port != nil
1248
+ authority << ":#{self.normalized_port}"
1249
+ end
1250
+ authority
1251
+ end
1252
+ # All normalized values should be UTF-8
1253
+ if @normalized_authority
1254
+ @normalized_authority.force_encoding(Encoding::UTF_8)
1255
+ end
1256
+ @normalized_authority
1257
+ end
1258
+
1259
+ ##
1260
+ # Sets the authority component for this URI.
1261
+ #
1262
+ # @param [String, #to_str] new_authority The new authority component.
1263
+ def authority=(new_authority)
1264
+ if new_authority
1265
+ if !new_authority.respond_to?(:to_str)
1266
+ raise TypeError, "Can't convert #{new_authority.class} into String."
1267
+ end
1268
+ new_authority = new_authority.to_str
1269
+ new_userinfo = new_authority[/^([^\[\]]*)@/, 1]
1270
+ if new_userinfo
1271
+ new_user = new_userinfo.strip[/^([^:]*):?/, 1]
1272
+ new_password = new_userinfo.strip[/:(.*)$/, 1]
1273
+ end
1274
+ new_host = new_authority.sub(
1275
+ /^([^\[\]]*)@/, EMPTY_STR
1276
+ ).sub(
1277
+ /:([^:@\[\]]*?)$/, EMPTY_STR
1278
+ )
1279
+ new_port =
1280
+ new_authority[/:([^:@\[\]]*?)$/, 1]
1281
+ end
1282
+
1283
+ # Password assigned first to ensure validity in case of nil
1284
+ self.password = defined?(new_password) ? new_password : nil
1285
+ self.user = defined?(new_user) ? new_user : nil
1286
+ self.host = defined?(new_host) ? new_host : nil
1287
+ self.port = defined?(new_port) ? new_port : nil
1288
+
1289
+ # Reset dependent values
1290
+ remove_instance_variable(:@userinfo) if defined?(@userinfo)
1291
+ remove_instance_variable(:@normalized_userinfo) if defined?(@normalized_userinfo)
1292
+ remove_composite_values
1293
+
1294
+ # Ensure we haven't created an invalid URI
1295
+ validate()
1296
+ end
1297
+
1298
+ ##
1299
+ # The origin for this URI, serialized to ASCII, as per
1300
+ # RFC 6454, section 6.2.
1301
+ #
1302
+ # @return [String] The serialized origin.
1303
+ def origin
1304
+ if self.scheme && self.authority
1305
+ if self.normalized_port
1306
+ "#{self.normalized_scheme}://#{self.normalized_host}" +
1307
+ ":#{self.normalized_port}"
1308
+ else
1309
+ "#{self.normalized_scheme}://#{self.normalized_host}"
1310
+ end
1311
+ else
1312
+ "null"
1313
+ end
1314
+ end
1315
+
1316
+ ##
1317
+ # Sets the origin for this URI, serialized to ASCII, as per
1318
+ # RFC 6454, section 6.2. This assignment will reset the `userinfo`
1319
+ # component.
1320
+ #
1321
+ # @param [String, #to_str] new_origin The new origin component.
1322
+ def origin=(new_origin)
1323
+ if new_origin
1324
+ if !new_origin.respond_to?(:to_str)
1325
+ raise TypeError, "Can't convert #{new_origin.class} into String."
1326
+ end
1327
+ new_origin = new_origin.to_str
1328
+ new_scheme = new_origin[/^([^:\/?#]+):\/\//, 1]
1329
+ unless new_scheme
1330
+ raise InvalidURIError, 'An origin cannot omit the scheme.'
1331
+ end
1332
+ new_host = new_origin[/:\/\/([^\/?#:]+)/, 1]
1333
+ unless new_host
1334
+ raise InvalidURIError, 'An origin cannot omit the host.'
1335
+ end
1336
+ new_port = new_origin[/:([^:@\[\]\/]*?)$/, 1]
1337
+ end
1338
+
1339
+ self.scheme = defined?(new_scheme) ? new_scheme : nil
1340
+ self.host = defined?(new_host) ? new_host : nil
1341
+ self.port = defined?(new_port) ? new_port : nil
1342
+ self.userinfo = nil
1343
+
1344
+ # Reset dependent values
1345
+ remove_instance_variable(:@userinfo) if defined?(@userinfo)
1346
+ remove_instance_variable(:@normalized_userinfo) if defined?(@normalized_userinfo)
1347
+ remove_instance_variable(:@authority) if defined?(@authority)
1348
+ remove_instance_variable(:@normalized_authority) if defined?(@normalized_authority)
1349
+ remove_composite_values
1350
+
1351
+ # Ensure we haven't created an invalid URI
1352
+ validate()
1353
+ end
1354
+
1355
+ # Returns an array of known ip-based schemes. These schemes typically
1356
+ # use a similar URI form:
1357
+ # <code>//<user>:<password>@<host>:<port>/<url-path></code>
1358
+ def self.ip_based_schemes
1359
+ return self.port_mapping.keys
1360
+ end
1361
+
1362
+ # Returns a hash of common IP-based schemes and their default port
1363
+ # numbers. Adding new schemes to this hash, as necessary, will allow
1364
+ # for better URI normalization.
1365
+ def self.port_mapping
1366
+ PORT_MAPPING
1367
+ end
1368
+
1369
+ ##
1370
+ # The port component for this URI.
1371
+ # This is the port number actually given in the URI. This does not
1372
+ # infer port numbers from default values.
1373
+ #
1374
+ # @return [Integer] The port component.
1375
+ def port
1376
+ return defined?(@port) ? @port : nil
1377
+ end
1378
+
1379
+ ##
1380
+ # The port component for this URI, normalized.
1381
+ #
1382
+ # @return [Integer] The port component, normalized.
1383
+ def normalized_port
1384
+ return nil unless self.port
1385
+ return @normalized_port if defined?(@normalized_port)
1386
+ @normalized_port ||= begin
1387
+ if URI.port_mapping[self.normalized_scheme] == self.port
1388
+ nil
1389
+ else
1390
+ self.port
1391
+ end
1392
+ end
1393
+ end
1394
+
1395
+ ##
1396
+ # Sets the port component for this URI.
1397
+ #
1398
+ # @param [String, Integer, #to_s] new_port The new port component.
1399
+ def port=(new_port)
1400
+ if new_port != nil && new_port.respond_to?(:to_str)
1401
+ new_port = Addressable::URI.unencode_component(new_port.to_str)
1402
+ end
1403
+
1404
+ if new_port.respond_to?(:valid_encoding?) && !new_port.valid_encoding?
1405
+ raise InvalidURIError, "Invalid encoding in port"
1406
+ end
1407
+
1408
+ if new_port != nil && !(new_port.to_s =~ /^\d+$/)
1409
+ raise InvalidURIError,
1410
+ "Invalid port number: #{new_port.inspect}"
1411
+ end
1412
+
1413
+ @port = new_port.to_s.to_i
1414
+ @port = nil if @port == 0
1415
+
1416
+ # Reset dependent values
1417
+ remove_instance_variable(:@authority) if defined?(@authority)
1418
+ remove_instance_variable(:@normalized_port) if defined?(@normalized_port)
1419
+ remove_composite_values
1420
+
1421
+ # Ensure we haven't created an invalid URI
1422
+ validate()
1423
+ end
1424
+
1425
+ ##
1426
+ # The inferred port component for this URI.
1427
+ # This method will normalize to the default port for the URI's scheme if
1428
+ # the port isn't explicitly specified in the URI.
1429
+ #
1430
+ # @return [Integer] The inferred port component.
1431
+ def inferred_port
1432
+ if self.port.to_i == 0
1433
+ self.default_port
1434
+ else
1435
+ self.port.to_i
1436
+ end
1437
+ end
1438
+
1439
+ ##
1440
+ # The default port for this URI's scheme.
1441
+ # This method will always returns the default port for the URI's scheme
1442
+ # regardless of the presence of an explicit port in the URI.
1443
+ #
1444
+ # @return [Integer] The default port.
1445
+ def default_port
1446
+ URI.port_mapping[self.scheme.strip.downcase] if self.scheme
1447
+ end
1448
+
1449
+ ##
1450
+ # The combination of components that represent a site.
1451
+ # Combines the scheme, user, password, host, and port components.
1452
+ # Primarily useful for HTTP and HTTPS.
1453
+ #
1454
+ # For example, <code>"http://example.com/path?query"</code> would have a
1455
+ # <code>site</code> value of <code>"http://example.com"</code>.
1456
+ #
1457
+ # @return [String] The components that identify a site.
1458
+ def site
1459
+ (self.scheme || self.authority) && @site ||= begin
1460
+ site_string = "".dup
1461
+ site_string << "#{self.scheme}:" if self.scheme != nil
1462
+ site_string << "//#{self.authority}" if self.authority != nil
1463
+ site_string
1464
+ end
1465
+ end
1466
+
1467
+ ##
1468
+ # The normalized combination of components that represent a site.
1469
+ # Combines the scheme, user, password, host, and port components.
1470
+ # Primarily useful for HTTP and HTTPS.
1471
+ #
1472
+ # For example, <code>"http://example.com/path?query"</code> would have a
1473
+ # <code>site</code> value of <code>"http://example.com"</code>.
1474
+ #
1475
+ # @return [String] The normalized components that identify a site.
1476
+ def normalized_site
1477
+ return nil unless self.site
1478
+ @normalized_site ||= begin
1479
+ site_string = "".dup
1480
+ if self.normalized_scheme != nil
1481
+ site_string << "#{self.normalized_scheme}:"
1482
+ end
1483
+ if self.normalized_authority != nil
1484
+ site_string << "//#{self.normalized_authority}"
1485
+ end
1486
+ site_string
1487
+ end
1488
+ # All normalized values should be UTF-8
1489
+ @normalized_site.force_encoding(Encoding::UTF_8) if @normalized_site
1490
+ @normalized_site
1491
+ end
1492
+
1493
+ ##
1494
+ # Sets the site value for this URI.
1495
+ #
1496
+ # @param [String, #to_str] new_site The new site value.
1497
+ def site=(new_site)
1498
+ if new_site
1499
+ if !new_site.respond_to?(:to_str)
1500
+ raise TypeError, "Can't convert #{new_site.class} into String."
1501
+ end
1502
+ new_site = new_site.to_str
1503
+ # These two regular expressions derived from the primary parsing
1504
+ # expression
1505
+ self.scheme = new_site[/^(?:([^:\/?#]+):)?(?:\/\/(?:[^\/?#]*))?$/, 1]
1506
+ self.authority = new_site[
1507
+ /^(?:(?:[^:\/?#]+):)?(?:\/\/([^\/?#]*))?$/, 1
1508
+ ]
1509
+ else
1510
+ self.scheme = nil
1511
+ self.authority = nil
1512
+ end
1513
+ end
1514
+
1515
+ ##
1516
+ # The path component for this URI.
1517
+ #
1518
+ # @return [String] The path component.
1519
+ def path
1520
+ return defined?(@path) ? @path : EMPTY_STR
1521
+ end
1522
+
1523
+ NORMPATH = /^(?!\/)[^\/:]*:.*$/
1524
+ ##
1525
+ # The path component for this URI, normalized.
1526
+ #
1527
+ # @return [String] The path component, normalized.
1528
+ def normalized_path
1529
+ @normalized_path ||= begin
1530
+ path = self.path.to_s
1531
+ if self.scheme == nil && path =~ NORMPATH
1532
+ # Relative paths with colons in the first segment are ambiguous.
1533
+ path = path.sub(":", "%2F")
1534
+ end
1535
+ # String#split(delimeter, -1) uses the more strict splitting behavior
1536
+ # found by default in Python.
1537
+ result = path.strip.split(SLASH, -1).map do |segment|
1538
+ Addressable::URI.normalize_component(
1539
+ segment,
1540
+ Addressable::URI::CharacterClasses::PCHAR
1541
+ )
1542
+ end.join(SLASH)
1543
+
1544
+ result = URI.normalize_path(result)
1545
+ if result.empty? &&
1546
+ ["http", "https", "ftp", "tftp"].include?(self.normalized_scheme)
1547
+ result = SLASH.dup
1548
+ end
1549
+ result
1550
+ end
1551
+ # All normalized values should be UTF-8
1552
+ @normalized_path.force_encoding(Encoding::UTF_8) if @normalized_path
1553
+ @normalized_path
1554
+ end
1555
+
1556
+ ##
1557
+ # Sets the path component for this URI.
1558
+ #
1559
+ # @param [String, #to_str] new_path The new path component.
1560
+ def path=(new_path)
1561
+ if new_path && !new_path.respond_to?(:to_str)
1562
+ raise TypeError, "Can't convert #{new_path.class} into String."
1563
+ end
1564
+ @path = (new_path || EMPTY_STR).to_str
1565
+ if !@path.empty? && @path[0..0] != SLASH && host != nil
1566
+ @path = "/#{@path}"
1567
+ end
1568
+
1569
+ # Reset dependent values
1570
+ remove_instance_variable(:@normalized_path) if defined?(@normalized_path)
1571
+ remove_composite_values
1572
+
1573
+ # Ensure we haven't created an invalid URI
1574
+ validate()
1575
+ end
1576
+
1577
+ ##
1578
+ # The basename, if any, of the file in the path component.
1579
+ #
1580
+ # @return [String] The path's basename.
1581
+ def basename
1582
+ # Path cannot be nil
1583
+ return File.basename(self.path).sub(/;[^\/]*$/, EMPTY_STR)
1584
+ end
1585
+
1586
+ ##
1587
+ # The extname, if any, of the file in the path component.
1588
+ # Empty string if there is no extension.
1589
+ #
1590
+ # @return [String] The path's extname.
1591
+ def extname
1592
+ return nil unless self.path
1593
+ return File.extname(self.basename)
1594
+ end
1595
+
1596
+ ##
1597
+ # The query component for this URI.
1598
+ #
1599
+ # @return [String] The query component.
1600
+ def query
1601
+ return defined?(@query) ? @query : nil
1602
+ end
1603
+
1604
+ ##
1605
+ # The query component for this URI, normalized.
1606
+ #
1607
+ # @return [String] The query component, normalized.
1608
+ def normalized_query(*flags)
1609
+ return nil unless self.query
1610
+ return @normalized_query if defined?(@normalized_query)
1611
+ @normalized_query ||= begin
1612
+ modified_query_class = Addressable::URI::CharacterClasses::QUERY.dup
1613
+ # Make sure possible key-value pair delimiters are escaped.
1614
+ modified_query_class.sub!("\\&", "").sub!("\\;", "")
1615
+ pairs = (self.query || "").split("&", -1)
1616
+ pairs.delete_if(&:empty?) if flags.include?(:compacted)
1617
+ pairs.sort! if flags.include?(:sorted)
1618
+ component = pairs.map do |pair|
1619
+ Addressable::URI.normalize_component(pair, modified_query_class, "+")
1620
+ end.join("&")
1621
+ component == "" ? nil : component
1622
+ end
1623
+ # All normalized values should be UTF-8
1624
+ @normalized_query.force_encoding(Encoding::UTF_8) if @normalized_query
1625
+ @normalized_query
1626
+ end
1627
+
1628
+ ##
1629
+ # Sets the query component for this URI.
1630
+ #
1631
+ # @param [String, #to_str] new_query The new query component.
1632
+ def query=(new_query)
1633
+ if new_query && !new_query.respond_to?(:to_str)
1634
+ raise TypeError, "Can't convert #{new_query.class} into String."
1635
+ end
1636
+ @query = new_query ? new_query.to_str : nil
1637
+
1638
+ # Reset dependent values
1639
+ remove_instance_variable(:@normalized_query) if defined?(@normalized_query)
1640
+ remove_composite_values
1641
+ end
1642
+
1643
+ ##
1644
+ # Converts the query component to a Hash value.
1645
+ #
1646
+ # @param [Class] return_type The return type desired. Value must be either
1647
+ # `Hash` or `Array`.
1648
+ #
1649
+ # @return [Hash, Array, nil] The query string parsed as a Hash or Array
1650
+ # or nil if the query string is blank.
1651
+ #
1652
+ # @example
1653
+ # Addressable::URI.parse("?one=1&two=2&three=3").query_values
1654
+ # #=> {"one" => "1", "two" => "2", "three" => "3"}
1655
+ # Addressable::URI.parse("?one=two&one=three").query_values(Array)
1656
+ # #=> [["one", "two"], ["one", "three"]]
1657
+ # Addressable::URI.parse("?one=two&one=three").query_values(Hash)
1658
+ # #=> {"one" => "three"}
1659
+ # Addressable::URI.parse("?").query_values
1660
+ # #=> {}
1661
+ # Addressable::URI.parse("").query_values
1662
+ # #=> nil
1663
+ def query_values(return_type=Hash)
1664
+ empty_accumulator = Array == return_type ? [] : {}
1665
+ if return_type != Hash && return_type != Array
1666
+ raise ArgumentError, "Invalid return type. Must be Hash or Array."
1667
+ end
1668
+ return nil if self.query == nil
1669
+ split_query = self.query.split("&").map do |pair|
1670
+ pair.split("=", 2) if pair && !pair.empty?
1671
+ end.compact
1672
+ return split_query.inject(empty_accumulator.dup) do |accu, pair|
1673
+ # I'd rather use key/value identifiers instead of array lookups,
1674
+ # but in this case I really want to maintain the exact pair structure,
1675
+ # so it's best to make all changes in-place.
1676
+ pair[0] = URI.unencode_component(pair[0])
1677
+ if pair[1].respond_to?(:to_str)
1678
+ # I loathe the fact that I have to do this. Stupid HTML 4.01.
1679
+ # Treating '+' as a space was just an unbelievably bad idea.
1680
+ # There was nothing wrong with '%20'!
1681
+ # If it ain't broke, don't fix it!
1682
+ pair[1] = URI.unencode_component(pair[1].to_str.tr("+", " "))
1683
+ end
1684
+ if return_type == Hash
1685
+ accu[pair[0]] = pair[1]
1686
+ else
1687
+ accu << pair
1688
+ end
1689
+ accu
1690
+ end
1691
+ end
1692
+
1693
+ ##
1694
+ # Sets the query component for this URI from a Hash object.
1695
+ # An empty Hash or Array will result in an empty query string.
1696
+ #
1697
+ # @param [Hash, #to_hash, Array] new_query_values The new query values.
1698
+ #
1699
+ # @example
1700
+ # uri.query_values = {:a => "a", :b => ["c", "d", "e"]}
1701
+ # uri.query
1702
+ # # => "a=a&b=c&b=d&b=e"
1703
+ # uri.query_values = [['a', 'a'], ['b', 'c'], ['b', 'd'], ['b', 'e']]
1704
+ # uri.query
1705
+ # # => "a=a&b=c&b=d&b=e"
1706
+ # uri.query_values = [['a', 'a'], ['b', ['c', 'd', 'e']]]
1707
+ # uri.query
1708
+ # # => "a=a&b=c&b=d&b=e"
1709
+ # uri.query_values = [['flag'], ['key', 'value']]
1710
+ # uri.query
1711
+ # # => "flag&key=value"
1712
+ def query_values=(new_query_values)
1713
+ if new_query_values == nil
1714
+ self.query = nil
1715
+ return nil
1716
+ end
1717
+
1718
+ if !new_query_values.is_a?(Array)
1719
+ if !new_query_values.respond_to?(:to_hash)
1720
+ raise TypeError,
1721
+ "Can't convert #{new_query_values.class} into Hash."
1722
+ end
1723
+ new_query_values = new_query_values.to_hash
1724
+ new_query_values = new_query_values.map do |key, value|
1725
+ key = key.to_s if key.kind_of?(Symbol)
1726
+ [key, value]
1727
+ end
1728
+ # Useful default for OAuth and caching.
1729
+ # Only to be used for non-Array inputs. Arrays should preserve order.
1730
+ new_query_values.sort!
1731
+ end
1732
+
1733
+ # new_query_values have form [['key1', 'value1'], ['key2', 'value2']]
1734
+ buffer = "".dup
1735
+ new_query_values.each do |key, value|
1736
+ encoded_key = URI.encode_component(
1737
+ key, CharacterClasses::UNRESERVED
1738
+ )
1739
+ if value == nil
1740
+ buffer << "#{encoded_key}&"
1741
+ elsif value.kind_of?(Array)
1742
+ value.each do |sub_value|
1743
+ encoded_value = URI.encode_component(
1744
+ sub_value, CharacterClasses::UNRESERVED
1745
+ )
1746
+ buffer << "#{encoded_key}=#{encoded_value}&"
1747
+ end
1748
+ else
1749
+ encoded_value = URI.encode_component(
1750
+ value, CharacterClasses::UNRESERVED
1751
+ )
1752
+ buffer << "#{encoded_key}=#{encoded_value}&"
1753
+ end
1754
+ end
1755
+ self.query = buffer.chop
1756
+ end
1757
+
1758
+ ##
1759
+ # The HTTP request URI for this URI. This is the path and the
1760
+ # query string.
1761
+ #
1762
+ # @return [String] The request URI required for an HTTP request.
1763
+ def request_uri
1764
+ return nil if self.absolute? && self.scheme !~ /^https?$/i
1765
+ return (
1766
+ (!self.path.empty? ? self.path : SLASH) +
1767
+ (self.query ? "?#{self.query}" : EMPTY_STR)
1768
+ )
1769
+ end
1770
+
1771
+ ##
1772
+ # Sets the HTTP request URI for this URI.
1773
+ #
1774
+ # @param [String, #to_str] new_request_uri The new HTTP request URI.
1775
+ def request_uri=(new_request_uri)
1776
+ if !new_request_uri.respond_to?(:to_str)
1777
+ raise TypeError, "Can't convert #{new_request_uri.class} into String."
1778
+ end
1779
+ if self.absolute? && self.scheme !~ /^https?$/i
1780
+ raise InvalidURIError,
1781
+ "Cannot set an HTTP request URI for a non-HTTP URI."
1782
+ end
1783
+ new_request_uri = new_request_uri.to_str
1784
+ path_component = new_request_uri[/^([^\?]*)\??(?:.*)$/, 1]
1785
+ query_component = new_request_uri[/^(?:[^\?]*)\?(.*)$/, 1]
1786
+ path_component = path_component.to_s
1787
+ path_component = (!path_component.empty? ? path_component : SLASH)
1788
+ self.path = path_component
1789
+ self.query = query_component
1790
+
1791
+ # Reset dependent values
1792
+ remove_composite_values
1793
+ end
1794
+
1795
+ ##
1796
+ # The fragment component for this URI.
1797
+ #
1798
+ # @return [String] The fragment component.
1799
+ def fragment
1800
+ return defined?(@fragment) ? @fragment : nil
1801
+ end
1802
+
1803
+ ##
1804
+ # The fragment component for this URI, normalized.
1805
+ #
1806
+ # @return [String] The fragment component, normalized.
1807
+ def normalized_fragment
1808
+ return nil unless self.fragment
1809
+ return @normalized_fragment if defined?(@normalized_fragment)
1810
+ @normalized_fragment ||= begin
1811
+ component = Addressable::URI.normalize_component(
1812
+ self.fragment,
1813
+ Addressable::URI::CharacterClasses::FRAGMENT
1814
+ )
1815
+ component == "" ? nil : component
1816
+ end
1817
+ # All normalized values should be UTF-8
1818
+ if @normalized_fragment
1819
+ @normalized_fragment.force_encoding(Encoding::UTF_8)
1820
+ end
1821
+ @normalized_fragment
1822
+ end
1823
+
1824
+ ##
1825
+ # Sets the fragment component for this URI.
1826
+ #
1827
+ # @param [String, #to_str] new_fragment The new fragment component.
1828
+ def fragment=(new_fragment)
1829
+ if new_fragment && !new_fragment.respond_to?(:to_str)
1830
+ raise TypeError, "Can't convert #{new_fragment.class} into String."
1831
+ end
1832
+ @fragment = new_fragment ? new_fragment.to_str : nil
1833
+
1834
+ # Reset dependent values
1835
+ remove_instance_variable(:@normalized_fragment) if defined?(@normalized_fragment)
1836
+ remove_composite_values
1837
+
1838
+ # Ensure we haven't created an invalid URI
1839
+ validate()
1840
+ end
1841
+
1842
+ ##
1843
+ # Determines if the scheme indicates an IP-based protocol.
1844
+ #
1845
+ # @return [TrueClass, FalseClass]
1846
+ # <code>true</code> if the scheme indicates an IP-based protocol.
1847
+ # <code>false</code> otherwise.
1848
+ def ip_based?
1849
+ if self.scheme
1850
+ return URI.ip_based_schemes.include?(
1851
+ self.scheme.strip.downcase)
1852
+ end
1853
+ return false
1854
+ end
1855
+
1856
+ ##
1857
+ # Determines if the URI is relative.
1858
+ #
1859
+ # @return [TrueClass, FalseClass]
1860
+ # <code>true</code> if the URI is relative. <code>false</code>
1861
+ # otherwise.
1862
+ def relative?
1863
+ return self.scheme.nil?
1864
+ end
1865
+
1866
+ ##
1867
+ # Determines if the URI is absolute.
1868
+ #
1869
+ # @return [TrueClass, FalseClass]
1870
+ # <code>true</code> if the URI is absolute. <code>false</code>
1871
+ # otherwise.
1872
+ def absolute?
1873
+ return !relative?
1874
+ end
1875
+
1876
+ ##
1877
+ # Joins two URIs together.
1878
+ #
1879
+ # @param [String, Addressable::URI, #to_str] The URI to join with.
1880
+ #
1881
+ # @return [Addressable::URI] The joined URI.
1882
+ def join(uri)
1883
+ if !uri.respond_to?(:to_str)
1884
+ raise TypeError, "Can't convert #{uri.class} into String."
1885
+ end
1886
+ if !uri.kind_of?(URI)
1887
+ # Otherwise, convert to a String, then parse.
1888
+ uri = URI.parse(uri.to_str)
1889
+ end
1890
+ if uri.to_s.empty?
1891
+ return self.dup
1892
+ end
1893
+
1894
+ joined_scheme = nil
1895
+ joined_user = nil
1896
+ joined_password = nil
1897
+ joined_host = nil
1898
+ joined_port = nil
1899
+ joined_path = nil
1900
+ joined_query = nil
1901
+ joined_fragment = nil
1902
+
1903
+ # Section 5.2.2 of RFC 3986
1904
+ if uri.scheme != nil
1905
+ joined_scheme = uri.scheme
1906
+ joined_user = uri.user
1907
+ joined_password = uri.password
1908
+ joined_host = uri.host
1909
+ joined_port = uri.port
1910
+ joined_path = URI.normalize_path(uri.path)
1911
+ joined_query = uri.query
1912
+ else
1913
+ if uri.authority != nil
1914
+ joined_user = uri.user
1915
+ joined_password = uri.password
1916
+ joined_host = uri.host
1917
+ joined_port = uri.port
1918
+ joined_path = URI.normalize_path(uri.path)
1919
+ joined_query = uri.query
1920
+ else
1921
+ if uri.path == nil || uri.path.empty?
1922
+ joined_path = self.path
1923
+ if uri.query != nil
1924
+ joined_query = uri.query
1925
+ else
1926
+ joined_query = self.query
1927
+ end
1928
+ else
1929
+ if uri.path[0..0] == SLASH
1930
+ joined_path = URI.normalize_path(uri.path)
1931
+ else
1932
+ base_path = self.path.dup
1933
+ base_path = EMPTY_STR if base_path == nil
1934
+ base_path = URI.normalize_path(base_path)
1935
+
1936
+ # Section 5.2.3 of RFC 3986
1937
+ #
1938
+ # Removes the right-most path segment from the base path.
1939
+ if base_path.include?(SLASH)
1940
+ base_path.sub!(/\/[^\/]+$/, SLASH)
1941
+ else
1942
+ base_path = EMPTY_STR
1943
+ end
1944
+
1945
+ # If the base path is empty and an authority segment has been
1946
+ # defined, use a base path of SLASH
1947
+ if base_path.empty? && self.authority != nil
1948
+ base_path = SLASH
1949
+ end
1950
+
1951
+ joined_path = URI.normalize_path(base_path + uri.path)
1952
+ end
1953
+ joined_query = uri.query
1954
+ end
1955
+ joined_user = self.user
1956
+ joined_password = self.password
1957
+ joined_host = self.host
1958
+ joined_port = self.port
1959
+ end
1960
+ joined_scheme = self.scheme
1961
+ end
1962
+ joined_fragment = uri.fragment
1963
+
1964
+ return self.class.new(
1965
+ :scheme => joined_scheme,
1966
+ :user => joined_user,
1967
+ :password => joined_password,
1968
+ :host => joined_host,
1969
+ :port => joined_port,
1970
+ :path => joined_path,
1971
+ :query => joined_query,
1972
+ :fragment => joined_fragment
1973
+ )
1974
+ end
1975
+ alias_method :+, :join
1976
+
1977
+ ##
1978
+ # Destructive form of <code>join</code>.
1979
+ #
1980
+ # @param [String, Addressable::URI, #to_str] The URI to join with.
1981
+ #
1982
+ # @return [Addressable::URI] The joined URI.
1983
+ #
1984
+ # @see Addressable::URI#join
1985
+ def join!(uri)
1986
+ replace_self(self.join(uri))
1987
+ end
1988
+
1989
+ ##
1990
+ # Merges a URI with a <code>Hash</code> of components.
1991
+ # This method has different behavior from <code>join</code>. Any
1992
+ # components present in the <code>hash</code> parameter will override the
1993
+ # original components. The path component is not treated specially.
1994
+ #
1995
+ # @param [Hash, Addressable::URI, #to_hash] The components to merge with.
1996
+ #
1997
+ # @return [Addressable::URI] The merged URI.
1998
+ #
1999
+ # @see Hash#merge
2000
+ def merge(hash)
2001
+ if !hash.respond_to?(:to_hash)
2002
+ raise TypeError, "Can't convert #{hash.class} into Hash."
2003
+ end
2004
+ hash = hash.to_hash
2005
+
2006
+ if hash.has_key?(:authority)
2007
+ if (hash.keys & [:userinfo, :user, :password, :host, :port]).any?
2008
+ raise ArgumentError,
2009
+ "Cannot specify both an authority and any of the components " +
2010
+ "within the authority."
2011
+ end
2012
+ end
2013
+ if hash.has_key?(:userinfo)
2014
+ if (hash.keys & [:user, :password]).any?
2015
+ raise ArgumentError,
2016
+ "Cannot specify both a userinfo and either the user or password."
2017
+ end
2018
+ end
2019
+
2020
+ uri = self.class.new
2021
+ uri.defer_validation do
2022
+ # Bunch of crazy logic required because of the composite components
2023
+ # like userinfo and authority.
2024
+ uri.scheme =
2025
+ hash.has_key?(:scheme) ? hash[:scheme] : self.scheme
2026
+ if hash.has_key?(:authority)
2027
+ uri.authority =
2028
+ hash.has_key?(:authority) ? hash[:authority] : self.authority
2029
+ end
2030
+ if hash.has_key?(:userinfo)
2031
+ uri.userinfo =
2032
+ hash.has_key?(:userinfo) ? hash[:userinfo] : self.userinfo
2033
+ end
2034
+ if !hash.has_key?(:userinfo) && !hash.has_key?(:authority)
2035
+ uri.user =
2036
+ hash.has_key?(:user) ? hash[:user] : self.user
2037
+ uri.password =
2038
+ hash.has_key?(:password) ? hash[:password] : self.password
2039
+ end
2040
+ if !hash.has_key?(:authority)
2041
+ uri.host =
2042
+ hash.has_key?(:host) ? hash[:host] : self.host
2043
+ uri.port =
2044
+ hash.has_key?(:port) ? hash[:port] : self.port
2045
+ end
2046
+ uri.path =
2047
+ hash.has_key?(:path) ? hash[:path] : self.path
2048
+ uri.query =
2049
+ hash.has_key?(:query) ? hash[:query] : self.query
2050
+ uri.fragment =
2051
+ hash.has_key?(:fragment) ? hash[:fragment] : self.fragment
2052
+ end
2053
+
2054
+ return uri
2055
+ end
2056
+
2057
+ ##
2058
+ # Destructive form of <code>merge</code>.
2059
+ #
2060
+ # @param [Hash, Addressable::URI, #to_hash] The components to merge with.
2061
+ #
2062
+ # @return [Addressable::URI] The merged URI.
2063
+ #
2064
+ # @see Addressable::URI#merge
2065
+ def merge!(uri)
2066
+ replace_self(self.merge(uri))
2067
+ end
2068
+
2069
+ ##
2070
+ # Returns the shortest normalized relative form of this URI that uses the
2071
+ # supplied URI as a base for resolution. Returns an absolute URI if
2072
+ # necessary. This is effectively the opposite of <code>route_to</code>.
2073
+ #
2074
+ # @param [String, Addressable::URI, #to_str] uri The URI to route from.
2075
+ #
2076
+ # @return [Addressable::URI]
2077
+ # The normalized relative URI that is equivalent to the original URI.
2078
+ def route_from(uri)
2079
+ uri = URI.parse(uri).normalize
2080
+ normalized_self = self.normalize
2081
+ if normalized_self.relative?
2082
+ raise ArgumentError, "Expected absolute URI, got: #{self.to_s}"
2083
+ end
2084
+ if uri.relative?
2085
+ raise ArgumentError, "Expected absolute URI, got: #{uri.to_s}"
2086
+ end
2087
+ if normalized_self == uri
2088
+ return Addressable::URI.parse("##{normalized_self.fragment}")
2089
+ end
2090
+ components = normalized_self.to_hash
2091
+ if normalized_self.scheme == uri.scheme
2092
+ components[:scheme] = nil
2093
+ if normalized_self.authority == uri.authority
2094
+ components[:user] = nil
2095
+ components[:password] = nil
2096
+ components[:host] = nil
2097
+ components[:port] = nil
2098
+ if normalized_self.path == uri.path
2099
+ components[:path] = nil
2100
+ if normalized_self.query == uri.query
2101
+ components[:query] = nil
2102
+ end
2103
+ else
2104
+ if uri.path != SLASH and components[:path]
2105
+ self_splitted_path = split_path(components[:path])
2106
+ uri_splitted_path = split_path(uri.path)
2107
+ self_dir = self_splitted_path.shift
2108
+ uri_dir = uri_splitted_path.shift
2109
+ while !self_splitted_path.empty? && !uri_splitted_path.empty? and self_dir == uri_dir
2110
+ self_dir = self_splitted_path.shift
2111
+ uri_dir = uri_splitted_path.shift
2112
+ end
2113
+ components[:path] = (uri_splitted_path.fill('..') + [self_dir] + self_splitted_path).join(SLASH)
2114
+ end
2115
+ end
2116
+ end
2117
+ end
2118
+ # Avoid network-path references.
2119
+ if components[:host] != nil
2120
+ components[:scheme] = normalized_self.scheme
2121
+ end
2122
+ return Addressable::URI.new(
2123
+ :scheme => components[:scheme],
2124
+ :user => components[:user],
2125
+ :password => components[:password],
2126
+ :host => components[:host],
2127
+ :port => components[:port],
2128
+ :path => components[:path],
2129
+ :query => components[:query],
2130
+ :fragment => components[:fragment]
2131
+ )
2132
+ end
2133
+
2134
+ ##
2135
+ # Returns the shortest normalized relative form of the supplied URI that
2136
+ # uses this URI as a base for resolution. Returns an absolute URI if
2137
+ # necessary. This is effectively the opposite of <code>route_from</code>.
2138
+ #
2139
+ # @param [String, Addressable::URI, #to_str] uri The URI to route to.
2140
+ #
2141
+ # @return [Addressable::URI]
2142
+ # The normalized relative URI that is equivalent to the supplied URI.
2143
+ def route_to(uri)
2144
+ return URI.parse(uri).route_from(self)
2145
+ end
2146
+
2147
+ ##
2148
+ # Returns a normalized URI object.
2149
+ #
2150
+ # NOTE: This method does not attempt to fully conform to specifications.
2151
+ # It exists largely to correct other people's failures to read the
2152
+ # specifications, and also to deal with caching issues since several
2153
+ # different URIs may represent the same resource and should not be
2154
+ # cached multiple times.
2155
+ #
2156
+ # @return [Addressable::URI] The normalized URI.
2157
+ def normalize
2158
+ # This is a special exception for the frequently misused feed
2159
+ # URI scheme.
2160
+ if normalized_scheme == "feed"
2161
+ if self.to_s =~ /^feed:\/*http:\/*/
2162
+ return URI.parse(
2163
+ self.to_s[/^feed:\/*(http:\/*.*)/, 1]
2164
+ ).normalize
2165
+ end
2166
+ end
2167
+
2168
+ return self.class.new(
2169
+ :scheme => normalized_scheme,
2170
+ :authority => normalized_authority,
2171
+ :path => normalized_path,
2172
+ :query => normalized_query,
2173
+ :fragment => normalized_fragment
2174
+ )
2175
+ end
2176
+
2177
+ ##
2178
+ # Destructively normalizes this URI object.
2179
+ #
2180
+ # @return [Addressable::URI] The normalized URI.
2181
+ #
2182
+ # @see Addressable::URI#normalize
2183
+ def normalize!
2184
+ replace_self(self.normalize)
2185
+ end
2186
+
2187
+ ##
2188
+ # Creates a URI suitable for display to users. If semantic attacks are
2189
+ # likely, the application should try to detect these and warn the user.
2190
+ # See <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>,
2191
+ # section 7.6 for more information.
2192
+ #
2193
+ # @return [Addressable::URI] A URI suitable for display purposes.
2194
+ def display_uri
2195
+ display_uri = self.normalize
2196
+ display_uri.host = ::Addressable::IDNA.to_unicode(display_uri.host)
2197
+ return display_uri
2198
+ end
2199
+
2200
+ ##
2201
+ # Returns <code>true</code> if the URI objects are equal. This method
2202
+ # normalizes both URIs before doing the comparison, and allows comparison
2203
+ # against <code>Strings</code>.
2204
+ #
2205
+ # @param [Object] uri The URI to compare.
2206
+ #
2207
+ # @return [TrueClass, FalseClass]
2208
+ # <code>true</code> if the URIs are equivalent, <code>false</code>
2209
+ # otherwise.
2210
+ def ===(uri)
2211
+ if uri.respond_to?(:normalize)
2212
+ uri_string = uri.normalize.to_s
2213
+ else
2214
+ begin
2215
+ uri_string = ::Addressable::URI.parse(uri).normalize.to_s
2216
+ rescue InvalidURIError, TypeError
2217
+ return false
2218
+ end
2219
+ end
2220
+ return self.normalize.to_s == uri_string
2221
+ end
2222
+
2223
+ ##
2224
+ # Returns <code>true</code> if the URI objects are equal. This method
2225
+ # normalizes both URIs before doing the comparison.
2226
+ #
2227
+ # @param [Object] uri The URI to compare.
2228
+ #
2229
+ # @return [TrueClass, FalseClass]
2230
+ # <code>true</code> if the URIs are equivalent, <code>false</code>
2231
+ # otherwise.
2232
+ def ==(uri)
2233
+ return false unless uri.kind_of?(URI)
2234
+ return self.normalize.to_s == uri.normalize.to_s
2235
+ end
2236
+
2237
+ ##
2238
+ # Returns <code>true</code> if the URI objects are equal. This method
2239
+ # does NOT normalize either URI before doing the comparison.
2240
+ #
2241
+ # @param [Object] uri The URI to compare.
2242
+ #
2243
+ # @return [TrueClass, FalseClass]
2244
+ # <code>true</code> if the URIs are equivalent, <code>false</code>
2245
+ # otherwise.
2246
+ def eql?(uri)
2247
+ return false unless uri.kind_of?(URI)
2248
+ return self.to_s == uri.to_s
2249
+ end
2250
+
2251
+ ##
2252
+ # A hash value that will make a URI equivalent to its normalized
2253
+ # form.
2254
+ #
2255
+ # @return [Integer] A hash of the URI.
2256
+ def hash
2257
+ @hash ||= self.to_s.hash * -1
2258
+ end
2259
+
2260
+ ##
2261
+ # Clones the URI object.
2262
+ #
2263
+ # @return [Addressable::URI] The cloned URI.
2264
+ def dup
2265
+ duplicated_uri = self.class.new(
2266
+ :scheme => self.scheme ? self.scheme.dup : nil,
2267
+ :user => self.user ? self.user.dup : nil,
2268
+ :password => self.password ? self.password.dup : nil,
2269
+ :host => self.host ? self.host.dup : nil,
2270
+ :port => self.port,
2271
+ :path => self.path ? self.path.dup : nil,
2272
+ :query => self.query ? self.query.dup : nil,
2273
+ :fragment => self.fragment ? self.fragment.dup : nil
2274
+ )
2275
+ return duplicated_uri
2276
+ end
2277
+
2278
+ ##
2279
+ # Omits components from a URI.
2280
+ #
2281
+ # @param [Symbol] *components The components to be omitted.
2282
+ #
2283
+ # @return [Addressable::URI] The URI with components omitted.
2284
+ #
2285
+ # @example
2286
+ # uri = Addressable::URI.parse("http://example.com/path?query")
2287
+ # #=> #<Addressable::URI:0xcc5e7a URI:http://example.com/path?query>
2288
+ # uri.omit(:scheme, :authority)
2289
+ # #=> #<Addressable::URI:0xcc4d86 URI:/path?query>
2290
+ def omit(*components)
2291
+ invalid_components = components - [
2292
+ :scheme, :user, :password, :userinfo, :host, :port, :authority,
2293
+ :path, :query, :fragment
2294
+ ]
2295
+ unless invalid_components.empty?
2296
+ raise ArgumentError,
2297
+ "Invalid component names: #{invalid_components.inspect}."
2298
+ end
2299
+ duplicated_uri = self.dup
2300
+ duplicated_uri.defer_validation do
2301
+ components.each do |component|
2302
+ duplicated_uri.send((component.to_s + "=").to_sym, nil)
2303
+ end
2304
+ duplicated_uri.user = duplicated_uri.normalized_user
2305
+ end
2306
+ duplicated_uri
2307
+ end
2308
+
2309
+ ##
2310
+ # Destructive form of omit.
2311
+ #
2312
+ # @param [Symbol] *components The components to be omitted.
2313
+ #
2314
+ # @return [Addressable::URI] The URI with components omitted.
2315
+ #
2316
+ # @see Addressable::URI#omit
2317
+ def omit!(*components)
2318
+ replace_self(self.omit(*components))
2319
+ end
2320
+
2321
+ ##
2322
+ # Determines if the URI is an empty string.
2323
+ #
2324
+ # @return [TrueClass, FalseClass]
2325
+ # Returns <code>true</code> if empty, <code>false</code> otherwise.
2326
+ def empty?
2327
+ return self.to_s.empty?
2328
+ end
2329
+
2330
+ ##
2331
+ # Converts the URI to a <code>String</code>.
2332
+ #
2333
+ # @return [String] The URI's <code>String</code> representation.
2334
+ def to_s
2335
+ if self.scheme == nil && self.path != nil && !self.path.empty? &&
2336
+ self.path =~ NORMPATH
2337
+ raise InvalidURIError,
2338
+ "Cannot assemble URI string with ambiguous path: '#{self.path}'"
2339
+ end
2340
+ @uri_string ||= begin
2341
+ uri_string = String.new
2342
+ uri_string << "#{self.scheme}:" if self.scheme != nil
2343
+ uri_string << "//#{self.authority}" if self.authority != nil
2344
+ uri_string << self.path.to_s
2345
+ uri_string << "?#{self.query}" if self.query != nil
2346
+ uri_string << "##{self.fragment}" if self.fragment != nil
2347
+ uri_string.force_encoding(Encoding::UTF_8)
2348
+ uri_string
2349
+ end
2350
+ end
2351
+
2352
+ ##
2353
+ # URI's are glorified <code>Strings</code>. Allow implicit conversion.
2354
+ alias_method :to_str, :to_s
2355
+
2356
+ ##
2357
+ # Returns a Hash of the URI components.
2358
+ #
2359
+ # @return [Hash] The URI as a <code>Hash</code> of components.
2360
+ def to_hash
2361
+ return {
2362
+ :scheme => self.scheme,
2363
+ :user => self.user,
2364
+ :password => self.password,
2365
+ :host => self.host,
2366
+ :port => self.port,
2367
+ :path => self.path,
2368
+ :query => self.query,
2369
+ :fragment => self.fragment
2370
+ }
2371
+ end
2372
+
2373
+ ##
2374
+ # Returns a <code>String</code> representation of the URI object's state.
2375
+ #
2376
+ # @return [String] The URI object's state, as a <code>String</code>.
2377
+ def inspect
2378
+ sprintf("#<%s:%#0x URI:%s>", URI.to_s, self.object_id, self.to_s)
2379
+ end
2380
+
2381
+ ##
2382
+ # This method allows you to make several changes to a URI simultaneously,
2383
+ # which separately would cause validation errors, but in conjunction,
2384
+ # are valid. The URI will be revalidated as soon as the entire block has
2385
+ # been executed.
2386
+ #
2387
+ # @param [Proc] block
2388
+ # A set of operations to perform on a given URI.
2389
+ def defer_validation
2390
+ raise LocalJumpError, "No block given." unless block_given?
2391
+ @validation_deferred = true
2392
+ yield
2393
+ @validation_deferred = false
2394
+ validate
2395
+ return nil
2396
+ end
2397
+
2398
+ protected
2399
+ SELF_REF = '.'
2400
+ PARENT = '..'
2401
+
2402
+ RULE_2A = /\/\.\/|\/\.$/
2403
+ RULE_2B_2C = /\/([^\/]*)\/\.\.\/|\/([^\/]*)\/\.\.$/
2404
+ RULE_2D = /^\.\.?\/?/
2405
+ RULE_PREFIXED_PARENT = /^\/\.\.?\/|^(\/\.\.?)+\/?$/
2406
+
2407
+ ##
2408
+ # Resolves paths to their simplest form.
2409
+ #
2410
+ # @param [String] path The path to normalize.
2411
+ #
2412
+ # @return [String] The normalized path.
2413
+ def self.normalize_path(path)
2414
+ # Section 5.2.4 of RFC 3986
2415
+
2416
+ return nil if path.nil?
2417
+ normalized_path = path.dup
2418
+ begin
2419
+ mod = nil
2420
+ mod ||= normalized_path.gsub!(RULE_2A, SLASH)
2421
+
2422
+ pair = normalized_path.match(RULE_2B_2C)
2423
+ parent, current = pair[1], pair[2] if pair
2424
+ if pair && ((parent != SELF_REF && parent != PARENT) ||
2425
+ (current != SELF_REF && current != PARENT))
2426
+ mod ||= normalized_path.gsub!(
2427
+ Regexp.new(
2428
+ "/#{Regexp.escape(parent.to_s)}/\\.\\./|" +
2429
+ "(/#{Regexp.escape(current.to_s)}/\\.\\.$)"
2430
+ ), SLASH
2431
+ )
2432
+ end
2433
+
2434
+ mod ||= normalized_path.gsub!(RULE_2D, EMPTY_STR)
2435
+ # Non-standard, removes prefixed dotted segments from path.
2436
+ mod ||= normalized_path.gsub!(RULE_PREFIXED_PARENT, SLASH)
2437
+ end until mod.nil?
2438
+
2439
+ return normalized_path
2440
+ end
2441
+
2442
+ ##
2443
+ # Ensures that the URI is valid.
2444
+ def validate
2445
+ return if !!@validation_deferred
2446
+ if self.scheme != nil && self.ip_based? &&
2447
+ (self.host == nil || self.host.empty?) &&
2448
+ (self.path == nil || self.path.empty?)
2449
+ raise InvalidURIError,
2450
+ "Absolute URI missing hierarchical segment: '#{self.to_s}'"
2451
+ end
2452
+ if self.host == nil
2453
+ if self.port != nil ||
2454
+ self.user != nil ||
2455
+ self.password != nil
2456
+ raise InvalidURIError, "Hostname not supplied: '#{self.to_s}'"
2457
+ end
2458
+ end
2459
+ if self.path != nil && !self.path.empty? && self.path[0..0] != SLASH &&
2460
+ self.authority != nil
2461
+ raise InvalidURIError,
2462
+ "Cannot have a relative path with an authority set: '#{self.to_s}'"
2463
+ end
2464
+ if self.path != nil && !self.path.empty? &&
2465
+ self.path[0..1] == SLASH + SLASH && self.authority == nil
2466
+ raise InvalidURIError,
2467
+ "Cannot have a path with two leading slashes " +
2468
+ "without an authority set: '#{self.to_s}'"
2469
+ end
2470
+ unreserved = CharacterClasses::UNRESERVED
2471
+ sub_delims = CharacterClasses::SUB_DELIMS
2472
+ if !self.host.nil? && (self.host =~ /[<>{}\/\\\?\#\@"[[:space:]]]/ ||
2473
+ (self.host[/^\[(.*)\]$/, 1] != nil && self.host[/^\[(.*)\]$/, 1] !~
2474
+ Regexp.new("^[#{unreserved}#{sub_delims}:]*$")))
2475
+ raise InvalidURIError, "Invalid character in host: '#{self.host.to_s}'"
2476
+ end
2477
+ return nil
2478
+ end
2479
+
2480
+ ##
2481
+ # Replaces the internal state of self with the specified URI's state.
2482
+ # Used in destructive operations to avoid massive code repetition.
2483
+ #
2484
+ # @param [Addressable::URI] uri The URI to replace <code>self</code> with.
2485
+ #
2486
+ # @return [Addressable::URI] <code>self</code>.
2487
+ def replace_self(uri)
2488
+ # Reset dependent values
2489
+ instance_variables.each do |var|
2490
+ if instance_variable_defined?(var) && var != :@validation_deferred
2491
+ remove_instance_variable(var)
2492
+ end
2493
+ end
2494
+
2495
+ @scheme = uri.scheme
2496
+ @user = uri.user
2497
+ @password = uri.password
2498
+ @host = uri.host
2499
+ @port = uri.port
2500
+ @path = uri.path
2501
+ @query = uri.query
2502
+ @fragment = uri.fragment
2503
+ return self
2504
+ end
2505
+
2506
+ ##
2507
+ # Splits path string with "/" (slash).
2508
+ # It is considered that there is empty string after last slash when
2509
+ # path ends with slash.
2510
+ #
2511
+ # @param [String] path The path to split.
2512
+ #
2513
+ # @return [Array<String>] An array of parts of path.
2514
+ def split_path(path)
2515
+ splitted = path.split(SLASH)
2516
+ splitted << EMPTY_STR if path.end_with? SLASH
2517
+ splitted
2518
+ end
2519
+
2520
+ ##
2521
+ # Resets composite values for the entire URI
2522
+ #
2523
+ # @api private
2524
+ def remove_composite_values
2525
+ remove_instance_variable(:@uri_string) if defined?(@uri_string)
2526
+ remove_instance_variable(:@hash) if defined?(@hash)
2527
+ end
2528
+ end
2529
+ end