abiquo-etk 0.4.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (530) hide show
  1. data/.document +5 -0
  2. data/.gitignore +21 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +17 -0
  5. data/Rakefile +87 -0
  6. data/TODO +6 -0
  7. data/VERSION +1 -0
  8. data/abiquo-etk.gemspec +577 -0
  9. data/abiquo-etk.spec +125 -0
  10. data/bin/abicli +90 -0
  11. data/bin/abiquo-check-16-install +129 -0
  12. data/bin/aetk-setup-rs +36 -0
  13. data/bin/aetk-setup-server +77 -0
  14. data/bin/aetk-setup-v2v +33 -0
  15. data/lib/abicli/commands/remote-services-settings.rb +24 -0
  16. data/lib/abicli/commands/server-settings.rb +22 -0
  17. data/lib/abicli/commands/set.rb +133 -0
  18. data/lib/abicli/commands/smoketest.rb +93 -0
  19. data/lib/abicli/commands/upload-template.rb +272 -0
  20. data/lib/abicli/commands/version.rb +5 -0
  21. data/lib/abiquo-etk.rb +191 -0
  22. data/lib/checks/01detect_abiquo.rb +4 -0
  23. data/lib/checks/abiquo_service.rb +34 -0
  24. data/lib/checks/abiquo_version.rb +24 -0
  25. data/lib/checks/components_installed.rb +6 -0
  26. data/lib/checks/firewall.rb +10 -0
  27. data/lib/checks/hv_passwords.rb +51 -0
  28. data/lib/checks/install_type.rb +8 -0
  29. data/lib/checks/java.rb +19 -0
  30. data/lib/checks/mysql.rb +33 -0
  31. data/lib/checks/nfs.rb +18 -0
  32. data/lib/checks/os_version.rb +5 -0
  33. data/lib/checks/virtualbox.rb +11 -0
  34. data/scripts/setup_rs +44 -0
  35. data/scripts/setup_v2v +1 -0
  36. data/vendor/activesupport-2.3.8/CHANGELOG +1367 -0
  37. data/vendor/activesupport-2.3.8/README +43 -0
  38. data/vendor/activesupport-2.3.8/lib/active_support/all.rb +8 -0
  39. data/vendor/activesupport-2.3.8/lib/active_support/backtrace_cleaner.rb +72 -0
  40. data/vendor/activesupport-2.3.8/lib/active_support/base64.rb +33 -0
  41. data/vendor/activesupport-2.3.8/lib/active_support/basic_object.rb +24 -0
  42. data/vendor/activesupport-2.3.8/lib/active_support/buffered_logger.rb +127 -0
  43. data/vendor/activesupport-2.3.8/lib/active_support/cache/compressed_mem_cache_store.rb +20 -0
  44. data/vendor/activesupport-2.3.8/lib/active_support/cache/drb_store.rb +14 -0
  45. data/vendor/activesupport-2.3.8/lib/active_support/cache/file_store.rb +72 -0
  46. data/vendor/activesupport-2.3.8/lib/active_support/cache/mem_cache_store.rb +143 -0
  47. data/vendor/activesupport-2.3.8/lib/active_support/cache/memory_store.rb +58 -0
  48. data/vendor/activesupport-2.3.8/lib/active_support/cache/strategy/local_cache.rb +104 -0
  49. data/vendor/activesupport-2.3.8/lib/active_support/cache/synchronized_memory_store.rb +47 -0
  50. data/vendor/activesupport-2.3.8/lib/active_support/cache.rb +248 -0
  51. data/vendor/activesupport-2.3.8/lib/active_support/callbacks.rb +279 -0
  52. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/array/access.rb +53 -0
  53. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/array/conversions.rb +197 -0
  54. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/array/extract_options.rb +20 -0
  55. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/array/grouping.rb +106 -0
  56. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/array/random_access.rb +22 -0
  57. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/array/wrapper.rb +24 -0
  58. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/array.rb +15 -0
  59. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/base64/encoding.rb +16 -0
  60. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/base64.rb +4 -0
  61. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/benchmark.rb +19 -0
  62. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/bigdecimal/conversions.rb +37 -0
  63. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/bigdecimal.rb +6 -0
  64. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/blank.rb +2 -0
  65. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +23 -0
  66. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/cgi.rb +5 -0
  67. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/class/attribute_accessors.rb +61 -0
  68. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/class/delegating_attributes.rb +47 -0
  69. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/class/inheritable_attributes.rb +140 -0
  70. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/class/removal.rb +50 -0
  71. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/class.rb +4 -0
  72. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/date/behavior.rb +42 -0
  73. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/date/calculations.rb +241 -0
  74. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/date/conversions.rb +107 -0
  75. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/date.rb +10 -0
  76. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/date_time/calculations.rb +126 -0
  77. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/date_time/conversions.rb +107 -0
  78. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/date_time.rb +12 -0
  79. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/duplicable.rb +43 -0
  80. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/enumerable.rb +120 -0
  81. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/exception.rb +45 -0
  82. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/file/atomic.rb +47 -0
  83. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/file.rb +5 -0
  84. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/float/rounding.rb +24 -0
  85. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/float/time.rb +27 -0
  86. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/float.rb +7 -0
  87. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/hash/conversions.rb +247 -0
  88. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/hash/deep_merge.rb +23 -0
  89. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/hash/diff.rb +19 -0
  90. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/hash/except.rb +25 -0
  91. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/hash/indifferent_access.rb +143 -0
  92. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/hash/keys.rb +52 -0
  93. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/hash/reverse_merge.rb +35 -0
  94. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/hash/slice.rb +40 -0
  95. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/hash.rb +14 -0
  96. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/integer/even_odd.rb +29 -0
  97. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/integer/inflections.rb +20 -0
  98. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/integer/time.rb +45 -0
  99. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/integer.rb +9 -0
  100. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/kernel/agnostics.rb +11 -0
  101. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/kernel/daemonizing.rb +7 -0
  102. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/kernel/debugger.rb +16 -0
  103. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/kernel/reporting.rb +59 -0
  104. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/kernel/requires.rb +24 -0
  105. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/kernel.rb +5 -0
  106. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/load_error.rb +38 -0
  107. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/logger.rb +145 -0
  108. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/module/aliasing.rb +74 -0
  109. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/module/attr_accessor_with_default.rb +31 -0
  110. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/module/attr_internal.rb +32 -0
  111. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/module/attribute_accessors.rb +67 -0
  112. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/module/delegation.rb +135 -0
  113. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/module/inclusion.rb +30 -0
  114. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/module/introspection.rb +90 -0
  115. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/module/loading.rb +23 -0
  116. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/module/model_naming.rb +25 -0
  117. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/module/synchronization.rb +39 -0
  118. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/module.rb +23 -0
  119. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/name_error.rb +19 -0
  120. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/numeric/bytes.rb +50 -0
  121. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/numeric/conversions.rb +19 -0
  122. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/numeric/time.rb +81 -0
  123. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/numeric.rb +9 -0
  124. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/object/blank.rb +76 -0
  125. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/object/conversions.rb +15 -0
  126. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/object/extending.rb +80 -0
  127. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/object/instance_variables.rb +74 -0
  128. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/object/metaclass.rb +14 -0
  129. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/object/misc.rb +90 -0
  130. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/object/singleton_class.rb +13 -0
  131. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/object.rb +7 -0
  132. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/pathname/clean_within.rb +14 -0
  133. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/pathname.rb +7 -0
  134. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/proc.rb +12 -0
  135. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/process/daemon.rb +25 -0
  136. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/process.rb +1 -0
  137. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/range/blockless_step.rb +32 -0
  138. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/range/conversions.rb +27 -0
  139. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/range/include_range.rb +30 -0
  140. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/range/overlaps.rb +15 -0
  141. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/range.rb +11 -0
  142. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/rexml.rb +41 -0
  143. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/string/access.rb +106 -0
  144. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/string/behavior.rb +13 -0
  145. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/string/bytesize.rb +5 -0
  146. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/string/conversions.rb +28 -0
  147. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/string/filters.rb +26 -0
  148. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/string/inflections.rb +167 -0
  149. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/string/iterators.rb +23 -0
  150. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/string/multibyte.rb +81 -0
  151. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/string/output_safety.rb +112 -0
  152. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/string/starts_ends_with.rb +33 -0
  153. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/string/xchar.rb +11 -0
  154. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/string.rb +24 -0
  155. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/symbol.rb +14 -0
  156. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/time/behavior.rb +13 -0
  157. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/time/calculations.rb +313 -0
  158. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/time/conversions.rb +90 -0
  159. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/time/zones.rb +86 -0
  160. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/time.rb +46 -0
  161. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/try.rb +36 -0
  162. data/vendor/activesupport-2.3.8/lib/active_support/core_ext/uri.rb +16 -0
  163. data/vendor/activesupport-2.3.8/lib/active_support/core_ext.rb +8 -0
  164. data/vendor/activesupport-2.3.8/lib/active_support/dependencies.rb +625 -0
  165. data/vendor/activesupport-2.3.8/lib/active_support/deprecation.rb +197 -0
  166. data/vendor/activesupport-2.3.8/lib/active_support/duration.rb +100 -0
  167. data/vendor/activesupport-2.3.8/lib/active_support/gzip.rb +25 -0
  168. data/vendor/activesupport-2.3.8/lib/active_support/inflections.rb +56 -0
  169. data/vendor/activesupport-2.3.8/lib/active_support/inflector.rb +409 -0
  170. data/vendor/activesupport-2.3.8/lib/active_support/json/backends/jsongem.rb +37 -0
  171. data/vendor/activesupport-2.3.8/lib/active_support/json/backends/yajl.rb +40 -0
  172. data/vendor/activesupport-2.3.8/lib/active_support/json/backends/yaml.rb +87 -0
  173. data/vendor/activesupport-2.3.8/lib/active_support/json/decoding.rb +50 -0
  174. data/vendor/activesupport-2.3.8/lib/active_support/json/encoders/date.rb +22 -0
  175. data/vendor/activesupport-2.3.8/lib/active_support/json/encoders/date_time.rb +22 -0
  176. data/vendor/activesupport-2.3.8/lib/active_support/json/encoders/enumerable.rb +17 -0
  177. data/vendor/activesupport-2.3.8/lib/active_support/json/encoders/false_class.rb +7 -0
  178. data/vendor/activesupport-2.3.8/lib/active_support/json/encoders/hash.rb +56 -0
  179. data/vendor/activesupport-2.3.8/lib/active_support/json/encoders/nil_class.rb +7 -0
  180. data/vendor/activesupport-2.3.8/lib/active_support/json/encoders/numeric.rb +21 -0
  181. data/vendor/activesupport-2.3.8/lib/active_support/json/encoders/object.rb +10 -0
  182. data/vendor/activesupport-2.3.8/lib/active_support/json/encoders/regexp.rb +9 -0
  183. data/vendor/activesupport-2.3.8/lib/active_support/json/encoders/string.rb +9 -0
  184. data/vendor/activesupport-2.3.8/lib/active_support/json/encoders/symbol.rb +5 -0
  185. data/vendor/activesupport-2.3.8/lib/active_support/json/encoders/time.rb +22 -0
  186. data/vendor/activesupport-2.3.8/lib/active_support/json/encoders/true_class.rb +7 -0
  187. data/vendor/activesupport-2.3.8/lib/active_support/json/encoding.rb +111 -0
  188. data/vendor/activesupport-2.3.8/lib/active_support/json/variable.rb +10 -0
  189. data/vendor/activesupport-2.3.8/lib/active_support/json.rb +2 -0
  190. data/vendor/activesupport-2.3.8/lib/active_support/locale/en.yml +33 -0
  191. data/vendor/activesupport-2.3.8/lib/active_support/memoizable.rb +100 -0
  192. data/vendor/activesupport-2.3.8/lib/active_support/message_encryptor.rb +70 -0
  193. data/vendor/activesupport-2.3.8/lib/active_support/message_verifier.rb +79 -0
  194. data/vendor/activesupport-2.3.8/lib/active_support/multibyte/chars.rb +707 -0
  195. data/vendor/activesupport-2.3.8/lib/active_support/multibyte/exceptions.rb +8 -0
  196. data/vendor/activesupport-2.3.8/lib/active_support/multibyte/unicode_database.rb +71 -0
  197. data/vendor/activesupport-2.3.8/lib/active_support/multibyte/utils.rb +60 -0
  198. data/vendor/activesupport-2.3.8/lib/active_support/multibyte.rb +57 -0
  199. data/vendor/activesupport-2.3.8/lib/active_support/option_merger.rb +23 -0
  200. data/vendor/activesupport-2.3.8/lib/active_support/ordered_hash.rb +158 -0
  201. data/vendor/activesupport-2.3.8/lib/active_support/ordered_options.rb +19 -0
  202. data/vendor/activesupport-2.3.8/lib/active_support/rescuable.rb +108 -0
  203. data/vendor/activesupport-2.3.8/lib/active_support/secure_random.rb +199 -0
  204. data/vendor/activesupport-2.3.8/lib/active_support/string_inquirer.rb +21 -0
  205. data/vendor/activesupport-2.3.8/lib/active_support/test_case.rb +40 -0
  206. data/vendor/activesupport-2.3.8/lib/active_support/testing/assertions.rb +79 -0
  207. data/vendor/activesupport-2.3.8/lib/active_support/testing/declarative.rb +21 -0
  208. data/vendor/activesupport-2.3.8/lib/active_support/testing/default.rb +9 -0
  209. data/vendor/activesupport-2.3.8/lib/active_support/testing/deprecation.rb +57 -0
  210. data/vendor/activesupport-2.3.8/lib/active_support/testing/performance.rb +452 -0
  211. data/vendor/activesupport-2.3.8/lib/active_support/testing/setup_and_teardown.rb +91 -0
  212. data/vendor/activesupport-2.3.8/lib/active_support/time_with_zone.rb +335 -0
  213. data/vendor/activesupport-2.3.8/lib/active_support/values/time_zone.rb +412 -0
  214. data/vendor/activesupport-2.3.8/lib/active_support/values/unicode_tables.dat +0 -0
  215. data/vendor/activesupport-2.3.8/lib/active_support/vendor/builder-2.1.2/blankslate.rb +113 -0
  216. data/vendor/activesupport-2.3.8/lib/active_support/vendor/builder-2.1.2/builder/blankslate.rb +20 -0
  217. data/vendor/activesupport-2.3.8/lib/active_support/vendor/builder-2.1.2/builder/css.rb +250 -0
  218. data/vendor/activesupport-2.3.8/lib/active_support/vendor/builder-2.1.2/builder/xchar.rb +115 -0
  219. data/vendor/activesupport-2.3.8/lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb +139 -0
  220. data/vendor/activesupport-2.3.8/lib/active_support/vendor/builder-2.1.2/builder/xmlevents.rb +63 -0
  221. data/vendor/activesupport-2.3.8/lib/active_support/vendor/builder-2.1.2/builder/xmlmarkup.rb +328 -0
  222. data/vendor/activesupport-2.3.8/lib/active_support/vendor/builder-2.1.2/builder.rb +13 -0
  223. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/backend/active_record/missing.rb +67 -0
  224. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/backend/active_record/store_procs.rb +38 -0
  225. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/backend/active_record/translation.rb +88 -0
  226. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/backend/active_record.rb +66 -0
  227. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/backend/base.rb +266 -0
  228. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/backend/cache.rb +76 -0
  229. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/backend/cascade.rb +58 -0
  230. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/backend/chain.rb +75 -0
  231. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/backend/cldr.rb +100 -0
  232. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/backend/fallbacks.rb +69 -0
  233. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/backend/fast.rb +69 -0
  234. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/backend/gettext.rb +75 -0
  235. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/backend/helpers.rb +68 -0
  236. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/backend/interpolation_compiler.rb +119 -0
  237. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/backend/links.rb +34 -0
  238. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/backend/metadata.rb +73 -0
  239. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/backend/pluralization.rb +57 -0
  240. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/backend/simple.rb +22 -0
  241. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/backend.rb +19 -0
  242. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/core_ext/hash/except.rb +8 -0
  243. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/core_ext/hash/slice.rb +8 -0
  244. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/core_ext/object/meta_class.rb +5 -0
  245. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/core_ext/string/interpolate.rb +99 -0
  246. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/exceptions.rb +61 -0
  247. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/gettext/po_parser.rb +329 -0
  248. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/gettext.rb +25 -0
  249. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/helpers/gettext.rb +65 -0
  250. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/helpers.rb +5 -0
  251. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/locale/fallbacks.rb +98 -0
  252. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/locale/tag/parents.rb +24 -0
  253. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/locale/tag/rfc4646.rb +76 -0
  254. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/locale/tag/simple.rb +41 -0
  255. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/locale/tag.rb +28 -0
  256. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/locale.rb +6 -0
  257. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n/version.rb +3 -0
  258. data/vendor/activesupport-2.3.8/lib/active_support/vendor/i18n-0.3.7/i18n.rb +335 -0
  259. data/vendor/activesupport-2.3.8/lib/active_support/vendor/memcache-client-1.7.4/memcache.rb +1107 -0
  260. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/data_timezone.rb +47 -0
  261. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/data_timezone_info.rb +228 -0
  262. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Algiers.rb +55 -0
  263. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Cairo.rb +219 -0
  264. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Casablanca.rb +40 -0
  265. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Harare.rb +18 -0
  266. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Johannesburg.rb +25 -0
  267. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Monrovia.rb +22 -0
  268. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Nairobi.rb +23 -0
  269. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Argentina/Buenos_Aires.rb +166 -0
  270. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Argentina/San_Juan.rb +86 -0
  271. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Bogota.rb +23 -0
  272. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Caracas.rb +23 -0
  273. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Chicago.rb +283 -0
  274. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Chihuahua.rb +136 -0
  275. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Denver.rb +204 -0
  276. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Godthab.rb +161 -0
  277. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Guatemala.rb +27 -0
  278. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Halifax.rb +274 -0
  279. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Indiana/Indianapolis.rb +149 -0
  280. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Juneau.rb +194 -0
  281. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/La_Paz.rb +22 -0
  282. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Lima.rb +35 -0
  283. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Los_Angeles.rb +232 -0
  284. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Mazatlan.rb +139 -0
  285. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Mexico_City.rb +144 -0
  286. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Monterrey.rb +131 -0
  287. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/New_York.rb +282 -0
  288. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Phoenix.rb +30 -0
  289. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Regina.rb +74 -0
  290. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Santiago.rb +205 -0
  291. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Sao_Paulo.rb +171 -0
  292. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/St_Johns.rb +288 -0
  293. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Tijuana.rb +196 -0
  294. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Almaty.rb +67 -0
  295. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Baghdad.rb +73 -0
  296. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Baku.rb +161 -0
  297. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Bangkok.rb +20 -0
  298. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Chongqing.rb +33 -0
  299. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Colombo.rb +30 -0
  300. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Dhaka.rb +27 -0
  301. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Hong_Kong.rb +87 -0
  302. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Irkutsk.rb +165 -0
  303. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Jakarta.rb +30 -0
  304. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Jerusalem.rb +163 -0
  305. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kabul.rb +20 -0
  306. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kamchatka.rb +163 -0
  307. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Karachi.rb +30 -0
  308. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Katmandu.rb +20 -0
  309. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kolkata.rb +25 -0
  310. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Krasnoyarsk.rb +163 -0
  311. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kuala_Lumpur.rb +31 -0
  312. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kuwait.rb +18 -0
  313. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Magadan.rb +163 -0
  314. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Muscat.rb +18 -0
  315. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Novosibirsk.rb +164 -0
  316. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Rangoon.rb +24 -0
  317. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Riyadh.rb +18 -0
  318. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Seoul.rb +34 -0
  319. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Shanghai.rb +35 -0
  320. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Singapore.rb +33 -0
  321. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Taipei.rb +59 -0
  322. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tashkent.rb +47 -0
  323. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tbilisi.rb +78 -0
  324. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tehran.rb +121 -0
  325. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tokyo.rb +30 -0
  326. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Ulaanbaatar.rb +65 -0
  327. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Urumqi.rb +33 -0
  328. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Vladivostok.rb +164 -0
  329. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Yakutsk.rb +163 -0
  330. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Yekaterinburg.rb +165 -0
  331. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Yerevan.rb +165 -0
  332. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Atlantic/Azores.rb +270 -0
  333. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Atlantic/Cape_Verde.rb +23 -0
  334. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Atlantic/South_Georgia.rb +18 -0
  335. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Adelaide.rb +187 -0
  336. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Brisbane.rb +35 -0
  337. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Darwin.rb +29 -0
  338. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Hobart.rb +193 -0
  339. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Melbourne.rb +185 -0
  340. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Perth.rb +37 -0
  341. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Sydney.rb +185 -0
  342. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Etc/UTC.rb +16 -0
  343. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Amsterdam.rb +228 -0
  344. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Athens.rb +185 -0
  345. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Belgrade.rb +163 -0
  346. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Berlin.rb +188 -0
  347. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Bratislava.rb +13 -0
  348. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Brussels.rb +232 -0
  349. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Bucharest.rb +181 -0
  350. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Budapest.rb +197 -0
  351. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Copenhagen.rb +179 -0
  352. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Dublin.rb +276 -0
  353. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Helsinki.rb +163 -0
  354. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Istanbul.rb +218 -0
  355. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Kiev.rb +168 -0
  356. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Lisbon.rb +268 -0
  357. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Ljubljana.rb +13 -0
  358. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/London.rb +288 -0
  359. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Madrid.rb +211 -0
  360. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Minsk.rb +170 -0
  361. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Moscow.rb +181 -0
  362. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Paris.rb +232 -0
  363. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Prague.rb +187 -0
  364. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Riga.rb +176 -0
  365. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Rome.rb +215 -0
  366. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Sarajevo.rb +13 -0
  367. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Skopje.rb +13 -0
  368. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Sofia.rb +173 -0
  369. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Stockholm.rb +165 -0
  370. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Tallinn.rb +172 -0
  371. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Vienna.rb +183 -0
  372. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Vilnius.rb +170 -0
  373. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Warsaw.rb +212 -0
  374. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Zagreb.rb +13 -0
  375. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Auckland.rb +202 -0
  376. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Fiji.rb +23 -0
  377. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Guam.rb +22 -0
  378. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Honolulu.rb +28 -0
  379. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Majuro.rb +20 -0
  380. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Midway.rb +25 -0
  381. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Noumea.rb +25 -0
  382. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Pago_Pago.rb +26 -0
  383. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Port_Moresby.rb +20 -0
  384. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Tongatapu.rb +27 -0
  385. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/info_timezone.rb +52 -0
  386. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/linked_timezone.rb +51 -0
  387. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/linked_timezone_info.rb +44 -0
  388. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/offset_rationals.rb +98 -0
  389. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/ruby_core_support.rb +56 -0
  390. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/time_or_datetime.rb +292 -0
  391. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb +508 -0
  392. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_definition.rb +56 -0
  393. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_info.rb +40 -0
  394. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_offset_info.rb +94 -0
  395. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb +198 -0
  396. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_transition_info.rb +129 -0
  397. data/vendor/activesupport-2.3.8/lib/active_support/vendor/tzinfo-0.3.12/tzinfo.rb +33 -0
  398. data/vendor/activesupport-2.3.8/lib/active_support/vendor.rb +36 -0
  399. data/vendor/activesupport-2.3.8/lib/active_support/version.rb +9 -0
  400. data/vendor/activesupport-2.3.8/lib/active_support/whiny_nil.rb +64 -0
  401. data/vendor/activesupport-2.3.8/lib/active_support/xml_mini/jdom.rb +162 -0
  402. data/vendor/activesupport-2.3.8/lib/active_support/xml_mini/libxml.rb +73 -0
  403. data/vendor/activesupport-2.3.8/lib/active_support/xml_mini/libxmlsax.rb +74 -0
  404. data/vendor/activesupport-2.3.8/lib/active_support/xml_mini/nokogiri.rb +72 -0
  405. data/vendor/activesupport-2.3.8/lib/active_support/xml_mini/nokogirisax.rb +73 -0
  406. data/vendor/activesupport-2.3.8/lib/active_support/xml_mini/rexml.rb +108 -0
  407. data/vendor/activesupport-2.3.8/lib/active_support/xml_mini.rb +31 -0
  408. data/vendor/activesupport-2.3.8/lib/active_support.rb +60 -0
  409. data/vendor/activesupport-2.3.8/lib/activesupport.rb +2 -0
  410. data/vendor/addressable-2.2.1/CHANGELOG +95 -0
  411. data/vendor/addressable-2.2.1/LICENSE +20 -0
  412. data/vendor/addressable-2.2.1/README +60 -0
  413. data/vendor/addressable-2.2.1/Rakefile +42 -0
  414. data/vendor/addressable-2.2.1/lib/addressable/idna.rb +4871 -0
  415. data/vendor/addressable-2.2.1/lib/addressable/template.rb +1049 -0
  416. data/vendor/addressable-2.2.1/lib/addressable/uri.rb +2250 -0
  417. data/vendor/addressable-2.2.1/lib/addressable/version.rb +36 -0
  418. data/vendor/addressable-2.2.1/spec/addressable/idna_spec.rb +194 -0
  419. data/vendor/addressable-2.2.1/spec/addressable/template_spec.rb +2152 -0
  420. data/vendor/addressable-2.2.1/spec/addressable/uri_spec.rb +4203 -0
  421. data/vendor/addressable-2.2.1/spec/data/rfc3986.txt +3419 -0
  422. data/vendor/addressable-2.2.1/tasks/clobber.rake +2 -0
  423. data/vendor/addressable-2.2.1/tasks/gem.rake +84 -0
  424. data/vendor/addressable-2.2.1/tasks/git.rake +40 -0
  425. data/vendor/addressable-2.2.1/tasks/metrics.rake +22 -0
  426. data/vendor/addressable-2.2.1/tasks/rdoc.rake +26 -0
  427. data/vendor/addressable-2.2.1/tasks/rubyforge.rake +89 -0
  428. data/vendor/addressable-2.2.1/tasks/spec.rake +47 -0
  429. data/vendor/addressable-2.2.1/tasks/yard.rake +26 -0
  430. data/vendor/addressable-2.2.1/website/index.html +110 -0
  431. data/vendor/api_ruby_client/Gemfile +10 -0
  432. data/vendor/api_ruby_client/LICENSE +20 -0
  433. data/vendor/api_ruby_client/README +39 -0
  434. data/vendor/api_ruby_client/Rakefile +89 -0
  435. data/vendor/api_ruby_client/abiquo.gemspec +43 -0
  436. data/vendor/api_ruby_client/examples/create_dc_and_hv.rb +38 -0
  437. data/vendor/api_ruby_client/examples/hypervisor_resource.rb +16 -0
  438. data/vendor/api_ruby_client/examples/rack_resource.rb +38 -0
  439. data/vendor/api_ruby_client/lib/abiquo.rb +201 -0
  440. data/vendor/api_ruby_client/lib/core_ext.rb +28 -0
  441. data/vendor/api_ruby_client/lib/to_xml.rb +22 -0
  442. data/vendor/api_ruby_client/spec/acceptance/create_resource_spec.rb +43 -0
  443. data/vendor/api_ruby_client/spec/acceptance/delete_resource_spec.rb +27 -0
  444. data/vendor/api_ruby_client/spec/acceptance/fetch_resource_collections_spec.rb +55 -0
  445. data/vendor/api_ruby_client/spec/acceptance/fetch_single_resources_spec.rb +47 -0
  446. data/vendor/api_ruby_client/spec/acceptance/from_xml_spec.rb +15 -0
  447. data/vendor/api_ruby_client/spec/acceptance/navigate_linked_resources_spec.rb +61 -0
  448. data/vendor/api_ruby_client/spec/acceptance/update_resource_spec.rb +26 -0
  449. data/vendor/api_ruby_client/spec/spec_helper.rb +32 -0
  450. data/vendor/api_ruby_client/spec/unit/to_xml_spec.rb +56 -0
  451. data/vendor/fattr-2.1.0/README +347 -0
  452. data/vendor/fattr-2.1.0/README.erb +82 -0
  453. data/vendor/fattr-2.1.0/Rakefile +242 -0
  454. data/vendor/fattr-2.1.0/a.rb +42 -0
  455. data/vendor/fattr-2.1.0/fattr.gemspec +29 -0
  456. data/vendor/fattr-2.1.0/lib/fattr.rb +193 -0
  457. data/vendor/fattr-2.1.0/samples/a.rb +21 -0
  458. data/vendor/fattr-2.1.0/samples/b.rb +22 -0
  459. data/vendor/fattr-2.1.0/samples/c.rb +12 -0
  460. data/vendor/fattr-2.1.0/samples/d.rb +34 -0
  461. data/vendor/fattr-2.1.0/samples/e.rb +17 -0
  462. data/vendor/fattr-2.1.0/samples/f.rb +21 -0
  463. data/vendor/fattr-2.1.0/samples/g.rb +15 -0
  464. data/vendor/fattr-2.1.0/samples/h.rb +29 -0
  465. data/vendor/fattr-2.1.0/test/fattr.rb +166 -0
  466. data/vendor/httpauth-0.1/LICENSE +16 -0
  467. data/vendor/httpauth-0.1/README +39 -0
  468. data/vendor/httpauth-0.1/Rakefile +76 -0
  469. data/vendor/httpauth-0.1/examples/client_digest_secure +132 -0
  470. data/vendor/httpauth-0.1/examples/server_digest_secure +47 -0
  471. data/vendor/httpauth-0.1/lib/httpauth/basic.rb +114 -0
  472. data/vendor/httpauth-0.1/lib/httpauth/constants.rb +14 -0
  473. data/vendor/httpauth-0.1/lib/httpauth/digest.rb +583 -0
  474. data/vendor/httpauth-0.1/lib/httpauth/exceptions.rb +6 -0
  475. data/vendor/httpauth-0.1/lib/httpauth.rb +4 -0
  476. data/vendor/options-2.3.0/README +186 -0
  477. data/vendor/options-2.3.0/README.erb +35 -0
  478. data/vendor/options-2.3.0/Rakefile +371 -0
  479. data/vendor/options-2.3.0/lib/options.rb +220 -0
  480. data/vendor/options-2.3.0/options.gemspec +26 -0
  481. data/vendor/options-2.3.0/samples/a.rb +15 -0
  482. data/vendor/options-2.3.0/samples/b.rb +50 -0
  483. data/vendor/options-2.3.0/samples/c.rb +20 -0
  484. data/vendor/options-2.3.0/samples/d.rb +17 -0
  485. data/vendor/options-2.3.0/spec/options_spec.rb +38 -0
  486. data/vendor/options-2.3.0/spec/spec_helper.rb +7 -0
  487. data/vendor/resourceful-1.0.1/History.txt +39 -0
  488. data/vendor/resourceful-1.0.1/MIT-LICENSE +21 -0
  489. data/vendor/resourceful-1.0.1/Manifest +43 -0
  490. data/vendor/resourceful-1.0.1/README.markdown +92 -0
  491. data/vendor/resourceful-1.0.1/Rakefile +91 -0
  492. data/vendor/resourceful-1.0.1/lib/resourceful/abstract_form_data.rb +18 -0
  493. data/vendor/resourceful-1.0.1/lib/resourceful/authentication_manager.rb +108 -0
  494. data/vendor/resourceful-1.0.1/lib/resourceful/cache_manager.rb +242 -0
  495. data/vendor/resourceful-1.0.1/lib/resourceful/exceptions.rb +34 -0
  496. data/vendor/resourceful-1.0.1/lib/resourceful/header.rb +355 -0
  497. data/vendor/resourceful-1.0.1/lib/resourceful/http_accessor.rb +103 -0
  498. data/vendor/resourceful-1.0.1/lib/resourceful/memcache_cache_manager.rb +75 -0
  499. data/vendor/resourceful-1.0.1/lib/resourceful/multipart_form_data.rb +46 -0
  500. data/vendor/resourceful-1.0.1/lib/resourceful/net_http_adapter.rb +84 -0
  501. data/vendor/resourceful-1.0.1/lib/resourceful/request.rb +235 -0
  502. data/vendor/resourceful-1.0.1/lib/resourceful/resource.rb +179 -0
  503. data/vendor/resourceful-1.0.1/lib/resourceful/response.rb +221 -0
  504. data/vendor/resourceful-1.0.1/lib/resourceful/simple.rb +36 -0
  505. data/vendor/resourceful-1.0.1/lib/resourceful/stubbed_resource_proxy.rb +47 -0
  506. data/vendor/resourceful-1.0.1/lib/resourceful/urlencoded_form_data.rb +17 -0
  507. data/vendor/resourceful-1.0.1/lib/resourceful/util.rb +6 -0
  508. data/vendor/resourceful-1.0.1/lib/resourceful.rb +26 -0
  509. data/vendor/resourceful-1.0.1/resourceful.gemspec +51 -0
  510. data/vendor/resourceful-1.0.1/spec/acceptance/authorization_spec.rb +16 -0
  511. data/vendor/resourceful-1.0.1/spec/acceptance/caching_spec.rb +190 -0
  512. data/vendor/resourceful-1.0.1/spec/acceptance/header_spec.rb +24 -0
  513. data/vendor/resourceful-1.0.1/spec/acceptance/redirecting_spec.rb +12 -0
  514. data/vendor/resourceful-1.0.1/spec/acceptance/resource_spec.rb +84 -0
  515. data/vendor/resourceful-1.0.1/spec/acceptance/resourceful_spec.rb +56 -0
  516. data/vendor/resourceful-1.0.1/spec/acceptance_shared_specs.rb +44 -0
  517. data/vendor/resourceful-1.0.1/spec/caching_spec.rb +89 -0
  518. data/vendor/resourceful-1.0.1/spec/old_acceptance_specs.rb +378 -0
  519. data/vendor/resourceful-1.0.1/spec/resourceful/header_spec.rb +153 -0
  520. data/vendor/resourceful-1.0.1/spec/resourceful/http_accessor_spec.rb +56 -0
  521. data/vendor/resourceful-1.0.1/spec/resourceful/multipart_form_data_spec.rb +77 -0
  522. data/vendor/resourceful-1.0.1/spec/resourceful/resource_spec.rb +20 -0
  523. data/vendor/resourceful-1.0.1/spec/resourceful/response_spec.rb +51 -0
  524. data/vendor/resourceful-1.0.1/spec/resourceful/urlencoded_form_data_spec.rb +44 -0
  525. data/vendor/resourceful-1.0.1/spec/resourceful_spec.rb +79 -0
  526. data/vendor/resourceful-1.0.1/spec/simple_sinatra_server.rb +74 -0
  527. data/vendor/resourceful-1.0.1/spec/simple_sinatra_server_spec.rb +98 -0
  528. data/vendor/resourceful-1.0.1/spec/spec.opts +3 -0
  529. data/vendor/resourceful-1.0.1/spec/spec_helper.rb +31 -0
  530. metadata +645 -0
