addressable 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG CHANGED
@@ -1,3 +1,8 @@
1
+ === Addressable 0.1.2
2
+ * improved normalization
3
+ * fixed bug in joining algorithm
4
+ * updated specifications
5
+
1
6
  === Addressable 0.1.1
2
7
  * updated documentation
3
8
  * added URI Template variable extraction
@@ -151,7 +151,7 @@ table.report tr.dark {
151
151
  </head>
152
152
  <body>
153
153
  <h3>C0 code coverage information</h3>
154
- <p>Generated on Wed Sep 05 16:05:30 -0400 2007 with <a href='http://eigenclass.org/hiki.rb?rcov'>rcov 0.8.0</a>
154
+ <p>Generated on Sun Oct 28 17:27:26 -0400 2007 with <a href='http://eigenclass.org/hiki.rb?rcov'>rcov 0.8.0</a>
155
155
  </p>
156
156
  <hr /> <table class='report'>
157
157
  <thead>
@@ -167,10 +167,10 @@ table.report tr.dark {
167
167
  <tr class='light'>
168
168
  <td>TOTAL</td>
169
169
  <td class='lines_total'>
170
- <tt>1207</tt>
170
+ <tt>1238</tt>
171
171
  </td>
172
172
  <td class='lines_code'>
173
- <tt>852</tt>
173
+ <tt>870</tt>
174
174
  </td>
175
175
  <td>
176
176
  <table cellspacing='0' cellpadding='0' align='right'>
@@ -210,10 +210,10 @@ table.report tr.dark {
210
210
  <a href='lib-addressable-uri_rb.html'>lib/addressable/uri.rb</a>
211
211
  </td>
212
212
  <td class='lines_total'>
213
- <tt>1175</tt>
213
+ <tt>1206</tt>
214
214
  </td>
215
215
  <td class='lines_code'>
216
- <tt>844</tt>
216
+ <tt>862</tt>
217
217
  </td>
218
218
  <td>
219
219
  <table cellspacing='0' cellpadding='0' align='right'>
@@ -556,7 +556,7 @@ span.run100 {
556
556
  </head>
557
557
  <body>
558
558
  <h3>C0 code coverage information</h3>
559
- <p>Generated on Wed Sep 05 16:05:34 -0400 2007 with <a href='http://eigenclass.org/hiki.rb?rcov'>rcov 0.8.0</a>
559
+ <p>Generated on Sun Oct 28 17:27:34 -0400 2007 with <a href='http://eigenclass.org/hiki.rb?rcov'>rcov 0.8.0</a>
560
560
  </p>
561
561
  <hr /><pre><span class='marked0'>Code reported as executed by Ruby looks like this...
562
562
  </span><span class='marked1'>and this: this line is also marked as covered.
@@ -580,10 +580,10 @@ span.run100 {
580
580
  <a href='lib-addressable-uri_rb.html'>lib/addressable/uri.rb</a>
581
581
  </td>
582
582
  <td class='lines_total'>
583
- <tt>1175</tt>
583
+ <tt>1206</tt>
584
584
  </td>
585
585
  <td class='lines_code'>
586
- <tt>844</tt>
586
+ <tt>862</tt>
587
587
  </td>
588
588
  <td>
589
589
  <table cellspacing='0' cellpadding='0' align='right'>
@@ -648,7 +648,7 @@ span.run100 {
648
648
  </span><span class="marked1"><a name="line27" /> 27 require 'addressable/version'
649
649
  </span><span class="inferred0"><a name="line28" /> 28
650
650
  </span><span class="marked1"><a name="line29" /> 29 module Addressable
651
- </span><span class="inferred0"><a name="line30" /> 30 # This is an implementation of a URI parser based on RFC 3986.
651
+ </span><span class="inferred0"><a name="line30" /> 30 # This is an implementation of a URI parser based on RFC 3986, 3987.
652
652
  </span><span class="marked1"><a name="line31" /> 31 class URI
653
653
  </span><span class="inferred0"><a name="line32" /> 32 # Raised if something other than a uri is supplied.
654
654
  </span><span class="marked1"><a name="line33" /> 33 class InvalidURIError &lt; StandardError
@@ -901,899 +901,930 @@ span.run100 {
901
901
  </span><span class="inferred0"><a name="line280" /> 280 end
902
902
  </span><span class="marked1"><a name="line281" /> 281 return mapping
903
903
  </span><span class="inferred0"><a name="line282" /> 282 else
904
- </span><span class="marked1"><a name="line283" /> 283 return nil
905
- </span><span class="inferred0"><a name="line284" /> 284 end
906
- </span><span class="inferred1"><a name="line285" /> 285 end
907
- </span><span class="inferred0"><a name="line286" /> 286
908
- </span><span class="inferred1"><a name="line287" /> 287 # Joins several uris together.
909
- </span><span class="marked0"><a name="line288" /> 288 def self.join(*uris)
910
- </span><span class="marked1"><a name="line289" /> 289 uri_objects = uris.collect do |uri|
911
- </span><span class="marked0"><a name="line290" /> 290 uri.kind_of?(self) ? uri : self.parse(uri.to_s)
912
- </span><span class="inferred1"><a name="line291" /> 291 end
913
- </span><span class="marked0"><a name="line292" /> 292 result = uri_objects.shift.dup
914
- </span><span class="marked1"><a name="line293" /> 293 for uri in uri_objects
915
- </span><span class="marked0"><a name="line294" /> 294 result.merge!(uri)
916
- </span><span class="inferred1"><a name="line295" /> 295 end
917
- </span><span class="marked0"><a name="line296" /> 296 return result
918
- </span><span class="inferred1"><a name="line297" /> 297 end
919
- </span><span class="inferred0"><a name="line298" /> 298
920
- </span><span class="inferred1"><a name="line299" /> 299 # Percent encodes a URI segment. Returns a string. Takes an optional
921
- </span><span class="inferred0"><a name="line300" /> 300 # character class parameter, which should be specified as a string
922
- </span><span class="inferred1"><a name="line301" /> 301 # containing a regular expression character class (not including the
923
- </span><span class="inferred0"><a name="line302" /> 302 # surrounding square brackets). The character class parameter defaults
924
- </span><span class="inferred1"><a name="line303" /> 303 # to the reserved plus unreserved character classes specified in
925
- </span><span class="inferred0"><a name="line304" /> 304 # RFC 3986. Usage of the constants within the CharacterClasses module is
926
- </span><span class="inferred1"><a name="line305" /> 305 # highly recommended when using this method.
927
- </span><span class="inferred0"><a name="line306" /> 306 #
928
- </span><span class="inferred1"><a name="line307" /> 307 # An example:
929
- </span><span class="inferred0"><a name="line308" /> 308 #
930
- </span><span class="inferred1"><a name="line309" /> 309 # Addressable::URI.escape_segment(&quot;simple-example&quot;, &quot;b-zB-Z0-9&quot;)
931
- </span><span class="inferred0"><a name="line310" /> 310 # =&gt; &quot;simple%2Dex%61mple&quot;
932
- </span><span class="marked1"><a name="line311" /> 311 def self.encode_segment(segment, character_class=
933
- </span><span class="inferred0"><a name="line312" /> 312 Addressable::URI::CharacterClasses::RESERVED +
934
- </span><span class="marked1"><a name="line313" /> 313 Addressable::URI::CharacterClasses::UNRESERVED)
935
- </span><span class="marked0"><a name="line314" /> 314 return nil if segment.nil?
936
- </span><span class="inferred1"><a name="line315" /> 315 return segment.gsub(
937
- </span><span class="inferred0"><a name="line316" /> 316 /[^#{character_class}]/
938
- </span><span class="inferred1"><a name="line317" /> 317 ) do |sequence|
939
- </span><span class="marked0"><a name="line318" /> 318 (&quot;%&quot; + sequence.unpack('C')[0].to_s(16).upcase)
940
- </span><span class="marked1"><a name="line319" /> 319 end
941
- </span><span class="inferred0"><a name="line320" /> 320 end
942
- </span><span class="inferred1"><a name="line321" /> 321
943
- </span><span class="inferred0"><a name="line322" /> 322 # Unencodes any percent encoded characters within a URI segment.
944
- </span><span class="inferred1"><a name="line323" /> 323 # Returns a string.
945
- </span><span class="marked0"><a name="line324" /> 324 def self.unencode_segment(segment)
946
- </span><span class="marked1"><a name="line325" /> 325 return nil if segment.nil?
947
- </span><span class="inferred0"><a name="line326" /> 326 return segment.to_s.gsub(/%[0-9a-f]{2}/i) do |sequence|
948
- </span><span class="marked1"><a name="line327" /> 327 sequence[1..3].to_i(16).chr
949
- </span><span class="marked0"><a name="line328" /> 328 end
950
- </span><span class="inferred1"><a name="line329" /> 329 end
951
- </span><span class="inferred0"><a name="line330" /> 330
952
- </span><span class="inferred1"><a name="line331" /> 331 # Percent encodes any special characters in the URI. This method does
953
- </span><span class="inferred0"><a name="line332" /> 332 # not take IRIs or IDNs into account.
954
- </span><span class="marked1"><a name="line333" /> 333 def self.encode(uri)
955
- </span><span class="marked0"><a name="line334" /> 334 uri_object = uri.kind_of?(self) ? uri : self.parse(uri.to_s)
956
- </span><span class="marked1"><a name="line335" /> 335 return Addressable::URI.new(
957
- </span><span class="marked0"><a name="line336" /> 336 self.encode_segment(uri_object.scheme,
958
- </span><span class="inferred1"><a name="line337" /> 337 Addressable::URI::CharacterClasses::SCHEME),
959
- </span><span class="marked0"><a name="line338" /> 338 self.encode_segment(uri_object.user,
960
- </span><span class="inferred1"><a name="line339" /> 339 Addressable::URI::CharacterClasses::AUTHORITY),
961
- </span><span class="marked0"><a name="line340" /> 340 self.encode_segment(uri_object.password,
962
- </span><span class="inferred1"><a name="line341" /> 341 Addressable::URI::CharacterClasses::AUTHORITY),
963
- </span><span class="marked0"><a name="line342" /> 342 self.encode_segment(uri_object.host,
964
- </span><span class="inferred1"><a name="line343" /> 343 Addressable::URI::CharacterClasses::AUTHORITY),
965
- </span><span class="marked0"><a name="line344" /> 344 self.encode_segment(uri_object.specified_port,
966
- </span><span class="inferred1"><a name="line345" /> 345 Addressable::URI::CharacterClasses::AUTHORITY),
967
- </span><span class="marked0"><a name="line346" /> 346 self.encode_segment(uri_object.path,
968
- </span><span class="inferred1"><a name="line347" /> 347 Addressable::URI::CharacterClasses::PATH),
969
- </span><span class="marked0"><a name="line348" /> 348 self.encode_segment(uri_object.query,
970
- </span><span class="inferred1"><a name="line349" /> 349 Addressable::URI::CharacterClasses::QUERY),
971
- </span><span class="marked0"><a name="line350" /> 350 self.encode_segment(uri_object.fragment,
972
- </span><span class="inferred1"><a name="line351" /> 351 Addressable::URI::CharacterClasses::FRAGMENT)
973
- </span><span class="marked0"><a name="line352" /> 352 ).to_s
974
- </span><span class="inferred1"><a name="line353" /> 353 end
975
- </span><span class="inferred0"><a name="line354" /> 354
976
- </span><span class="marked1"><a name="line355" /> 355 class &lt;&lt; self
977
- </span><span class="marked0"><a name="line356" /> 356 alias_method :escape, :encode
978
- </span><span class="inferred1"><a name="line357" /> 357 end
979
- </span><span class="inferred0"><a name="line358" /> 358
980
- </span><span class="inferred1"><a name="line359" /> 359 # Normalizes the encoding of a URI. Characters within a hostname are
981
- </span><span class="inferred0"><a name="line360" /> 360 # not percent encoded to allow for internationalized domain names.
982
- </span><span class="marked1"><a name="line361" /> 361 def self.normalized_encode(uri)
983
- </span><span class="marked0"><a name="line362" /> 362 uri_object = uri.kind_of?(self) ? uri : self.parse(uri.to_s)
984
- </span><span class="marked1"><a name="line363" /> 363 segments = {
985
- </span><span class="marked0"><a name="line364" /> 364 :scheme =&gt; self.unencode_segment(uri_object.scheme),
986
- </span><span class="marked1"><a name="line365" /> 365 :user =&gt; self.unencode_segment(uri_object.user),
987
- </span><span class="marked0"><a name="line366" /> 366 :password =&gt; self.unencode_segment(uri_object.password),
988
- </span><span class="marked1"><a name="line367" /> 367 :host =&gt; self.unencode_segment(uri_object.host),
989
- </span><span class="marked0"><a name="line368" /> 368 :port =&gt; self.unencode_segment(uri_object.specified_port),
990
- </span><span class="marked1"><a name="line369" /> 369 :path =&gt; self.unencode_segment(uri_object.path),
991
- </span><span class="marked0"><a name="line370" /> 370 :query =&gt; self.unencode_segment(uri_object.query),
992
- </span><span class="marked1"><a name="line371" /> 371 :fragment =&gt; self.unencode_segment(uri_object.fragment)
993
- </span><span class="inferred0"><a name="line372" /> 372 }
994
- </span><span class="marked1"><a name="line373" /> 373 if URI::IDNA.send(:use_libidn?)
995
- </span><span class="marked0"><a name="line374" /> 374 segments.each do |key, value|
996
- </span><span class="marked1"><a name="line375" /> 375 if value != nil
997
- </span><span class="marked0"><a name="line376" /> 376 segments[key] = IDN::Stringprep.nfkc_normalize(value.to_s)
998
- </span><span class="inferred1"><a name="line377" /> 377 end
999
- </span><span class="inferred0"><a name="line378" /> 378 end
1000
- </span><span class="inferred1"><a name="line379" /> 379 end
1001
- </span><span class="marked0"><a name="line380" /> 380 return Addressable::URI.new(
1002
- </span><span class="marked1"><a name="line381" /> 381 self.encode_segment(segments[:scheme],
1003
- </span><span class="inferred0"><a name="line382" /> 382 Addressable::URI::CharacterClasses::SCHEME),
1004
- </span><span class="marked1"><a name="line383" /> 383 self.encode_segment(segments[:user],
1005
- </span><span class="inferred0"><a name="line384" /> 384 Addressable::URI::CharacterClasses::AUTHORITY),
1006
- </span><span class="marked1"><a name="line385" /> 385 self.encode_segment(segments[:password],
1007
- </span><span class="inferred0"><a name="line386" /> 386 Addressable::URI::CharacterClasses::AUTHORITY),
1008
- </span><span class="inferred1"><a name="line387" /> 387 segments[:host],
1009
- </span><span class="inferred0"><a name="line388" /> 388 segments[:port],
1010
- </span><span class="marked1"><a name="line389" /> 389 self.encode_segment(segments[:path],
1011
- </span><span class="inferred0"><a name="line390" /> 390 Addressable::URI::CharacterClasses::PATH),
1012
- </span><span class="marked1"><a name="line391" /> 391 self.encode_segment(segments[:query],
1013
- </span><span class="inferred0"><a name="line392" /> 392 Addressable::URI::CharacterClasses::QUERY),
1014
- </span><span class="marked1"><a name="line393" /> 393 self.encode_segment(segments[:fragment],
1015
- </span><span class="inferred0"><a name="line394" /> 394 Addressable::URI::CharacterClasses::FRAGMENT)
1016
- </span><span class="marked1"><a name="line395" /> 395 ).to_s
1017
- </span><span class="inferred0"><a name="line396" /> 396 end
1018
- </span><span class="inferred1"><a name="line397" /> 397
1019
- </span><span class="inferred0"><a name="line398" /> 398 # Extracts uris from an arbitrary body of text.
1020
- </span><span class="marked1"><a name="line399" /> 399 def self.extract(text, options={})
1021
- </span><span class="marked0"><a name="line400" /> 400 defaults = {:base =&gt; nil, :parse =&gt; false}
1022
- </span><span class="marked1"><a name="line401" /> 401 options = defaults.merge(options)
1023
- </span><span class="marked0"><a name="line402" /> 402 raise InvalidOptionError unless (options.keys - defaults.keys).empty?
1024
- </span><span class="inferred1"><a name="line403" /> 403 # This regular expression needs to be less forgiving or else it would
1025
- </span><span class="inferred0"><a name="line404" /> 404 # match virtually all text. Which isn't exactly what we're going for.
1026
- </span><span class="marked1"><a name="line405" /> 405 extract_regex = /((([a-z\+]+):)[^ \n\&lt;\&gt;\&quot;\\]+[\w\/])/
1027
- </span><span class="marked0"><a name="line406" /> 406 extracted_uris =
1028
- </span><span class="marked1"><a name="line407" /> 407 text.scan(extract_regex).collect { |match| match[0] }
1029
- </span><span class="marked0"><a name="line408" /> 408 sgml_extract_regex = /&lt;[^&gt;]+href=\&quot;([^\&quot;]+?)\&quot;[^&gt;]*&gt;/
1030
- </span><span class="marked1"><a name="line409" /> 409 sgml_extracted_uris =
1031
- </span><span class="inferred0"><a name="line410" /> 410 text.scan(sgml_extract_regex).collect { |match| match[0] }
1032
- </span><span class="marked1"><a name="line411" /> 411 extracted_uris.concat(sgml_extracted_uris - extracted_uris)
1033
- </span><span class="marked0"><a name="line412" /> 412 textile_extract_regex = /\&quot;.+?\&quot;:([^ ]+\/[^ ]+)[ \,\.\;\:\?\!\&lt;\&gt;\&quot;]/i
1034
- </span><span class="marked1"><a name="line413" /> 413 textile_extracted_uris =
1035
- </span><span class="inferred0"><a name="line414" /> 414 text.scan(textile_extract_regex).collect { |match| match[0] }
1036
- </span><span class="marked1"><a name="line415" /> 415 extracted_uris.concat(textile_extracted_uris - extracted_uris)
1037
- </span><span class="marked0"><a name="line416" /> 416 parsed_uris = []
1038
- </span><span class="marked1"><a name="line417" /> 417 base_uri = nil
1039
- </span><span class="marked0"><a name="line418" /> 418 if options[:base] != nil
1040
- </span><span class="marked1"><a name="line419" /> 419 base_uri = options[:base] if options[:base].kind_of?(self)
1041
- </span><span class="marked0"><a name="line420" /> 420 base_uri = self.parse(options[:base].to_s) if base_uri == nil
1042
- </span><span class="inferred1"><a name="line421" /> 421 end
1043
- </span><span class="marked0"><a name="line422" /> 422 for uri_string in extracted_uris
1044
- </span><span class="marked1"><a name="line423" /> 423 begin
1045
- </span><span class="marked0"><a name="line424" /> 424 if base_uri == nil
1046
- </span><span class="marked1"><a name="line425" /> 425 parsed_uris &lt;&lt; self.parse(uri_string)
1047
- </span><span class="inferred0"><a name="line426" /> 426 else
1048
- </span><span class="marked1"><a name="line427" /> 427 parsed_uris &lt;&lt; (base_uri + self.parse(uri_string))
1049
- </span><span class="inferred0"><a name="line428" /> 428 end
1050
- </span><span class="inferred1"><a name="line429" /> 429 rescue Exception
1051
- </span><span class="marked0"><a name="line430" /> 430 nil
1052
- </span><span class="inferred1"><a name="line431" /> 431 end
1053
- </span><span class="inferred0"><a name="line432" /> 432 end
1054
- </span><span class="marked1"><a name="line433" /> 433 parsed_uris.reject! do |uri|
1055
- </span><span class="marked0"><a name="line434" /> 434 (uri.scheme =~ /T\d+/ ||
1056
- </span><span class="marked1"><a name="line435" /> 435 uri.scheme == &quot;xmlns&quot; ||
1057
- </span><span class="marked0"><a name="line436" /> 436 uri.scheme == &quot;xml&quot; ||
1058
- </span><span class="marked1"><a name="line437" /> 437 uri.scheme == &quot;thr&quot; ||
1059
- </span><span class="marked0"><a name="line438" /> 438 uri.scheme == &quot;this&quot; ||
1060
- </span><span class="marked1"><a name="line439" /> 439 uri.scheme == &quot;float&quot; ||
1061
- </span><span class="marked0"><a name="line440" /> 440 uri.scheme == &quot;user&quot; ||
1062
- </span><span class="marked1"><a name="line441" /> 441 uri.scheme == &quot;username&quot; ||
1063
- </span><span class="marked0"><a name="line442" /> 442 uri.scheme == &quot;out&quot;)
1064
- </span><span class="inferred1"><a name="line443" /> 443 end
1065
- </span><span class="marked0"><a name="line444" /> 444 if options[:parse]
1066
- </span><span class="marked1"><a name="line445" /> 445 return parsed_uris
1067
- </span><span class="inferred0"><a name="line446" /> 446 else
1068
- </span><span class="marked1"><a name="line447" /> 447 return parsed_uris.collect { |uri| uri.to_s }
1069
- </span><span class="inferred0"><a name="line448" /> 448 end
1070
- </span><span class="inferred1"><a name="line449" /> 449 end
1071
- </span><span class="inferred0"><a name="line450" /> 450
1072
- </span><span class="inferred1"><a name="line451" /> 451 # Creates a new uri object from component parts. Passing nil for
1073
- </span><span class="inferred0"><a name="line452" /> 452 # any of these parameters is acceptable.
1074
- </span><span class="marked1"><a name="line453" /> 453 def initialize(scheme, user, password, host, port, path, query, fragment)
1075
- </span><span class="marked0"><a name="line454" /> 454 @scheme = scheme
1076
- </span><span class="marked1"><a name="line455" /> 455 @scheme = nil if @scheme.to_s.strip == &quot;&quot;
1077
- </span><span class="marked0"><a name="line456" /> 456 @user = user
1078
- </span><span class="marked1"><a name="line457" /> 457 @password = password
1079
- </span><span class="marked0"><a name="line458" /> 458 @host = host
1080
- </span><span class="marked1"><a name="line459" /> 459 @specified_port = port.to_s
1081
- </span><span class="marked0"><a name="line460" /> 460 @port = port
1082
- </span><span class="marked1"><a name="line461" /> 461 @port = @port.to_s if @port.kind_of?(Fixnum)
1083
- </span><span class="marked0"><a name="line462" /> 462 if @port != nil &amp;&amp; !(@port =~ /^\d+$/)
1084
- </span><span class="marked1"><a name="line463" /> 463 raise InvalidURIError,
1085
- </span><span class="inferred0"><a name="line464" /> 464 &quot;Invalid port number: #{@port.inspect}&quot;
1086
- </span><span class="inferred1"><a name="line465" /> 465 end
1087
- </span><span class="marked0"><a name="line466" /> 466 @port = @port.to_i
1088
- </span><span class="marked1"><a name="line467" /> 467 @port = nil if @port == 0
1089
- </span><span class="marked0"><a name="line468" /> 468 @path = path
1090
- </span><span class="marked1"><a name="line469" /> 469 @query = query
1091
- </span><span class="marked0"><a name="line470" /> 470 @fragment = fragment
1092
- </span><span class="inferred1"><a name="line471" /> 471
1093
- </span><span class="marked0"><a name="line472" /> 472 validate()
1094
- </span><span class="inferred1"><a name="line473" /> 473 end
1095
- </span><span class="inferred0"><a name="line474" /> 474
1096
- </span><span class="inferred1"><a name="line475" /> 475 # Returns the scheme (protocol) for this URI.
1097
- </span><span class="marked0"><a name="line476" /> 476 def scheme
1098
- </span><span class="marked1"><a name="line477" /> 477 return @scheme
1099
- </span><span class="marked0"><a name="line478" /> 478 end
1100
- </span><span class="inferred1"><a name="line479" /> 479
1101
- </span><span class="inferred0"><a name="line480" /> 480 # Sets the scheme (protocol for this URI.)
1102
- </span><span class="marked1"><a name="line481" /> 481 def scheme=(new_scheme)
1103
- </span><span class="marked0"><a name="line482" /> 482 @scheme = new_scheme
1104
- </span><span class="marked1"><a name="line483" /> 483 end
1105
- </span><span class="inferred0"><a name="line484" /> 484
1106
- </span><span class="inferred1"><a name="line485" /> 485 # Returns the user for this URI.
1107
- </span><span class="marked0"><a name="line486" /> 486 def user
1108
- </span><span class="marked1"><a name="line487" /> 487 return @user
1109
- </span><span class="marked0"><a name="line488" /> 488 end
1110
- </span><span class="inferred1"><a name="line489" /> 489
1111
- </span><span class="inferred0"><a name="line490" /> 490 # Sets the user for this URI.
1112
- </span><span class="marked1"><a name="line491" /> 491 def user=(new_user)
1113
- </span><span class="marked0"><a name="line492" /> 492 @user = new_user
1114
- </span><span class="inferred1"><a name="line493" /> 493
1115
- </span><span class="inferred0"><a name="line494" /> 494 # You can't have a nil user with a non-nil password
1116
- </span><span class="marked1"><a name="line495" /> 495 if @password != nil
1117
- </span><span class="marked0"><a name="line496" /> 496 @user = &quot;&quot; if @user.nil?
1118
- </span><span class="inferred1"><a name="line497" /> 497 end
1119
- </span><span class="inferred0"><a name="line498" /> 498
1120
- </span><span class="inferred1"><a name="line499" /> 499 # Reset dependant values
1121
- </span><span class="marked0"><a name="line500" /> 500 @userinfo = nil
1122
- </span><span class="marked1"><a name="line501" /> 501 @authority = nil
1123
- </span><span class="inferred0"><a name="line502" /> 502
1124
- </span><span class="inferred1"><a name="line503" /> 503 # Ensure we haven't created an invalid URI
1125
- </span><span class="marked0"><a name="line504" /> 504 validate()
1126
- </span><span class="inferred1"><a name="line505" /> 505 end
1127
- </span><span class="inferred0"><a name="line506" /> 506
1128
- </span><span class="inferred1"><a name="line507" /> 507 # Returns the password for this URI.
1129
- </span><span class="marked0"><a name="line508" /> 508 def password
1130
- </span><span class="marked1"><a name="line509" /> 509 return @password
1131
- </span><span class="marked0"><a name="line510" /> 510 end
1132
- </span><span class="inferred1"><a name="line511" /> 511
1133
- </span><span class="inferred0"><a name="line512" /> 512 # Sets the password for this URI.
1134
- </span><span class="marked1"><a name="line513" /> 513 def password=(new_password)
1135
- </span><span class="marked0"><a name="line514" /> 514 @password = new_password
1136
- </span><span class="inferred1"><a name="line515" /> 515
1137
- </span><span class="inferred0"><a name="line516" /> 516 # You can't have a nil user with a non-nil password
1138
- </span><span class="marked1"><a name="line517" /> 517 if @password != nil
1139
- </span><span class="marked0"><a name="line518" /> 518 @user = &quot;&quot; if @user.nil?
1140
- </span><span class="inferred1"><a name="line519" /> 519 end
1141
- </span><span class="inferred0"><a name="line520" /> 520
1142
- </span><span class="inferred1"><a name="line521" /> 521 # Reset dependant values
1143
- </span><span class="marked0"><a name="line522" /> 522 @userinfo = nil
1144
- </span><span class="marked1"><a name="line523" /> 523 @authority = nil
1145
- </span><span class="inferred0"><a name="line524" /> 524
1146
- </span><span class="inferred1"><a name="line525" /> 525 # Ensure we haven't created an invalid URI
1147
- </span><span class="marked0"><a name="line526" /> 526 validate()
1148
- </span><span class="inferred1"><a name="line527" /> 527 end
1149
- </span><span class="inferred0"><a name="line528" /> 528
1150
- </span><span class="inferred1"><a name="line529" /> 529 # Returns the username and password segment of this URI.
1151
- </span><span class="marked0"><a name="line530" /> 530 def userinfo
1152
- </span><span class="marked1"><a name="line531" /> 531 if !defined?(@userinfo) || @userinfo.nil?
1153
- </span><span class="marked0"><a name="line532" /> 532 current_user = self.user
1154
- </span><span class="marked1"><a name="line533" /> 533 current_password = self.password
1155
- </span><span class="marked0"><a name="line534" /> 534 if current_user == nil &amp;&amp; current_password == nil
1156
- </span><span class="marked1"><a name="line535" /> 535 @userinfo = nil
1157
- </span><span class="marked0"><a name="line536" /> 536 elsif current_user != nil &amp;&amp; current_password == nil
1158
- </span><span class="marked1"><a name="line537" /> 537 @userinfo = &quot;#{current_user}&quot;
1159
- </span><span class="marked0"><a name="line538" /> 538 elsif current_user != nil &amp;&amp; current_password != nil
1160
- </span><span class="marked1"><a name="line539" /> 539 @userinfo = &quot;#{current_user}:#{current_password}&quot;
1161
- </span><span class="inferred0"><a name="line540" /> 540 end
1162
- </span><span class="inferred1"><a name="line541" /> 541 end
1163
- </span><span class="marked0"><a name="line542" /> 542 return @userinfo
1164
- </span><span class="inferred1"><a name="line543" /> 543 end
1165
- </span><span class="inferred0"><a name="line544" /> 544
1166
- </span><span class="inferred1"><a name="line545" /> 545 # Sets the username and password segment of this URI.
1167
- </span><span class="marked0"><a name="line546" /> 546 def userinfo=(new_userinfo)
1168
- </span><span class="marked1"><a name="line547" /> 547 new_user = new_userinfo.to_s.strip.scan(/^(.*):/).flatten[0]
1169
- </span><span class="marked0"><a name="line548" /> 548 new_password = new_userinfo.to_s.strip.scan(/:(.*)$/).flatten[0]
1170
- </span><span class="inferred1"><a name="line549" /> 549
1171
- </span><span class="inferred0"><a name="line550" /> 550 # Password assigned first to ensure validity in case of nil
1172
- </span><span class="marked1"><a name="line551" /> 551 self.password = new_password
1173
- </span><span class="marked0"><a name="line552" /> 552 self.user = new_user
1174
- </span><span class="inferred1"><a name="line553" /> 553
1175
- </span><span class="inferred0"><a name="line554" /> 554 # Reset dependant values
1176
- </span><span class="marked1"><a name="line555" /> 555 @authority = nil
1177
- </span><span class="inferred0"><a name="line556" /> 556
1178
- </span><span class="inferred1"><a name="line557" /> 557 # Ensure we haven't created an invalid URI
1179
- </span><span class="marked0"><a name="line558" /> 558 validate()
1180
- </span><span class="inferred1"><a name="line559" /> 559 end
1181
- </span><span class="inferred0"><a name="line560" /> 560
1182
- </span><span class="inferred1"><a name="line561" /> 561 # Returns the host for this URI.
1183
- </span><span class="marked0"><a name="line562" /> 562 def host
1184
- </span><span class="marked1"><a name="line563" /> 563 return @host
1185
- </span><span class="marked0"><a name="line564" /> 564 end
1186
- </span><span class="inferred1"><a name="line565" /> 565
1187
- </span><span class="inferred0"><a name="line566" /> 566 # Sets the host for this URI.
1188
- </span><span class="marked1"><a name="line567" /> 567 def host=(new_host)
1189
- </span><span class="marked0"><a name="line568" /> 568 @host = new_host
1190
- </span><span class="inferred1"><a name="line569" /> 569
1191
- </span><span class="inferred0"><a name="line570" /> 570 # Reset dependant values
1192
- </span><span class="marked1"><a name="line571" /> 571 @authority = nil
1193
- </span><span class="inferred0"><a name="line572" /> 572
1194
- </span><span class="inferred1"><a name="line573" /> 573 # Ensure we haven't created an invalid URI
1195
- </span><span class="marked0"><a name="line574" /> 574 validate()
1196
- </span><span class="inferred1"><a name="line575" /> 575 end
1197
- </span><span class="inferred0"><a name="line576" /> 576
1198
- </span><span class="inferred1"><a name="line577" /> 577 # Returns the authority segment of this URI.
1199
- </span><span class="marked0"><a name="line578" /> 578 def authority
1200
- </span><span class="marked1"><a name="line579" /> 579 if !defined?(@authority) || @authority.nil?
1201
- </span><span class="marked0"><a name="line580" /> 580 return nil if self.host.nil?
1202
- </span><span class="marked1"><a name="line581" /> 581 @authority = &quot;&quot;
1203
- </span><span class="marked0"><a name="line582" /> 582 if self.userinfo != nil
1204
- </span><span class="marked1"><a name="line583" /> 583 @authority &lt;&lt; &quot;#{self.userinfo}@&quot;
1205
- </span><span class="inferred0"><a name="line584" /> 584 end
1206
- </span><span class="marked1"><a name="line585" /> 585 @authority &lt;&lt; self.host
1207
- </span><span class="marked0"><a name="line586" /> 586 if self.specified_port != nil
1208
- </span><span class="marked1"><a name="line587" /> 587 @authority &lt;&lt; &quot;:#{self.specified_port}&quot;
1209
- </span><span class="inferred0"><a name="line588" /> 588 end
1210
- </span><span class="inferred1"><a name="line589" /> 589 end
1211
- </span><span class="marked0"><a name="line590" /> 590 return @authority
1212
- </span><span class="inferred1"><a name="line591" /> 591 end
1213
- </span><span class="inferred0"><a name="line592" /> 592
1214
- </span><span class="inferred1"><a name="line593" /> 593 # Sets the authority segment of this URI.
1215
- </span><span class="marked0"><a name="line594" /> 594 def authority=(new_authority)
1216
- </span><span class="marked1"><a name="line595" /> 595 if new_authority != nil
1217
- </span><span class="marked0"><a name="line596" /> 596 new_userinfo = new_authority.scan(/^([^\[\]]*)@/).flatten[0]
1218
- </span><span class="marked1"><a name="line597" /> 597 if new_userinfo != nil
1219
- </span><span class="marked0"><a name="line598" /> 598 new_user = new_userinfo.strip.scan(/^([^:]*):?/).flatten[0]
1220
- </span><span class="marked1"><a name="line599" /> 599 new_password = new_userinfo.strip.scan(/:(.*)$/).flatten[0]
1221
- </span><span class="inferred0"><a name="line600" /> 600 end
1222
- </span><span class="marked1"><a name="line601" /> 601 new_host =
1223
- </span><span class="inferred0"><a name="line602" /> 602 new_authority.gsub(/^([^\[\]]*)@/, &quot;&quot;).gsub(/:([^:@\[\]]*?)$/, &quot;&quot;)
1224
- </span><span class="marked1"><a name="line603" /> 603 new_port =
1225
- </span><span class="inferred0"><a name="line604" /> 604 new_authority.scan(/:([^:@\[\]]*?)$/).flatten[0]
1226
- </span><span class="inferred1"><a name="line605" /> 605 end
1227
- </span><span class="marked0"><a name="line606" /> 606 new_port = nil if new_port == &quot;&quot;
1228
- </span><span class="inferred1"><a name="line607" /> 607
1229
- </span><span class="inferred0"><a name="line608" /> 608 # Password assigned first to ensure validity in case of nil
1230
- </span><span class="marked1"><a name="line609" /> 609 self.password = new_password
1231
- </span><span class="marked0"><a name="line610" /> 610 self.user = new_user
1232
- </span><span class="marked1"><a name="line611" /> 611 self.host = new_host
1233
- </span><span class="inferred0"><a name="line612" /> 612
1234
- </span><span class="inferred1"><a name="line613" /> 613 # Port reset to allow port normalization
1235
- </span><span class="marked0"><a name="line614" /> 614 @port = nil
1236
- </span><span class="marked1"><a name="line615" /> 615 @specified_port = new_port
1237
- </span><span class="inferred0"><a name="line616" /> 616
1238
- </span><span class="inferred1"><a name="line617" /> 617 # Ensure we haven't created an invalid URI
1239
- </span><span class="marked0"><a name="line618" /> 618 validate()
1240
- </span><span class="inferred1"><a name="line619" /> 619 end
1241
- </span><span class="inferred0"><a name="line620" /> 620
1242
- </span><span class="inferred1"><a name="line621" /> 621 # Returns an array of known ip-based schemes. These schemes typically
1243
- </span><span class="inferred0"><a name="line622" /> 622 # use a similar URI form:
1244
- </span><span class="inferred1"><a name="line623" /> 623 # //&lt;user&gt;:&lt;password&gt;@&lt;host&gt;:&lt;port&gt;/&lt;url-path&gt;
1245
- </span><span class="marked0"><a name="line624" /> 624 def self.ip_based_schemes
1246
- </span><span class="marked1"><a name="line625" /> 625 return self.scheme_mapping.keys
1247
- </span><span class="marked0"><a name="line626" /> 626 end
1248
- </span><span class="inferred1"><a name="line627" /> 627
1249
- </span><span class="inferred0"><a name="line628" /> 628 # Returns a hash of common IP-based schemes and their default port
1250
- </span><span class="inferred1"><a name="line629" /> 629 # numbers. Adding new schemes to this hash, as necessary, will allow
1251
- </span><span class="inferred0"><a name="line630" /> 630 # for better URI normalization.
1252
- </span><span class="marked1"><a name="line631" /> 631 def self.scheme_mapping
1253
- </span><span class="marked0"><a name="line632" /> 632 if !defined?(@protocol_mapping) || @protocol_mapping.nil?
1254
- </span><span class="marked1"><a name="line633" /> 633 @protocol_mapping = {
1255
- </span><span class="inferred0"><a name="line634" /> 634 &quot;http&quot; =&gt; 80,
1256
- </span><span class="inferred1"><a name="line635" /> 635 &quot;https&quot; =&gt; 443,
1257
- </span><span class="inferred0"><a name="line636" /> 636 &quot;ftp&quot; =&gt; 21,
1258
- </span><span class="inferred1"><a name="line637" /> 637 &quot;tftp&quot; =&gt; 69,
1259
- </span><span class="inferred0"><a name="line638" /> 638 &quot;ssh&quot; =&gt; 22,
1260
- </span><span class="inferred1"><a name="line639" /> 639 &quot;svn+ssh&quot; =&gt; 22,
1261
- </span><span class="inferred0"><a name="line640" /> 640 &quot;telnet&quot; =&gt; 23,
1262
- </span><span class="inferred1"><a name="line641" /> 641 &quot;nntp&quot; =&gt; 119,
1263
- </span><span class="inferred0"><a name="line642" /> 642 &quot;gopher&quot; =&gt; 70,
1264
- </span><span class="inferred1"><a name="line643" /> 643 &quot;wais&quot; =&gt; 210,
1265
- </span><span class="inferred0"><a name="line644" /> 644 &quot;ldap&quot; =&gt; 389,
1266
- </span><span class="inferred1"><a name="line645" /> 645 &quot;prospero&quot; =&gt; 1525
1267
- </span><span class="inferred0"><a name="line646" /> 646 }
1268
- </span><span class="inferred1"><a name="line647" /> 647 end
1269
- </span><span class="marked0"><a name="line648" /> 648 return @protocol_mapping
1270
- </span><span class="inferred1"><a name="line649" /> 649 end
1271
- </span><span class="inferred0"><a name="line650" /> 650
1272
- </span><span class="inferred1"><a name="line651" /> 651 # Returns the port number for this URI. This method will normalize to the
1273
- </span><span class="inferred0"><a name="line652" /> 652 # default port for the URI's scheme if the port isn't explicitly specified
1274
- </span><span class="inferred1"><a name="line653" /> 653 # in the URI.
1275
- </span><span class="marked0"><a name="line654" /> 654 def port
1276
- </span><span class="marked1"><a name="line655" /> 655 if @port.to_i == 0
1277
- </span><span class="marked0"><a name="line656" /> 656 if self.scheme.nil?
1278
- </span><span class="marked1"><a name="line657" /> 657 @port = nil
1279
- </span><span class="inferred0"><a name="line658" /> 658 else
1280
- </span><span class="marked1"><a name="line659" /> 659 @port = self.class.scheme_mapping[self.scheme.strip.downcase]
1281
- </span><span class="inferred0"><a name="line660" /> 660 end
1282
- </span><span class="marked1"><a name="line661" /> 661 return @port
1283
- </span><span class="inferred0"><a name="line662" /> 662 else
1284
- </span><span class="marked1"><a name="line663" /> 663 @port = @port.to_i
1285
- </span><span class="marked0"><a name="line664" /> 664 return @port
1286
- </span><span class="inferred1"><a name="line665" /> 665 end
1287
- </span><span class="marked0"><a name="line666" /> 666 end
1288
- </span><span class="inferred1"><a name="line667" /> 667
1289
- </span><span class="inferred0"><a name="line668" /> 668 # Sets the port for this URI.
1290
- </span><span class="marked1"><a name="line669" /> 669 def port=(new_port)
1291
- </span><span class="marked0"><a name="line670" /> 670 @port = new_port.to_s.to_i
1292
- </span><span class="marked1"><a name="line671" /> 671 @specified_port = @port
1293
- </span><span class="marked0"><a name="line672" /> 672 @authority = nil
1294
- </span><span class="inferred1"><a name="line673" /> 673 end
1295
- </span><span class="inferred0"><a name="line674" /> 674
1296
- </span><span class="inferred1"><a name="line675" /> 675 # Returns the port number that was actually specified in the URI string.
1297
- </span><span class="marked0"><a name="line676" /> 676 def specified_port
1298
- </span><span class="marked1"><a name="line677" /> 677 port = @specified_port.to_s.to_i
1299
- </span><span class="marked0"><a name="line678" /> 678 if port == 0
1300
- </span><span class="marked1"><a name="line679" /> 679 return nil
1301
- </span><span class="inferred0"><a name="line680" /> 680 else
1302
- </span><span class="marked1"><a name="line681" /> 681 return port
1303
- </span><span class="inferred0"><a name="line682" /> 682 end
1304
- </span><span class="inferred1"><a name="line683" /> 683 end
1305
- </span><span class="inferred0"><a name="line684" /> 684
1306
- </span><span class="inferred1"><a name="line685" /> 685 # Returns the path for this URI.
1307
- </span><span class="marked0"><a name="line686" /> 686 def path
1308
- </span><span class="marked1"><a name="line687" /> 687 return @path
1309
- </span><span class="marked0"><a name="line688" /> 688 end
1310
- </span><span class="inferred1"><a name="line689" /> 689
1311
- </span><span class="inferred0"><a name="line690" /> 690 # Sets the path for this URI.
1312
- </span><span class="marked1"><a name="line691" /> 691 def path=(new_path)
1313
- </span><span class="marked0"><a name="line692" /> 692 @path = new_path
1314
- </span><span class="marked1"><a name="line693" /> 693 end
1315
- </span><span class="inferred0"><a name="line694" /> 694
1316
- </span><span class="inferred1"><a name="line695" /> 695 # Returns the basename, if any, of the file at the path being referenced.
1317
- </span><span class="inferred0"><a name="line696" /> 696 # Returns nil if there is no path component.
1318
- </span><span class="marked1"><a name="line697" /> 697 def basename
1319
- </span><span class="marked0"><a name="line698" /> 698 return nil if self.path == nil
1320
- </span><span class="marked1"><a name="line699" /> 699 return File.basename(self.path).gsub(/;[^\/]*$/, &quot;&quot;)
1321
- </span><span class="inferred0"><a name="line700" /> 700 end
1322
- </span><span class="inferred1"><a name="line701" /> 701
1323
- </span><span class="inferred0"><a name="line702" /> 702 # Returns the extension, if any, of the file at the path being referenced.
1324
- </span><span class="inferred1"><a name="line703" /> 703 # Returns &quot;&quot; if there is no extension or nil if there is no path
1325
- </span><span class="inferred0"><a name="line704" /> 704 # component.
1326
- </span><span class="marked1"><a name="line705" /> 705 def extname
1327
- </span><span class="marked0"><a name="line706" /> 706 return nil if self.path == nil
1328
- </span><span class="marked1"><a name="line707" /> 707 return File.extname(self.basename.gsub(/;[^\/]*$/, &quot;&quot;))
1329
- </span><span class="inferred0"><a name="line708" /> 708 end
1330
- </span><span class="inferred1"><a name="line709" /> 709
1331
- </span><span class="inferred0"><a name="line710" /> 710 # Returns the query string for this URI.
1332
- </span><span class="marked1"><a name="line711" /> 711 def query
1333
- </span><span class="marked0"><a name="line712" /> 712 return @query
1334
- </span><span class="marked1"><a name="line713" /> 713 end
1335
- </span><span class="inferred0"><a name="line714" /> 714
1336
- </span><span class="inferred1"><a name="line715" /> 715 # Sets the query string for this URI.
1337
- </span><span class="marked0"><a name="line716" /> 716 def query=(new_query)
1338
- </span><span class="marked1"><a name="line717" /> 717 @query = new_query
1339
- </span><span class="marked0"><a name="line718" /> 718 end
1340
- </span><span class="inferred1"><a name="line719" /> 719
1341
- </span><span class="inferred0"><a name="line720" /> 720 # Returns the fragment for this URI.
1342
- </span><span class="marked1"><a name="line721" /> 721 def fragment
1343
- </span><span class="marked0"><a name="line722" /> 722 return @fragment
1344
- </span><span class="marked1"><a name="line723" /> 723 end
1345
- </span><span class="inferred0"><a name="line724" /> 724
1346
- </span><span class="inferred1"><a name="line725" /> 725 # Sets the fragment for this URI.
1347
- </span><span class="marked0"><a name="line726" /> 726 def fragment=(new_fragment)
1348
- </span><span class="marked1"><a name="line727" /> 727 @fragment = new_fragment
1349
- </span><span class="marked0"><a name="line728" /> 728 end
1350
- </span><span class="inferred1"><a name="line729" /> 729
1351
- </span><span class="inferred0"><a name="line730" /> 730 # Returns true if the URI uses an IP-based protocol.
1352
- </span><span class="marked1"><a name="line731" /> 731 def ip_based?
1353
- </span><span class="marked0"><a name="line732" /> 732 return false if self.scheme.nil?
1354
- </span><span class="marked1"><a name="line733" /> 733 return self.class.ip_based_schemes.include?(self.scheme.strip.downcase)
1355
- </span><span class="inferred0"><a name="line734" /> 734 end
1356
- </span><span class="inferred1"><a name="line735" /> 735
1357
- </span><span class="inferred0"><a name="line736" /> 736 # Returns true if this URI is known to be relative.
1358
- </span><span class="marked1"><a name="line737" /> 737 def relative?
1359
- </span><span class="marked0"><a name="line738" /> 738 return self.scheme.nil?
1360
- </span><span class="marked1"><a name="line739" /> 739 end
1361
- </span><span class="inferred0"><a name="line740" /> 740
1362
- </span><span class="inferred1"><a name="line741" /> 741 # Returns true if this URI is known to be absolute.
1363
- </span><span class="marked0"><a name="line742" /> 742 def absolute?
1364
- </span><span class="marked1"><a name="line743" /> 743 return !relative?
1365
- </span><span class="marked0"><a name="line744" /> 744 end
1366
- </span><span class="inferred1"><a name="line745" /> 745
1367
- </span><span class="inferred0"><a name="line746" /> 746 # Joins two URIs together.
1368
- </span><span class="marked1"><a name="line747" /> 747 def +(uri)
1369
- </span><span class="marked0"><a name="line748" /> 748 if !uri.kind_of?(self.class)
1370
- </span><span class="marked1"><a name="line749" /> 749 uri = URI.parse(uri.to_s)
1371
- </span><span class="inferred0"><a name="line750" /> 750 end
1372
- </span><span class="marked1"><a name="line751" /> 751 if uri.to_s == &quot;&quot;
1373
- </span><span class="marked0"><a name="line752" /> 752 return self.dup
1374
- </span><span class="inferred1"><a name="line753" /> 753 end
1375
- </span><span class="inferred0"><a name="line754" /> 754
1376
- </span><span class="marked1"><a name="line755" /> 755 joined_scheme = nil
1377
- </span><span class="marked0"><a name="line756" /> 756 joined_user = nil
1378
- </span><span class="marked1"><a name="line757" /> 757 joined_password = nil
1379
- </span><span class="marked0"><a name="line758" /> 758 joined_host = nil
1380
- </span><span class="marked1"><a name="line759" /> 759 joined_port = nil
1381
- </span><span class="marked0"><a name="line760" /> 760 joined_path = nil
1382
- </span><span class="marked1"><a name="line761" /> 761 joined_query = nil
1383
- </span><span class="marked0"><a name="line762" /> 762 joined_fragment = nil
1384
- </span><span class="inferred1"><a name="line763" /> 763
1385
- </span><span class="inferred0"><a name="line764" /> 764 # Section 5.2.2 of RFC 3986
1386
- </span><span class="marked1"><a name="line765" /> 765 if uri.scheme != nil
1387
- </span><span class="marked0"><a name="line766" /> 766 joined_scheme = uri.scheme
1388
- </span><span class="marked1"><a name="line767" /> 767 joined_user = uri.user
1389
- </span><span class="marked0"><a name="line768" /> 768 joined_password = uri.password
1390
- </span><span class="marked1"><a name="line769" /> 769 joined_host = uri.host
1391
- </span><span class="marked0"><a name="line770" /> 770 joined_port = uri.specified_port
1392
- </span><span class="marked1"><a name="line771" /> 771 joined_path = self.class.normalize_path(uri.path)
1393
- </span><span class="marked0"><a name="line772" /> 772 joined_query = uri.query
1394
- </span><span class="inferred1"><a name="line773" /> 773 else
1395
- </span><span class="marked0"><a name="line774" /> 774 if uri.authority != nil
1396
- </span><span class="marked1"><a name="line775" /> 775 joined_user = uri.user
1397
- </span><span class="marked0"><a name="line776" /> 776 joined_password = uri.password
1398
- </span><span class="marked1"><a name="line777" /> 777 joined_host = uri.host
1399
- </span><span class="marked0"><a name="line778" /> 778 joined_port = uri.specified_port
1400
- </span><span class="marked1"><a name="line779" /> 779 joined_path = self.class.normalize_path(uri.path)
1401
- </span><span class="marked0"><a name="line780" /> 780 joined_query = uri.query
1402
- </span><span class="inferred1"><a name="line781" /> 781 else
1403
- </span><span class="marked0"><a name="line782" /> 782 if uri.path == nil || uri.path == &quot;&quot;
1404
- </span><span class="marked1"><a name="line783" /> 783 joined_path = self.path
1405
- </span><span class="marked0"><a name="line784" /> 784 if uri.query != nil
1406
- </span><span class="marked1"><a name="line785" /> 785 joined_query = uri.query
1407
- </span><span class="inferred0"><a name="line786" /> 786 else
1408
- </span><span class="marked1"><a name="line787" /> 787 joined_query = self.query
1409
- </span><span class="inferred0"><a name="line788" /> 788 end
1410
- </span><span class="inferred1"><a name="line789" /> 789 else
1411
- </span><span class="marked0"><a name="line790" /> 790 if uri.path[0..0] == &quot;/&quot;
1412
- </span><span class="marked1"><a name="line791" /> 791 joined_path = self.class.normalize_path(uri.path)
1413
- </span><span class="inferred0"><a name="line792" /> 792 else
1414
- </span><span class="marked1"><a name="line793" /> 793 base_path = self.path.nil? ? &quot;&quot; : self.path.dup
1415
- </span><span class="marked0"><a name="line794" /> 794 base_path = self.class.normalize_path(base_path)
1416
- </span><span class="marked1"><a name="line795" /> 795 base_path.gsub!(/\/[^\/]+$/, &quot;/&quot;)
1417
- </span><span class="marked0"><a name="line796" /> 796 joined_path = self.class.normalize_path(base_path + uri.path)
1418
- </span><span class="inferred1"><a name="line797" /> 797 end
1419
- </span><span class="marked0"><a name="line798" /> 798 joined_query = uri.query
1420
- </span><span class="inferred1"><a name="line799" /> 799 end
1421
- </span><span class="marked0"><a name="line800" /> 800 joined_user = self.user
1422
- </span><span class="marked1"><a name="line801" /> 801 joined_password = self.password
1423
- </span><span class="marked0"><a name="line802" /> 802 joined_host = self.host
1424
- </span><span class="marked1"><a name="line803" /> 803 joined_port = self.specified_port
1425
- </span><span class="inferred0"><a name="line804" /> 804 end
1426
- </span><span class="marked1"><a name="line805" /> 805 joined_scheme = self.scheme
1427
- </span><span class="inferred0"><a name="line806" /> 806 end
1428
- </span><span class="marked1"><a name="line807" /> 807 joined_fragment = uri.fragment
1429
- </span><span class="inferred0"><a name="line808" /> 808
1430
- </span><span class="marked1"><a name="line809" /> 809 return Addressable::URI.new(
1431
- </span><span class="inferred0"><a name="line810" /> 810 joined_scheme,
1432
- </span><span class="inferred1"><a name="line811" /> 811 joined_user,
1433
- </span><span class="inferred0"><a name="line812" /> 812 joined_password,
1434
- </span><span class="inferred1"><a name="line813" /> 813 joined_host,
1435
- </span><span class="inferred0"><a name="line814" /> 814 joined_port,
1436
- </span><span class="inferred1"><a name="line815" /> 815 joined_path,
1437
- </span><span class="inferred0"><a name="line816" /> 816 joined_query,
1438
- </span><span class="inferred1"><a name="line817" /> 817 joined_fragment
1439
- </span><span class="marked0"><a name="line818" /> 818 )
1440
- </span><span class="inferred1"><a name="line819" /> 819 end
1441
- </span><span class="inferred0"><a name="line820" /> 820
1442
- </span><span class="inferred1"><a name="line821" /> 821 # Merges two URIs together.
1443
- </span><span class="marked0"><a name="line822" /> 822 def merge(uri)
1444
- </span><span class="marked1"><a name="line823" /> 823 return self + uri
1445
- </span><span class="marked0"><a name="line824" /> 824 end
1446
- </span><span class="inferred1"><a name="line825" /> 825
1447
- </span><span class="inferred0"><a name="line826" /> 826 # Destructive form of merge.
1448
- </span><span class="marked1"><a name="line827" /> 827 def merge!(uri)
1449
- </span><span class="marked0"><a name="line828" /> 828 replace_self(self.merge(uri))
1450
- </span><span class="marked1"><a name="line829" /> 829 end
1451
- </span><span class="inferred0"><a name="line830" /> 830
1452
- </span><span class="inferred1"><a name="line831" /> 831 # Returns the shortest normalized relative form of this URI that uses the
1453
- </span><span class="inferred0"><a name="line832" /> 832 # supplied URI as a base for resolution. Returns an absolute URI if
1454
- </span><span class="inferred1"><a name="line833" /> 833 # necessary.
1455
- </span><span class="marked0"><a name="line834" /> 834 def route_from(uri)
1456
- </span><span class="marked1"><a name="line835" /> 835 uri = uri.kind_of?(self.class) ? uri : self.class.parse(uri.to_s)
1457
- </span><span class="marked0"><a name="line836" /> 836 uri = uri.normalize
1458
- </span><span class="marked1"><a name="line837" /> 837 normalized_self = self.normalize
1459
- </span><span class="marked0"><a name="line838" /> 838 if normalized_self.relative?
1460
- </span><span class="marked1"><a name="line839" /> 839 raise ArgumentError, &quot;Expected absolute URI, got: #{self.to_s}&quot;
1461
- </span><span class="inferred0"><a name="line840" /> 840 end
1462
- </span><span class="marked1"><a name="line841" /> 841 if uri.relative?
1463
- </span><span class="marked0"><a name="line842" /> 842 raise ArgumentError, &quot;Expected absolute URI, got: #{self.to_s}&quot;
1464
- </span><span class="inferred1"><a name="line843" /> 843 end
1465
- </span><span class="marked0"><a name="line844" /> 844 if normalized_self == uri
1466
- </span><span class="marked1"><a name="line845" /> 845 return Addressable::URI.parse(&quot;##{normalized_self.fragment}&quot;)
1467
- </span><span class="inferred0"><a name="line846" /> 846 end
1468
- </span><span class="marked1"><a name="line847" /> 847 segments = normalized_self.to_h
1469
- </span><span class="marked0"><a name="line848" /> 848 if normalized_self.scheme == uri.scheme
1470
- </span><span class="marked1"><a name="line849" /> 849 segments[:scheme] = nil
1471
- </span><span class="marked0"><a name="line850" /> 850 if normalized_self.authority == uri.authority
1472
- </span><span class="marked1"><a name="line851" /> 851 segments[:user] = nil
1473
- </span><span class="marked0"><a name="line852" /> 852 segments[:password] = nil
1474
- </span><span class="marked1"><a name="line853" /> 853 segments[:host] = nil
1475
- </span><span class="marked0"><a name="line854" /> 854 segments[:port] = nil
1476
- </span><span class="marked1"><a name="line855" /> 855 if normalized_self.path == uri.path
1477
- </span><span class="marked0"><a name="line856" /> 856 segments[:path] = nil
1478
- </span><span class="marked1"><a name="line857" /> 857 if normalized_self.query == uri.query
1479
- </span><span class="marked0"><a name="line858" /> 858 segments[:query] = nil
1480
- </span><span class="inferred1"><a name="line859" /> 859 end
1481
- </span><span class="inferred0"><a name="line860" /> 860 end
1482
- </span><span class="inferred1"><a name="line861" /> 861 end
904
+ </span><span class="inferred1"><a name="line283" /> 283 # Pattern failed to match URI.
905
+ </span><span class="marked0"><a name="line284" /> 284 return nil
906
+ </span><span class="inferred1"><a name="line285" /> 285 end
907
+ </span><span class="inferred0"><a name="line286" /> 286 end
908
+ </span><span class="inferred1"><a name="line287" /> 287
909
+ </span><span class="inferred0"><a name="line288" /> 288 # Joins several uris together.
910
+ </span><span class="marked1"><a name="line289" /> 289 def self.join(*uris)
911
+ </span><span class="marked0"><a name="line290" /> 290 uri_objects = uris.collect do |uri|
912
+ </span><span class="marked1"><a name="line291" /> 291 uri.kind_of?(self) ? uri : self.parse(uri.to_s)
913
+ </span><span class="inferred0"><a name="line292" /> 292 end
914
+ </span><span class="marked1"><a name="line293" /> 293 result = uri_objects.shift.dup
915
+ </span><span class="marked0"><a name="line294" /> 294 for uri in uri_objects
916
+ </span><span class="marked1"><a name="line295" /> 295 result.merge!(uri)
917
+ </span><span class="inferred0"><a name="line296" /> 296 end
918
+ </span><span class="marked1"><a name="line297" /> 297 return result
919
+ </span><span class="inferred0"><a name="line298" /> 298 end
920
+ </span><span class="inferred1"><a name="line299" /> 299
921
+ </span><span class="inferred0"><a name="line300" /> 300 # Percent encodes a URI segment. Returns a string. Takes an optional
922
+ </span><span class="inferred1"><a name="line301" /> 301 # character class parameter, which should be specified as a string
923
+ </span><span class="inferred0"><a name="line302" /> 302 # containing a regular expression character class (not including the
924
+ </span><span class="inferred1"><a name="line303" /> 303 # surrounding square brackets). The character class parameter defaults
925
+ </span><span class="inferred0"><a name="line304" /> 304 # to the reserved plus unreserved character classes specified in
926
+ </span><span class="inferred1"><a name="line305" /> 305 # RFC 3986. Usage of the constants within the CharacterClasses module is
927
+ </span><span class="inferred0"><a name="line306" /> 306 # highly recommended when using this method.
928
+ </span><span class="inferred1"><a name="line307" /> 307 #
929
+ </span><span class="inferred0"><a name="line308" /> 308 # An example:
930
+ </span><span class="inferred1"><a name="line309" /> 309 #
931
+ </span><span class="inferred0"><a name="line310" /> 310 # Addressable::URI.escape_segment(&quot;simple-example&quot;, &quot;b-zB-Z0-9&quot;)
932
+ </span><span class="inferred1"><a name="line311" /> 311 # =&gt; &quot;simple%2Dex%61mple&quot;
933
+ </span><span class="marked0"><a name="line312" /> 312 def self.encode_segment(segment, character_class=
934
+ </span><span class="inferred1"><a name="line313" /> 313 Addressable::URI::CharacterClasses::RESERVED +
935
+ </span><span class="marked0"><a name="line314" /> 314 Addressable::URI::CharacterClasses::UNRESERVED)
936
+ </span><span class="marked1"><a name="line315" /> 315 return nil if segment.nil?
937
+ </span><span class="inferred0"><a name="line316" /> 316 return segment.gsub(
938
+ </span><span class="inferred1"><a name="line317" /> 317 /[^#{character_class}]/
939
+ </span><span class="inferred0"><a name="line318" /> 318 ) do |sequence|
940
+ </span><span class="marked1"><a name="line319" /> 319 (&quot;%&quot; + sequence.unpack('C')[0].to_s(16).upcase)
941
+ </span><span class="marked0"><a name="line320" /> 320 end
942
+ </span><span class="inferred1"><a name="line321" /> 321 end
943
+ </span><span class="inferred0"><a name="line322" /> 322
944
+ </span><span class="inferred1"><a name="line323" /> 323 # Unencodes any percent encoded characters within a URI segment.
945
+ </span><span class="inferred0"><a name="line324" /> 324 # Returns a string.
946
+ </span><span class="marked1"><a name="line325" /> 325 def self.unencode_segment(segment)
947
+ </span><span class="marked0"><a name="line326" /> 326 return nil if segment.nil?
948
+ </span><span class="inferred1"><a name="line327" /> 327 return segment.to_s.gsub(/%[0-9a-f]{2}/i) do |sequence|
949
+ </span><span class="marked0"><a name="line328" /> 328 sequence[1..3].to_i(16).chr
950
+ </span><span class="marked1"><a name="line329" /> 329 end
951
+ </span><span class="inferred0"><a name="line330" /> 330 end
952
+ </span><span class="inferred1"><a name="line331" /> 331
953
+ </span><span class="inferred0"><a name="line332" /> 332 # Percent encodes any special characters in the URI. This method does
954
+ </span><span class="inferred1"><a name="line333" /> 333 # not take IRIs or IDNs into account.
955
+ </span><span class="marked0"><a name="line334" /> 334 def self.encode(uri)
956
+ </span><span class="marked1"><a name="line335" /> 335 uri_object = uri.kind_of?(self) ? uri : self.parse(uri.to_s)
957
+ </span><span class="marked0"><a name="line336" /> 336 return Addressable::URI.new(
958
+ </span><span class="marked1"><a name="line337" /> 337 self.encode_segment(uri_object.scheme,
959
+ </span><span class="inferred0"><a name="line338" /> 338 Addressable::URI::CharacterClasses::SCHEME),
960
+ </span><span class="marked1"><a name="line339" /> 339 self.encode_segment(uri_object.user,
961
+ </span><span class="inferred0"><a name="line340" /> 340 Addressable::URI::CharacterClasses::AUTHORITY),
962
+ </span><span class="marked1"><a name="line341" /> 341 self.encode_segment(uri_object.password,
963
+ </span><span class="inferred0"><a name="line342" /> 342 Addressable::URI::CharacterClasses::AUTHORITY),
964
+ </span><span class="marked1"><a name="line343" /> 343 self.encode_segment(uri_object.host,
965
+ </span><span class="inferred0"><a name="line344" /> 344 Addressable::URI::CharacterClasses::AUTHORITY),
966
+ </span><span class="marked1"><a name="line345" /> 345 self.encode_segment(uri_object.specified_port,
967
+ </span><span class="inferred0"><a name="line346" /> 346 Addressable::URI::CharacterClasses::AUTHORITY),
968
+ </span><span class="marked1"><a name="line347" /> 347 self.encode_segment(uri_object.path,
969
+ </span><span class="inferred0"><a name="line348" /> 348 Addressable::URI::CharacterClasses::PATH),
970
+ </span><span class="marked1"><a name="line349" /> 349 self.encode_segment(uri_object.query,
971
+ </span><span class="inferred0"><a name="line350" /> 350 Addressable::URI::CharacterClasses::QUERY),
972
+ </span><span class="marked1"><a name="line351" /> 351 self.encode_segment(uri_object.fragment,
973
+ </span><span class="inferred0"><a name="line352" /> 352 Addressable::URI::CharacterClasses::FRAGMENT)
974
+ </span><span class="marked1"><a name="line353" /> 353 ).to_s
975
+ </span><span class="inferred0"><a name="line354" /> 354 end
976
+ </span><span class="inferred1"><a name="line355" /> 355
977
+ </span><span class="marked0"><a name="line356" /> 356 class &lt;&lt; self
978
+ </span><span class="marked1"><a name="line357" /> 357 alias_method :escape, :encode
979
+ </span><span class="inferred0"><a name="line358" /> 358 end
980
+ </span><span class="inferred1"><a name="line359" /> 359
981
+ </span><span class="inferred0"><a name="line360" /> 360 # Normalizes the encoding of a URI. Characters within a hostname are
982
+ </span><span class="inferred1"><a name="line361" /> 361 # not percent encoded to allow for internationalized domain names.
983
+ </span><span class="marked0"><a name="line362" /> 362 def self.normalized_encode(uri)
984
+ </span><span class="marked1"><a name="line363" /> 363 uri_object = uri.kind_of?(self) ? uri : self.parse(uri.to_s)
985
+ </span><span class="marked0"><a name="line364" /> 364 segments = {
986
+ </span><span class="marked1"><a name="line365" /> 365 :scheme =&gt; self.unencode_segment(uri_object.scheme),
987
+ </span><span class="marked0"><a name="line366" /> 366 :user =&gt; self.unencode_segment(uri_object.user),
988
+ </span><span class="marked1"><a name="line367" /> 367 :password =&gt; self.unencode_segment(uri_object.password),
989
+ </span><span class="marked0"><a name="line368" /> 368 :host =&gt; self.unencode_segment(uri_object.host),
990
+ </span><span class="marked1"><a name="line369" /> 369 :port =&gt; self.unencode_segment(uri_object.specified_port),
991
+ </span><span class="marked0"><a name="line370" /> 370 :path =&gt; self.unencode_segment(uri_object.path),
992
+ </span><span class="marked1"><a name="line371" /> 371 :query =&gt; self.unencode_segment(uri_object.query),
993
+ </span><span class="marked0"><a name="line372" /> 372 :fragment =&gt; self.unencode_segment(uri_object.fragment)
994
+ </span><span class="inferred1"><a name="line373" /> 373 }
995
+ </span><span class="marked0"><a name="line374" /> 374 if URI::IDNA.send(:use_libidn?)
996
+ </span><span class="marked1"><a name="line375" /> 375 segments.each do |key, value|
997
+ </span><span class="marked0"><a name="line376" /> 376 if value != nil
998
+ </span><span class="marked1"><a name="line377" /> 377 segments[key] = IDN::Stringprep.nfkc_normalize(value.to_s)
999
+ </span><span class="inferred0"><a name="line378" /> 378 end
1000
+ </span><span class="inferred1"><a name="line379" /> 379 end
1001
+ </span><span class="inferred0"><a name="line380" /> 380 end
1002
+ </span><span class="marked1"><a name="line381" /> 381 return Addressable::URI.new(
1003
+ </span><span class="marked0"><a name="line382" /> 382 self.encode_segment(segments[:scheme],
1004
+ </span><span class="inferred1"><a name="line383" /> 383 Addressable::URI::CharacterClasses::SCHEME),
1005
+ </span><span class="marked0"><a name="line384" /> 384 self.encode_segment(segments[:user],
1006
+ </span><span class="inferred1"><a name="line385" /> 385 Addressable::URI::CharacterClasses::AUTHORITY),
1007
+ </span><span class="marked0"><a name="line386" /> 386 self.encode_segment(segments[:password],
1008
+ </span><span class="inferred1"><a name="line387" /> 387 Addressable::URI::CharacterClasses::AUTHORITY),
1009
+ </span><span class="inferred0"><a name="line388" /> 388 segments[:host],
1010
+ </span><span class="inferred1"><a name="line389" /> 389 segments[:port],
1011
+ </span><span class="marked0"><a name="line390" /> 390 self.encode_segment(segments[:path],
1012
+ </span><span class="inferred1"><a name="line391" /> 391 Addressable::URI::CharacterClasses::PATH),
1013
+ </span><span class="marked0"><a name="line392" /> 392 self.encode_segment(segments[:query],
1014
+ </span><span class="inferred1"><a name="line393" /> 393 Addressable::URI::CharacterClasses::QUERY),
1015
+ </span><span class="marked0"><a name="line394" /> 394 self.encode_segment(segments[:fragment],
1016
+ </span><span class="inferred1"><a name="line395" /> 395 Addressable::URI::CharacterClasses::FRAGMENT)
1017
+ </span><span class="marked0"><a name="line396" /> 396 ).to_s
1018
+ </span><span class="inferred1"><a name="line397" /> 397 end
1019
+ </span><span class="inferred0"><a name="line398" /> 398
1020
+ </span><span class="inferred1"><a name="line399" /> 399 # Extracts uris from an arbitrary body of text.
1021
+ </span><span class="marked0"><a name="line400" /> 400 def self.extract(text, options={})
1022
+ </span><span class="marked1"><a name="line401" /> 401 defaults = {:base =&gt; nil, :parse =&gt; false}
1023
+ </span><span class="marked0"><a name="line402" /> 402 options = defaults.merge(options)
1024
+ </span><span class="marked1"><a name="line403" /> 403 raise InvalidOptionError unless (options.keys - defaults.keys).empty?
1025
+ </span><span class="inferred0"><a name="line404" /> 404 # This regular expression needs to be less forgiving or else it would
1026
+ </span><span class="inferred1"><a name="line405" /> 405 # match virtually all text. Which isn't exactly what we're going for.
1027
+ </span><span class="marked0"><a name="line406" /> 406 extract_regex = /((([a-z\+]+):)[^ \n\&lt;\&gt;\&quot;\\]+[\w\/])/
1028
+ </span><span class="marked1"><a name="line407" /> 407 extracted_uris =
1029
+ </span><span class="marked0"><a name="line408" /> 408 text.scan(extract_regex).collect { |match| match[0] }
1030
+ </span><span class="marked1"><a name="line409" /> 409 sgml_extract_regex = /&lt;[^&gt;]+href=\&quot;([^\&quot;]+?)\&quot;[^&gt;]*&gt;/
1031
+ </span><span class="marked0"><a name="line410" /> 410 sgml_extracted_uris =
1032
+ </span><span class="inferred1"><a name="line411" /> 411 text.scan(sgml_extract_regex).collect { |match| match[0] }
1033
+ </span><span class="marked0"><a name="line412" /> 412 extracted_uris.concat(sgml_extracted_uris - extracted_uris)
1034
+ </span><span class="marked1"><a name="line413" /> 413 textile_extract_regex = /\&quot;.+?\&quot;:([^ ]+\/[^ ]+)[ \,\.\;\:\?\!\&lt;\&gt;\&quot;]/i
1035
+ </span><span class="marked0"><a name="line414" /> 414 textile_extracted_uris =
1036
+ </span><span class="inferred1"><a name="line415" /> 415 text.scan(textile_extract_regex).collect { |match| match[0] }
1037
+ </span><span class="marked0"><a name="line416" /> 416 extracted_uris.concat(textile_extracted_uris - extracted_uris)
1038
+ </span><span class="marked1"><a name="line417" /> 417 parsed_uris = []
1039
+ </span><span class="marked0"><a name="line418" /> 418 base_uri = nil
1040
+ </span><span class="marked1"><a name="line419" /> 419 if options[:base] != nil
1041
+ </span><span class="marked0"><a name="line420" /> 420 base_uri = options[:base] if options[:base].kind_of?(self)
1042
+ </span><span class="marked1"><a name="line421" /> 421 base_uri = self.parse(options[:base].to_s) if base_uri == nil
1043
+ </span><span class="inferred0"><a name="line422" /> 422 end
1044
+ </span><span class="marked1"><a name="line423" /> 423 for uri_string in extracted_uris
1045
+ </span><span class="marked0"><a name="line424" /> 424 begin
1046
+ </span><span class="marked1"><a name="line425" /> 425 if base_uri == nil
1047
+ </span><span class="marked0"><a name="line426" /> 426 parsed_uris &lt;&lt; self.parse(uri_string)
1048
+ </span><span class="inferred1"><a name="line427" /> 427 else
1049
+ </span><span class="marked0"><a name="line428" /> 428 parsed_uris &lt;&lt; (base_uri + self.parse(uri_string))
1050
+ </span><span class="inferred1"><a name="line429" /> 429 end
1051
+ </span><span class="inferred0"><a name="line430" /> 430 rescue Exception
1052
+ </span><span class="marked1"><a name="line431" /> 431 nil
1053
+ </span><span class="inferred0"><a name="line432" /> 432 end
1054
+ </span><span class="inferred1"><a name="line433" /> 433 end
1055
+ </span><span class="marked0"><a name="line434" /> 434 parsed_uris.reject! do |uri|
1056
+ </span><span class="marked1"><a name="line435" /> 435 (uri.scheme =~ /T\d+/ ||
1057
+ </span><span class="marked0"><a name="line436" /> 436 uri.scheme == &quot;xmlns&quot; ||
1058
+ </span><span class="marked1"><a name="line437" /> 437 uri.scheme == &quot;xml&quot; ||
1059
+ </span><span class="marked0"><a name="line438" /> 438 uri.scheme == &quot;thr&quot; ||
1060
+ </span><span class="marked1"><a name="line439" /> 439 uri.scheme == &quot;this&quot; ||
1061
+ </span><span class="marked0"><a name="line440" /> 440 uri.scheme == &quot;float&quot; ||
1062
+ </span><span class="marked1"><a name="line441" /> 441 uri.scheme == &quot;user&quot; ||
1063
+ </span><span class="marked0"><a name="line442" /> 442 uri.scheme == &quot;username&quot; ||
1064
+ </span><span class="marked1"><a name="line443" /> 443 uri.scheme == &quot;out&quot;)
1065
+ </span><span class="inferred0"><a name="line444" /> 444 end
1066
+ </span><span class="marked1"><a name="line445" /> 445 if options[:parse]
1067
+ </span><span class="marked0"><a name="line446" /> 446 return parsed_uris
1068
+ </span><span class="inferred1"><a name="line447" /> 447 else
1069
+ </span><span class="marked0"><a name="line448" /> 448 return parsed_uris.collect { |uri| uri.to_s }
1070
+ </span><span class="inferred1"><a name="line449" /> 449 end
1071
+ </span><span class="inferred0"><a name="line450" /> 450 end
1072
+ </span><span class="inferred1"><a name="line451" /> 451
1073
+ </span><span class="inferred0"><a name="line452" /> 452 # Creates a new uri object from component parts. Passing nil for
1074
+ </span><span class="inferred1"><a name="line453" /> 453 # any of these parameters is acceptable.
1075
+ </span><span class="marked0"><a name="line454" /> 454 def initialize(scheme, user, password, host, port, path, query, fragment)
1076
+ </span><span class="marked1"><a name="line455" /> 455 @scheme = scheme
1077
+ </span><span class="marked0"><a name="line456" /> 456 @scheme = nil if @scheme.to_s.strip == &quot;&quot;
1078
+ </span><span class="marked1"><a name="line457" /> 457 @user = user
1079
+ </span><span class="marked0"><a name="line458" /> 458 @password = password
1080
+ </span><span class="marked1"><a name="line459" /> 459 @host = host
1081
+ </span><span class="marked0"><a name="line460" /> 460 @specified_port = port.to_s
1082
+ </span><span class="marked1"><a name="line461" /> 461 @port = port
1083
+ </span><span class="marked0"><a name="line462" /> 462 @port = @port.to_s if @port.kind_of?(Fixnum)
1084
+ </span><span class="marked1"><a name="line463" /> 463 if @port != nil &amp;&amp; !(@port =~ /^\d+$/)
1085
+ </span><span class="marked0"><a name="line464" /> 464 raise InvalidURIError,
1086
+ </span><span class="inferred1"><a name="line465" /> 465 &quot;Invalid port number: #{@port.inspect}&quot;
1087
+ </span><span class="inferred0"><a name="line466" /> 466 end
1088
+ </span><span class="marked1"><a name="line467" /> 467 @port = @port.to_i
1089
+ </span><span class="marked0"><a name="line468" /> 468 @port = nil if @port == 0
1090
+ </span><span class="marked1"><a name="line469" /> 469 @path = path
1091
+ </span><span class="marked0"><a name="line470" /> 470 @query = query
1092
+ </span><span class="marked1"><a name="line471" /> 471 @fragment = fragment
1093
+ </span><span class="inferred0"><a name="line472" /> 472
1094
+ </span><span class="marked1"><a name="line473" /> 473 validate()
1095
+ </span><span class="inferred0"><a name="line474" /> 474 end
1096
+ </span><span class="inferred1"><a name="line475" /> 475
1097
+ </span><span class="inferred0"><a name="line476" /> 476 # Returns the scheme (protocol) for this URI.
1098
+ </span><span class="marked1"><a name="line477" /> 477 def scheme
1099
+ </span><span class="marked0"><a name="line478" /> 478 return @scheme
1100
+ </span><span class="marked1"><a name="line479" /> 479 end
1101
+ </span><span class="inferred0"><a name="line480" /> 480
1102
+ </span><span class="inferred1"><a name="line481" /> 481 # Sets the scheme (protocol for this URI.)
1103
+ </span><span class="marked0"><a name="line482" /> 482 def scheme=(new_scheme)
1104
+ </span><span class="marked1"><a name="line483" /> 483 @scheme = new_scheme
1105
+ </span><span class="marked0"><a name="line484" /> 484 end
1106
+ </span><span class="inferred1"><a name="line485" /> 485
1107
+ </span><span class="inferred0"><a name="line486" /> 486 # Returns the user for this URI.
1108
+ </span><span class="marked1"><a name="line487" /> 487 def user
1109
+ </span><span class="marked0"><a name="line488" /> 488 return @user
1110
+ </span><span class="marked1"><a name="line489" /> 489 end
1111
+ </span><span class="inferred0"><a name="line490" /> 490
1112
+ </span><span class="inferred1"><a name="line491" /> 491 # Sets the user for this URI.
1113
+ </span><span class="marked0"><a name="line492" /> 492 def user=(new_user)
1114
+ </span><span class="marked1"><a name="line493" /> 493 @user = new_user
1115
+ </span><span class="inferred0"><a name="line494" /> 494
1116
+ </span><span class="inferred1"><a name="line495" /> 495 # You can't have a nil user with a non-nil password
1117
+ </span><span class="marked0"><a name="line496" /> 496 if @password != nil
1118
+ </span><span class="marked1"><a name="line497" /> 497 @user = &quot;&quot; if @user.nil?
1119
+ </span><span class="inferred0"><a name="line498" /> 498 end
1120
+ </span><span class="inferred1"><a name="line499" /> 499
1121
+ </span><span class="inferred0"><a name="line500" /> 500 # Reset dependant values
1122
+ </span><span class="marked1"><a name="line501" /> 501 @userinfo = nil
1123
+ </span><span class="marked0"><a name="line502" /> 502 @authority = nil
1124
+ </span><span class="inferred1"><a name="line503" /> 503
1125
+ </span><span class="inferred0"><a name="line504" /> 504 # Ensure we haven't created an invalid URI
1126
+ </span><span class="marked1"><a name="line505" /> 505 validate()
1127
+ </span><span class="inferred0"><a name="line506" /> 506 end
1128
+ </span><span class="inferred1"><a name="line507" /> 507
1129
+ </span><span class="inferred0"><a name="line508" /> 508 # Returns the password for this URI.
1130
+ </span><span class="marked1"><a name="line509" /> 509 def password
1131
+ </span><span class="marked0"><a name="line510" /> 510 return @password
1132
+ </span><span class="marked1"><a name="line511" /> 511 end
1133
+ </span><span class="inferred0"><a name="line512" /> 512
1134
+ </span><span class="inferred1"><a name="line513" /> 513 # Sets the password for this URI.
1135
+ </span><span class="marked0"><a name="line514" /> 514 def password=(new_password)
1136
+ </span><span class="marked1"><a name="line515" /> 515 @password = new_password
1137
+ </span><span class="inferred0"><a name="line516" /> 516
1138
+ </span><span class="inferred1"><a name="line517" /> 517 # You can't have a nil user with a non-nil password
1139
+ </span><span class="marked0"><a name="line518" /> 518 if @password != nil
1140
+ </span><span class="marked1"><a name="line519" /> 519 @user = &quot;&quot; if @user.nil?
1141
+ </span><span class="inferred0"><a name="line520" /> 520 end
1142
+ </span><span class="inferred1"><a name="line521" /> 521
1143
+ </span><span class="inferred0"><a name="line522" /> 522 # Reset dependant values
1144
+ </span><span class="marked1"><a name="line523" /> 523 @userinfo = nil
1145
+ </span><span class="marked0"><a name="line524" /> 524 @authority = nil
1146
+ </span><span class="inferred1"><a name="line525" /> 525
1147
+ </span><span class="inferred0"><a name="line526" /> 526 # Ensure we haven't created an invalid URI
1148
+ </span><span class="marked1"><a name="line527" /> 527 validate()
1149
+ </span><span class="inferred0"><a name="line528" /> 528 end
1150
+ </span><span class="inferred1"><a name="line529" /> 529
1151
+ </span><span class="inferred0"><a name="line530" /> 530 # Returns the username and password segment of this URI.
1152
+ </span><span class="marked1"><a name="line531" /> 531 def userinfo
1153
+ </span><span class="marked0"><a name="line532" /> 532 if !defined?(@userinfo) || @userinfo.nil?
1154
+ </span><span class="marked1"><a name="line533" /> 533 current_user = self.user
1155
+ </span><span class="marked0"><a name="line534" /> 534 current_password = self.password
1156
+ </span><span class="marked1"><a name="line535" /> 535 if current_user == nil &amp;&amp; current_password == nil
1157
+ </span><span class="marked0"><a name="line536" /> 536 @userinfo = nil
1158
+ </span><span class="marked1"><a name="line537" /> 537 elsif current_user != nil &amp;&amp; current_password == nil
1159
+ </span><span class="marked0"><a name="line538" /> 538 @userinfo = &quot;#{current_user}&quot;
1160
+ </span><span class="marked1"><a name="line539" /> 539 elsif current_user != nil &amp;&amp; current_password != nil
1161
+ </span><span class="marked0"><a name="line540" /> 540 @userinfo = &quot;#{current_user}:#{current_password}&quot;
1162
+ </span><span class="inferred1"><a name="line541" /> 541 end
1163
+ </span><span class="inferred0"><a name="line542" /> 542 end
1164
+ </span><span class="marked1"><a name="line543" /> 543 return @userinfo
1165
+ </span><span class="inferred0"><a name="line544" /> 544 end
1166
+ </span><span class="inferred1"><a name="line545" /> 545
1167
+ </span><span class="inferred0"><a name="line546" /> 546 # Sets the username and password segment of this URI.
1168
+ </span><span class="marked1"><a name="line547" /> 547 def userinfo=(new_userinfo)
1169
+ </span><span class="marked0"><a name="line548" /> 548 new_user = new_userinfo.to_s.strip.scan(/^(.*):/).flatten[0]
1170
+ </span><span class="marked1"><a name="line549" /> 549 new_password = new_userinfo.to_s.strip.scan(/:(.*)$/).flatten[0]
1171
+ </span><span class="inferred0"><a name="line550" /> 550
1172
+ </span><span class="inferred1"><a name="line551" /> 551 # Password assigned first to ensure validity in case of nil
1173
+ </span><span class="marked0"><a name="line552" /> 552 self.password = new_password
1174
+ </span><span class="marked1"><a name="line553" /> 553 self.user = new_user
1175
+ </span><span class="inferred0"><a name="line554" /> 554
1176
+ </span><span class="inferred1"><a name="line555" /> 555 # Reset dependant values
1177
+ </span><span class="marked0"><a name="line556" /> 556 @authority = nil
1178
+ </span><span class="inferred1"><a name="line557" /> 557
1179
+ </span><span class="inferred0"><a name="line558" /> 558 # Ensure we haven't created an invalid URI
1180
+ </span><span class="marked1"><a name="line559" /> 559 validate()
1181
+ </span><span class="inferred0"><a name="line560" /> 560 end
1182
+ </span><span class="inferred1"><a name="line561" /> 561
1183
+ </span><span class="inferred0"><a name="line562" /> 562 # Returns the host for this URI.
1184
+ </span><span class="marked1"><a name="line563" /> 563 def host
1185
+ </span><span class="marked0"><a name="line564" /> 564 return @host
1186
+ </span><span class="marked1"><a name="line565" /> 565 end
1187
+ </span><span class="inferred0"><a name="line566" /> 566
1188
+ </span><span class="inferred1"><a name="line567" /> 567 # Sets the host for this URI.
1189
+ </span><span class="marked0"><a name="line568" /> 568 def host=(new_host)
1190
+ </span><span class="marked1"><a name="line569" /> 569 @host = new_host
1191
+ </span><span class="inferred0"><a name="line570" /> 570
1192
+ </span><span class="inferred1"><a name="line571" /> 571 # Reset dependant values
1193
+ </span><span class="marked0"><a name="line572" /> 572 @authority = nil
1194
+ </span><span class="inferred1"><a name="line573" /> 573
1195
+ </span><span class="inferred0"><a name="line574" /> 574 # Ensure we haven't created an invalid URI
1196
+ </span><span class="marked1"><a name="line575" /> 575 validate()
1197
+ </span><span class="inferred0"><a name="line576" /> 576 end
1198
+ </span><span class="inferred1"><a name="line577" /> 577
1199
+ </span><span class="inferred0"><a name="line578" /> 578 # Returns the authority segment of this URI.
1200
+ </span><span class="marked1"><a name="line579" /> 579 def authority
1201
+ </span><span class="marked0"><a name="line580" /> 580 if !defined?(@authority) || @authority.nil?
1202
+ </span><span class="marked1"><a name="line581" /> 581 return nil if self.host.nil?
1203
+ </span><span class="marked0"><a name="line582" /> 582 @authority = &quot;&quot;
1204
+ </span><span class="marked1"><a name="line583" /> 583 if self.userinfo != nil
1205
+ </span><span class="marked0"><a name="line584" /> 584 @authority &lt;&lt; &quot;#{self.userinfo}@&quot;
1206
+ </span><span class="inferred1"><a name="line585" /> 585 end
1207
+ </span><span class="marked0"><a name="line586" /> 586 @authority &lt;&lt; self.host
1208
+ </span><span class="marked1"><a name="line587" /> 587 if self.specified_port != nil
1209
+ </span><span class="marked0"><a name="line588" /> 588 @authority &lt;&lt; &quot;:#{self.specified_port}&quot;
1210
+ </span><span class="inferred1"><a name="line589" /> 589 end
1211
+ </span><span class="inferred0"><a name="line590" /> 590 end
1212
+ </span><span class="marked1"><a name="line591" /> 591 return @authority
1213
+ </span><span class="inferred0"><a name="line592" /> 592 end
1214
+ </span><span class="inferred1"><a name="line593" /> 593
1215
+ </span><span class="inferred0"><a name="line594" /> 594 # Sets the authority segment of this URI.
1216
+ </span><span class="marked1"><a name="line595" /> 595 def authority=(new_authority)
1217
+ </span><span class="marked0"><a name="line596" /> 596 if new_authority != nil
1218
+ </span><span class="marked1"><a name="line597" /> 597 new_userinfo = new_authority.scan(/^([^\[\]]*)@/).flatten[0]
1219
+ </span><span class="marked0"><a name="line598" /> 598 if new_userinfo != nil
1220
+ </span><span class="marked1"><a name="line599" /> 599 new_user = new_userinfo.strip.scan(/^([^:]*):?/).flatten[0]
1221
+ </span><span class="marked0"><a name="line600" /> 600 new_password = new_userinfo.strip.scan(/:(.*)$/).flatten[0]
1222
+ </span><span class="inferred1"><a name="line601" /> 601 end
1223
+ </span><span class="marked0"><a name="line602" /> 602 new_host =
1224
+ </span><span class="inferred1"><a name="line603" /> 603 new_authority.gsub(/^([^\[\]]*)@/, &quot;&quot;).gsub(/:([^:@\[\]]*?)$/, &quot;&quot;)
1225
+ </span><span class="marked0"><a name="line604" /> 604 new_port =
1226
+ </span><span class="inferred1"><a name="line605" /> 605 new_authority.scan(/:([^:@\[\]]*?)$/).flatten[0]
1227
+ </span><span class="inferred0"><a name="line606" /> 606 end
1228
+ </span><span class="marked1"><a name="line607" /> 607 new_port = nil if new_port == &quot;&quot;
1229
+ </span><span class="inferred0"><a name="line608" /> 608
1230
+ </span><span class="inferred1"><a name="line609" /> 609 # Password assigned first to ensure validity in case of nil
1231
+ </span><span class="marked0"><a name="line610" /> 610 self.password = new_password
1232
+ </span><span class="marked1"><a name="line611" /> 611 self.user = new_user
1233
+ </span><span class="marked0"><a name="line612" /> 612 self.host = new_host
1234
+ </span><span class="inferred1"><a name="line613" /> 613
1235
+ </span><span class="inferred0"><a name="line614" /> 614 # Port reset to allow port normalization
1236
+ </span><span class="marked1"><a name="line615" /> 615 @port = nil
1237
+ </span><span class="marked0"><a name="line616" /> 616 @specified_port = new_port
1238
+ </span><span class="inferred1"><a name="line617" /> 617
1239
+ </span><span class="inferred0"><a name="line618" /> 618 # Ensure we haven't created an invalid URI
1240
+ </span><span class="marked1"><a name="line619" /> 619 validate()
1241
+ </span><span class="inferred0"><a name="line620" /> 620 end
1242
+ </span><span class="inferred1"><a name="line621" /> 621
1243
+ </span><span class="inferred0"><a name="line622" /> 622 # Returns an array of known ip-based schemes. These schemes typically
1244
+ </span><span class="inferred1"><a name="line623" /> 623 # use a similar URI form:
1245
+ </span><span class="inferred0"><a name="line624" /> 624 # //&lt;user&gt;:&lt;password&gt;@&lt;host&gt;:&lt;port&gt;/&lt;url-path&gt;
1246
+ </span><span class="marked1"><a name="line625" /> 625 def self.ip_based_schemes
1247
+ </span><span class="marked0"><a name="line626" /> 626 return self.scheme_mapping.keys
1248
+ </span><span class="marked1"><a name="line627" /> 627 end
1249
+ </span><span class="inferred0"><a name="line628" /> 628
1250
+ </span><span class="inferred1"><a name="line629" /> 629 # Returns a hash of common IP-based schemes and their default port
1251
+ </span><span class="inferred0"><a name="line630" /> 630 # numbers. Adding new schemes to this hash, as necessary, will allow
1252
+ </span><span class="inferred1"><a name="line631" /> 631 # for better URI normalization.
1253
+ </span><span class="marked0"><a name="line632" /> 632 def self.scheme_mapping
1254
+ </span><span class="marked1"><a name="line633" /> 633 if !defined?(@protocol_mapping) || @protocol_mapping.nil?
1255
+ </span><span class="marked0"><a name="line634" /> 634 @protocol_mapping = {
1256
+ </span><span class="inferred1"><a name="line635" /> 635 &quot;http&quot; =&gt; 80,
1257
+ </span><span class="inferred0"><a name="line636" /> 636 &quot;https&quot; =&gt; 443,
1258
+ </span><span class="inferred1"><a name="line637" /> 637 &quot;ftp&quot; =&gt; 21,
1259
+ </span><span class="inferred0"><a name="line638" /> 638 &quot;tftp&quot; =&gt; 69,
1260
+ </span><span class="inferred1"><a name="line639" /> 639 &quot;ssh&quot; =&gt; 22,
1261
+ </span><span class="inferred0"><a name="line640" /> 640 &quot;svn+ssh&quot; =&gt; 22,
1262
+ </span><span class="inferred1"><a name="line641" /> 641 &quot;telnet&quot; =&gt; 23,
1263
+ </span><span class="inferred0"><a name="line642" /> 642 &quot;nntp&quot; =&gt; 119,
1264
+ </span><span class="inferred1"><a name="line643" /> 643 &quot;gopher&quot; =&gt; 70,
1265
+ </span><span class="inferred0"><a name="line644" /> 644 &quot;wais&quot; =&gt; 210,
1266
+ </span><span class="inferred1"><a name="line645" /> 645 &quot;ldap&quot; =&gt; 389,
1267
+ </span><span class="inferred0"><a name="line646" /> 646 &quot;prospero&quot; =&gt; 1525
1268
+ </span><span class="inferred1"><a name="line647" /> 647 }
1269
+ </span><span class="inferred0"><a name="line648" /> 648 end
1270
+ </span><span class="marked1"><a name="line649" /> 649 return @protocol_mapping
1271
+ </span><span class="inferred0"><a name="line650" /> 650 end
1272
+ </span><span class="inferred1"><a name="line651" /> 651
1273
+ </span><span class="inferred0"><a name="line652" /> 652 # Returns the port number for this URI. This method will normalize to the
1274
+ </span><span class="inferred1"><a name="line653" /> 653 # default port for the URI's scheme if the port isn't explicitly specified
1275
+ </span><span class="inferred0"><a name="line654" /> 654 # in the URI.
1276
+ </span><span class="marked1"><a name="line655" /> 655 def port
1277
+ </span><span class="marked0"><a name="line656" /> 656 if @port.to_i == 0
1278
+ </span><span class="marked1"><a name="line657" /> 657 if self.scheme.nil?
1279
+ </span><span class="marked0"><a name="line658" /> 658 @port = nil
1280
+ </span><span class="inferred1"><a name="line659" /> 659 else
1281
+ </span><span class="marked0"><a name="line660" /> 660 @port = self.class.scheme_mapping[self.scheme.strip.downcase]
1282
+ </span><span class="inferred1"><a name="line661" /> 661 end
1283
+ </span><span class="marked0"><a name="line662" /> 662 return @port
1284
+ </span><span class="inferred1"><a name="line663" /> 663 else
1285
+ </span><span class="marked0"><a name="line664" /> 664 @port = @port.to_i
1286
+ </span><span class="marked1"><a name="line665" /> 665 return @port
1287
+ </span><span class="inferred0"><a name="line666" /> 666 end
1288
+ </span><span class="marked1"><a name="line667" /> 667 end
1289
+ </span><span class="inferred0"><a name="line668" /> 668
1290
+ </span><span class="inferred1"><a name="line669" /> 669 # Sets the port for this URI.
1291
+ </span><span class="marked0"><a name="line670" /> 670 def port=(new_port)
1292
+ </span><span class="marked1"><a name="line671" /> 671 @port = new_port.to_s.to_i
1293
+ </span><span class="marked0"><a name="line672" /> 672 @specified_port = @port
1294
+ </span><span class="marked1"><a name="line673" /> 673 @authority = nil
1295
+ </span><span class="inferred0"><a name="line674" /> 674 end
1296
+ </span><span class="inferred1"><a name="line675" /> 675
1297
+ </span><span class="inferred0"><a name="line676" /> 676 # Returns the port number that was actually specified in the URI string.
1298
+ </span><span class="marked1"><a name="line677" /> 677 def specified_port
1299
+ </span><span class="marked0"><a name="line678" /> 678 port = @specified_port.to_s.to_i
1300
+ </span><span class="marked1"><a name="line679" /> 679 if port == 0
1301
+ </span><span class="marked0"><a name="line680" /> 680 return nil
1302
+ </span><span class="inferred1"><a name="line681" /> 681 else
1303
+ </span><span class="marked0"><a name="line682" /> 682 return port
1304
+ </span><span class="inferred1"><a name="line683" /> 683 end
1305
+ </span><span class="inferred0"><a name="line684" /> 684 end
1306
+ </span><span class="inferred1"><a name="line685" /> 685
1307
+ </span><span class="inferred0"><a name="line686" /> 686 # Returns the path for this URI.
1308
+ </span><span class="marked1"><a name="line687" /> 687 def path
1309
+ </span><span class="marked0"><a name="line688" /> 688 return @path
1310
+ </span><span class="marked1"><a name="line689" /> 689 end
1311
+ </span><span class="inferred0"><a name="line690" /> 690
1312
+ </span><span class="inferred1"><a name="line691" /> 691 # Sets the path for this URI.
1313
+ </span><span class="marked0"><a name="line692" /> 692 def path=(new_path)
1314
+ </span><span class="marked1"><a name="line693" /> 693 @path = new_path
1315
+ </span><span class="marked0"><a name="line694" /> 694 end
1316
+ </span><span class="inferred1"><a name="line695" /> 695
1317
+ </span><span class="inferred0"><a name="line696" /> 696 # Returns the basename, if any, of the file at the path being referenced.
1318
+ </span><span class="inferred1"><a name="line697" /> 697 # Returns nil if there is no path component.
1319
+ </span><span class="marked0"><a name="line698" /> 698 def basename
1320
+ </span><span class="marked1"><a name="line699" /> 699 return nil if self.path == nil
1321
+ </span><span class="marked0"><a name="line700" /> 700 return File.basename(self.path).gsub(/;[^\/]*$/, &quot;&quot;)
1322
+ </span><span class="inferred1"><a name="line701" /> 701 end
1323
+ </span><span class="inferred0"><a name="line702" /> 702
1324
+ </span><span class="inferred1"><a name="line703" /> 703 # Returns the extension, if any, of the file at the path being referenced.
1325
+ </span><span class="inferred0"><a name="line704" /> 704 # Returns &quot;&quot; if there is no extension or nil if there is no path
1326
+ </span><span class="inferred1"><a name="line705" /> 705 # component.
1327
+ </span><span class="marked0"><a name="line706" /> 706 def extname
1328
+ </span><span class="marked1"><a name="line707" /> 707 return nil if self.path == nil
1329
+ </span><span class="marked0"><a name="line708" /> 708 return File.extname(self.basename.gsub(/;[^\/]*$/, &quot;&quot;))
1330
+ </span><span class="inferred1"><a name="line709" /> 709 end
1331
+ </span><span class="inferred0"><a name="line710" /> 710
1332
+ </span><span class="inferred1"><a name="line711" /> 711 # Returns the query string for this URI.
1333
+ </span><span class="marked0"><a name="line712" /> 712 def query
1334
+ </span><span class="marked1"><a name="line713" /> 713 return @query
1335
+ </span><span class="marked0"><a name="line714" /> 714 end
1336
+ </span><span class="inferred1"><a name="line715" /> 715
1337
+ </span><span class="inferred0"><a name="line716" /> 716 # Sets the query string for this URI.
1338
+ </span><span class="marked1"><a name="line717" /> 717 def query=(new_query)
1339
+ </span><span class="marked0"><a name="line718" /> 718 @query = new_query
1340
+ </span><span class="marked1"><a name="line719" /> 719 end
1341
+ </span><span class="inferred0"><a name="line720" /> 720
1342
+ </span><span class="inferred1"><a name="line721" /> 721 # Returns the fragment for this URI.
1343
+ </span><span class="marked0"><a name="line722" /> 722 def fragment
1344
+ </span><span class="marked1"><a name="line723" /> 723 return @fragment
1345
+ </span><span class="marked0"><a name="line724" /> 724 end
1346
+ </span><span class="inferred1"><a name="line725" /> 725
1347
+ </span><span class="inferred0"><a name="line726" /> 726 # Sets the fragment for this URI.
1348
+ </span><span class="marked1"><a name="line727" /> 727 def fragment=(new_fragment)
1349
+ </span><span class="marked0"><a name="line728" /> 728 @fragment = new_fragment
1350
+ </span><span class="marked1"><a name="line729" /> 729 end
1351
+ </span><span class="inferred0"><a name="line730" /> 730
1352
+ </span><span class="inferred1"><a name="line731" /> 731 # Returns true if the URI uses an IP-based protocol.
1353
+ </span><span class="marked0"><a name="line732" /> 732 def ip_based?
1354
+ </span><span class="marked1"><a name="line733" /> 733 return false if self.scheme.nil?
1355
+ </span><span class="marked0"><a name="line734" /> 734 return self.class.ip_based_schemes.include?(self.scheme.strip.downcase)
1356
+ </span><span class="inferred1"><a name="line735" /> 735 end
1357
+ </span><span class="inferred0"><a name="line736" /> 736
1358
+ </span><span class="inferred1"><a name="line737" /> 737 # Returns true if this URI is known to be relative.
1359
+ </span><span class="marked0"><a name="line738" /> 738 def relative?
1360
+ </span><span class="marked1"><a name="line739" /> 739 return self.scheme.nil?
1361
+ </span><span class="marked0"><a name="line740" /> 740 end
1362
+ </span><span class="inferred1"><a name="line741" /> 741
1363
+ </span><span class="inferred0"><a name="line742" /> 742 # Returns true if this URI is known to be absolute.
1364
+ </span><span class="marked1"><a name="line743" /> 743 def absolute?
1365
+ </span><span class="marked0"><a name="line744" /> 744 return !relative?
1366
+ </span><span class="marked1"><a name="line745" /> 745 end
1367
+ </span><span class="inferred0"><a name="line746" /> 746
1368
+ </span><span class="inferred1"><a name="line747" /> 747 # Joins two URIs together.
1369
+ </span><span class="marked0"><a name="line748" /> 748 def +(uri)
1370
+ </span><span class="marked1"><a name="line749" /> 749 if !uri.kind_of?(self.class)
1371
+ </span><span class="marked0"><a name="line750" /> 750 uri = URI.parse(uri.to_s)
1372
+ </span><span class="inferred1"><a name="line751" /> 751 end
1373
+ </span><span class="marked0"><a name="line752" /> 752 if uri.to_s == &quot;&quot;
1374
+ </span><span class="marked1"><a name="line753" /> 753 return self.dup
1375
+ </span><span class="inferred0"><a name="line754" /> 754 end
1376
+ </span><span class="inferred1"><a name="line755" /> 755
1377
+ </span><span class="marked0"><a name="line756" /> 756 joined_scheme = nil
1378
+ </span><span class="marked1"><a name="line757" /> 757 joined_user = nil
1379
+ </span><span class="marked0"><a name="line758" /> 758 joined_password = nil
1380
+ </span><span class="marked1"><a name="line759" /> 759 joined_host = nil
1381
+ </span><span class="marked0"><a name="line760" /> 760 joined_port = nil
1382
+ </span><span class="marked1"><a name="line761" /> 761 joined_path = nil
1383
+ </span><span class="marked0"><a name="line762" /> 762 joined_query = nil
1384
+ </span><span class="marked1"><a name="line763" /> 763 joined_fragment = nil
1385
+ </span><span class="inferred0"><a name="line764" /> 764
1386
+ </span><span class="inferred1"><a name="line765" /> 765 # Section 5.2.2 of RFC 3986
1387
+ </span><span class="marked0"><a name="line766" /> 766 if uri.scheme != nil
1388
+ </span><span class="marked1"><a name="line767" /> 767 joined_scheme = uri.scheme
1389
+ </span><span class="marked0"><a name="line768" /> 768 joined_user = uri.user
1390
+ </span><span class="marked1"><a name="line769" /> 769 joined_password = uri.password
1391
+ </span><span class="marked0"><a name="line770" /> 770 joined_host = uri.host
1392
+ </span><span class="marked1"><a name="line771" /> 771 joined_port = uri.specified_port
1393
+ </span><span class="marked0"><a name="line772" /> 772 joined_path = self.class.normalize_path(uri.path)
1394
+ </span><span class="marked1"><a name="line773" /> 773 joined_query = uri.query
1395
+ </span><span class="inferred0"><a name="line774" /> 774 else
1396
+ </span><span class="marked1"><a name="line775" /> 775 if uri.authority != nil
1397
+ </span><span class="marked0"><a name="line776" /> 776 joined_user = uri.user
1398
+ </span><span class="marked1"><a name="line777" /> 777 joined_password = uri.password
1399
+ </span><span class="marked0"><a name="line778" /> 778 joined_host = uri.host
1400
+ </span><span class="marked1"><a name="line779" /> 779 joined_port = uri.specified_port
1401
+ </span><span class="marked0"><a name="line780" /> 780 joined_path = self.class.normalize_path(uri.path)
1402
+ </span><span class="marked1"><a name="line781" /> 781 joined_query = uri.query
1403
+ </span><span class="inferred0"><a name="line782" /> 782 else
1404
+ </span><span class="marked1"><a name="line783" /> 783 if uri.path == nil || uri.path == &quot;&quot;
1405
+ </span><span class="marked0"><a name="line784" /> 784 joined_path = self.path
1406
+ </span><span class="marked1"><a name="line785" /> 785 if uri.query != nil
1407
+ </span><span class="marked0"><a name="line786" /> 786 joined_query = uri.query
1408
+ </span><span class="inferred1"><a name="line787" /> 787 else
1409
+ </span><span class="marked0"><a name="line788" /> 788 joined_query = self.query
1410
+ </span><span class="inferred1"><a name="line789" /> 789 end
1411
+ </span><span class="inferred0"><a name="line790" /> 790 else
1412
+ </span><span class="marked1"><a name="line791" /> 791 if uri.path[0..0] == &quot;/&quot;
1413
+ </span><span class="marked0"><a name="line792" /> 792 joined_path = self.class.normalize_path(uri.path)
1414
+ </span><span class="inferred1"><a name="line793" /> 793 else
1415
+ </span><span class="marked0"><a name="line794" /> 794 base_path = self.path.dup
1416
+ </span><span class="marked1"><a name="line795" /> 795 base_path = &quot;&quot; if base_path == nil
1417
+ </span><span class="marked0"><a name="line796" /> 796 base_path = self.class.normalize_path(base_path)
1418
+ </span><span class="inferred1"><a name="line797" /> 797
1419
+ </span><span class="inferred0"><a name="line798" /> 798 # Section 5.2.3 of RFC 3986
1420
+ </span><span class="inferred1"><a name="line799" /> 799 #
1421
+ </span><span class="inferred0"><a name="line800" /> 800 # Removes the right-most path segment from the base path.
1422
+ </span><span class="marked1"><a name="line801" /> 801 if base_path =~ /\//
1423
+ </span><span class="marked0"><a name="line802" /> 802 base_path.gsub!(/\/[^\/]+$/, &quot;/&quot;)
1424
+ </span><span class="inferred1"><a name="line803" /> 803 else
1425
+ </span><span class="marked0"><a name="line804" /> 804 base_path = &quot;&quot;
1426
+ </span><span class="inferred1"><a name="line805" /> 805 end
1427
+ </span><span class="inferred0"><a name="line806" /> 806
1428
+ </span><span class="inferred1"><a name="line807" /> 807 # If the base path is empty and an authority segment has been
1429
+ </span><span class="inferred0"><a name="line808" /> 808 # defined, use a base path of &quot;/&quot;
1430
+ </span><span class="marked1"><a name="line809" /> 809 if base_path == &quot;&quot; &amp;&amp; self.authority != nil
1431
+ </span><span class="marked0"><a name="line810" /> 810 base_path = &quot;/&quot;
1432
+ </span><span class="inferred1"><a name="line811" /> 811 end
1433
+ </span><span class="inferred0"><a name="line812" /> 812
1434
+ </span><span class="marked1"><a name="line813" /> 813 joined_path = self.class.normalize_path(base_path + uri.path)
1435
+ </span><span class="inferred0"><a name="line814" /> 814 end
1436
+ </span><span class="marked1"><a name="line815" /> 815 joined_query = uri.query
1437
+ </span><span class="inferred0"><a name="line816" /> 816 end
1438
+ </span><span class="marked1"><a name="line817" /> 817 joined_user = self.user
1439
+ </span><span class="marked0"><a name="line818" /> 818 joined_password = self.password
1440
+ </span><span class="marked1"><a name="line819" /> 819 joined_host = self.host
1441
+ </span><span class="marked0"><a name="line820" /> 820 joined_port = self.specified_port
1442
+ </span><span class="inferred1"><a name="line821" /> 821 end
1443
+ </span><span class="marked0"><a name="line822" /> 822 joined_scheme = self.scheme
1444
+ </span><span class="inferred1"><a name="line823" /> 823 end
1445
+ </span><span class="marked0"><a name="line824" /> 824 joined_fragment = uri.fragment
1446
+ </span><span class="inferred1"><a name="line825" /> 825
1447
+ </span><span class="marked0"><a name="line826" /> 826 return Addressable::URI.new(
1448
+ </span><span class="inferred1"><a name="line827" /> 827 joined_scheme,
1449
+ </span><span class="inferred0"><a name="line828" /> 828 joined_user,
1450
+ </span><span class="inferred1"><a name="line829" /> 829 joined_password,
1451
+ </span><span class="inferred0"><a name="line830" /> 830 joined_host,
1452
+ </span><span class="inferred1"><a name="line831" /> 831 joined_port,
1453
+ </span><span class="inferred0"><a name="line832" /> 832 joined_path,
1454
+ </span><span class="inferred1"><a name="line833" /> 833 joined_query,
1455
+ </span><span class="inferred0"><a name="line834" /> 834 joined_fragment
1456
+ </span><span class="marked1"><a name="line835" /> 835 )
1457
+ </span><span class="inferred0"><a name="line836" /> 836 end
1458
+ </span><span class="inferred1"><a name="line837" /> 837
1459
+ </span><span class="inferred0"><a name="line838" /> 838 # Merges two URIs together.
1460
+ </span><span class="marked1"><a name="line839" /> 839 def merge(uri)
1461
+ </span><span class="marked0"><a name="line840" /> 840 return self + uri
1462
+ </span><span class="marked1"><a name="line841" /> 841 end
1463
+ </span><span class="marked0"><a name="line842" /> 842 alias_method :join, :merge
1464
+ </span><span class="inferred1"><a name="line843" /> 843
1465
+ </span><span class="inferred0"><a name="line844" /> 844 # Destructive form of merge.
1466
+ </span><span class="marked1"><a name="line845" /> 845 def merge!(uri)
1467
+ </span><span class="marked0"><a name="line846" /> 846 replace_self(self.merge(uri))
1468
+ </span><span class="marked1"><a name="line847" /> 847 end
1469
+ </span><span class="marked0"><a name="line848" /> 848 alias_method :join!, :merge!
1470
+ </span><span class="inferred1"><a name="line849" /> 849
1471
+ </span><span class="inferred0"><a name="line850" /> 850 # Returns the shortest normalized relative form of this URI that uses the
1472
+ </span><span class="inferred1"><a name="line851" /> 851 # supplied URI as a base for resolution. Returns an absolute URI if
1473
+ </span><span class="inferred0"><a name="line852" /> 852 # necessary.
1474
+ </span><span class="marked1"><a name="line853" /> 853 def route_from(uri)
1475
+ </span><span class="marked0"><a name="line854" /> 854 uri = uri.kind_of?(self.class) ? uri : self.class.parse(uri.to_s)
1476
+ </span><span class="marked1"><a name="line855" /> 855 uri = uri.normalize
1477
+ </span><span class="marked0"><a name="line856" /> 856 normalized_self = self.normalize
1478
+ </span><span class="marked1"><a name="line857" /> 857 if normalized_self.relative?
1479
+ </span><span class="marked0"><a name="line858" /> 858 raise ArgumentError, &quot;Expected absolute URI, got: #{self.to_s}&quot;
1480
+ </span><span class="inferred1"><a name="line859" /> 859 end
1481
+ </span><span class="marked0"><a name="line860" /> 860 if uri.relative?
1482
+ </span><span class="marked1"><a name="line861" /> 861 raise ArgumentError, &quot;Expected absolute URI, got: #{self.to_s}&quot;
1483
1483
  </span><span class="inferred0"><a name="line862" /> 862 end
1484
- </span><span class="inferred1"><a name="line863" /> 863 # Avoid network-path references.
1485
- </span><span class="marked0"><a name="line864" /> 864 if segments[:scheme] == nil &amp;&amp; segments[:host] != nil
1486
- </span><span class="marked1"><a name="line865" /> 865 segments[:scheme] = normalized_self.scheme
1487
- </span><span class="inferred0"><a name="line866" /> 866 end
1488
- </span><span class="marked1"><a name="line867" /> 867 return Addressable::URI.new(
1489
- </span><span class="inferred0"><a name="line868" /> 868 segments[:scheme],
1490
- </span><span class="inferred1"><a name="line869" /> 869 segments[:user],
1491
- </span><span class="inferred0"><a name="line870" /> 870 segments[:password],
1492
- </span><span class="inferred1"><a name="line871" /> 871 segments[:host],
1493
- </span><span class="inferred0"><a name="line872" /> 872 segments[:port],
1494
- </span><span class="inferred1"><a name="line873" /> 873 segments[:path],
1495
- </span><span class="inferred0"><a name="line874" /> 874 segments[:query],
1496
- </span><span class="inferred1"><a name="line875" /> 875 segments[:fragment]
1497
- </span><span class="marked0"><a name="line876" /> 876 )
1498
- </span><span class="inferred1"><a name="line877" /> 877 end
1499
- </span><span class="inferred0"><a name="line878" /> 878
1500
- </span><span class="inferred1"><a name="line879" /> 879 # Returns the shortest normalized relative form of the supplied URI that
1501
- </span><span class="inferred0"><a name="line880" /> 880 # uses this URI as a base for resolution. Returns an absolute URI if
1502
- </span><span class="inferred1"><a name="line881" /> 881 # necessary.
1503
- </span><span class="marked0"><a name="line882" /> 882 def route_to(uri)
1504
- </span><span class="marked1"><a name="line883" /> 883 uri = uri.kind_of?(self.class) ? uri : self.class.parse(uri.to_s)
1505
- </span><span class="marked0"><a name="line884" /> 884 return uri.route_from(self)
1506
- </span><span class="inferred1"><a name="line885" /> 885 end
1507
- </span><span class="inferred0"><a name="line886" /> 886
1508
- </span><span class="inferred1"><a name="line887" /> 887 # Returns a normalized URI object.
1509
- </span><span class="inferred0"><a name="line888" /> 888 #
1510
- </span><span class="inferred1"><a name="line889" /> 889 # NOTE: This method does not attempt to fully conform to specifications.
1511
- </span><span class="inferred0"><a name="line890" /> 890 # It exists largely to correct other people's failures to read the
1512
- </span><span class="inferred1"><a name="line891" /> 891 # specifications, and also to deal with caching issues since several
1513
- </span><span class="inferred0"><a name="line892" /> 892 # different URIs may represent the same resource and should not be
1514
- </span><span class="inferred1"><a name="line893" /> 893 # cached multiple times.
1515
- </span><span class="marked0"><a name="line894" /> 894 def normalize
1516
- </span><span class="marked1"><a name="line895" /> 895 normalized_scheme = nil
1517
- </span><span class="marked0"><a name="line896" /> 896 normalized_scheme = self.scheme.strip.downcase if self.scheme != nil
1518
- </span><span class="marked1"><a name="line897" /> 897 normalized_scheme = &quot;svn+ssh&quot; if normalized_scheme == &quot;ssh+svn&quot;
1519
- </span><span class="marked0"><a name="line898" /> 898 if normalized_scheme == &quot;feed&quot;
1520
- </span><span class="marked1"><a name="line899" /> 899 if self.to_s =~ /^feed:\/*http:\/*/
1521
- </span><span class="marked0"><a name="line900" /> 900 return self.class.parse(
1522
- </span><span class="marked1"><a name="line901" /> 901 self.to_s.scan(/^feed:\/*(http:\/*.*)/).flatten[0]).normalize
1523
- </span><span class="inferred0"><a name="line902" /> 902 end
1524
- </span><span class="inferred1"><a name="line903" /> 903 end
1525
- </span><span class="marked0"><a name="line904" /> 904 normalized_user = nil
1526
- </span><span class="marked1"><a name="line905" /> 905 normalized_user = self.user.strip if self.user != nil
1527
- </span><span class="marked0"><a name="line906" /> 906 normalized_password = nil
1528
- </span><span class="marked1"><a name="line907" /> 907 normalized_password = self.password.strip if self.password != nil
1529
- </span><span class="marked0"><a name="line908" /> 908 normalized_host = nil
1530
- </span><span class="marked1"><a name="line909" /> 909 normalized_host = self.host.strip.downcase if self.host != nil
1531
- </span><span class="marked0"><a name="line910" /> 910 if normalized_host != nil
1532
- </span><span class="marked1"><a name="line911" /> 911 begin
1533
- </span><span class="marked0"><a name="line912" /> 912 normalized_host = URI::IDNA.to_ascii(normalized_host)
1534
- </span><span class="inferred1"><a name="line913" /> 913 rescue Exception
1535
- </span><span class="marked0"><a name="line914" /> 914 nil
1536
- </span><span class="inferred1"><a name="line915" /> 915 end
1537
- </span><span class="inferred0"><a name="line916" /> 916 end
1538
- </span><span class="inferred1"><a name="line917" /> 917
1539
- </span><span class="marked0"><a name="line918" /> 918 normalized_port = self.port
1540
- </span><span class="marked1"><a name="line919" /> 919 if self.class.scheme_mapping[normalized_scheme] == normalized_port
1541
- </span><span class="marked0"><a name="line920" /> 920 normalized_port = nil
1542
- </span><span class="inferred1"><a name="line921" /> 921 end
1543
- </span><span class="marked0"><a name="line922" /> 922 normalized_path = nil
1544
- </span><span class="marked1"><a name="line923" /> 923 normalized_path = self.path.strip if self.path != nil
1545
- </span><span class="inferred0"><a name="line924" /> 924 if normalized_path == nil &amp;&amp;
1546
- </span><span class="marked1"><a name="line925" /> 925 normalized_scheme != nil &amp;&amp;
1547
- </span><span class="inferred0"><a name="line926" /> 926 normalized_host != nil
1548
- </span><span class="marked1"><a name="line927" /> 927 normalized_path = &quot;/&quot;
1549
- </span><span class="inferred0"><a name="line928" /> 928 end
1550
- </span><span class="marked1"><a name="line929" /> 929 if normalized_path != nil
1551
- </span><span class="marked0"><a name="line930" /> 930 normalized_path = self.class.normalize_path(normalized_path)
1552
- </span><span class="inferred1"><a name="line931" /> 931 end
1553
- </span><span class="marked0"><a name="line932" /> 932 if normalized_path == &quot;&quot;
1554
- </span><span class="marked1"><a name="line933" /> 933 if [&quot;http&quot;, &quot;https&quot;, &quot;ftp&quot;, &quot;tftp&quot;].include?(normalized_scheme)
1555
- </span><span class="marked0"><a name="line934" /> 934 normalized_path = &quot;/&quot;
1556
- </span><span class="inferred1"><a name="line935" /> 935 end
1557
- </span><span class="inferred0"><a name="line936" /> 936 end
1558
- </span><span class="inferred1"><a name="line937" /> 937
1559
- </span><span class="marked0"><a name="line938" /> 938 normalized_query = nil
1560
- </span><span class="marked1"><a name="line939" /> 939 normalized_query = self.query.strip if self.query != nil
1561
- </span><span class="inferred0"><a name="line940" /> 940
1562
- </span><span class="marked1"><a name="line941" /> 941 normalized_fragment = nil
1563
- </span><span class="marked0"><a name="line942" /> 942 normalized_fragment = self.fragment.strip if self.fragment != nil
1564
- </span><span class="marked1"><a name="line943" /> 943 return Addressable::URI.parse(
1565
- </span><span class="marked0"><a name="line944" /> 944 Addressable::URI.normalized_encode(Addressable::URI.new(
1566
- </span><span class="inferred1"><a name="line945" /> 945 normalized_scheme,
1567
- </span><span class="inferred0"><a name="line946" /> 946 normalized_user,
1568
- </span><span class="inferred1"><a name="line947" /> 947 normalized_password,
1569
- </span><span class="inferred0"><a name="line948" /> 948 normalized_host,
1570
- </span><span class="inferred1"><a name="line949" /> 949 normalized_port,
1571
- </span><span class="inferred0"><a name="line950" /> 950 normalized_path,
1572
- </span><span class="inferred1"><a name="line951" /> 951 normalized_query,
1573
- </span><span class="inferred0"><a name="line952" /> 952 normalized_fragment
1574
- </span><span class="marked1"><a name="line953" /> 953 )))
1575
- </span><span class="inferred0"><a name="line954" /> 954 end
1576
- </span><span class="inferred1"><a name="line955" /> 955
1577
- </span><span class="inferred0"><a name="line956" /> 956 # Destructively normalizes this URI object.
1578
- </span><span class="marked1"><a name="line957" /> 957 def normalize!
1579
- </span><span class="marked0"><a name="line958" /> 958 replace_self(self.normalize)
1580
- </span><span class="marked1"><a name="line959" /> 959 end
1581
- </span><span class="inferred0"><a name="line960" /> 960
1582
- </span><span class="inferred1"><a name="line961" /> 961 # Creates a URI suitable for display to users. If semantic attacks are
1583
- </span><span class="inferred0"><a name="line962" /> 962 # likely, the application should try to detect these and warn the user.
1584
- </span><span class="inferred1"><a name="line963" /> 963 # See RFC 3986 section 7.6 for more information.
1585
- </span><span class="marked0"><a name="line964" /> 964 def display_uri
1586
- </span><span class="marked1"><a name="line965" /> 965 display_uri = self.normalize
1587
- </span><span class="marked0"><a name="line966" /> 966 begin
1588
- </span><span class="marked1"><a name="line967" /> 967 display_uri.instance_variable_set(&quot;@host&quot;,
1589
- </span><span class="marked0"><a name="line968" /> 968 URI::IDNA.to_unicode(display_uri.host))
1590
- </span><span class="inferred1"><a name="line969" /> 969 rescue Exception
1591
- </span><span class="marked0"><a name="line970" /> 970 nil
1592
- </span><span class="inferred1"><a name="line971" /> 971 end
1593
- </span><span class="marked0"><a name="line972" /> 972 return display_uri
1594
- </span><span class="inferred1"><a name="line973" /> 973 end
1595
- </span><span class="inferred0"><a name="line974" /> 974
1596
- </span><span class="inferred1"><a name="line975" /> 975 # Returns true if the URI objects are equal. This method normalizes
1597
- </span><span class="inferred0"><a name="line976" /> 976 # both URIs before doing the comparison, and allows comparison against
1598
- </span><span class="inferred1"><a name="line977" /> 977 # strings.
1599
- </span><span class="marked0"><a name="line978" /> 978 def ===(uri)
1600
- </span><span class="marked1"><a name="line979" /> 979 uri_string = nil
1601
- </span><span class="marked0"><a name="line980" /> 980 if uri.respond_to?(:normalize)
1602
- </span><span class="marked1"><a name="line981" /> 981 uri_string = uri.normalize.to_s
1603
- </span><span class="inferred0"><a name="line982" /> 982 else
1604
- </span><span class="marked1"><a name="line983" /> 983 begin
1605
- </span><span class="marked0"><a name="line984" /> 984 uri_string = URI.parse(uri.to_s).normalize.to_s
1606
- </span><span class="inferred1"><a name="line985" /> 985 rescue Exception
1607
- </span><span class="marked0"><a name="line986" /> 986 return false
1608
- </span><span class="inferred1"><a name="line987" /> 987 end
1609
- </span><span class="inferred0"><a name="line988" /> 988 end
1610
- </span><span class="marked1"><a name="line989" /> 989 return self.normalize.to_s == uri_string
1611
- </span><span class="inferred0"><a name="line990" /> 990 end
1612
- </span><span class="inferred1"><a name="line991" /> 991
1613
- </span><span class="inferred0"><a name="line992" /> 992 # Returns true if the URI objects are equal. This method normalizes
1614
- </span><span class="inferred1"><a name="line993" /> 993 # both URIs before doing the comparison.
1615
- </span><span class="marked0"><a name="line994" /> 994 def ==(uri)
1616
- </span><span class="marked1"><a name="line995" /> 995 return false unless uri.kind_of?(self.class)
1617
- </span><span class="marked0"><a name="line996" /> 996 return self.normalize.to_s == uri.normalize.to_s
1618
- </span><span class="inferred1"><a name="line997" /> 997 end
1619
- </span><span class="inferred0"><a name="line998" /> 998
1620
- </span><span class="inferred1"><a name="line999" /> 999 # Returns true if the URI objects are equal. This method does NOT
1621
- </span><span class="inferred0"><a name="line1000" />1000 # normalize either URI before doing the comparison.
1622
- </span><span class="marked1"><a name="line1001" />1001 def eql?(uri)
1623
- </span><span class="marked0"><a name="line1002" />1002 return false unless uri.kind_of?(self.class)
1624
- </span><span class="marked1"><a name="line1003" />1003 return self.to_s == uri.to_s
1625
- </span><span class="inferred0"><a name="line1004" />1004 end
1626
- </span><span class="inferred1"><a name="line1005" />1005
1627
- </span><span class="inferred0"><a name="line1006" />1006 # Clones the URI object.
1628
- </span><span class="marked1"><a name="line1007" />1007 def dup
1629
- </span><span class="marked0"><a name="line1008" />1008 duplicated_scheme = nil
1630
- </span><span class="marked1"><a name="line1009" />1009 duplicated_scheme = self.scheme.dup if self.scheme != nil
1631
- </span><span class="marked0"><a name="line1010" />1010 duplicated_user = nil
1632
- </span><span class="marked1"><a name="line1011" />1011 duplicated_user = self.user.dup if self.user != nil
1633
- </span><span class="marked0"><a name="line1012" />1012 duplicated_password = nil
1634
- </span><span class="marked1"><a name="line1013" />1013 duplicated_password = self.password.dup if self.password != nil
1635
- </span><span class="marked0"><a name="line1014" />1014 duplicated_host = nil
1636
- </span><span class="marked1"><a name="line1015" />1015 duplicated_host = self.host.dup if self.host != nil
1637
- </span><span class="marked0"><a name="line1016" />1016 duplicated_port = self.port
1638
- </span><span class="marked1"><a name="line1017" />1017 duplicated_path = nil
1639
- </span><span class="marked0"><a name="line1018" />1018 duplicated_path = self.path.dup if self.path != nil
1640
- </span><span class="marked1"><a name="line1019" />1019 duplicated_query = nil
1641
- </span><span class="marked0"><a name="line1020" />1020 duplicated_query = self.query.dup if self.query != nil
1642
- </span><span class="marked1"><a name="line1021" />1021 duplicated_fragment = nil
1643
- </span><span class="marked0"><a name="line1022" />1022 duplicated_fragment = self.fragment.dup if self.fragment != nil
1644
- </span><span class="marked1"><a name="line1023" />1023 duplicated_uri = Addressable::URI.new(
1645
- </span><span class="inferred0"><a name="line1024" />1024 duplicated_scheme,
1646
- </span><span class="inferred1"><a name="line1025" />1025 duplicated_user,
1647
- </span><span class="inferred0"><a name="line1026" />1026 duplicated_password,
1648
- </span><span class="inferred1"><a name="line1027" />1027 duplicated_host,
1649
- </span><span class="inferred0"><a name="line1028" />1028 duplicated_port,
1650
- </span><span class="inferred1"><a name="line1029" />1029 duplicated_path,
1651
- </span><span class="inferred0"><a name="line1030" />1030 duplicated_query,
1652
- </span><span class="inferred1"><a name="line1031" />1031 duplicated_fragment
1653
- </span><span class="inferred0"><a name="line1032" />1032 )
1654
- </span><span class="marked1"><a name="line1033" />1033 @specified_port = nil if !defined?(@specified_port)
1655
- </span><span class="marked0"><a name="line1034" />1034 duplicated_uri.instance_variable_set(&quot;@specified_port&quot;, @specified_port)
1656
- </span><span class="marked1"><a name="line1035" />1035 return duplicated_uri
1657
- </span><span class="inferred0"><a name="line1036" />1036 end
1658
- </span><span class="inferred1"><a name="line1037" />1037
1659
- </span><span class="inferred0"><a name="line1038" />1038 # Returns the assembled URI as a string.
1660
- </span><span class="marked1"><a name="line1039" />1039 def to_s
1661
- </span><span class="marked0"><a name="line1040" />1040 uri_string = &quot;&quot;
1662
- </span><span class="marked1"><a name="line1041" />1041 uri_string &lt;&lt; &quot;#{self.scheme}:&quot; if self.scheme != nil
1663
- </span><span class="marked0"><a name="line1042" />1042 uri_string &lt;&lt; &quot;//#{self.authority}&quot; if self.authority != nil
1664
- </span><span class="marked1"><a name="line1043" />1043 uri_string &lt;&lt; self.path.to_s
1665
- </span><span class="marked0"><a name="line1044" />1044 uri_string &lt;&lt; &quot;?#{self.query}&quot; if self.query != nil
1666
- </span><span class="marked1"><a name="line1045" />1045 uri_string &lt;&lt; &quot;##{self.fragment}&quot; if self.fragment != nil
1667
- </span><span class="marked0"><a name="line1046" />1046 return uri_string
1668
- </span><span class="inferred1"><a name="line1047" />1047 end
1669
- </span><span class="inferred0"><a name="line1048" />1048
1670
- </span><span class="inferred1"><a name="line1049" />1049 # Returns a Hash of the URI segments.
1671
- </span><span class="marked0"><a name="line1050" />1050 def to_h
1672
- </span><span class="inferred1"><a name="line1051" />1051 return {
1673
- </span><span class="marked0"><a name="line1052" />1052 :scheme =&gt; self.scheme,
1674
- </span><span class="marked1"><a name="line1053" />1053 :user =&gt; self.user,
1675
- </span><span class="marked0"><a name="line1054" />1054 :password =&gt; self.password,
1676
- </span><span class="marked1"><a name="line1055" />1055 :host =&gt; self.host,
1677
- </span><span class="marked0"><a name="line1056" />1056 :port =&gt; self.specified_port,
1678
- </span><span class="marked1"><a name="line1057" />1057 :path =&gt; self.path,
1679
- </span><span class="marked0"><a name="line1058" />1058 :query =&gt; self.query,
1680
- </span><span class="marked1"><a name="line1059" />1059 :fragment =&gt; self.fragment
1681
- </span><span class="marked0"><a name="line1060" />1060 }
1682
- </span><span class="marked1"><a name="line1061" />1061 end
1683
- </span><span class="inferred0"><a name="line1062" />1062
1684
- </span><span class="inferred1"><a name="line1063" />1063 # Returns a string representation of the URI object's state.
1685
- </span><span class="marked0"><a name="line1064" />1064 def inspect
1686
- </span><span class="marked1"><a name="line1065" />1065 sprintf(&quot;#&lt;%s:%#0x URI:%s&gt;&quot;, self.class.to_s, self.object_id, self.to_s)
1687
- </span><span class="marked0"><a name="line1066" />1066 end
1688
- </span><span class="inferred1"><a name="line1067" />1067
1689
- </span><span class="inferred0"><a name="line1068" />1068 # This module handles internationalized domain names. When Ruby has an
1690
- </span><span class="inferred1"><a name="line1069" />1069 # implementation of nameprep, stringprep, punycode, etc, this
1691
- </span><span class="inferred0"><a name="line1070" />1070 # module should contain an actual implementation of IDNA instead of
1692
- </span><span class="inferred1"><a name="line1071" />1071 # returning nil if libidn can't be used.
1693
- </span><span class="marked0"><a name="line1072" />1072 module IDNA
1694
- </span><span class="inferred1"><a name="line1073" />1073 # Returns the ascii representation of the label.
1695
- </span><span class="marked0"><a name="line1074" />1074 def self.to_ascii(label)
1696
- </span><span class="marked1"><a name="line1075" />1075 return nil if label.nil?
1697
- </span><span class="marked0"><a name="line1076" />1076 if self.use_libidn?
1698
- </span><span class="marked1"><a name="line1077" />1077 return IDN::Idna.toASCII(label)
1699
- </span><span class="inferred0"><a name="line1078" />1078 else
1700
- </span><span class="marked1"><a name="line1079" />1079 raise NotImplementedError,
1701
- </span><span class="inferred0"><a name="line1080" />1080 &quot;There is no available pure-ruby implementation. &quot; +
1702
- </span><span class="inferred1"><a name="line1081" />1081 &quot;Install libidn bindings.&quot;
1703
- </span><span class="inferred0"><a name="line1082" />1082 end
1704
- </span><span class="inferred1"><a name="line1083" />1083 end
1705
- </span><span class="inferred0"><a name="line1084" />1084
1706
- </span><span class="inferred1"><a name="line1085" />1085 # Returns the unicode representation of the label.
1707
- </span><span class="marked0"><a name="line1086" />1086 def self.to_unicode(label)
1708
- </span><span class="marked1"><a name="line1087" />1087 return nil if label.nil?
1709
- </span><span class="marked0"><a name="line1088" />1088 if self.use_libidn?
1710
- </span><span class="marked1"><a name="line1089" />1089 return IDN::Idna.toUnicode(label)
1711
- </span><span class="inferred0"><a name="line1090" />1090 else
1712
- </span><span class="marked1"><a name="line1091" />1091 raise NotImplementedError,
1713
- </span><span class="inferred0"><a name="line1092" />1092 &quot;There is no available pure-ruby implementation. &quot; +
1714
- </span><span class="inferred1"><a name="line1093" />1093 &quot;Install libidn bindings.&quot;
1715
- </span><span class="inferred0"><a name="line1094" />1094 end
1716
- </span><span class="inferred1"><a name="line1095" />1095 end
1717
- </span><span class="inferred0"><a name="line1096" />1096
1718
- </span><span class="marked1"><a name="line1097" />1097 private
1719
- </span><span class="inferred0"><a name="line1098" />1098 # Determines if the libidn bindings are available and able to be used.
1720
- </span><span class="marked1"><a name="line1099" />1099 def self.use_libidn?
1721
- </span><span class="marked0"><a name="line1100" />1100 if !defined?(@use_libidn) || @use_libidn.nil?
1722
- </span><span class="marked1"><a name="line1101" />1101 begin
1723
- </span><span class="marked0"><a name="line1102" />1102 require 'rubygems'
1724
- </span><span class="inferred1"><a name="line1103" />1103 rescue LoadError
1725
- </span><span class="marked0"><a name="line1104" />1104 nil
1726
- </span><span class="inferred1"><a name="line1105" />1105 end
1727
- </span><span class="marked0"><a name="line1106" />1106 begin
1728
- </span><span class="marked1"><a name="line1107" />1107 require 'idn'
1729
- </span><span class="inferred0"><a name="line1108" />1108 rescue LoadError
1730
- </span><span class="marked1"><a name="line1109" />1109 nil
1731
- </span><span class="inferred0"><a name="line1110" />1110 end
1732
- </span><span class="marked1"><a name="line1111" />1111 @use_libidn = !!(defined?(IDN::Idna))
1733
- </span><span class="inferred0"><a name="line1112" />1112 end
1734
- </span><span class="marked1"><a name="line1113" />1113 return @use_libidn
1735
- </span><span class="inferred0"><a name="line1114" />1114 end
1736
- </span><span class="inferred1"><a name="line1115" />1115 end
1737
- </span><span class="inferred0"><a name="line1116" />1116
1738
- </span><span class="marked1"><a name="line1117" />1117 private
1739
- </span><span class="inferred0"><a name="line1118" />1118 # Resolves paths to their simplest form.
1740
- </span><span class="marked1"><a name="line1119" />1119 def self.normalize_path(path)
1741
- </span><span class="marked0"><a name="line1120" />1120 return nil if path.nil?
1742
- </span><span class="marked1"><a name="line1121" />1121 normalized_path = path.dup
1743
- </span><span class="marked0"><a name="line1122" />1122 previous_state = normalized_path.dup
1744
- </span><span class="inferred1"><a name="line1123" />1123 begin
1745
- </span><span class="marked0"><a name="line1124" />1124 previous_state = normalized_path.dup
1746
- </span><span class="marked1"><a name="line1125" />1125 normalized_path.gsub!(/\/\.\//, &quot;/&quot;)
1747
- </span><span class="marked0"><a name="line1126" />1126 normalized_path.gsub!(/\/\.$/, &quot;/&quot;)
1748
- </span><span class="marked1"><a name="line1127" />1127 parent = normalized_path.scan(/\/([^\/]+)\/\.\.\//).flatten[0]
1749
- </span><span class="marked0"><a name="line1128" />1128 if parent != &quot;.&quot; &amp;&amp; parent != &quot;..&quot;
1750
- </span><span class="marked1"><a name="line1129" />1129 normalized_path.gsub!(/\/#{parent}\/\.\.\//, &quot;/&quot;)
1751
- </span><span class="inferred0"><a name="line1130" />1130 end
1752
- </span><span class="marked1"><a name="line1131" />1131 parent = normalized_path.scan(/\/([^\/]+)\/\.\.$/).flatten[0]
1753
- </span><span class="marked0"><a name="line1132" />1132 if parent != &quot;.&quot; &amp;&amp; parent != &quot;..&quot;
1754
- </span><span class="marked1"><a name="line1133" />1133 normalized_path.gsub!(/\/#{parent}\/\.\.$/, &quot;/&quot;)
1755
- </span><span class="inferred0"><a name="line1134" />1134 end
1756
- </span><span class="marked1"><a name="line1135" />1135 normalized_path.gsub!(/^\.\.?\/?/, &quot;&quot;)
1757
- </span><span class="marked0"><a name="line1136" />1136 normalized_path.gsub!(/^\/\.\.?\//, &quot;/&quot;)
1758
- </span><span class="marked1"><a name="line1137" />1137 end until previous_state == normalized_path
1759
- </span><span class="marked0"><a name="line1138" />1138 return normalized_path
1760
- </span><span class="inferred1"><a name="line1139" />1139 end
1761
- </span><span class="inferred0"><a name="line1140" />1140
1762
- </span><span class="inferred1"><a name="line1141" />1141 # Ensures that the URI is valid.
1763
- </span><span class="marked0"><a name="line1142" />1142 def validate
1764
- </span><span class="marked1"><a name="line1143" />1143 if self.scheme == nil &amp;&amp; self.user == nil &amp;&amp; self.password == nil &amp;&amp;
1765
- </span><span class="marked0"><a name="line1144" />1144 self.host == nil &amp;&amp; self.port == nil &amp;&amp; self.path == nil &amp;&amp;
1766
- </span><span class="marked1"><a name="line1145" />1145 self.query == nil &amp;&amp; self.fragment == nil
1767
- </span><span class="marked0"><a name="line1146" />1146 raise InvalidURIError, &quot;All segments were nil.&quot;
1768
- </span><span class="inferred1"><a name="line1147" />1147 end
1769
- </span><span class="marked0"><a name="line1148" />1148 if self.scheme != nil &amp;&amp;
1770
- </span><span class="marked1"><a name="line1149" />1149 (self.host == nil || self.host == &quot;&quot;) &amp;&amp;
1771
- </span><span class="marked0"><a name="line1150" />1150 (self.path == nil || self.path == &quot;&quot;)
1772
- </span><span class="marked1"><a name="line1151" />1151 raise InvalidURIError,
1773
- </span><span class="inferred0"><a name="line1152" />1152 &quot;Absolute URI missing hierarchical segment.&quot;
1774
- </span><span class="inferred1"><a name="line1153" />1153 end
1775
- </span><span class="inferred0"><a name="line1154" />1154 end
1776
- </span><span class="inferred1"><a name="line1155" />1155
1777
- </span><span class="inferred0"><a name="line1156" />1156 # Replaces the internal state of self with the specified URI's state.
1778
- </span><span class="inferred1"><a name="line1157" />1157 # Used in destructive operations to avoid massive code repetition.
1779
- </span><span class="marked0"><a name="line1158" />1158 def replace_self(uri)
1780
- </span><span class="inferred1"><a name="line1159" />1159 # Reset dependant values
1781
- </span><span class="marked0"><a name="line1160" />1160 @userinfo = nil
1782
- </span><span class="marked1"><a name="line1161" />1161 @authority = nil
1783
- </span><span class="inferred0"><a name="line1162" />1162
1784
- </span><span class="marked1"><a name="line1163" />1163 @scheme = uri.scheme
1785
- </span><span class="marked0"><a name="line1164" />1164 @user = uri.user
1786
- </span><span class="marked1"><a name="line1165" />1165 @password = uri.password
1787
- </span><span class="marked0"><a name="line1166" />1166 @host = uri.host
1788
- </span><span class="marked1"><a name="line1167" />1167 @specified_port = uri.instance_variable_get(&quot;@specified_port&quot;)
1789
- </span><span class="marked0"><a name="line1168" />1168 @port = @specified_port.to_s.to_i
1790
- </span><span class="marked1"><a name="line1169" />1169 @path = uri.path
1791
- </span><span class="marked0"><a name="line1170" />1170 @query = uri.query
1792
- </span><span class="marked1"><a name="line1171" />1171 @fragment = uri.fragment
1793
- </span><span class="marked0"><a name="line1172" />1172 return self
1794
- </span><span class="inferred1"><a name="line1173" />1173 end
1795
- </span><span class="inferred0"><a name="line1174" />1174 end
1796
- </span><span class="inferred1"><a name="line1175" />1175 end
1484
+ </span><span class="marked1"><a name="line863" /> 863 if normalized_self == uri
1485
+ </span><span class="marked0"><a name="line864" /> 864 return Addressable::URI.parse(&quot;##{normalized_self.fragment}&quot;)
1486
+ </span><span class="inferred1"><a name="line865" /> 865 end
1487
+ </span><span class="marked0"><a name="line866" /> 866 segments = normalized_self.to_h
1488
+ </span><span class="marked1"><a name="line867" /> 867 if normalized_self.scheme == uri.scheme
1489
+ </span><span class="marked0"><a name="line868" /> 868 segments[:scheme] = nil
1490
+ </span><span class="marked1"><a name="line869" /> 869 if normalized_self.authority == uri.authority
1491
+ </span><span class="marked0"><a name="line870" /> 870 segments[:user] = nil
1492
+ </span><span class="marked1"><a name="line871" /> 871 segments[:password] = nil
1493
+ </span><span class="marked0"><a name="line872" /> 872 segments[:host] = nil
1494
+ </span><span class="marked1"><a name="line873" /> 873 segments[:port] = nil
1495
+ </span><span class="marked0"><a name="line874" /> 874 if normalized_self.path == uri.path
1496
+ </span><span class="marked1"><a name="line875" /> 875 segments[:path] = nil
1497
+ </span><span class="marked0"><a name="line876" /> 876 if normalized_self.query == uri.query
1498
+ </span><span class="marked1"><a name="line877" /> 877 segments[:query] = nil
1499
+ </span><span class="inferred0"><a name="line878" /> 878 end
1500
+ </span><span class="inferred1"><a name="line879" /> 879 end
1501
+ </span><span class="inferred0"><a name="line880" /> 880 end
1502
+ </span><span class="inferred1"><a name="line881" /> 881 end
1503
+ </span><span class="inferred0"><a name="line882" /> 882 # Avoid network-path references.
1504
+ </span><span class="marked1"><a name="line883" /> 883 if segments[:scheme] == nil &amp;&amp; segments[:host] != nil
1505
+ </span><span class="marked0"><a name="line884" /> 884 segments[:scheme] = normalized_self.scheme
1506
+ </span><span class="inferred1"><a name="line885" /> 885 end
1507
+ </span><span class="marked0"><a name="line886" /> 886 return Addressable::URI.new(
1508
+ </span><span class="inferred1"><a name="line887" /> 887 segments[:scheme],
1509
+ </span><span class="inferred0"><a name="line888" /> 888 segments[:user],
1510
+ </span><span class="inferred1"><a name="line889" /> 889 segments[:password],
1511
+ </span><span class="inferred0"><a name="line890" /> 890 segments[:host],
1512
+ </span><span class="inferred1"><a name="line891" /> 891 segments[:port],
1513
+ </span><span class="inferred0"><a name="line892" /> 892 segments[:path],
1514
+ </span><span class="inferred1"><a name="line893" /> 893 segments[:query],
1515
+ </span><span class="inferred0"><a name="line894" /> 894 segments[:fragment]
1516
+ </span><span class="marked1"><a name="line895" /> 895 )
1517
+ </span><span class="inferred0"><a name="line896" /> 896 end
1518
+ </span><span class="inferred1"><a name="line897" /> 897
1519
+ </span><span class="inferred0"><a name="line898" /> 898 # Returns the shortest normalized relative form of the supplied URI that
1520
+ </span><span class="inferred1"><a name="line899" /> 899 # uses this URI as a base for resolution. Returns an absolute URI if
1521
+ </span><span class="inferred0"><a name="line900" /> 900 # necessary.
1522
+ </span><span class="marked1"><a name="line901" /> 901 def route_to(uri)
1523
+ </span><span class="marked0"><a name="line902" /> 902 uri = uri.kind_of?(self.class) ? uri : self.class.parse(uri.to_s)
1524
+ </span><span class="marked1"><a name="line903" /> 903 return uri.route_from(self)
1525
+ </span><span class="inferred0"><a name="line904" /> 904 end
1526
+ </span><span class="inferred1"><a name="line905" /> 905
1527
+ </span><span class="inferred0"><a name="line906" /> 906 # Returns a normalized URI object.
1528
+ </span><span class="inferred1"><a name="line907" /> 907 #
1529
+ </span><span class="inferred0"><a name="line908" /> 908 # NOTE: This method does not attempt to fully conform to specifications.
1530
+ </span><span class="inferred1"><a name="line909" /> 909 # It exists largely to correct other people's failures to read the
1531
+ </span><span class="inferred0"><a name="line910" /> 910 # specifications, and also to deal with caching issues since several
1532
+ </span><span class="inferred1"><a name="line911" /> 911 # different URIs may represent the same resource and should not be
1533
+ </span><span class="inferred0"><a name="line912" /> 912 # cached multiple times.
1534
+ </span><span class="marked1"><a name="line913" /> 913 def normalize
1535
+ </span><span class="marked0"><a name="line914" /> 914 normalized_scheme = nil
1536
+ </span><span class="marked1"><a name="line915" /> 915 normalized_scheme = self.scheme.strip.downcase if self.scheme != nil
1537
+ </span><span class="marked0"><a name="line916" /> 916 normalized_scheme = &quot;svn+ssh&quot; if normalized_scheme == &quot;ssh+svn&quot;
1538
+ </span><span class="marked1"><a name="line917" /> 917 if normalized_scheme == &quot;feed&quot;
1539
+ </span><span class="marked0"><a name="line918" /> 918 if self.to_s =~ /^feed:\/*http:\/*/
1540
+ </span><span class="marked1"><a name="line919" /> 919 return self.class.parse(
1541
+ </span><span class="marked0"><a name="line920" /> 920 self.to_s.scan(/^feed:\/*(http:\/*.*)/).flatten[0]).normalize
1542
+ </span><span class="inferred1"><a name="line921" /> 921 end
1543
+ </span><span class="inferred0"><a name="line922" /> 922 end
1544
+ </span><span class="marked1"><a name="line923" /> 923 normalized_user = nil
1545
+ </span><span class="marked0"><a name="line924" /> 924 normalized_user = self.user.strip if self.user != nil
1546
+ </span><span class="marked1"><a name="line925" /> 925 normalized_password = nil
1547
+ </span><span class="marked0"><a name="line926" /> 926 normalized_password = self.password.strip if self.password != nil
1548
+ </span><span class="inferred1"><a name="line927" /> 927
1549
+ </span><span class="marked0"><a name="line928" /> 928 if normalized_scheme =~ /https?/ &amp;&amp; normalized_user == &quot;&quot; &amp;&amp;
1550
+ </span><span class="marked1"><a name="line929" /> 929 (normalized_password == nil || normalized_password == &quot;&quot;)
1551
+ </span><span class="marked0"><a name="line930" /> 930 normalized_user = nil
1552
+ </span><span class="marked1"><a name="line931" /> 931 normalized_password = nil
1553
+ </span><span class="inferred0"><a name="line932" /> 932 end
1554
+ </span><span class="inferred1"><a name="line933" /> 933
1555
+ </span><span class="marked0"><a name="line934" /> 934 normalized_host = nil
1556
+ </span><span class="marked1"><a name="line935" /> 935 normalized_host = self.host.strip.downcase if self.host != nil
1557
+ </span><span class="marked0"><a name="line936" /> 936 if normalized_host != nil
1558
+ </span><span class="marked1"><a name="line937" /> 937 begin
1559
+ </span><span class="marked0"><a name="line938" /> 938 normalized_host = URI::IDNA.to_ascii(normalized_host)
1560
+ </span><span class="inferred1"><a name="line939" /> 939 rescue Exception
1561
+ </span><span class="marked0"><a name="line940" /> 940 nil
1562
+ </span><span class="inferred1"><a name="line941" /> 941 end
1563
+ </span><span class="marked0"><a name="line942" /> 942 if normalized_host[-1..-1] == &quot;.&quot;
1564
+ </span><span class="marked1"><a name="line943" /> 943 normalized_host = normalized_host[0...-1]
1565
+ </span><span class="inferred0"><a name="line944" /> 944 end
1566
+ </span><span class="inferred1"><a name="line945" /> 945 end
1567
+ </span><span class="inferred0"><a name="line946" /> 946
1568
+ </span><span class="marked1"><a name="line947" /> 947 normalized_port = self.port
1569
+ </span><span class="marked0"><a name="line948" /> 948 if self.class.scheme_mapping[normalized_scheme] == normalized_port
1570
+ </span><span class="marked1"><a name="line949" /> 949 normalized_port = nil
1571
+ </span><span class="inferred0"><a name="line950" /> 950 end
1572
+ </span><span class="marked1"><a name="line951" /> 951 normalized_path = nil
1573
+ </span><span class="marked0"><a name="line952" /> 952 normalized_path = self.path.strip if self.path != nil
1574
+ </span><span class="inferred1"><a name="line953" /> 953 if normalized_path == nil &amp;&amp;
1575
+ </span><span class="marked0"><a name="line954" /> 954 normalized_scheme != nil &amp;&amp;
1576
+ </span><span class="inferred1"><a name="line955" /> 955 normalized_host != nil
1577
+ </span><span class="marked0"><a name="line956" /> 956 normalized_path = &quot;/&quot;
1578
+ </span><span class="inferred1"><a name="line957" /> 957 end
1579
+ </span><span class="marked0"><a name="line958" /> 958 if normalized_path != nil
1580
+ </span><span class="marked1"><a name="line959" /> 959 normalized_path = self.class.normalize_path(normalized_path)
1581
+ </span><span class="inferred0"><a name="line960" /> 960 end
1582
+ </span><span class="marked1"><a name="line961" /> 961 if normalized_path == &quot;&quot;
1583
+ </span><span class="marked0"><a name="line962" /> 962 if [&quot;http&quot;, &quot;https&quot;, &quot;ftp&quot;, &quot;tftp&quot;].include?(normalized_scheme)
1584
+ </span><span class="marked1"><a name="line963" /> 963 normalized_path = &quot;/&quot;
1585
+ </span><span class="inferred0"><a name="line964" /> 964 end
1586
+ </span><span class="inferred1"><a name="line965" /> 965 end
1587
+ </span><span class="inferred0"><a name="line966" /> 966
1588
+ </span><span class="marked1"><a name="line967" /> 967 normalized_query = nil
1589
+ </span><span class="marked0"><a name="line968" /> 968 normalized_query = self.query.strip if self.query != nil
1590
+ </span><span class="inferred1"><a name="line969" /> 969
1591
+ </span><span class="marked0"><a name="line970" /> 970 normalized_fragment = nil
1592
+ </span><span class="marked1"><a name="line971" /> 971 normalized_fragment = self.fragment.strip if self.fragment != nil
1593
+ </span><span class="marked0"><a name="line972" /> 972 return Addressable::URI.parse(
1594
+ </span><span class="marked1"><a name="line973" /> 973 Addressable::URI.normalized_encode(Addressable::URI.new(
1595
+ </span><span class="inferred0"><a name="line974" /> 974 normalized_scheme,
1596
+ </span><span class="inferred1"><a name="line975" /> 975 normalized_user,
1597
+ </span><span class="inferred0"><a name="line976" /> 976 normalized_password,
1598
+ </span><span class="inferred1"><a name="line977" /> 977 normalized_host,
1599
+ </span><span class="inferred0"><a name="line978" /> 978 normalized_port,
1600
+ </span><span class="inferred1"><a name="line979" /> 979 normalized_path,
1601
+ </span><span class="inferred0"><a name="line980" /> 980 normalized_query,
1602
+ </span><span class="inferred1"><a name="line981" /> 981 normalized_fragment
1603
+ </span><span class="marked0"><a name="line982" /> 982 )))
1604
+ </span><span class="inferred1"><a name="line983" /> 983 end
1605
+ </span><span class="inferred0"><a name="line984" /> 984
1606
+ </span><span class="inferred1"><a name="line985" /> 985 # Destructively normalizes this URI object.
1607
+ </span><span class="marked0"><a name="line986" /> 986 def normalize!
1608
+ </span><span class="marked1"><a name="line987" /> 987 replace_self(self.normalize)
1609
+ </span><span class="marked0"><a name="line988" /> 988 end
1610
+ </span><span class="inferred1"><a name="line989" /> 989
1611
+ </span><span class="inferred0"><a name="line990" /> 990 # Creates a URI suitable for display to users. If semantic attacks are
1612
+ </span><span class="inferred1"><a name="line991" /> 991 # likely, the application should try to detect these and warn the user.
1613
+ </span><span class="inferred0"><a name="line992" /> 992 # See RFC 3986 section 7.6 for more information.
1614
+ </span><span class="marked1"><a name="line993" /> 993 def display_uri
1615
+ </span><span class="marked0"><a name="line994" /> 994 display_uri = self.normalize
1616
+ </span><span class="marked1"><a name="line995" /> 995 begin
1617
+ </span><span class="marked0"><a name="line996" /> 996 display_uri.instance_variable_set(&quot;@host&quot;,
1618
+ </span><span class="marked1"><a name="line997" /> 997 URI::IDNA.to_unicode(display_uri.host))
1619
+ </span><span class="inferred0"><a name="line998" /> 998 rescue Exception
1620
+ </span><span class="marked1"><a name="line999" /> 999 nil
1621
+ </span><span class="inferred0"><a name="line1000" />1000 end
1622
+ </span><span class="marked1"><a name="line1001" />1001 return display_uri
1623
+ </span><span class="inferred0"><a name="line1002" />1002 end
1624
+ </span><span class="inferred1"><a name="line1003" />1003
1625
+ </span><span class="inferred0"><a name="line1004" />1004 # Returns true if the URI objects are equal. This method normalizes
1626
+ </span><span class="inferred1"><a name="line1005" />1005 # both URIs before doing the comparison, and allows comparison against
1627
+ </span><span class="inferred0"><a name="line1006" />1006 # strings.
1628
+ </span><span class="marked1"><a name="line1007" />1007 def ===(uri)
1629
+ </span><span class="marked0"><a name="line1008" />1008 uri_string = nil
1630
+ </span><span class="marked1"><a name="line1009" />1009 if uri.respond_to?(:normalize)
1631
+ </span><span class="marked0"><a name="line1010" />1010 uri_string = uri.normalize.to_s
1632
+ </span><span class="inferred1"><a name="line1011" />1011 else
1633
+ </span><span class="marked0"><a name="line1012" />1012 begin
1634
+ </span><span class="marked1"><a name="line1013" />1013 uri_string = URI.parse(uri.to_s).normalize.to_s
1635
+ </span><span class="inferred0"><a name="line1014" />1014 rescue Exception
1636
+ </span><span class="marked1"><a name="line1015" />1015 return false
1637
+ </span><span class="inferred0"><a name="line1016" />1016 end
1638
+ </span><span class="inferred1"><a name="line1017" />1017 end
1639
+ </span><span class="marked0"><a name="line1018" />1018 return self.normalize.to_s == uri_string
1640
+ </span><span class="inferred1"><a name="line1019" />1019 end
1641
+ </span><span class="inferred0"><a name="line1020" />1020
1642
+ </span><span class="inferred1"><a name="line1021" />1021 # Returns true if the URI objects are equal. This method normalizes
1643
+ </span><span class="inferred0"><a name="line1022" />1022 # both URIs before doing the comparison.
1644
+ </span><span class="marked1"><a name="line1023" />1023 def ==(uri)
1645
+ </span><span class="marked0"><a name="line1024" />1024 return false unless uri.kind_of?(self.class)
1646
+ </span><span class="marked1"><a name="line1025" />1025 return self.normalize.to_s == uri.normalize.to_s
1647
+ </span><span class="inferred0"><a name="line1026" />1026 end
1648
+ </span><span class="inferred1"><a name="line1027" />1027
1649
+ </span><span class="inferred0"><a name="line1028" />1028 # Returns true if the URI objects are equal. This method does NOT
1650
+ </span><span class="inferred1"><a name="line1029" />1029 # normalize either URI before doing the comparison.
1651
+ </span><span class="marked0"><a name="line1030" />1030 def eql?(uri)
1652
+ </span><span class="marked1"><a name="line1031" />1031 return false unless uri.kind_of?(self.class)
1653
+ </span><span class="marked0"><a name="line1032" />1032 return self.to_s == uri.to_s
1654
+ </span><span class="inferred1"><a name="line1033" />1033 end
1655
+ </span><span class="inferred0"><a name="line1034" />1034
1656
+ </span><span class="inferred1"><a name="line1035" />1035 # Clones the URI object.
1657
+ </span><span class="marked0"><a name="line1036" />1036 def dup
1658
+ </span><span class="marked1"><a name="line1037" />1037 duplicated_scheme = nil
1659
+ </span><span class="marked0"><a name="line1038" />1038 duplicated_scheme = self.scheme.dup if self.scheme != nil
1660
+ </span><span class="marked1"><a name="line1039" />1039 duplicated_user = nil
1661
+ </span><span class="marked0"><a name="line1040" />1040 duplicated_user = self.user.dup if self.user != nil
1662
+ </span><span class="marked1"><a name="line1041" />1041 duplicated_password = nil
1663
+ </span><span class="marked0"><a name="line1042" />1042 duplicated_password = self.password.dup if self.password != nil
1664
+ </span><span class="marked1"><a name="line1043" />1043 duplicated_host = nil
1665
+ </span><span class="marked0"><a name="line1044" />1044 duplicated_host = self.host.dup if self.host != nil
1666
+ </span><span class="marked1"><a name="line1045" />1045 duplicated_port = self.port
1667
+ </span><span class="marked0"><a name="line1046" />1046 duplicated_path = nil
1668
+ </span><span class="marked1"><a name="line1047" />1047 duplicated_path = self.path.dup if self.path != nil
1669
+ </span><span class="marked0"><a name="line1048" />1048 duplicated_query = nil
1670
+ </span><span class="marked1"><a name="line1049" />1049 duplicated_query = self.query.dup if self.query != nil
1671
+ </span><span class="marked0"><a name="line1050" />1050 duplicated_fragment = nil
1672
+ </span><span class="marked1"><a name="line1051" />1051 duplicated_fragment = self.fragment.dup if self.fragment != nil
1673
+ </span><span class="marked0"><a name="line1052" />1052 duplicated_uri = Addressable::URI.new(
1674
+ </span><span class="inferred1"><a name="line1053" />1053 duplicated_scheme,
1675
+ </span><span class="inferred0"><a name="line1054" />1054 duplicated_user,
1676
+ </span><span class="inferred1"><a name="line1055" />1055 duplicated_password,
1677
+ </span><span class="inferred0"><a name="line1056" />1056 duplicated_host,
1678
+ </span><span class="inferred1"><a name="line1057" />1057 duplicated_port,
1679
+ </span><span class="inferred0"><a name="line1058" />1058 duplicated_path,
1680
+ </span><span class="inferred1"><a name="line1059" />1059 duplicated_query,
1681
+ </span><span class="inferred0"><a name="line1060" />1060 duplicated_fragment
1682
+ </span><span class="inferred1"><a name="line1061" />1061 )
1683
+ </span><span class="marked0"><a name="line1062" />1062 @specified_port = nil if !defined?(@specified_port)
1684
+ </span><span class="marked1"><a name="line1063" />1063 duplicated_uri.instance_variable_set(&quot;@specified_port&quot;, @specified_port)
1685
+ </span><span class="marked0"><a name="line1064" />1064 return duplicated_uri
1686
+ </span><span class="inferred1"><a name="line1065" />1065 end
1687
+ </span><span class="inferred0"><a name="line1066" />1066
1688
+ </span><span class="inferred1"><a name="line1067" />1067 # Returns the assembled URI as a string.
1689
+ </span><span class="marked0"><a name="line1068" />1068 def to_s
1690
+ </span><span class="marked1"><a name="line1069" />1069 uri_string = &quot;&quot;
1691
+ </span><span class="marked0"><a name="line1070" />1070 uri_string &lt;&lt; &quot;#{self.scheme}:&quot; if self.scheme != nil
1692
+ </span><span class="marked1"><a name="line1071" />1071 uri_string &lt;&lt; &quot;//#{self.authority}&quot; if self.authority != nil
1693
+ </span><span class="marked0"><a name="line1072" />1072 uri_string &lt;&lt; self.path.to_s
1694
+ </span><span class="marked1"><a name="line1073" />1073 uri_string &lt;&lt; &quot;?#{self.query}&quot; if self.query != nil
1695
+ </span><span class="marked0"><a name="line1074" />1074 uri_string &lt;&lt; &quot;##{self.fragment}&quot; if self.fragment != nil
1696
+ </span><span class="marked1"><a name="line1075" />1075 return uri_string
1697
+ </span><span class="inferred0"><a name="line1076" />1076 end
1698
+ </span><span class="inferred1"><a name="line1077" />1077
1699
+ </span><span class="inferred0"><a name="line1078" />1078 # Returns a Hash of the URI segments.
1700
+ </span><span class="marked1"><a name="line1079" />1079 def to_h
1701
+ </span><span class="inferred0"><a name="line1080" />1080 return {
1702
+ </span><span class="marked1"><a name="line1081" />1081 :scheme =&gt; self.scheme,
1703
+ </span><span class="marked0"><a name="line1082" />1082 :user =&gt; self.user,
1704
+ </span><span class="marked1"><a name="line1083" />1083 :password =&gt; self.password,
1705
+ </span><span class="marked0"><a name="line1084" />1084 :host =&gt; self.host,
1706
+ </span><span class="marked1"><a name="line1085" />1085 :port =&gt; self.specified_port,
1707
+ </span><span class="marked0"><a name="line1086" />1086 :path =&gt; self.path,
1708
+ </span><span class="marked1"><a name="line1087" />1087 :query =&gt; self.query,
1709
+ </span><span class="marked0"><a name="line1088" />1088 :fragment =&gt; self.fragment
1710
+ </span><span class="marked1"><a name="line1089" />1089 }
1711
+ </span><span class="marked0"><a name="line1090" />1090 end
1712
+ </span><span class="inferred1"><a name="line1091" />1091
1713
+ </span><span class="inferred0"><a name="line1092" />1092 # Returns a string representation of the URI object's state.
1714
+ </span><span class="marked1"><a name="line1093" />1093 def inspect
1715
+ </span><span class="marked0"><a name="line1094" />1094 sprintf(&quot;#&lt;%s:%#0x URI:%s&gt;&quot;, self.class.to_s, self.object_id, self.to_s)
1716
+ </span><span class="marked1"><a name="line1095" />1095 end
1717
+ </span><span class="inferred0"><a name="line1096" />1096
1718
+ </span><span class="inferred1"><a name="line1097" />1097 # This module handles internationalized domain names. When Ruby has an
1719
+ </span><span class="inferred0"><a name="line1098" />1098 # implementation of nameprep, stringprep, punycode, etc, this
1720
+ </span><span class="inferred1"><a name="line1099" />1099 # module should contain an actual implementation of IDNA instead of
1721
+ </span><span class="inferred0"><a name="line1100" />1100 # returning nil if libidn can't be used.
1722
+ </span><span class="marked1"><a name="line1101" />1101 module IDNA
1723
+ </span><span class="inferred0"><a name="line1102" />1102 # Returns the ascii representation of the label.
1724
+ </span><span class="marked1"><a name="line1103" />1103 def self.to_ascii(label)
1725
+ </span><span class="marked0"><a name="line1104" />1104 return nil if label.nil?
1726
+ </span><span class="marked1"><a name="line1105" />1105 if self.use_libidn?
1727
+ </span><span class="marked0"><a name="line1106" />1106 return IDN::Idna.toASCII(label)
1728
+ </span><span class="inferred1"><a name="line1107" />1107 else
1729
+ </span><span class="marked0"><a name="line1108" />1108 raise NotImplementedError,
1730
+ </span><span class="inferred1"><a name="line1109" />1109 &quot;There is no available pure-ruby implementation. &quot; +
1731
+ </span><span class="inferred0"><a name="line1110" />1110 &quot;Install libidn bindings.&quot;
1732
+ </span><span class="inferred1"><a name="line1111" />1111 end
1733
+ </span><span class="inferred0"><a name="line1112" />1112 end
1734
+ </span><span class="inferred1"><a name="line1113" />1113
1735
+ </span><span class="inferred0"><a name="line1114" />1114 # Returns the unicode representation of the label.
1736
+ </span><span class="marked1"><a name="line1115" />1115 def self.to_unicode(label)
1737
+ </span><span class="marked0"><a name="line1116" />1116 return nil if label.nil?
1738
+ </span><span class="marked1"><a name="line1117" />1117 if self.use_libidn?
1739
+ </span><span class="marked0"><a name="line1118" />1118 return IDN::Idna.toUnicode(label)
1740
+ </span><span class="inferred1"><a name="line1119" />1119 else
1741
+ </span><span class="marked0"><a name="line1120" />1120 raise NotImplementedError,
1742
+ </span><span class="inferred1"><a name="line1121" />1121 &quot;There is no available pure-ruby implementation. &quot; +
1743
+ </span><span class="inferred0"><a name="line1122" />1122 &quot;Install libidn bindings.&quot;
1744
+ </span><span class="inferred1"><a name="line1123" />1123 end
1745
+ </span><span class="inferred0"><a name="line1124" />1124 end
1746
+ </span><span class="inferred1"><a name="line1125" />1125
1747
+ </span><span class="marked0"><a name="line1126" />1126 private
1748
+ </span><span class="inferred1"><a name="line1127" />1127 # Determines if the libidn bindings are available and able to be used.
1749
+ </span><span class="marked0"><a name="line1128" />1128 def self.use_libidn?
1750
+ </span><span class="marked1"><a name="line1129" />1129 if !defined?(@use_libidn) || @use_libidn.nil?
1751
+ </span><span class="marked0"><a name="line1130" />1130 begin
1752
+ </span><span class="marked1"><a name="line1131" />1131 require 'rubygems'
1753
+ </span><span class="inferred0"><a name="line1132" />1132 rescue LoadError
1754
+ </span><span class="marked1"><a name="line1133" />1133 nil
1755
+ </span><span class="inferred0"><a name="line1134" />1134 end
1756
+ </span><span class="marked1"><a name="line1135" />1135 begin
1757
+ </span><span class="marked0"><a name="line1136" />1136 require 'idn'
1758
+ </span><span class="inferred1"><a name="line1137" />1137 rescue LoadError
1759
+ </span><span class="marked0"><a name="line1138" />1138 nil
1760
+ </span><span class="inferred1"><a name="line1139" />1139 end
1761
+ </span><span class="marked0"><a name="line1140" />1140 @use_libidn = !!(defined?(IDN::Idna))
1762
+ </span><span class="inferred1"><a name="line1141" />1141 end
1763
+ </span><span class="marked0"><a name="line1142" />1142 return @use_libidn
1764
+ </span><span class="inferred1"><a name="line1143" />1143 end
1765
+ </span><span class="inferred0"><a name="line1144" />1144 end
1766
+ </span><span class="inferred1"><a name="line1145" />1145
1767
+ </span><span class="marked0"><a name="line1146" />1146 private
1768
+ </span><span class="inferred1"><a name="line1147" />1147 # Resolves paths to their simplest form.
1769
+ </span><span class="marked0"><a name="line1148" />1148 def self.normalize_path(path)
1770
+ </span><span class="inferred1"><a name="line1149" />1149 # Section 5.2.4 of RFC 3986
1771
+ </span><span class="inferred0"><a name="line1150" />1150
1772
+ </span><span class="marked1"><a name="line1151" />1151 return nil if path.nil?
1773
+ </span><span class="marked0"><a name="line1152" />1152 normalized_path = path.dup
1774
+ </span><span class="marked1"><a name="line1153" />1153 previous_state = normalized_path.dup
1775
+ </span><span class="inferred0"><a name="line1154" />1154 begin
1776
+ </span><span class="marked1"><a name="line1155" />1155 previous_state = normalized_path.dup
1777
+ </span><span class="marked0"><a name="line1156" />1156 normalized_path.gsub!(/\/\.\//, &quot;/&quot;)
1778
+ </span><span class="marked1"><a name="line1157" />1157 normalized_path.gsub!(/\/\.$/, &quot;/&quot;)
1779
+ </span><span class="marked0"><a name="line1158" />1158 parent = normalized_path.scan(/\/([^\/]+)\/\.\.\//).flatten[0]
1780
+ </span><span class="marked1"><a name="line1159" />1159 if parent != &quot;.&quot; &amp;&amp; parent != &quot;..&quot;
1781
+ </span><span class="marked0"><a name="line1160" />1160 normalized_path.gsub!(/\/#{parent}\/\.\.\//, &quot;/&quot;)
1782
+ </span><span class="inferred1"><a name="line1161" />1161 end
1783
+ </span><span class="marked0"><a name="line1162" />1162 parent = normalized_path.scan(/\/([^\/]+)\/\.\.$/).flatten[0]
1784
+ </span><span class="marked1"><a name="line1163" />1163 if parent != &quot;.&quot; &amp;&amp; parent != &quot;..&quot;
1785
+ </span><span class="marked0"><a name="line1164" />1164 normalized_path.gsub!(/\/#{parent}\/\.\.$/, &quot;/&quot;)
1786
+ </span><span class="inferred1"><a name="line1165" />1165 end
1787
+ </span><span class="marked0"><a name="line1166" />1166 normalized_path.gsub!(/^\.\.?\/?/, &quot;&quot;)
1788
+ </span><span class="marked1"><a name="line1167" />1167 normalized_path.gsub!(/^\/\.\.?\//, &quot;/&quot;)
1789
+ </span><span class="marked0"><a name="line1168" />1168 end until previous_state == normalized_path
1790
+ </span><span class="marked1"><a name="line1169" />1169 return normalized_path
1791
+ </span><span class="inferred0"><a name="line1170" />1170 end
1792
+ </span><span class="inferred1"><a name="line1171" />1171
1793
+ </span><span class="inferred0"><a name="line1172" />1172 # Ensures that the URI is valid.
1794
+ </span><span class="marked1"><a name="line1173" />1173 def validate
1795
+ </span><span class="marked0"><a name="line1174" />1174 if self.scheme == nil &amp;&amp; self.user == nil &amp;&amp; self.password == nil &amp;&amp;
1796
+ </span><span class="marked1"><a name="line1175" />1175 self.host == nil &amp;&amp; self.port == nil &amp;&amp; self.path == nil &amp;&amp;
1797
+ </span><span class="marked0"><a name="line1176" />1176 self.query == nil &amp;&amp; self.fragment == nil
1798
+ </span><span class="marked1"><a name="line1177" />1177 raise InvalidURIError, &quot;All segments were nil.&quot;
1799
+ </span><span class="inferred0"><a name="line1178" />1178 end
1800
+ </span><span class="marked1"><a name="line1179" />1179 if self.scheme != nil &amp;&amp;
1801
+ </span><span class="marked0"><a name="line1180" />1180 (self.host == nil || self.host == &quot;&quot;) &amp;&amp;
1802
+ </span><span class="marked1"><a name="line1181" />1181 (self.path == nil || self.path == &quot;&quot;)
1803
+ </span><span class="marked0"><a name="line1182" />1182 raise InvalidURIError,
1804
+ </span><span class="inferred1"><a name="line1183" />1183 &quot;Absolute URI missing hierarchical segment.&quot;
1805
+ </span><span class="inferred0"><a name="line1184" />1184 end
1806
+ </span><span class="inferred1"><a name="line1185" />1185 end
1807
+ </span><span class="inferred0"><a name="line1186" />1186
1808
+ </span><span class="inferred1"><a name="line1187" />1187 # Replaces the internal state of self with the specified URI's state.
1809
+ </span><span class="inferred0"><a name="line1188" />1188 # Used in destructive operations to avoid massive code repetition.
1810
+ </span><span class="marked1"><a name="line1189" />1189 def replace_self(uri)
1811
+ </span><span class="inferred0"><a name="line1190" />1190 # Reset dependant values
1812
+ </span><span class="marked1"><a name="line1191" />1191 @userinfo = nil
1813
+ </span><span class="marked0"><a name="line1192" />1192 @authority = nil
1814
+ </span><span class="inferred1"><a name="line1193" />1193
1815
+ </span><span class="marked0"><a name="line1194" />1194 @scheme = uri.scheme
1816
+ </span><span class="marked1"><a name="line1195" />1195 @user = uri.user
1817
+ </span><span class="marked0"><a name="line1196" />1196 @password = uri.password
1818
+ </span><span class="marked1"><a name="line1197" />1197 @host = uri.host
1819
+ </span><span class="marked0"><a name="line1198" />1198 @specified_port = uri.instance_variable_get(&quot;@specified_port&quot;)
1820
+ </span><span class="marked1"><a name="line1199" />1199 @port = @specified_port.to_s.to_i
1821
+ </span><span class="marked0"><a name="line1200" />1200 @path = uri.path
1822
+ </span><span class="marked1"><a name="line1201" />1201 @query = uri.query
1823
+ </span><span class="marked0"><a name="line1202" />1202 @fragment = uri.fragment
1824
+ </span><span class="marked1"><a name="line1203" />1203 return self
1825
+ </span><span class="inferred0"><a name="line1204" />1204 end
1826
+ </span><span class="inferred1"><a name="line1205" />1205 end
1827
+ </span><span class="inferred0"><a name="line1206" />1206 end
1797
1828
  </span></pre><hr /> <p>Generated using the <a href='http://eigenclass.org/hiki.rb?rcov'>rcov code coverage analysis tool for Ruby</a> version 0.8.0.</p><p>
1798
1829
  <a href='http://validator.w3.org/check/referer'>
1799
1830
  <img src='http://www.w3.org/Icons/valid-xhtml10' height='31' alt='Valid XHTML 1.0!' width='88' />