@@ -0,0 +1,2250 @@
1
+ # encoding:utf-8
2
+ #--
3
+ # Addressable, Copyright (c) 2006-2010 Bob Aman
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ #++
24
+
25
+ require "addressable/version"
26
+ require "addressable/idna"
27
+
28
+ module Addressable
29
+ ##
30
+ # This is an implementation of a URI parser based on
31
+ # <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>,
32
+ # <a href="http://www.ietf.org/rfc/rfc3987.txt">RFC 3987</a>.
33
+ class URI
34
+ ##
35
+ # Raised if something other than a uri is supplied.
36
+ class InvalidURIError < StandardError
37
+ end
38
+
39
+ ##
40
+ # Container for the character classes specified in
41
+ # <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>.
42
+ module CharacterClasses
43
+ ALPHA = "a-zA-Z"
44
+ DIGIT = "0-9"
45
+ GEN_DELIMS = "\\:\\/\\?\\#\\[\\]\\@"
46
+ SUB_DELIMS = "\\!\\$\\&\\'\\(\\)\\*\\+\\,\\;\\="
47
+ RESERVED = GEN_DELIMS + SUB_DELIMS
48
+ UNRESERVED = ALPHA + DIGIT + "\\-\\.\\_\\~"
49
+ PCHAR = UNRESERVED + SUB_DELIMS + "\\:\\@"
50
+ SCHEME = ALPHA + DIGIT + "\\-\\+\\."
51
+ AUTHORITY = PCHAR
52
+ PATH = PCHAR + "\\/"
53
+ QUERY = PCHAR + "\\/\\?"
54
+ FRAGMENT = PCHAR + "\\/\\?"
55
+ end
56
+
57
+ ##
58
+ # Returns a URI object based on the parsed string.
59
+ #
60
+ # @param [String, Addressable::URI, #to_str] uri
61
+ # The URI string to parse.
62
+ # No parsing is performed if the object is already an
63
+ # <code>Addressable::URI</code>.
64
+ #
65
+ # @return [Addressable::URI] The parsed URI.
66
+ def self.parse(uri)
67
+ # If we were given nil, return nil.
68
+ return nil unless uri
69
+ # If a URI object is passed, just return itself.
70
+ return uri if uri.kind_of?(self)
71
+
72
+ # If a URI object of the Ruby standard library variety is passed,
73
+ # convert it to a string, then parse the string.
74
+ # We do the check this way because we don't want to accidentally
75
+ # cause a missing constant exception to be thrown.
76
+ if uri.class.name =~ /^URI\b/
77
+ uri = uri.to_s
78
+ end
79
+
80
+ if !uri.respond_to?(:to_str)
81
+ raise TypeError, "Can't convert #{uri.class} into String."
82
+ end
83
+ # Otherwise, convert to a String
84
+ uri = uri.to_str
85
+
86
+ # This Regexp supplied as an example in RFC 3986, and it works great.
87
+ uri_regex =
88
+ /^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/
89
+ scan = uri.scan(uri_regex)
90
+ fragments = scan[0]
91
+ scheme = fragments[1]
92
+ authority = fragments[3]
93
+ path = fragments[4]
94
+ query = fragments[6]
95
+ fragment = fragments[8]
96
+ user = nil
97
+ password = nil
98
+ host = nil
99
+ port = nil
100
+ if authority != nil
101
+ # The Regexp above doesn't split apart the authority.
102
+ userinfo = authority[/^([^\[\]]*)@/, 1]
103
+ if userinfo != nil
104
+ user = userinfo.strip[/^([^:]*):?/, 1]
105
+ password = userinfo.strip[/:(.*)$/, 1]
106
+ end
107
+ host = authority.gsub(/^([^\[\]]*)@/, "").gsub(/:([^:@\[\]]*?)$/, "")
108
+ port = authority[/:([^:@\[\]]*?)$/, 1]
109
+ end
110
+ if port == ""
111
+ port = nil
112
+ end
113
+
114
+ return Addressable::URI.new(
115
+ :scheme => scheme,
116
+ :user => user,
117
+ :password => password,
118
+ :host => host,
119
+ :port => port,
120
+ :path => path,
121
+ :query => query,
122
+ :fragment => fragment
123
+ )
124
+ end
125
+
126
+ ##
127
+ # Converts an input to a URI. The input does not have to be a valid
128
+ # URI — the method will use heuristics to guess what URI was intended.
129
+ # This is not standards-compliant, merely user-friendly.
130
+ #
131
+ # @param [String, Addressable::URI, #to_str] uri
132
+ # The URI string to parse.
133
+ # No parsing is performed if the object is already an
134
+ # <code>Addressable::URI</code>.
135
+ # @param [Hash] hints
136
+ # A <code>Hash</code> of hints to the heuristic parser.
137
+ # Defaults to <code>{:scheme => "http"}</code>.
138
+ #
139
+ # @return [Addressable::URI] The parsed URI.
140
+ def self.heuristic_parse(uri, hints={})
141
+ # If we were given nil, return nil.
142
+ return nil unless uri
143
+ # If a URI object is passed, just return itself.
144
+ return uri if uri.kind_of?(self)
145
+ if !uri.respond_to?(:to_str)
146
+ raise TypeError, "Can't convert #{uri.class} into String."
147
+ end
148
+ # Otherwise, convert to a String
149
+ uri = uri.to_str.dup
150
+ hints = {
151
+ :scheme => "http"
152
+ }.merge(hints)
153
+ case uri
154
+ when /^http:\/+/
155
+ uri.gsub!(/^http:\/+/, "http://")
156
+ when /^feed:\/+http:\/+/
157
+ uri.gsub!(/^feed:\/+http:\/+/, "feed:http://")
158
+ when /^feed:\/+/
159
+ uri.gsub!(/^feed:\/+/, "feed://")
160
+ when /^file:\/+/
161
+ uri.gsub!(/^file:\/+/, "file:///")
162
+ end
163
+ parsed = self.parse(uri)
164
+ if parsed.scheme =~ /^[^\/?#\.]+\.[^\/?#]+$/
165
+ parsed = self.parse(hints[:scheme] + "://" + uri)
166
+ end
167
+ if parsed.path.include?(".")
168
+ new_host = parsed.path[/^([^\/]+\.[^\/]*)/, 1]
169
+ if new_host
170
+ parsed.defer_validation do
171
+ new_path = parsed.path.gsub(
172
+ Regexp.new("^" + Regexp.escape(new_host)), "")
173
+ parsed.host = new_host
174
+ parsed.path = new_path
175
+ parsed.scheme = hints[:scheme] unless parsed.scheme
176
+ end
177
+ end
178
+ end
179
+ return parsed
180
+ end
181
+
182
+ ##
183
+ # Converts a path to a file scheme URI. If the path supplied is
184
+ # relative, it will be returned as a relative URI. If the path supplied
185
+ # is actually a non-file URI, it will parse the URI as if it had been
186
+ # parsed with <code>Addressable::URI.parse</code>. Handles all of the
187
+ # various Microsoft-specific formats for specifying paths.
188
+ #
189
+ # @param [String, Addressable::URI, #to_str] path
190
+ # Typically a <code>String</code> path to a file or directory, but
191
+ # will return a sensible return value if an absolute URI is supplied
192
+ # instead.
193
+ #
194
+ # @return [Addressable::URI]
195
+ # The parsed file scheme URI or the original URI if some other URI
196
+ # scheme was provided.
197
+ #
198
+ # @example
199
+ # base = Addressable::URI.convert_path("/absolute/path/")
200
+ # uri = Addressable::URI.convert_path("relative/path")
201
+ # (base + uri).to_s
202
+ # #=> "file:///absolute/path/relative/path"
203
+ #
204
+ # Addressable::URI.convert_path(
205
+ # "c:\\windows\\My Documents 100%20\\foo.txt"
206
+ # ).to_s
207
+ # #=> "file:///c:/windows/My%20Documents%20100%20/foo.txt"
208
+ #
209
+ # Addressable::URI.convert_path("http://example.com/").to_s
210
+ # #=> "http://example.com/"
211
+ def self.convert_path(path)
212
+ # If we were given nil, return nil.
213
+ return nil unless path
214
+ # If a URI object is passed, just return itself.
215
+ return path if path.kind_of?(self)
216
+ if !path.respond_to?(:to_str)
217
+ raise TypeError, "Can't convert #{path.class} into String."
218
+ end
219
+ # Otherwise, convert to a String
220
+ path = path.to_str.strip
221
+
222
+ path.gsub!(/^file:\/?\/?/, "") if path =~ /^file:\/?\/?/
223
+ path = "/" + path if path =~ /^([a-zA-Z])[\|:]/
224
+ uri = self.parse(path)
225
+
226
+ if uri.scheme == nil
227
+ # Adjust windows-style uris
228
+ uri.path.gsub!(/^\/?([a-zA-Z])[\|:][\\\/]/) do
229
+ "/#{$1.downcase}:/"
230
+ end
231
+ uri.path.gsub!(/\\/, "/")
232
+ if File.exists?(uri.path) &&
233
+ File.stat(uri.path).directory?
234
+ uri.path.gsub!(/\/$/, "")
235
+ uri.path = uri.path + '/'
236
+ end
237
+
238
+ # If the path is absolute, set the scheme and host.
239
+ if uri.path =~ /^\//
240
+ uri.scheme = "file"
241
+ uri.host = ""
242
+ end
243
+ uri.normalize!
244
+ end
245
+
246
+ return uri
247
+ end
248
+
249
+ ##
250
+ # Joins several URIs together.
251
+ #
252
+ # @param [String, Addressable::URI, #to_str] *uris
253
+ # The URIs to join.
254
+ #
255
+ # @return [Addressable::URI] The joined URI.
256
+ #
257
+ # @example
258
+ # base = "http://example.com/"
259
+ # uri = Addressable::URI.parse("relative/path")
260
+ # Addressable::URI.join(base, uri)
261
+ # #=> #<Addressable::URI:0xcab390 URI:http://example.com/relative/path>
262
+ def self.join(*uris)
263
+ uri_objects = uris.collect do |uri|
264
+ if !uri.respond_to?(:to_str)
265
+ raise TypeError, "Can't convert #{uri.class} into String."
266
+ end
267
+ uri.kind_of?(self) ? uri : self.parse(uri.to_str)
268
+ end
269
+ result = uri_objects.shift.dup
270
+ for uri in uri_objects
271
+ result.join!(uri)
272
+ end
273
+ return result
274
+ end
275
+
276
+ ##
277
+ # Percent encodes a URI component.
278
+ #
279
+ # @param [String, #to_str] component The URI component to encode.
280
+ #
281
+ # @param [String, Regexp] character_class
282
+ # The characters which are not percent encoded. If a <code>String</code>
283
+ # is passed, the <code>String</code> must be formatted as a regular
284
+ # expression character class. (Do not include the surrounding square
285
+ # brackets.) For example, <code>"b-zB-Z0-9"</code> would cause
286
+ # everything but the letters 'b' through 'z' and the numbers '0' through
287
+ # '9' to be percent encoded. If a <code>Regexp</code> is passed, the
288
+ # value <code>/[^b-zB-Z0-9]/</code> would have the same effect. A set of
289
+ # useful <code>String</code> values may be found in the
290
+ # <code>Addressable::URI::CharacterClasses</code> module. The default
291
+ # value is the reserved plus unreserved character classes specified in
292
+ # <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>.
293
+ #
294
+ # @return [String] The encoded component.
295
+ #
296
+ # @example
297
+ # Addressable::URI.encode_component("simple/example", "b-zB-Z0-9")
298
+ # => "simple%2Fex%61mple"
299
+ # Addressable::URI.encode_component("simple/example", /[^b-zB-Z0-9]/)
300
+ # => "simple%2Fex%61mple"
301
+ # Addressable::URI.encode_component(
302
+ # "simple/example", Addressable::URI::CharacterClasses::UNRESERVED
303
+ # )
304
+ # => "simple%2Fexample"
305
+ def self.encode_component(component, character_class=
306
+ CharacterClasses::RESERVED + CharacterClasses::UNRESERVED)
307
+ return nil if component.nil?
308
+ if !component.respond_to?(:to_str)
309
+ raise TypeError, "Can't convert #{component.class} into String."
310
+ end
311
+ component = component.to_str
312
+ if ![String, Regexp].include?(character_class.class)
313
+ raise TypeError,
314
+ "Expected String or Regexp, got #{character_class.inspect}"
315
+ end
316
+ if character_class.kind_of?(String)
317
+ character_class = /[^#{character_class}]/
318
+ end
319
+ if component.respond_to?(:force_encoding)
320
+ # We can't perform regexps on invalid UTF sequences, but
321
+ # here we need to, so switch to ASCII.
322
+ component = component.dup
323
+ component.force_encoding(Encoding::ASCII_8BIT)
324
+ end
325
+ return component.gsub(character_class) do |sequence|
326
+ (sequence.unpack('C*').map { |c| "%" + ("%02x" % c).upcase }).join("")
327
+ end
328
+ end
329
+
330
+ class << self
331
+ alias_method :encode_component, :encode_component
332
+ end
333
+
334
+ ##
335
+ # Unencodes any percent encoded characters within a URI component.
336
+ # This method may be used for unencoding either components or full URIs,
337
+ # however, it is recommended to use the <code>unencode_component</code>
338
+ # alias when unencoding components.
339
+ #
340
+ # @param [String, Addressable::URI, #to_str] uri
341
+ # The URI or component to unencode.
342
+ #
343
+ # @param [Class] returning
344
+ # The type of object to return.
345
+ # This value may only be set to <code>String</code> or
346
+ # <code>Addressable::URI</code>. All other values are invalid. Defaults
347
+ # to <code>String</code>.
348
+ #
349
+ # @return [String, Addressable::URI]
350
+ # The unencoded component or URI.
351
+ # The return type is determined by the <code>returning</code> parameter.
352
+ def self.unencode(uri, returning=String)
353
+ return nil if uri.nil?
354
+ if !uri.respond_to?(:to_str)
355
+ raise TypeError, "Can't convert #{uri.class} into String."
356
+ end
357
+ if ![String, ::Addressable::URI].include?(returning)
358
+ raise TypeError,
359
+ "Expected Class (String or Addressable::URI), " +
360
+ "got #{returning.inspect}"
361
+ end
362
+ result = uri.to_str.gsub(/%[0-9a-f]{2}/i) do |sequence|
363
+ sequence[1..3].to_i(16).chr
364
+ end
365
+ result.force_encoding("utf-8") if result.respond_to?(:force_encoding)
366
+ if returning == String
367
+ return result
368
+ elsif returning == ::Addressable::URI
369
+ return ::Addressable::URI.parse(result)
370
+ end
371
+ end
372
+
373
+ class << self
374
+ alias_method :unescape, :unencode
375
+ alias_method :unencode_component, :unencode
376
+ alias_method :unescape_component, :unencode
377
+ end
378
+
379
+
380
+ ##
381
+ # Normalizes the encoding of a URI component.
382
+ #
383
+ # @param [String, #to_str] component The URI component to encode.
384
+ #
385
+ # @param [String, Regexp] character_class
386
+ # The characters which are not percent encoded. If a <code>String</code>
387
+ # is passed, the <code>String</code> must be formatted as a regular
388
+ # expression character class. (Do not include the surrounding square
389
+ # brackets.) For example, <code>"b-zB-Z0-9"</code> would cause
390
+ # everything but the letters 'b' through 'z' and the numbers '0' through
391
+ # '9' to be percent encoded. If a <code>Regexp</code> is passed, the
392
+ # value <code>/[^b-zB-Z0-9]/</code> would have the same effect. A set of
393
+ # useful <code>String</code> values may be found in the
394
+ # <code>Addressable::URI::CharacterClasses</code> module. The default
395
+ # value is the reserved plus unreserved character classes specified in
396
+ # <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>.
397
+ #
398
+ # @return [String] The normalized component.
399
+ #
400
+ # @example
401
+ # Addressable::URI.normalize_component("simpl%65/%65xampl%65", "b-zB-Z")
402
+ # => "simple%2Fex%61mple"
403
+ # Addressable::URI.normalize_component(
404
+ # "simpl%65/%65xampl%65", /[^b-zB-Z]/
405
+ # )
406
+ # => "simple%2Fex%61mple"
407
+ # Addressable::URI.normalize_component(
408
+ # "simpl%65/%65xampl%65",
409
+ # Addressable::URI::CharacterClasses::UNRESERVED
410
+ # )
411
+ # => "simple%2Fexample"
412
+ def self.normalize_component(component, character_class=
413
+ CharacterClasses::RESERVED + CharacterClasses::UNRESERVED)
414
+ return nil if component.nil?
415
+ if !component.respond_to?(:to_str)
416
+ raise TypeError, "Can't convert #{component.class} into String."
417
+ end
418
+ component = component.to_str
419
+ if ![String, Regexp].include?(character_class.class)
420
+ raise TypeError,
421
+ "Expected String or Regexp, got #{character_class.inspect}"
422
+ end
423
+ if character_class.kind_of?(String)
424
+ character_class = /[^#{character_class}]/
425
+ end
426
+ if component.respond_to?(:force_encoding)
427
+ # We can't perform regexps on invalid UTF sequences, but
428
+ # here we need to, so switch to ASCII.
429
+ component = component.dup
430
+ component.force_encoding(Encoding::ASCII_8BIT)
431
+ end
432
+ unencoded = self.unencode_component(component)
433
+ begin
434
+ encoded = self.encode_component(
435
+ Addressable::IDNA.unicode_normalize_kc(unencoded),
436
+ character_class
437
+ )
438
+ rescue ArgumentError
439
+ encoded = self.encode_component(unencoded)
440
+ end
441
+ return encoded
442
+ end
443
+
444
+ ##
445
+ # Percent encodes any special characters in the URI.
446
+ #
447
+ # @param [String, Addressable::URI, #to_str] uri
448
+ # The URI to encode.
449
+ #
450
+ # @param [Class] returning
451
+ # The type of object to return.
452
+ # This value may only be set to <code>String</code> or
453
+ # <code>Addressable::URI</code>. All other values are invalid. Defaults
454
+ # to <code>String</code>.
455
+ #
456
+ # @return [String, Addressable::URI]
457
+ # The encoded URI.
458
+ # The return type is determined by the <code>returning</code> parameter.
459
+ def self.encode(uri, returning=String)
460
+ return nil if uri.nil?
461
+ if !uri.respond_to?(:to_str)
462
+ raise TypeError, "Can't convert #{uri.class} into String."
463
+ end
464
+ if ![String, ::Addressable::URI].include?(returning)
465
+ raise TypeError,
466
+ "Expected Class (String or Addressable::URI), " +
467
+ "got #{returning.inspect}"
468
+ end
469
+ uri_object = uri.kind_of?(self) ? uri : self.parse(uri.to_str)
470
+ encoded_uri = Addressable::URI.new(
471
+ :scheme => self.encode_component(uri_object.scheme,
472
+ Addressable::URI::CharacterClasses::SCHEME),
473
+ :authority => self.encode_component(uri_object.authority,
474
+ Addressable::URI::CharacterClasses::AUTHORITY),
475
+ :path => self.encode_component(uri_object.path,
476
+ Addressable::URI::CharacterClasses::PATH),
477
+ :query => self.encode_component(uri_object.query,
478
+ Addressable::URI::CharacterClasses::QUERY),
479
+ :fragment => self.encode_component(uri_object.fragment,
480
+ Addressable::URI::CharacterClasses::FRAGMENT)
481
+ )
482
+ if returning == String
483
+ return encoded_uri.to_s
484
+ elsif returning == ::Addressable::URI
485
+ return encoded_uri
486
+ end
487
+ end
488
+
489
+ class << self
490
+ alias_method :escape, :encode
491
+ end
492
+
493
+ ##
494
+ # Normalizes the encoding of a URI. Characters within a hostname are
495
+ # not percent encoded to allow for internationalized domain names.
496
+ #
497
+ # @param [String, Addressable::URI, #to_str] uri
498
+ # The URI to encode.
499
+ #
500
+ # @param [Class] returning
501
+ # The type of object to return.
502
+ # This value may only be set to <code>String</code> or
503
+ # <code>Addressable::URI</code>. All other values are invalid. Defaults
504
+ # to <code>String</code>.
505
+ #
506
+ # @return [String, Addressable::URI]
507
+ # The encoded URI.
508
+ # The return type is determined by the <code>returning</code> parameter.
509
+ def self.normalized_encode(uri, returning=String)
510
+ if !uri.respond_to?(:to_str)
511
+ raise TypeError, "Can't convert #{uri.class} into String."
512
+ end
513
+ if ![String, ::Addressable::URI].include?(returning)
514
+ raise TypeError,
515
+ "Expected Class (String or Addressable::URI), " +
516
+ "got #{returning.inspect}"
517
+ end
518
+ uri_object = uri.kind_of?(self) ? uri : self.parse(uri.to_str)
519
+ components = {
520
+ :scheme => self.unencode_component(uri_object.scheme),
521
+ :user => self.unencode_component(uri_object.user),
522
+ :password => self.unencode_component(uri_object.password),
523
+ :host => self.unencode_component(uri_object.host),
524
+ :port => uri_object.port,
525
+ :path => self.unencode_component(uri_object.path),
526
+ :query => self.unencode_component(uri_object.query),
527
+ :fragment => self.unencode_component(uri_object.fragment)
528
+ }
529
+ components.each do |key, value|
530
+ if value != nil
531
+ begin
532
+ components[key] =
533
+ Addressable::IDNA.unicode_normalize_kc(value.to_str)
534
+ rescue ArgumentError
535
+ # Likely a malformed UTF-8 character, skip unicode normalization
536
+ components[key] = value.to_str
537
+ end
538
+ end
539
+ end
540
+ encoded_uri = Addressable::URI.new(
541
+ :scheme => self.encode_component(components[:scheme],
542
+ Addressable::URI::CharacterClasses::SCHEME),
543
+ :user => self.encode_component(components[:user],
544
+ Addressable::URI::CharacterClasses::UNRESERVED),
545
+ :password => self.encode_component(components[:password],
546
+ Addressable::URI::CharacterClasses::UNRESERVED),
547
+ :host => components[:host],
548
+ :port => components[:port],
549
+ :path => self.encode_component(components[:path],
550
+ Addressable::URI::CharacterClasses::PATH),
551
+ :query => self.encode_component(components[:query],
552
+ Addressable::URI::CharacterClasses::QUERY),
553
+ :fragment => self.encode_component(components[:fragment],
554
+ Addressable::URI::CharacterClasses::FRAGMENT)
555
+ )
556
+ if returning == String
557
+ return encoded_uri.to_s
558
+ elsif returning == ::Addressable::URI
559
+ return encoded_uri
560
+ end
561
+ end
562
+
563
+ ##
564
+ # Encodes a set of key/value pairs according to the rules for the
565
+ # <code>application/x-www-form-urlencoded</code> MIME type.
566
+ #
567
+ # @param [#to_hash, #to_ary] form_values
568
+ # The form values to encode.
569
+ #
570
+ # @param [TrueClass, FalseClass] sort
571
+ # Sort the key/value pairs prior to encoding.
572
+ # Defaults to <code>false</code>.
573
+ #
574
+ # @return [String]
575
+ # The encoded value.
576
+ def self.form_encode(form_values, sort=false)
577
+ if form_values.respond_to?(:to_hash)
578
+ form_values = form_values.to_hash.to_a
579
+ elsif form_values.respond_to?(:to_ary)
580
+ form_values = form_values.to_ary
581
+ else
582
+ raise TypeError, "Can't convert #{form_values.class} into Array."
583
+ end
584
+ form_values = form_values.map do |(key, value)|
585
+ [key.to_s, value.to_s]
586
+ end
587
+ if sort
588
+ # Useful for OAuth and optimizing caching systems
589
+ form_values = form_values.sort
590
+ end
591
+ escaped_form_values = form_values.map do |(key, value)|
592
+ # Line breaks are CRLF pairs
593
+ [
594
+ self.encode_component(
595
+ key.gsub(/(\r\n|\n|\r)/, "\r\n"),
596
+ CharacterClasses::UNRESERVED
597
+ ).gsub("%20", "+"),
598
+ self.encode_component(
599
+ value.gsub(/(\r\n|\n|\r)/, "\r\n"),
600
+ CharacterClasses::UNRESERVED
601
+ ).gsub("%20", "+")
602
+ ]
603
+ end
604
+ return (escaped_form_values.map do |(key, value)|
605
+ "#{key}=#{value}"
606
+ end).join("&")
607
+ end
608
+
609
+ ##
610
+ # Decodes a <code>String</code> according to the rules for the
611
+ # <code>application/x-www-form-urlencoded</code> MIME type.
612
+ #
613
+ # @param [String, #to_str] encoded_value
614
+ # The form values to decode.
615
+ #
616
+ # @return [Array]
617
+ # The decoded values.
618
+ # This is not a <code>Hash</code> because of the possibility for
619
+ # duplicate keys.
620
+ def self.form_unencode(encoded_value)
621
+ if !encoded_value.respond_to?(:to_str)
622
+ raise TypeError, "Can't convert #{encoded_value.class} into String."
623
+ end
624
+ encoded_value = encoded_value.to_str
625
+ split_values = encoded_value.split("&").map do |pair|
626
+ pair.split("=", 2)
627
+ end
628
+ return split_values.map do |(key, value)|
629
+ [
630
+ key ? self.unencode_component(
631
+ key.gsub("+", "%20")).gsub(/(\r\n|\n|\r)/, "\n") : nil,
632
+ value ? (self.unencode_component(
633
+ value.gsub("+", "%20")).gsub(/(\r\n|\n|\r)/, "\n")) : nil
634
+ ]
635
+ end
636
+ end
637
+
638
+ ##
639
+ # Creates a new uri object from component parts.
640
+ #
641
+ # @option [String, #to_str] scheme The scheme component.
642
+ # @option [String, #to_str] user The user component.
643
+ # @option [String, #to_str] password The password component.
644
+ # @option [String, #to_str] userinfo
645
+ # The userinfo component. If this is supplied, the user and password
646
+ # components must be omitted.
647
+ # @option [String, #to_str] host The host component.
648
+ # @option [String, #to_str] port The port component.
649
+ # @option [String, #to_str] authority
650
+ # The authority component. If this is supplied, the user, password,
651
+ # userinfo, host, and port components must be omitted.
652
+ # @option [String, #to_str] path The path component.
653
+ # @option [String, #to_str] query The query component.
654
+ # @option [String, #to_str] fragment The fragment component.
655
+ #
656
+ # @return [Addressable::URI] The constructed URI object.
657
+ def initialize(options={})
658
+ if options.has_key?(:authority)
659
+ if (options.keys & [:userinfo, :user, :password, :host, :port]).any?
660
+ raise ArgumentError,
661
+ "Cannot specify both an authority and any of the components " +
662
+ "within the authority."
663
+ end
664
+ end
665
+ if options.has_key?(:userinfo)
666
+ if (options.keys & [:user, :password]).any?
667
+ raise ArgumentError,
668
+ "Cannot specify both a userinfo and either the user or password."
669
+ end
670
+ end
671
+
672
+ self.defer_validation do
673
+ # Bunch of crazy logic required because of the composite components
674
+ # like userinfo and authority.
675
+ self.scheme = options[:scheme] if options[:scheme]
676
+ self.user = options[:user] if options[:user]
677
+ self.password = options[:password] if options[:password]
678
+ self.userinfo = options[:userinfo] if options[:userinfo]
679
+ self.host = options[:host] if options[:host]
680
+ self.port = options[:port] if options[:port]
681
+ self.authority = options[:authority] if options[:authority]
682
+ self.path = options[:path] if options[:path]
683
+ self.query = options[:query] if options[:query]
684
+ self.fragment = options[:fragment] if options[:fragment]
685
+ end
686
+ end
687
+
688
+ ##
689
+ # The scheme component for this URI.
690
+ #
691
+ # @return [String] The scheme component.
692
+ def scheme
693
+ return @scheme ||= nil
694
+ end
695
+
696
+ ##
697
+ # The scheme component for this URI, normalized.
698
+ #
699
+ # @return [String] The scheme component, normalized.
700
+ def normalized_scheme
701
+ @normalized_scheme ||= (begin
702
+ if self.scheme != nil
703
+ if self.scheme =~ /^\s*ssh\+svn\s*$/i
704
+ "svn+ssh"
705
+ else
706
+ Addressable::URI.normalize_component(
707
+ self.scheme.strip.downcase,
708
+ Addressable::URI::CharacterClasses::SCHEME
709
+ )
710
+ end
711
+ else
712
+ nil
713
+ end
714
+ end)
715
+ end
716
+
717
+ ##
718
+ # Sets the scheme component for this URI.
719
+ #
720
+ # @param [String, #to_str] new_scheme The new scheme component.
721
+ def scheme=(new_scheme)
722
+ # Check for frozenness
723
+ raise TypeError, "Can't modify frozen URI." if self.frozen?
724
+
725
+ if new_scheme && !new_scheme.respond_to?(:to_str)
726
+ raise TypeError, "Can't convert #{new_scheme.class} into String."
727
+ elsif new_scheme
728
+ new_scheme = new_scheme.to_str
729
+ end
730
+ if new_scheme && new_scheme !~ /[a-z][a-z0-9\.\+\-]*/i
731
+ raise InvalidURIError, "Invalid scheme format."
732
+ end
733
+ @scheme = new_scheme
734
+ @scheme = nil if @scheme.to_s.strip == ""
735
+
736
+ # Reset dependant values
737
+ @normalized_scheme = nil
738
+ @uri_string = nil
739
+ @hash = nil
740
+
741
+ # Ensure we haven't created an invalid URI
742
+ validate()
743
+ end
744
+
745
+ ##
746
+ # The user component for this URI.
747
+ #
748
+ # @return [String] The user component.
749
+ def user
750
+ return @user ||= nil
751
+ end
752
+
753
+ ##
754
+ # The user component for this URI, normalized.
755
+ #
756
+ # @return [String] The user component, normalized.
757
+ def normalized_user
758
+ @normalized_user ||= (begin
759
+ if self.user
760
+ if normalized_scheme =~ /https?/ && self.user.strip == "" &&
761
+ (!self.password || self.password.strip == "")
762
+ nil
763
+ else
764
+ Addressable::URI.normalize_component(
765
+ self.user.strip,
766
+ Addressable::URI::CharacterClasses::UNRESERVED
767
+ )
768
+ end
769
+ else
770
+ nil
771
+ end
772
+ end)
773
+ end
774
+
775
+ ##
776
+ # Sets the user component for this URI.
777
+ #
778
+ # @param [String, #to_str] new_user The new user component.
779
+ def user=(new_user)
780
+ # Check for frozenness
781
+ raise TypeError, "Can't modify frozen URI." if self.frozen?
782
+
783
+ if new_user && !new_user.respond_to?(:to_str)
784
+ raise TypeError, "Can't convert #{new_user.class} into String."
785
+ end
786
+ @user = new_user ? new_user.to_str : nil
787
+
788
+ # You can't have a nil user with a non-nil password
789
+ @password ||= nil
790
+ if @password != nil
791
+ @user = "" if @user.nil?
792
+ end
793
+
794
+ # Reset dependant values
795
+ @userinfo = nil
796
+ @normalized_userinfo = nil
797
+ @authority = nil
798
+ @normalized_user = nil
799
+ @uri_string = nil
800
+ @hash = nil
801
+
802
+ # Ensure we haven't created an invalid URI
803
+ validate()
804
+ end
805
+
806
+ ##
807
+ # The password component for this URI.
808
+ #
809
+ # @return [String] The password component.
810
+ def password
811
+ return @password ||= nil
812
+ end
813
+
814
+ ##
815
+ # The password component for this URI, normalized.
816
+ #
817
+ # @return [String] The password component, normalized.
818
+ def normalized_password
819
+ @normalized_password ||= (begin
820
+ if self.password
821
+ if normalized_scheme =~ /https?/ && self.password.strip == "" &&
822
+ (!self.user || self.user.strip == "")
823
+ nil
824
+ else
825
+ Addressable::URI.normalize_component(
826
+ self.password.strip,
827
+ Addressable::URI::CharacterClasses::UNRESERVED
828
+ )
829
+ end
830
+ else
831
+ nil
832
+ end
833
+ end)
834
+ end
835
+
836
+ ##
837
+ # Sets the password component for this URI.
838
+ #
839
+ # @param [String, #to_str] new_password The new password component.
840
+ def password=(new_password)
841
+ # Check for frozenness
842
+ raise TypeError, "Can't modify frozen URI." if self.frozen?
843
+
844
+ if new_password && !new_password.respond_to?(:to_str)
845
+ raise TypeError, "Can't convert #{new_password.class} into String."
846
+ end
847
+ @password = new_password ? new_password.to_str : nil
848
+
849
+ # You can't have a nil user with a non-nil password
850
+ @password ||= nil
851
+ @user ||= nil
852
+ if @password != nil
853
+ @user = "" if @user.nil?
854
+ end
855
+
856
+ # Reset dependant values
857
+ @userinfo = nil
858
+ @normalized_userinfo = nil
859
+ @authority = nil
860
+ @normalized_password = nil
861
+ @uri_string = nil
862
+ @hash = nil
863
+
864
+ # Ensure we haven't created an invalid URI
865
+ validate()
866
+ end
867
+
868
+ ##
869
+ # The userinfo component for this URI.
870
+ # Combines the user and password components.
871
+ #
872
+ # @return [String] The userinfo component.
873
+ def userinfo
874
+ @userinfo ||= (begin
875
+ current_user = self.user
876
+ current_password = self.password
877
+ if !current_user && !current_password
878
+ nil
879
+ elsif current_user && current_password
880
+ "#{current_user}:#{current_password}"
881
+ elsif current_user && !current_password
882
+ "#{current_user}"
883
+ end
884
+ end)
885
+ end
886
+
887
+ ##
888
+ # The userinfo component for this URI, normalized.
889
+ #
890
+ # @return [String] The userinfo component, normalized.
891
+ def normalized_userinfo
892
+ @normalized_userinfo ||= (begin
893
+ current_user = self.normalized_user
894
+ current_password = self.normalized_password
895
+ if !current_user && !current_password
896
+ nil
897
+ elsif current_user && current_password
898
+ "#{current_user}:#{current_password}"
899
+ elsif current_user && !current_password
900
+ "#{current_user}"
901
+ end
902
+ end)
903
+ end
904
+
905
+ ##
906
+ # Sets the userinfo component for this URI.
907
+ #
908
+ # @param [String, #to_str] new_userinfo The new userinfo component.
909
+ def userinfo=(new_userinfo)
910
+ # Check for frozenness
911
+ raise TypeError, "Can't modify frozen URI." if self.frozen?
912
+
913
+ if new_userinfo && !new_userinfo.respond_to?(:to_str)
914
+ raise TypeError, "Can't convert #{new_userinfo.class} into String."
915
+ end
916
+ new_user, new_password = if new_userinfo
917
+ [
918
+ new_userinfo.to_str.strip[/^(.*):/, 1],
919
+ new_userinfo.to_str.strip[/:(.*)$/, 1]
920
+ ]
921
+ else
922
+ [nil, nil]
923
+ end
924
+
925
+ # Password assigned first to ensure validity in case of nil
926
+ self.password = new_password
927
+ self.user = new_user
928
+
929
+ # Reset dependant values
930
+ @authority = nil
931
+ @uri_string = nil
932
+ @hash = nil
933
+
934
+ # Ensure we haven't created an invalid URI
935
+ validate()
936
+ end
937
+
938
+ ##
939
+ # The host component for this URI.
940
+ #
941
+ # @return [String] The host component.
942
+ def host
943
+ return @host ||= nil
944
+ end
945
+
946
+ ##
947
+ # The host component for this URI, normalized.
948
+ #
949
+ # @return [String] The host component, normalized.
950
+ def normalized_host
951
+ @normalized_host ||= (begin
952
+ if self.host != nil
953
+ if self.host.strip != ""
954
+ result = ::Addressable::IDNA.to_ascii(
955
+ self.class.unencode_component(self.host.strip.downcase)
956
+ )
957
+ if result[-1..-1] == "."
958
+ # Trailing dots are unnecessary
959
+ result = result[0...-1]
960
+ end
961
+ result
962
+ else
963
+ ""
964
+ end
965
+ else
966
+ nil
967
+ end
968
+ end)
969
+ end
970
+
971
+ ##
972
+ # Sets the host component for this URI.
973
+ #
974
+ # @param [String, #to_str] new_host The new host component.
975
+ def host=(new_host)
976
+ # Check for frozenness
977
+ raise TypeError, "Can't modify frozen URI." if self.frozen?
978
+
979
+ if new_host && !new_host.respond_to?(:to_str)
980
+ raise TypeError, "Can't convert #{new_host.class} into String."
981
+ end
982
+ @host = new_host ? new_host.to_str : nil
983
+
984
+ # Reset dependant values
985
+ @authority = nil
986
+ @normalized_host = nil
987
+ @uri_string = nil
988
+ @hash = nil
989
+
990
+ # Ensure we haven't created an invalid URI
991
+ validate()
992
+ end
993
+
994
+ ##
995
+ # The authority component for this URI.
996
+ # Combines the user, password, host, and port components.
997
+ #
998
+ # @return [String] The authority component.
999
+ def authority
1000
+ @authority ||= (begin
1001
+ if self.host.nil?
1002
+ nil
1003
+ else
1004
+ authority = ""
1005
+ if self.userinfo != nil
1006
+ authority << "#{self.userinfo}@"
1007
+ end
1008
+ authority << self.host
1009
+ if self.port != nil
1010
+ authority << ":#{self.port}"
1011
+ end
1012
+ authority
1013
+ end
1014
+ end)
1015
+ end
1016
+
1017
+ ##
1018
+ # The authority component for this URI, normalized.
1019
+ #
1020
+ # @return [String] The authority component, normalized.
1021
+ def normalized_authority
1022
+ @normalized_authority ||= (begin
1023
+ if self.normalized_host.nil?
1024
+ nil
1025
+ else
1026
+ authority = ""
1027
+ if self.normalized_userinfo != nil
1028
+ authority << "#{self.normalized_userinfo}@"
1029
+ end
1030
+ authority << self.normalized_host
1031
+ if self.normalized_port != nil
1032
+ authority << ":#{self.normalized_port}"
1033
+ end
1034
+ authority
1035
+ end
1036
+ end)
1037
+ end
1038
+
1039
+ ##
1040
+ # Sets the authority component for this URI.
1041
+ #
1042
+ # @param [String, #to_str] new_authority The new authority component.
1043
+ def authority=(new_authority)
1044
+ # Check for frozenness
1045
+ raise TypeError, "Can't modify frozen URI." if self.frozen?
1046
+
1047
+ if new_authority
1048
+ if !new_authority.respond_to?(:to_str)
1049
+ raise TypeError, "Can't convert #{new_authority.class} into String."
1050
+ end
1051
+ new_authority = new_authority.to_str
1052
+ new_userinfo = new_authority[/^([^\[\]]*)@/, 1]
1053
+ if new_userinfo
1054
+ new_user = new_userinfo.strip[/^([^:]*):?/, 1]
1055
+ new_password = new_userinfo.strip[/:(.*)$/, 1]
1056
+ end
1057
+ new_host =
1058
+ new_authority.gsub(/^([^\[\]]*)@/, "").gsub(/:([^:@\[\]]*?)$/, "")
1059
+ new_port =
1060
+ new_authority[/:([^:@\[\]]*?)$/, 1]
1061
+ end
1062
+
1063
+ # Password assigned first to ensure validity in case of nil
1064
+ self.password = defined?(new_password) ? new_password : nil
1065
+ self.user = defined?(new_user) ? new_user : nil
1066
+ self.host = defined?(new_host) ? new_host : nil
1067
+ self.port = defined?(new_port) ? new_port : nil
1068
+
1069
+ # Reset dependant values
1070
+ @inferred_port = nil
1071
+ @userinfo = nil
1072
+ @normalized_userinfo = nil
1073
+ @uri_string = nil
1074
+ @hash = nil
1075
+
1076
+ # Ensure we haven't created an invalid URI
1077
+ validate()
1078
+ end
1079
+
1080
+ # Returns an array of known ip-based schemes. These schemes typically
1081
+ # use a similar URI form:
1082
+ # <code>//<user>:<password>@<host>:<port>/<url-path></code>
1083
+ def self.ip_based_schemes
1084
+ return self.port_mapping.keys
1085
+ end
1086
+
1087
+ # Returns a hash of common IP-based schemes and their default port
1088
+ # numbers. Adding new schemes to this hash, as necessary, will allow
1089
+ # for better URI normalization.
1090
+ def self.port_mapping
1091
+ @port_mapping ||= {
1092
+ "http" => 80,
1093
+ "https" => 443,
1094
+ "ftp" => 21,
1095
+ "tftp" => 69,
1096
+ "sftp" => 22,
1097
+ "ssh" => 22,
1098
+ "svn+ssh" => 22,
1099
+ "telnet" => 23,
1100
+ "nntp" => 119,
1101
+ "gopher" => 70,
1102
+ "wais" => 210,
1103
+ "ldap" => 389,
1104
+ "prospero" => 1525
1105
+ }
1106
+ end
1107
+
1108
+ ##
1109
+ # The port component for this URI.
1110
+ # This is the port number actually given in the URI. This does not
1111
+ # infer port numbers from default values.
1112
+ #
1113
+ # @return [Integer] The port component.
1114
+ def port
1115
+ return @port ||= nil
1116
+ end
1117
+
1118
+ ##
1119
+ # The port component for this URI, normalized.
1120
+ #
1121
+ # @return [Integer] The port component, normalized.
1122
+ def normalized_port
1123
+ @normalized_port ||= (begin
1124
+ if self.class.port_mapping[normalized_scheme] == self.port
1125
+ nil
1126
+ else
1127
+ self.port
1128
+ end
1129
+ end)
1130
+ end
1131
+
1132
+ ##
1133
+ # Sets the port component for this URI.
1134
+ #
1135
+ # @param [String, Integer, #to_s] new_port The new port component.
1136
+ def port=(new_port)
1137
+ # Check for frozenness
1138
+ raise TypeError, "Can't modify frozen URI." if self.frozen?
1139
+
1140
+ if new_port != nil && new_port.respond_to?(:to_str)
1141
+ new_port = Addressable::URI.unencode_component(new_port.to_str)
1142
+ end
1143
+ if new_port != nil && !(new_port.to_s =~ /^\d+$/)
1144
+ raise InvalidURIError,
1145
+ "Invalid port number: #{new_port.inspect}"
1146
+ end
1147
+
1148
+ @port = new_port.to_s.to_i
1149
+ @port = nil if @port == 0
1150
+
1151
+ # Reset dependant values
1152
+ @authority = nil
1153
+ @inferred_port = nil
1154
+ @normalized_port = nil
1155
+ @uri_string = nil
1156
+ @hash = nil
1157
+
1158
+ # Ensure we haven't created an invalid URI
1159
+ validate()
1160
+ end
1161
+
1162
+ ##
1163
+ # The inferred port component for this URI.
1164
+ # This method will normalize to the default port for the URI's scheme if
1165
+ # the port isn't explicitly specified in the URI.
1166
+ #
1167
+ # @return [Integer] The inferred port component.
1168
+ def inferred_port
1169
+ @inferred_port ||= (begin
1170
+ if port.to_i == 0
1171
+ if scheme
1172
+ self.class.port_mapping[scheme.strip.downcase]
1173
+ else
1174
+ nil
1175
+ end
1176
+ else
1177
+ port.to_i
1178
+ end
1179
+ end)
1180
+ end
1181
+
1182
+ ##
1183
+ # The combination of components that represent a site.
1184
+ # Combines the scheme, user, password, host, and port components.
1185
+ # Primarily useful for HTTP and HTTPS.
1186
+ #
1187
+ # For example, <code>"http://example.com/path?query"</code> would have a
1188
+ # <code>site</code> value of <code>"http://example.com"</code>.
1189
+ #
1190
+ # @return [String] The components that identify a site.
1191
+ def site
1192
+ @site ||= (begin
1193
+ if self.scheme || self.authority
1194
+ site_string = ""
1195
+ site_string << "#{self.scheme}:" if self.scheme != nil
1196
+ site_string << "//#{self.authority}" if self.authority != nil
1197
+ site_string
1198
+ else
1199
+ nil
1200
+ end
1201
+ end)
1202
+ end
1203
+
1204
+ ##
1205
+ # The normalized combination of components that represent a site.
1206
+ # Combines the scheme, user, password, host, and port components.
1207
+ # Primarily useful for HTTP and HTTPS.
1208
+ #
1209
+ # For example, <code>"http://example.com/path?query"</code> would have a
1210
+ # <code>site</code> value of <code>"http://example.com"</code>.
1211
+ #
1212
+ # @return [String] The normalized components that identify a site.
1213
+ def normalized_site
1214
+ @site ||= (begin
1215
+ if self.normalized_scheme || self.normalized_authority
1216
+ site_string = ""
1217
+ if self.normalized_scheme != nil
1218
+ site_string << "#{self.normalized_scheme}:"
1219
+ end
1220
+ if self.normalized_authority != nil
1221
+ site_string << "//#{self.normalized_authority}"
1222
+ end
1223
+ site_string
1224
+ else
1225
+ nil
1226
+ end
1227
+ end)
1228
+ end
1229
+
1230
+ ##
1231
+ # Sets the site value for this URI.
1232
+ #
1233
+ # @param [String, #to_str] new_site The new site value.
1234
+ def site=(new_site)
1235
+ if new_site
1236
+ if !new_site.respond_to?(:to_str)
1237
+ raise TypeError, "Can't convert #{new_site.class} into String."
1238
+ end
1239
+ new_site = new_site.to_str
1240
+ # These two regular expressions derived from the primary parsing
1241
+ # expression
1242
+ self.scheme = new_site[/^(?:([^:\/?#]+):)?(?:\/\/(?:[^\/?#]*))?$/, 1]
1243
+ self.authority = new_site[
1244
+ /^(?:(?:[^:\/?#]+):)?(?:\/\/([^\/?#]*))?$/, 1
1245
+ ]
1246
+ else
1247
+ self.scheme = nil
1248
+ self.authority = nil
1249
+ end
1250
+ end
1251
+
1252
+ ##
1253
+ # The path component for this URI.
1254
+ #
1255
+ # @return [String] The path component.
1256
+ def path
1257
+ @path ||= ""
1258
+ return @path
1259
+ end
1260
+
1261
+ ##
1262
+ # The path component for this URI, normalized.
1263
+ #
1264
+ # @return [String] The path component, normalized.
1265
+ def normalized_path
1266
+ @normalized_path ||= (begin
1267
+ if self.scheme == nil && self.path != nil && self.path != "" &&
1268
+ self.path =~ /^(?!\/)[^\/:]*:.*$/
1269
+ # Relative paths with colons in the first segment are ambiguous.
1270
+ self.path.sub!(":", "%2F")
1271
+ end
1272
+ # String#split(delimeter, -1) uses the more strict splitting behavior
1273
+ # found by default in Python.
1274
+ result = (self.path.strip.split("/", -1).map do |segment|
1275
+ Addressable::URI.normalize_component(
1276
+ segment,
1277
+ Addressable::URI::CharacterClasses::PCHAR
1278
+ )
1279
+ end).join("/")
1280
+ result = self.class.normalize_path(result)
1281
+ if result == "" &&
1282
+ ["http", "https", "ftp", "tftp"].include?(self.normalized_scheme)
1283
+ result = "/"
1284
+ end
1285
+ result
1286
+ end)
1287
+ end
1288
+
1289
+ ##
1290
+ # Sets the path component for this URI.
1291
+ #
1292
+ # @param [String, #to_str] new_path The new path component.
1293
+ def path=(new_path)
1294
+ # Check for frozenness
1295
+ raise TypeError, "Can't modify frozen URI." if self.frozen?
1296
+
1297
+ if new_path && !new_path.respond_to?(:to_str)
1298
+ raise TypeError, "Can't convert #{new_path.class} into String."
1299
+ end
1300
+ @path = (new_path || "").to_str
1301
+ if @path != "" && @path[0..0] != "/" && host != nil
1302
+ @path = "/#{@path}"
1303
+ end
1304
+
1305
+ # Reset dependant values
1306
+ @normalized_path = nil
1307
+ @uri_string = nil
1308
+ @hash = nil
1309
+ end
1310
+
1311
+ ##
1312
+ # The basename, if any, of the file in the path component.
1313
+ #
1314
+ # @return [String] The path's basename.
1315
+ def basename
1316
+ # Path cannot be nil
1317
+ return File.basename(self.path).gsub(/;[^\/]*$/, "")
1318
+ end
1319
+
1320
+ ##
1321
+ # The extname, if any, of the file in the path component.
1322
+ # Empty string if there is no extension.
1323
+ #
1324
+ # @return [String] The path's extname.
1325
+ def extname
1326
+ return nil unless self.path
1327
+ return File.extname(self.basename)
1328
+ end
1329
+
1330
+ ##
1331
+ # The query component for this URI.
1332
+ #
1333
+ # @return [String] The query component.
1334
+ def query
1335
+ return @query ||= nil
1336
+ end
1337
+
1338
+ ##
1339
+ # The query component for this URI, normalized.
1340
+ #
1341
+ # @return [String] The query component, normalized.
1342
+ def normalized_query
1343
+ @normalized_query ||= (begin
1344
+ if self.query
1345
+ Addressable::URI.normalize_component(
1346
+ self.query.strip,
1347
+ Addressable::URI::CharacterClasses::QUERY
1348
+ )
1349
+ else
1350
+ nil
1351
+ end
1352
+ end)
1353
+ end
1354
+
1355
+ ##
1356
+ # Sets the query component for this URI.
1357
+ #
1358
+ # @param [String, #to_str] new_query The new query component.
1359
+ def query=(new_query)
1360
+ # Check for frozenness
1361
+ raise TypeError, "Can't modify frozen URI." if self.frozen?
1362
+
1363
+ if new_query && !new_query.respond_to?(:to_str)
1364
+ raise TypeError, "Can't convert #{new_query.class} into String."
1365
+ end
1366
+ @query = new_query ? new_query.to_str : nil
1367
+
1368
+ # Reset dependant values
1369
+ @normalized_query = nil
1370
+ @uri_string = nil
1371
+ @hash = nil
1372
+ end
1373
+
1374
+ ##
1375
+ # Converts the query component to a Hash value.
1376
+ #
1377
+ # @option [Symbol] notation
1378
+ # May be one of <code>:flat</code>, <code>:dot</code>, or
1379
+ # <code>:subscript</code>. The <code>:dot</code> notation is not
1380
+ # supported for assignment. Default value is <code>:subscript</code>.
1381
+ #
1382
+ # @return [Hash] The query string parsed as a Hash object.
1383
+ #
1384
+ # @example
1385
+ # Addressable::URI.parse("?one=1&two=2&three=3").query_values
1386
+ # #=> {"one" => "1", "two" => "2", "three" => "3"}
1387
+ # Addressable::URI.parse("?one[two][three]=four").query_values
1388
+ # #=> {"one" => {"two" => {"three" => "four"}}}
1389
+ # Addressable::URI.parse("?one.two.three=four").query_values(
1390
+ # :notation => :dot
1391
+ # )
1392
+ # #=> {"one" => {"two" => {"three" => "four"}}}
1393
+ # Addressable::URI.parse("?one[two][three]=four").query_values(
1394
+ # :notation => :flat
1395
+ # )
1396
+ # #=> {"one[two][three]" => "four"}
1397
+ # Addressable::URI.parse("?one.two.three=four").query_values(
1398
+ # :notation => :flat
1399
+ # )
1400
+ # #=> {"one.two.three" => "four"}
1401
+ # Addressable::URI.parse(
1402
+ # "?one[two][three][]=four&one[two][three][]=five"
1403
+ # ).query_values
1404
+ # #=> {"one" => {"two" => {"three" => ["four", "five"]}}}
1405
+ def query_values(options={})
1406
+ defaults = {:notation => :subscript}
1407
+ options = defaults.merge(options)
1408
+ if ![:flat, :dot, :subscript].include?(options[:notation])
1409
+ raise ArgumentError,
1410
+ "Invalid notation. Must be one of: [:flat, :dot, :subscript]."
1411
+ end
1412
+ dehash = lambda do |hash|
1413
+ hash.each do |(key, value)|
1414
+ if value.kind_of?(Hash)
1415
+ hash[key] = dehash.call(value)
1416
+ end
1417
+ end
1418
+ if hash != {} && hash.keys.all? { |key| key =~ /^\d+$/ }
1419
+ hash.sort.inject([]) do |accu, (key, value)|
1420
+ accu << value; accu
1421
+ end
1422
+ else
1423
+ hash
1424
+ end
1425
+ end
1426
+ return nil if self.query == nil
1427
+ return ((self.query.split("&").map do |pair|
1428
+ pair.split("=", -1) if pair && pair != ""
1429
+ end).compact.inject({}) do |accumulator, (key, value)|
1430
+ value = true if value.nil?
1431
+ key = self.class.unencode_component(key)
1432
+ if value != true
1433
+ value = self.class.unencode_component(value).gsub(/\+/, " ")
1434
+ end
1435
+ if options[:notation] == :flat
1436
+ if accumulator[key]
1437
+ raise ArgumentError, "Key was repeated: #{key.inspect}"
1438
+ end
1439
+ accumulator[key] = value
1440
+ else
1441
+ if options[:notation] == :dot
1442
+ array_value = false
1443
+ subkeys = key.split(".")
1444
+ elsif options[:notation] == :subscript
1445
+ array_value = !!(key =~ /\[\]$/)
1446
+ subkeys = key.split(/[\[\]]+/)
1447
+ end
1448
+ current_hash = accumulator
1449
+ for i in 0...(subkeys.size - 1)
1450
+ subkey = subkeys[i]
1451
+ current_hash[subkey] = {} unless current_hash[subkey]
1452
+ current_hash = current_hash[subkey]
1453
+ end
1454
+ if array_value
1455
+ current_hash[subkeys.last] = [] unless current_hash[subkeys.last]
1456
+ current_hash[subkeys.last] << value
1457
+ else
1458
+ current_hash[subkeys.last] = value
1459
+ end
1460
+ end
1461
+ accumulator
1462
+ end).inject({}) do |accumulator, (key, value)|
1463
+ accumulator[key] = value.kind_of?(Hash) ? dehash.call(value) : value
1464
+ accumulator
1465
+ end
1466
+ end
1467
+
1468
+ ##
1469
+ # Sets the query component for this URI from a Hash object.
1470
+ # This method produces a query string using the :subscript notation.
1471
+ # An empty Hash will result in a nil query.
1472
+ #
1473
+ # @param [Hash, #to_hash] new_query_values The new query values.
1474
+ def query_values=(new_query_values)
1475
+ # Check for frozenness
1476
+ raise TypeError, "Can't modify frozen URI." if self.frozen?
1477
+ if new_query_values == nil
1478
+ self.query = nil
1479
+ return nil
1480
+ end
1481
+ if !new_query_values.respond_to?(:to_hash)
1482
+ raise TypeError, "Can't convert #{new_query_values.class} into Hash."
1483
+ end
1484
+ new_query_values = new_query_values.to_hash
1485
+ new_query_values = new_query_values.map do |key, value|
1486
+ key = key.to_s if key.kind_of?(Symbol)
1487
+ [key, value]
1488
+ end
1489
+ new_query_values.sort! # Useful default for OAuth and caching
1490
+
1491
+ # Algorithm shamelessly stolen from Julien Genestoux, slightly modified
1492
+ buffer = ""
1493
+ stack = []
1494
+ e = lambda do |component|
1495
+ component = component.to_s if component.kind_of?(Symbol)
1496
+ self.class.encode_component(component, CharacterClasses::UNRESERVED)
1497
+ end
1498
+ new_query_values.each do |key, value|
1499
+ if value.kind_of?(Hash)
1500
+ stack << [key, value]
1501
+ elsif value.kind_of?(Array)
1502
+ stack << [
1503
+ key,
1504
+ value.inject({}) { |accu, x| accu[accu.size.to_s] = x; accu }
1505
+ ]
1506
+ elsif value == true
1507
+ buffer << "#{e.call(key)}&"
1508
+ else
1509
+ buffer << "#{e.call(key)}=#{e.call(value)}&"
1510
+ end
1511
+ end
1512
+ stack.each do |(parent, hash)|
1513
+ (hash.sort_by { |key| key.to_s }).each do |(key, value)|
1514
+ if value.kind_of?(Hash)
1515
+ stack << ["#{parent}[#{key}]", value]
1516
+ elsif value == true
1517
+ buffer << "#{parent}[#{e.call(key)}]&"
1518
+ else
1519
+ buffer << "#{parent}[#{e.call(key)}]=#{e.call(value)}&"
1520
+ end
1521
+ end
1522
+ end
1523
+ self.query = buffer.chop
1524
+ end
1525
+
1526
+ ##
1527
+ # The HTTP request URI for this URI. This is the path and the
1528
+ # query string.
1529
+ #
1530
+ # @return [String] The request URI required for an HTTP request.
1531
+ def request_uri
1532
+ return nil if self.absolute? && self.scheme !~ /^https?$/
1533
+ return (
1534
+ (self.path != "" ? self.path : "/") +
1535
+ (self.query ? "?#{self.query}" : "")
1536
+ )
1537
+ end
1538
+
1539
+ ##
1540
+ # Sets the HTTP request URI for this URI.
1541
+ #
1542
+ # @param [String, #to_str] new_request_uri The new HTTP request URI.
1543
+ def request_uri=(new_request_uri)
1544
+ if !new_request_uri.respond_to?(:to_str)
1545
+ raise TypeError, "Can't convert #{new_request_uri.class} into String."
1546
+ end
1547
+ if self.absolute? && self.scheme !~ /^https?$/
1548
+ raise InvalidURIError,
1549
+ "Cannot set an HTTP request URI for a non-HTTP URI."
1550
+ end
1551
+ new_request_uri = new_request_uri.to_str
1552
+ path_component = new_request_uri[/^([^\?]*)\?(?:.*)$/, 1]
1553
+ query_component = new_request_uri[/^(?:[^\?]*)\?(.*)$/, 1]
1554
+ path_component = path_component.to_s
1555
+ path_component = (path_component != "" ? path_component : "/")
1556
+ self.path = path_component
1557
+ self.query = query_component
1558
+
1559
+ # Reset dependant values
1560
+ @uri_string = nil
1561
+ @hash = nil
1562
+ end
1563
+
1564
+ ##
1565
+ # The fragment component for this URI.
1566
+ #
1567
+ # @return [String] The fragment component.
1568
+ def fragment
1569
+ return @fragment ||= nil
1570
+ end
1571
+
1572
+ ##
1573
+ # The fragment component for this URI, normalized.
1574
+ #
1575
+ # @return [String] The fragment component, normalized.
1576
+ def normalized_fragment
1577
+ @normalized_fragment ||= (begin
1578
+ if self.fragment
1579
+ Addressable::URI.normalize_component(
1580
+ self.fragment.strip,
1581
+ Addressable::URI::CharacterClasses::FRAGMENT
1582
+ )
1583
+ else
1584
+ nil
1585
+ end
1586
+ end)
1587
+ end
1588
+
1589
+ ##
1590
+ # Sets the fragment component for this URI.
1591
+ #
1592
+ # @param [String, #to_str] new_fragment The new fragment component.
1593
+ def fragment=(new_fragment)
1594
+ # Check for frozenness
1595
+ raise TypeError, "Can't modify frozen URI." if self.frozen?
1596
+
1597
+ if new_fragment && !new_fragment.respond_to?(:to_str)
1598
+ raise TypeError, "Can't convert #{new_fragment.class} into String."
1599
+ end
1600
+ @fragment = new_fragment ? new_fragment.to_str : nil
1601
+
1602
+ # Reset dependant values
1603
+ @normalized_fragment = nil
1604
+ @uri_string = nil
1605
+ @hash = nil
1606
+
1607
+ # Ensure we haven't created an invalid URI
1608
+ validate()
1609
+ end
1610
+
1611
+ ##
1612
+ # Determines if the scheme indicates an IP-based protocol.
1613
+ #
1614
+ # @return [TrueClass, FalseClass]
1615
+ # <code>true</code> if the scheme indicates an IP-based protocol.
1616
+ # <code>false</code> otherwise.
1617
+ def ip_based?
1618
+ if self.scheme
1619
+ return self.class.ip_based_schemes.include?(
1620
+ self.scheme.strip.downcase)
1621
+ end
1622
+ return false
1623
+ end
1624
+
1625
+ ##
1626
+ # Determines if the URI is relative.
1627
+ #
1628
+ # @return [TrueClass, FalseClass]
1629
+ # <code>true</code> if the URI is relative. <code>false</code>
1630
+ # otherwise.
1631
+ def relative?
1632
+ return self.scheme.nil?
1633
+ end
1634
+
1635
+ ##
1636
+ # Determines if the URI is absolute.
1637
+ #
1638
+ # @return [TrueClass, FalseClass]
1639
+ # <code>true</code> if the URI is absolute. <code>false</code>
1640
+ # otherwise.
1641
+ def absolute?
1642
+ return !relative?
1643
+ end
1644
+
1645
+ ##
1646
+ # Joins two URIs together.
1647
+ #
1648
+ # @param [String, Addressable::URI, #to_str] The URI to join with.
1649
+ #
1650
+ # @return [Addressable::URI] The joined URI.
1651
+ def join(uri)
1652
+ if !uri.respond_to?(:to_str)
1653
+ raise TypeError, "Can't convert #{uri.class} into String."
1654
+ end
1655
+ if !uri.kind_of?(self.class)
1656
+ # Otherwise, convert to a String, then parse.
1657
+ uri = self.class.parse(uri.to_str)
1658
+ end
1659
+ if uri.to_s == ""
1660
+ return self.dup
1661
+ end
1662
+
1663
+ joined_scheme = nil
1664
+ joined_user = nil
1665
+ joined_password = nil
1666
+ joined_host = nil
1667
+ joined_port = nil
1668
+ joined_path = nil
1669
+ joined_query = nil
1670
+ joined_fragment = nil
1671
+
1672
+ # Section 5.2.2 of RFC 3986
1673
+ if uri.scheme != nil
1674
+ joined_scheme = uri.scheme
1675
+ joined_user = uri.user
1676
+ joined_password = uri.password
1677
+ joined_host = uri.host
1678
+ joined_port = uri.port
1679
+ joined_path = self.class.normalize_path(uri.path)
1680
+ joined_query = uri.query
1681
+ else
1682
+ if uri.authority != nil
1683
+ joined_user = uri.user
1684
+ joined_password = uri.password
1685
+ joined_host = uri.host
1686
+ joined_port = uri.port
1687
+ joined_path = self.class.normalize_path(uri.path)
1688
+ joined_query = uri.query
1689
+ else
1690
+ if uri.path == nil || uri.path == ""
1691
+ joined_path = self.path
1692
+ if uri.query != nil
1693
+ joined_query = uri.query
1694
+ else
1695
+ joined_query = self.query
1696
+ end
1697
+ else
1698
+ if uri.path[0..0] == "/"
1699
+ joined_path = self.class.normalize_path(uri.path)
1700
+ else
1701
+ base_path = self.path.dup
1702
+ base_path = "" if base_path == nil
1703
+ base_path = self.class.normalize_path(base_path)
1704
+
1705
+ # Section 5.2.3 of RFC 3986
1706
+ #
1707
+ # Removes the right-most path segment from the base path.
1708
+ if base_path =~ /\//
1709
+ base_path.gsub!(/\/[^\/]+$/, "/")
1710
+ else
1711
+ base_path = ""
1712
+ end
1713
+
1714
+ # If the base path is empty and an authority segment has been
1715
+ # defined, use a base path of "/"
1716
+ if base_path == "" && self.authority != nil
1717
+ base_path = "/"
1718
+ end
1719
+
1720
+ joined_path = self.class.normalize_path(base_path + uri.path)
1721
+ end
1722
+ joined_query = uri.query
1723
+ end
1724
+ joined_user = self.user
1725
+ joined_password = self.password
1726
+ joined_host = self.host
1727
+ joined_port = self.port
1728
+ end
1729
+ joined_scheme = self.scheme
1730
+ end
1731
+ joined_fragment = uri.fragment
1732
+
1733
+ return Addressable::URI.new(
1734
+ :scheme => joined_scheme,
1735
+ :user => joined_user,
1736
+ :password => joined_password,
1737
+ :host => joined_host,
1738
+ :port => joined_port,
1739
+ :path => joined_path,
1740
+ :query => joined_query,
1741
+ :fragment => joined_fragment
1742
+ )
1743
+ end
1744
+ alias_method :+, :join
1745
+
1746
+ ##
1747
+ # Destructive form of <code>join</code>.
1748
+ #
1749
+ # @param [String, Addressable::URI, #to_str] The URI to join with.
1750
+ #
1751
+ # @return [Addressable::URI] The joined URI.
1752
+ #
1753
+ # @see Addressable::URI#join
1754
+ def join!(uri)
1755
+ replace_self(self.join(uri))
1756
+ end
1757
+
1758
+ ##
1759
+ # Merges a URI with a <code>Hash</code> of components.
1760
+ # This method has different behavior from <code>join</code>. Any
1761
+ # components present in the <code>hash</code> parameter will override the
1762
+ # original components. The path component is not treated specially.
1763
+ #
1764
+ # @param [Hash, Addressable::URI, #to_hash] The components to merge with.
1765
+ #
1766
+ # @return [Addressable::URI] The merged URI.
1767
+ #
1768
+ # @see Hash#merge
1769
+ def merge(hash)
1770
+ if !hash.respond_to?(:to_hash)
1771
+ raise TypeError, "Can't convert #{hash.class} into Hash."
1772
+ end
1773
+ hash = hash.to_hash
1774
+
1775
+ if hash.has_key?(:authority)
1776
+ if (hash.keys & [:userinfo, :user, :password, :host, :port]).any?
1777
+ raise ArgumentError,
1778
+ "Cannot specify both an authority and any of the components " +
1779
+ "within the authority."
1780
+ end
1781
+ end
1782
+ if hash.has_key?(:userinfo)
1783
+ if (hash.keys & [:user, :password]).any?
1784
+ raise ArgumentError,
1785
+ "Cannot specify both a userinfo and either the user or password."
1786
+ end
1787
+ end
1788
+
1789
+ uri = Addressable::URI.new
1790
+ uri.defer_validation do
1791
+ # Bunch of crazy logic required because of the composite components
1792
+ # like userinfo and authority.
1793
+ uri.scheme =
1794
+ hash.has_key?(:scheme) ? hash[:scheme] : self.scheme
1795
+ if hash.has_key?(:authority)
1796
+ uri.authority =
1797
+ hash.has_key?(:authority) ? hash[:authority] : self.authority
1798
+ end
1799
+ if hash.has_key?(:userinfo)
1800
+ uri.userinfo =
1801
+ hash.has_key?(:userinfo) ? hash[:userinfo] : self.userinfo
1802
+ end
1803
+ if !hash.has_key?(:userinfo) && !hash.has_key?(:authority)
1804
+ uri.user =
1805
+ hash.has_key?(:user) ? hash[:user] : self.user
1806
+ uri.password =
1807
+ hash.has_key?(:password) ? hash[:password] : self.password
1808
+ end
1809
+ if !hash.has_key?(:authority)
1810
+ uri.host =
1811
+ hash.has_key?(:host) ? hash[:host] : self.host
1812
+ uri.port =
1813
+ hash.has_key?(:port) ? hash[:port] : self.port
1814
+ end
1815
+ uri.path =
1816
+ hash.has_key?(:path) ? hash[:path] : self.path
1817
+ uri.query =
1818
+ hash.has_key?(:query) ? hash[:query] : self.query
1819
+ uri.fragment =
1820
+ hash.has_key?(:fragment) ? hash[:fragment] : self.fragment
1821
+ end
1822
+
1823
+ return uri
1824
+ end
1825
+
1826
+ ##
1827
+ # Destructive form of <code>merge</code>.
1828
+ #
1829
+ # @param [Hash, Addressable::URI, #to_hash] The components to merge with.
1830
+ #
1831
+ # @return [Addressable::URI] The merged URI.
1832
+ #
1833
+ # @see Addressable::URI#merge
1834
+ def merge!(uri)
1835
+ replace_self(self.merge(uri))
1836
+ end
1837
+
1838
+ ##
1839
+ # Returns the shortest normalized relative form of this URI that uses the
1840
+ # supplied URI as a base for resolution. Returns an absolute URI if
1841
+ # necessary. This is effectively the opposite of <code>route_to</code>.
1842
+ #
1843
+ # @param [String, Addressable::URI, #to_str] uri The URI to route from.
1844
+ #
1845
+ # @return [Addressable::URI]
1846
+ # The normalized relative URI that is equivalent to the original URI.
1847
+ def route_from(uri)
1848
+ uri = self.class.parse(uri).normalize
1849
+ normalized_self = self.normalize
1850
+ if normalized_self.relative?
1851
+ raise ArgumentError, "Expected absolute URI, got: #{self.to_s}"
1852
+ end
1853
+ if uri.relative?
1854
+ raise ArgumentError, "Expected absolute URI, got: #{uri.to_s}"
1855
+ end
1856
+ if normalized_self == uri
1857
+ return Addressable::URI.parse("##{normalized_self.fragment}")
1858
+ end
1859
+ components = normalized_self.to_hash
1860
+ if normalized_self.scheme == uri.scheme
1861
+ components[:scheme] = nil
1862
+ if normalized_self.authority == uri.authority
1863
+ components[:user] = nil
1864
+ components[:password] = nil
1865
+ components[:host] = nil
1866
+ components[:port] = nil
1867
+ if normalized_self.path == uri.path
1868
+ components[:path] = nil
1869
+ if normalized_self.query == uri.query
1870
+ components[:query] = nil
1871
+ end
1872
+ else
1873
+ if uri.path != "/"
1874
+ components[:path].gsub!(
1875
+ Regexp.new("^" + Regexp.escape(uri.path)), "")
1876
+ end
1877
+ end
1878
+ end
1879
+ end
1880
+ # Avoid network-path references.
1881
+ if components[:host] != nil
1882
+ components[:scheme] = normalized_self.scheme
1883
+ end
1884
+ return Addressable::URI.new(
1885
+ :scheme => components[:scheme],
1886
+ :user => components[:user],
1887
+ :password => components[:password],
1888
+ :host => components[:host],
1889
+ :port => components[:port],
1890
+ :path => components[:path],
1891
+ :query => components[:query],
1892
+ :fragment => components[:fragment]
1893
+ )
1894
+ end
1895
+
1896
+ ##
1897
+ # Returns the shortest normalized relative form of the supplied URI that
1898
+ # uses this URI as a base for resolution. Returns an absolute URI if
1899
+ # necessary. This is effectively the opposite of <code>route_from</code>.
1900
+ #
1901
+ # @param [String, Addressable::URI, #to_str] uri The URI to route to.
1902
+ #
1903
+ # @return [Addressable::URI]
1904
+ # The normalized relative URI that is equivalent to the supplied URI.
1905
+ def route_to(uri)
1906
+ return self.class.parse(uri).route_from(self)
1907
+ end
1908
+
1909
+ ##
1910
+ # Returns a normalized URI object.
1911
+ #
1912
+ # NOTE: This method does not attempt to fully conform to specifications.
1913
+ # It exists largely to correct other people's failures to read the
1914
+ # specifications, and also to deal with caching issues since several
1915
+ # different URIs may represent the same resource and should not be
1916
+ # cached multiple times.
1917
+ #
1918
+ # @return [Addressable::URI] The normalized URI.
1919
+ def normalize
1920
+ # This is a special exception for the frequently misused feed
1921
+ # URI scheme.
1922
+ if normalized_scheme == "feed"
1923
+ if self.to_s =~ /^feed:\/*http:\/*/
1924
+ return self.class.parse(
1925
+ self.to_s[/^feed:\/*(http:\/*.*)/, 1]
1926
+ ).normalize
1927
+ end
1928
+ end
1929
+
1930
+ return Addressable::URI.new(
1931
+ :scheme => normalized_scheme,
1932
+ :authority => normalized_authority,
1933
+ :path => normalized_path,
1934
+ :query => normalized_query,
1935
+ :fragment => normalized_fragment
1936
+ )
1937
+ end
1938
+
1939
+ ##
1940
+ # Destructively normalizes this URI object.
1941
+ #
1942
+ # @return [Addressable::URI] The normalized URI.
1943
+ #
1944
+ # @see Addressable::URI#normalize
1945
+ def normalize!
1946
+ replace_self(self.normalize)
1947
+ end
1948
+
1949
+ ##
1950
+ # Creates a URI suitable for display to users. If semantic attacks are
1951
+ # likely, the application should try to detect these and warn the user.
1952
+ # See <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>,
1953
+ # section 7.6 for more information.
1954
+ #
1955
+ # @return [Addressable::URI] A URI suitable for display purposes.
1956
+ def display_uri
1957
+ display_uri = self.normalize
1958
+ display_uri.host = ::Addressable::IDNA.to_unicode(display_uri.host)
1959
+ return display_uri
1960
+ end
1961
+
1962
+ ##
1963
+ # Returns <code>true</code> if the URI objects are equal. This method
1964
+ # normalizes both URIs before doing the comparison, and allows comparison
1965
+ # against <code>Strings</code>.
1966
+ #
1967
+ # @param [Object] uri The URI to compare.
1968
+ #
1969
+ # @return [TrueClass, FalseClass]
1970
+ # <code>true</code> if the URIs are equivalent, <code>false</code>
1971
+ # otherwise.
1972
+ def ===(uri)
1973
+ if uri.respond_to?(:normalize)
1974
+ uri_string = uri.normalize.to_s
1975
+ else
1976
+ begin
1977
+ uri_string = ::Addressable::URI.parse(uri).normalize.to_s
1978
+ rescue InvalidURIError, TypeError
1979
+ return false
1980
+ end
1981
+ end
1982
+ return self.normalize.to_s == uri_string
1983
+ end
1984
+
1985
+ ##
1986
+ # Returns <code>true</code> if the URI objects are equal. This method
1987
+ # normalizes both URIs before doing the comparison.
1988
+ #
1989
+ # @param [Object] uri The URI to compare.
1990
+ #
1991
+ # @return [TrueClass, FalseClass]
1992
+ # <code>true</code> if the URIs are equivalent, <code>false</code>
1993
+ # otherwise.
1994
+ def ==(uri)
1995
+ return false unless uri.kind_of?(self.class)
1996
+ return self.normalize.to_s == uri.normalize.to_s
1997
+ end
1998
+
1999
+ ##
2000
+ # Returns <code>true</code> if the URI objects are equal. This method
2001
+ # does NOT normalize either URI before doing the comparison.
2002
+ #
2003
+ # @param [Object] uri The URI to compare.
2004
+ #
2005
+ # @return [TrueClass, FalseClass]
2006
+ # <code>true</code> if the URIs are equivalent, <code>false</code>
2007
+ # otherwise.
2008
+ def eql?(uri)
2009
+ return false unless uri.kind_of?(self.class)
2010
+ return self.to_s == uri.to_s
2011
+ end
2012
+
2013
+ ##
2014
+ # A hash value that will make a URI equivalent to its normalized
2015
+ # form.
2016
+ #
2017
+ # @return [Integer] A hash of the URI.
2018
+ def hash
2019
+ return @hash ||= (self.to_s.hash * -1)
2020
+ end
2021
+
2022
+ ##
2023
+ # Clones the URI object.
2024
+ #
2025
+ # @return [Addressable::URI] The cloned URI.
2026
+ def dup
2027
+ duplicated_uri = Addressable::URI.new(
2028
+ :scheme => self.scheme ? self.scheme.dup : nil,
2029
+ :user => self.user ? self.user.dup : nil,
2030
+ :password => self.password ? self.password.dup : nil,
2031
+ :host => self.host ? self.host.dup : nil,
2032
+ :port => self.port,
2033
+ :path => self.path ? self.path.dup : nil,
2034
+ :query => self.query ? self.query.dup : nil,
2035
+ :fragment => self.fragment ? self.fragment.dup : nil
2036
+ )
2037
+ return duplicated_uri
2038
+ end
2039
+
2040
+ ##
2041
+ # Freezes the URI object.
2042
+ #
2043
+ # @return [Addressable::URI] The frozen URI.
2044
+ def freeze
2045
+ # Unfortunately, because of the memoized implementation of many of the
2046
+ # URI methods, the default freeze method will cause unexpected errors.
2047
+ # As an alternative, we freeze the string representation of the URI
2048
+ # instead. This should generally produce the desired effect.
2049
+ self.to_s.freeze
2050
+ return self
2051
+ end
2052
+
2053
+ ##
2054
+ # Determines if the URI is frozen.
2055
+ #
2056
+ # @return [TrueClass, FalseClass]
2057
+ # <code>true</code> if the URI is frozen, <code>false</code> otherwise.
2058
+ def frozen?
2059
+ self.to_s.frozen?
2060
+ end
2061
+
2062
+ ##
2063
+ # Omits components from a URI.
2064
+ #
2065
+ # @param [Symbol] *components The components to be omitted.
2066
+ #
2067
+ # @return [Addressable::URI] The URI with components omitted.
2068
+ #
2069
+ # @example
2070
+ # uri = Addressable::URI.parse("http://example.com/path?query")
2071
+ # #=> #<Addressable::URI:0xcc5e7a URI:http://example.com/path?query>
2072
+ # uri.omit(:scheme, :authority)
2073
+ # #=> #<Addressable::URI:0xcc4d86 URI:/path?query>
2074
+ def omit(*components)
2075
+ invalid_components = components - [
2076
+ :scheme, :user, :password, :userinfo, :host, :port, :authority,
2077
+ :path, :query, :fragment
2078
+ ]
2079
+ unless invalid_components.empty?
2080
+ raise ArgumentError,
2081
+ "Invalid component names: #{invalid_components.inspect}."
2082
+ end
2083
+ duplicated_uri = self.dup
2084
+ duplicated_uri.defer_validation do
2085
+ components.each do |component|
2086
+ duplicated_uri.send((component.to_s + "=").to_sym, nil)
2087
+ end
2088
+ duplicated_uri.user = duplicated_uri.normalized_user
2089
+ end
2090
+ duplicated_uri
2091
+ end
2092
+
2093
+ ##
2094
+ # Destructive form of omit.
2095
+ #
2096
+ # @param [Symbol] *components The components to be omitted.
2097
+ #
2098
+ # @return [Addressable::URI] The URI with components omitted.
2099
+ #
2100
+ # @see Addressable::URI#omit
2101
+ def omit!(*components)
2102
+ replace_self(self.omit(*components))
2103
+ end
2104
+
2105
+ ##
2106
+ # Converts the URI to a <code>String</code>.
2107
+ #
2108
+ # @return [String] The URI's <code>String</code> representation.
2109
+ def to_s
2110
+ @uri_string ||= (begin
2111
+ uri_string = ""
2112
+ uri_string << "#{self.scheme}:" if self.scheme != nil
2113
+ uri_string << "//#{self.authority}" if self.authority != nil
2114
+ uri_string << self.path.to_s
2115
+ uri_string << "?#{self.query}" if self.query != nil
2116
+ uri_string << "##{self.fragment}" if self.fragment != nil
2117
+ if uri_string.respond_to?(:force_encoding)
2118
+ uri_string.force_encoding(Encoding::UTF_8)
2119
+ end
2120
+ uri_string
2121
+ end)
2122
+ end
2123
+
2124
+ ##
2125
+ # URI's are glorified <code>Strings</code>. Allow implicit conversion.
2126
+ alias_method :to_str, :to_s
2127
+
2128
+ ##
2129
+ # Returns a Hash of the URI components.
2130
+ #
2131
+ # @return [Hash] The URI as a <code>Hash</code> of components.
2132
+ def to_hash
2133
+ return {
2134
+ :scheme => self.scheme,
2135
+ :user => self.user,
2136
+ :password => self.password,
2137
+ :host => self.host,
2138
+ :port => self.port,
2139
+ :path => self.path,
2140
+ :query => self.query,
2141
+ :fragment => self.fragment
2142
+ }
2143
+ end
2144
+
2145
+ ##
2146
+ # Returns a <code>String</code> representation of the URI object's state.
2147
+ #
2148
+ # @return [String] The URI object's state, as a <code>String</code>.
2149
+ def inspect
2150
+ sprintf("#<%s:%#0x URI:%s>", self.class.to_s, self.object_id, self.to_s)
2151
+ end
2152
+
2153
+ ##
2154
+ # This method allows you to make several changes to a URI simultaneously,
2155
+ # which separately would cause validation errors, but in conjunction,
2156
+ # are valid. The URI will be revalidated as soon as the entire block has
2157
+ # been executed.
2158
+ #
2159
+ # @param [Proc] block
2160
+ # A set of operations to perform on a given URI.
2161
+ def defer_validation(&block)
2162
+ raise LocalJumpError, "No block given." unless block
2163
+ @validation_deferred = true
2164
+ block.call()
2165
+ @validation_deferred = false
2166
+ validate
2167
+ return nil
2168
+ end
2169
+
2170
+ private
2171
+ ##
2172
+ # Resolves paths to their simplest form.
2173
+ #
2174
+ # @param [String] path The path to normalize.
2175
+ #
2176
+ # @return [String] The normalized path.
2177
+ def self.normalize_path(path)
2178
+ # Section 5.2.4 of RFC 3986
2179
+
2180
+ return nil if path.nil?
2181
+ normalized_path = path.dup
2182
+ previous_state = normalized_path.dup
2183
+ begin
2184
+ previous_state = normalized_path.dup
2185
+ normalized_path.gsub!(/\/\.\//, "/")
2186
+ normalized_path.gsub!(/\/\.$/, "/")
2187
+ parent = normalized_path[/\/([^\/]+)\/\.\.\//, 1]
2188
+ if parent != "." && parent != ".."
2189
+ normalized_path.gsub!(/\/#{parent}\/\.\.\//, "/")
2190
+ end
2191
+ parent = normalized_path[/\/([^\/]+)\/\.\.$/, 1]
2192
+ if parent != "." && parent != ".."
2193
+ normalized_path.gsub!(/\/#{parent}\/\.\.$/, "/")
2194
+ end
2195
+ normalized_path.gsub!(/^\.\.?\/?/, "")
2196
+ normalized_path.gsub!(/^\/\.\.?\//, "/")
2197
+ end until previous_state == normalized_path
2198
+ return normalized_path
2199
+ end
2200
+
2201
+ ##
2202
+ # Ensures that the URI is valid.
2203
+ def validate
2204
+ return if !!@validation_deferred
2205
+ if self.scheme != nil &&
2206
+ (self.host == nil || self.host == "") &&
2207
+ (self.path == nil || self.path == "")
2208
+ raise InvalidURIError,
2209
+ "Absolute URI missing hierarchical segment: '#{self.to_s}'"
2210
+ end
2211
+ if self.host == nil
2212
+ if self.port != nil ||
2213
+ self.user != nil ||
2214
+ self.password != nil
2215
+ raise InvalidURIError, "Hostname not supplied: '#{self.to_s}'"
2216
+ end
2217
+ end
2218
+ if self.path != nil && self.path != "" && self.path[0..0] != "/" &&
2219
+ self.authority != nil
2220
+ raise InvalidURIError,
2221
+ "Cannot have a relative path with an authority set: '#{self.to_s}'"
2222
+ end
2223
+ return nil
2224
+ end
2225
+
2226
+ ##
2227
+ # Replaces the internal state of self with the specified URI's state.
2228
+ # Used in destructive operations to avoid massive code repetition.
2229
+ #
2230
+ # @param [Addressable::URI] uri The URI to replace <code>self</code> with.
2231
+ #
2232
+ # @return [Addressable::URI] <code>self</code>.
2233
+ def replace_self(uri)
2234
+ # Reset dependant values
2235
+ instance_variables.each do |var|
2236
+ instance_variable_set(var, nil)
2237
+ end
2238
+
2239
+ @scheme = uri.scheme
2240
+ @user = uri.user
2241
+ @password = uri.password
2242
+ @host = uri.host
2243
+ @port = uri.port
2244
+ @path = uri.path
2245
+ @query = uri.query
2246
+ @fragment = uri.fragment
2247
+ return self
2248
+ end
2249
+ end
2250
+ end