Class | URI::Generic |
In: |
lib/open-uri.rb
lib/uri/generic.rb |
Parent: | Object |
DEFAULT_PORT | = | nil |
COMPONENT | = | [ :scheme, :userinfo, :host, :port, :registry, :path, :opaque, :query, :fragment |
USE_REGISTRY | = | false |
fragment | [R] | |
host | [R] | |
opaque | [R] | |
path | [R] | |
port | [R] | |
query | [R] | |
registry | [R] | |
scheme | [R] |
See new
Creates a new URI::Generic instance from components of URI::Generic with check. Components are: scheme, userinfo, host, port, registry, path, opaque, query and fragment. You can provide arguments either by an Array or a Hash. See new for hash keys to use or for order of array items.
# File lib/uri/generic.rb, line 108 108: def self.build(args) 109: if args.kind_of?(Array) && 110: args.size == ::URI::Generic::COMPONENT.size 111: tmp = args 112: elsif args.kind_of?(Hash) 113: tmp = ::URI::Generic::COMPONENT.collect do |c| 114: if args.include?(c) 115: args[c] 116: else 117: nil 118: end 119: end 120: else 121: raise ArgumentError, 122: "expected Array of or Hash of components of #{self.class} (#{self.class.component.join(', ')})" 123: end 124: 125: tmp << true 126: return self.new(*tmp) 127: end
See new
At first, tries to create a new URI::Generic instance using URI::Generic::build. But, if exception URI::InvalidComponentError is raised, then it URI::Escape.escape all URI components and tries again.
# File lib/uri/generic.rb, line 70 70: def self.build2(args) 71: begin 72: return self.build(args) 73: rescue InvalidComponentError 74: if args.kind_of?(Array) 75: return self.build(args.collect{|x| 76: if x 77: URI.escape(x) 78: else 79: x 80: end 81: }) 82: elsif args.kind_of?(Hash) 83: tmp = {} 84: args.each do |key, value| 85: tmp[key] = if value 86: URI.escape(value) 87: else 88: value 89: end 90: end 91: return self.build(tmp) 92: end 93: end 94: end
Returns default port
# File lib/uri/generic.rb, line 26 26: def self.default_port 27: self::DEFAULT_PORT 28: end
scheme: | Protocol scheme, i.e. ‘http’,’ftp’,’mailto’ and so on. |
userinfo: | User name and password, i.e. ‘sdmitry:bla‘ |
host: | Server host name |
port: | Server port |
registry: | DOC: FIXME! |
path: | Path on server |
opaque: | DOC: FIXME! |
query: | Query data |
fragment: | A part of URI after ’#’ sign |
arg_check: | Check arguments [false by default] |
Creates a new URI::Generic instance from ``generic’’ components without check.
# File lib/uri/generic.rb, line 156 156: def initialize(scheme, 157: userinfo, host, port, registry, 158: path, opaque, 159: query, 160: fragment, 161: arg_check = false) 162: @scheme = nil 163: @user = nil 164: @password = nil 165: @host = nil 166: @port = nil 167: @path = nil 168: @query = nil 169: @opaque = nil 170: @registry = nil 171: @fragment = nil 172: 173: if arg_check 174: self.scheme = scheme 175: self.userinfo = userinfo 176: self.host = host 177: self.port = port 178: self.path = path 179: self.query = query 180: self.opaque = opaque 181: self.registry = registry 182: self.fragment = fragment 183: else 184: self.set_scheme(scheme) 185: self.set_userinfo(userinfo) 186: self.set_host(host) 187: self.set_port(port) 188: self.set_path(path) 189: self.set_query(query) 190: self.set_opaque(opaque) 191: self.set_registry(registry) 192: self.set_fragment(fragment) 193: end 194: if @registry && !self.class.use_registry 195: raise InvalidURIError, 196: "the scheme #{@scheme} does not accept registry part: #{@registry} (or bad hostname?)" 197: end 198: 199: @scheme.freeze if @scheme 200: self.set_path('') if !@path && !@opaque # (see RFC2396 Section 5.2) 201: self.set_port(self.default_port) if self.default_port && !@port 202: end
DOC: FIXME!
# File lib/uri/generic.rb, line 54 54: def self.use_registry 55: self::USE_REGISTRY 56: end
# File lib/uri/generic.rb, line 1108 1108: def coerce(oth) 1109: case oth 1110: when String 1111: oth = URI.parse(oth) 1112: else 1113: super 1114: end 1115: 1116: return oth, self 1117: end
# File lib/uri/generic.rb, line 1052 1052: def eql?(oth) 1053: self.class == oth.class && 1054: self.component_ary.eql?(oth.component_ary) 1055: end
returns a proxy URI. The proxy URI is obtained from environment variables such as http_proxy, ftp_proxy, no_proxy, etc. If there is no proper proxy, nil is returned.
Note that capitalized variables (HTTP_PROXY, FTP_PROXY, NO_PROXY, etc.) are examined too.
But http_proxy and HTTP_PROXY is treated specially under CGI environment. It‘s because HTTP_PROXY may be set by Proxy: header. So HTTP_PROXY is not used. http_proxy is not used too if the variable is case insensitive. CGI_HTTP_PROXY can be used instead.
# File lib/open-uri.rb, line 550 550: def find_proxy 551: name = self.scheme.downcase + '_proxy' 552: proxy_uri = nil 553: if name == 'http_proxy' && ENV.include?('REQUEST_METHOD') # CGI? 554: # HTTP_PROXY conflicts with *_proxy for proxy settings and 555: # HTTP_* for header information in CGI. 556: # So it should be careful to use it. 557: pairs = ENV.reject {|k, v| /\Ahttp_proxy\z/i !~ k } 558: case pairs.length 559: when 0 # no proxy setting anyway. 560: proxy_uri = nil 561: when 1 562: k, v = pairs.shift 563: if k == 'http_proxy' && ENV[k.upcase] == nil 564: # http_proxy is safe to use because ENV is case sensitive. 565: proxy_uri = ENV[name] 566: else 567: proxy_uri = nil 568: end 569: else # http_proxy is safe to use because ENV is case sensitive. 570: proxy_uri = ENV.to_hash[name] 571: end 572: if !proxy_uri 573: # Use CGI_HTTP_PROXY. cf. libwww-perl. 574: proxy_uri = ENV["CGI_#{name.upcase}"] 575: end 576: elsif name == 'http_proxy' 577: unless proxy_uri = ENV[name] 578: if proxy_uri = ENV[name.upcase] 579: warn 'The environment variable HTTP_PROXY is discouraged. Use http_proxy.' 580: end 581: end 582: else 583: proxy_uri = ENV[name] || ENV[name.upcase] 584: end 585: 586: if proxy_uri && self.host 587: require 'socket' 588: begin 589: addr = IPSocket.getaddress(self.host) 590: proxy_uri = nil if /\A127\.|\A::1\z/ =~ addr 591: rescue SocketError 592: end 593: end 594: 595: if proxy_uri 596: proxy_uri = URI.parse(proxy_uri) 597: name = 'no_proxy' 598: if no_proxy = ENV[name] || ENV[name.upcase] 599: no_proxy.scan(/([^:,]*)(?::(\d+))?/) {|host, port| 600: if /(\A|\.)#{Regexp.quote host}\z/i =~ self.host && 601: (!port || self.port == port.to_i) 602: proxy_uri = nil 603: break 604: end 605: } 606: end 607: proxy_uri 608: else 609: nil 610: end 611: end
# File lib/uri/generic.rb, line 577 577: def fragment=(v) 578: check_fragment(v) 579: set_fragment(v) 580: v 581: end
# File lib/uri/generic.rb, line 396 396: def host=(v) 397: check_host(v) 398: set_host(v) 399: v 400: end
# File lib/uri/generic.rb, line 1104 1104: def inspect 1105: @@to_s.bind(self).call.sub!(/>\z/) {" URL:#{self}>"} 1106: end
oth: | URI or String |
Merges two URI‘s.
require 'uri' uri = URI.parse("http://my.example.com") p uri.merge("/main.rbx?page=1") # => #<URI::HTTP:0x2021f3b0 URL:http://my.example.com/main.rbx?page=1>
# File lib/uri/generic.rb, line 728 728: def merge(oth) 729: begin 730: base, rel = merge0(oth) 731: rescue 732: raise $!.class, $!.message 733: end 734: 735: if base == rel 736: return base 737: end 738: 739: authority = rel.userinfo || rel.host || rel.port 740: 741: # RFC2396, Section 5.2, 2) 742: if (rel.path.nil? || rel.path.empty?) && !authority && !rel.query 743: base.set_fragment(rel.fragment) if rel.fragment 744: return base 745: end 746: 747: base.set_query(nil) 748: base.set_fragment(nil) 749: 750: # RFC2396, Section 5.2, 4) 751: if !authority 752: base.set_path(merge_path(base.path, rel.path)) if base.path && rel.path 753: else 754: # RFC2396, Section 5.2, 4) 755: base.set_path(rel.path) if rel.path 756: end 757: 758: # RFC2396, Section 5.2, 7) 759: base.set_userinfo(rel.userinfo) if rel.userinfo 760: base.set_host(rel.host) if rel.host 761: base.set_port(rel.port) if rel.port 762: base.set_query(rel.query) if rel.query 763: base.set_fragment(rel.fragment) if rel.fragment 764: 765: return base 766: end
oth: | URI or String |
Destructive form of merge
require 'uri' uri = URI.parse("http://my.example.com") uri.merge!("/main.rbx?page=1") p uri # => #<URI::HTTP:0x2021f3b0 URL:http://my.example.com/main.rbx?page=1>
# File lib/uri/generic.rb, line 700 700: def merge!(oth) 701: t = merge(oth) 702: if self == t 703: nil 704: else 705: replace!(t) 706: self 707: end 708: end
# File lib/uri/generic.rb, line 554 554: def opaque=(v) 555: check_opaque(v) 556: set_opaque(v) 557: v 558: end
# File lib/uri/generic.rb, line 316 316: def password=(password) 317: check_password(password) 318: set_password(password) 319: # returns password 320: end
# File lib/uri/generic.rb, line 494 494: def path=(v) 495: check_path(v) 496: set_path(v) 497: v 498: end
# File lib/uri/generic.rb, line 429 429: def port=(v) 430: check_port(v) 431: set_port(v) 432: port 433: end
# File lib/uri/generic.rb, line 525 525: def query=(v) 526: check_query(v) 527: set_query(v) 528: v 529: end
# File lib/uri/generic.rb, line 458 458: def registry=(v) 459: check_registry(v) 460: set_registry(v) 461: v 462: end
oth: | URI or String |
Calculates relative path from oth to self
require 'uri' uri = URI.parse('http://my.example.com/main.rbx?page=1') p uri.route_from('http://my.example.com') #=> #<URI::Generic:0x20218858 URL:/main.rbx?page=1>
# File lib/uri/generic.rb, line 910 910: def route_from(oth) 911: # you can modify `rel', but can not `oth'. 912: begin 913: oth, rel = route_from0(oth) 914: rescue 915: raise $!.class, $!.message 916: end 917: if oth == rel 918: return rel 919: end 920: 921: rel.set_path(route_from_path(oth.path, self.path)) 922: if rel.path == './' && self.query 923: # "./?foo" -> "?foo" 924: rel.set_path('') 925: end 926: 927: return rel 928: end
oth: | URI or String |
Calculates relative path to oth from self
require 'uri' uri = URI.parse('http://my.example.com') p uri.route_to('http://my.example.com/main.rbx?page=1') #=> #<URI::Generic:0x2020c2f6 URL:/main.rbx?page=1>
# File lib/uri/generic.rb, line 950 950: def route_to(oth) 951: case oth 952: when Generic 953: when String 954: oth = URI.parse(oth) 955: else 956: raise ArgumentError, 957: "bad argument(expected URI object or URI string)" 958: end 959: 960: oth.route_from(self) 961: end
# File lib/uri/generic.rb, line 243 243: def scheme=(v) 244: check_scheme(v) 245: set_scheme(v) 246: v 247: end
components: | Multiple Symbol arguments defined in URI::HTTP |
Selects specified components from URI
require 'uri' uri = URI.parse('http://myuser:mypass@my.example.com/test.rbx') p uri.select(:userinfo, :host, :path) # => ["myuser:mypass", "my.example.com", "/test.rbx"]
# File lib/uri/generic.rb, line 1092 1092: def select(*components) 1093: components.collect do |c| 1094: if component.include?(c) 1095: self.send(c) 1096: else 1097: raise ArgumentError, 1098: "expected of components of #{self.class} (#{self.class.component.join(', ')})" 1099: end 1100: end 1101: end
# File lib/uri/generic.rb, line 996 996: def to_s 997: str = '' 998: if @scheme 999: str << @scheme 1000: str << ':' 1001: end 1002: 1003: if @opaque 1004: str << @opaque 1005: 1006: else 1007: if @registry 1008: str << @registry 1009: else 1010: if @host 1011: str << '//' 1012: end 1013: if self.userinfo 1014: str << self.userinfo 1015: str << '@' 1016: end 1017: if @host 1018: str << @host 1019: end 1020: if @port && @port != self.default_port 1021: str << ':' 1022: str << @port.to_s 1023: end 1024: end 1025: 1026: str << path_query 1027: end 1028: 1029: if @fragment 1030: str << '#' 1031: str << @fragment 1032: end 1033: 1034: str 1035: end
# File lib/uri/generic.rb, line 310 310: def user=(user) 311: check_user(user) 312: set_user(user) 313: # returns user 314: end
# File lib/uri/generic.rb, line 358 358: def userinfo 359: if @user.nil? 360: nil 361: elsif @password.nil? 362: @user 363: else 364: @user + ':' + @password 365: end 366: end
# File lib/uri/generic.rb, line 1068 1068: def component_ary 1069: component.collect do |x| 1070: self.send(x) 1071: end 1072: end
# File lib/uri/generic.rb, line 339 339: def set_password(v) 340: @password = v 341: # returns v 342: end
# File lib/uri/generic.rb, line 417 417: def set_port(v) 418: unless !v || v.kind_of?(Fixnum) 419: if v.empty? 420: v = nil 421: else 422: v = v.to_i 423: end 424: end 425: @port = v 426: end
# File lib/uri/generic.rb, line 333 333: def set_user(v) 334: set_userinfo(v, @password) 335: v 336: end
# File lib/uri/generic.rb, line 322 322: def set_userinfo(user, password = nil) 323: unless password 324: user, password = split_userinfo(user) 325: end 326: @user = user 327: @password = password if password 328: 329: [@user, @password] 330: end
# File lib/uri/generic.rb, line 560 560: def check_fragment(v) 561: return v unless v 562: 563: if v && v != '' && FRAGMENT !~ v 564: raise InvalidComponentError, 565: "bad component(expected fragment component): #{v}" 566: end 567: 568: return true 569: end
# File lib/uri/generic.rb, line 376 376: def check_host(v) 377: return v unless v 378: 379: if @registry || @opaque 380: raise InvalidURIError, 381: "can not set host with registry or opaque" 382: elsif HOST !~ v 383: raise InvalidComponentError, 384: "bad component(expected host component): #{v}" 385: end 386: 387: return true 388: end
# File lib/uri/generic.rb, line 531 531: def check_opaque(v) 532: return v unless v 533: 534: # raise if both hier and opaque are not nil, because: 535: # absoluteURI = scheme ":" ( hier_part | opaque_part ) 536: # hier_part = ( net_path | abs_path ) [ "?" query ] 537: if @host || @port || @user || @path # userinfo = @user + ':' + @password 538: raise InvalidURIError, 539: "can not set opaque with host, port, userinfo or path" 540: elsif v && OPAQUE !~ v 541: raise InvalidComponentError, 542: "bad component(expected opaque component): #{v}" 543: end 544: 545: return true 546: end
# File lib/uri/generic.rb, line 277 277: def check_password(v, user = @user) 278: if @registry || @opaque 279: raise InvalidURIError, 280: "can not set password with registry or opaque" 281: end 282: return v unless v 283: 284: if !user 285: raise InvalidURIError, 286: "password component depends user component" 287: end 288: 289: if USERINFO !~ v 290: raise InvalidComponentError, 291: "bad component(expected user component): #{v}" 292: end 293: 294: return true 295: end
# File lib/uri/generic.rb, line 464 464: def check_path(v) 465: # raise if both hier and opaque are not nil, because: 466: # absoluteURI = scheme ":" ( hier_part | opaque_part ) 467: # hier_part = ( net_path | abs_path ) [ "?" query ] 468: if v && @opaque 469: raise InvalidURIError, 470: "path conflicts with opaque" 471: end 472: 473: if @scheme 474: if v && v != '' && ABS_PATH !~ v 475: raise InvalidComponentError, 476: "bad component(expected absolute path component): #{v}" 477: end 478: else 479: if v && v != '' && ABS_PATH !~ v && REL_PATH !~ v 480: raise InvalidComponentError, 481: "bad component(expected relative path component): #{v}" 482: end 483: end 484: 485: return true 486: end
# File lib/uri/generic.rb, line 402 402: def check_port(v) 403: return v unless v 404: 405: if @registry || @opaque 406: raise InvalidURIError, 407: "can not set port with registry or opaque" 408: elsif !v.kind_of?(Fixnum) && PORT !~ v 409: raise InvalidComponentError, 410: "bad component(expected port component): #{v}" 411: end 412: 413: return true 414: end
# File lib/uri/generic.rb, line 500 500: def check_query(v) 501: return v unless v 502: 503: # raise if both hier and opaque are not nil, because: 504: # absoluteURI = scheme ":" ( hier_part | opaque_part ) 505: # hier_part = ( net_path | abs_path ) [ "?" query ] 506: if @opaque 507: raise InvalidURIError, 508: "query conflicts with opaque" 509: end 510: 511: if v && v != '' && QUERY !~ v 512: raise InvalidComponentError, 513: "bad component(expected query component): #{v}" 514: end 515: 516: return true 517: end
# File lib/uri/generic.rb, line 435 435: def check_registry(v) 436: return v unless v 437: 438: # raise if both server and registry are not nil, because: 439: # authority = server | reg_name 440: # server = [ [ userinfo "@" ] hostport ] 441: if @host || @port || @user # userinfo = @user + ':' + @password 442: raise InvalidURIError, 443: "can not set registry with host, port, or userinfo" 444: elsif v && REGISTRY !~ v 445: raise InvalidComponentError, 446: "bad component(expected registry component): #{v}" 447: end 448: 449: return true 450: end
# File lib/uri/generic.rb, line 228 228: def check_scheme(v) 229: if v && SCHEME !~ v 230: raise InvalidComponentError, 231: "bad component(expected scheme component): #{v}" 232: end 233: 234: return true 235: end
# File lib/uri/generic.rb, line 260 260: def check_user(v) 261: if @registry || @opaque 262: raise InvalidURIError, 263: "can not set user with registry or opaque" 264: end 265: 266: return v unless v 267: 268: if USERINFO !~ v 269: raise InvalidComponentError, 270: "bad component(expected userinfo component or user component): #{v}" 271: end 272: 273: return true 274: end
# File lib/uri/generic.rb, line 249 249: def check_userinfo(user, password = nil) 250: if !password 251: user, password = split_userinfo(user) 252: end 253: check_user(user) 254: check_password(password, user) 255: 256: return true 257: end
# File lib/uri/generic.rb, line 353 353: def escape_userpass(v) 354: v = URI.escape(v, /[@:\/]/o) # RFC 1738 section 3.1 #/ 355: end
return base and rel. you can modify `base’, but can not `rel’.
# File lib/uri/generic.rb, line 771 771: def merge0(oth) 772: case oth 773: when Generic 774: when String 775: oth = URI.parse(oth) 776: else 777: raise ArgumentError, 778: "bad argument(expected URI object or URI string)" 779: end 780: 781: if self.relative? && oth.relative? 782: raise BadURIError, 783: "both URI are relative" 784: end 785: 786: if self.absolute? && oth.absolute? 787: #raise BadURIError, 788: # "both URI are absolute" 789: # hmm... should return oth for usability? 790: return oth, oth 791: end 792: 793: if self.absolute? 794: return self.dup, oth 795: else 796: return oth, oth 797: end 798: end
# File lib/uri/generic.rb, line 618 618: def merge_path(base, rel) 619: 620: # RFC2396, Section 5.2, 5) 621: # RFC2396, Section 5.2, 6) 622: base_path = split_path(base) 623: rel_path = split_path(rel) 624: 625: # RFC2396, Section 5.2, 6), a) 626: base_path << '' if base_path.last == '..' 627: while i = base_path.index('..') 628: base_path.slice!(i - 1, 2) 629: end 630: 631: if (first = rel_path.first) and first.empty? 632: base_path.clear 633: rel_path.shift 634: end 635: 636: # RFC2396, Section 5.2, 6), c) 637: # RFC2396, Section 5.2, 6), d) 638: rel_path.push('') if rel_path.last == '.' || rel_path.last == '..' 639: rel_path.delete('.') 640: 641: # RFC2396, Section 5.2, 6), e) 642: tmp = [] 643: rel_path.each do |x| 644: if x == '..' && 645: !(tmp.empty? || tmp.last == '..') 646: tmp.pop 647: else 648: tmp << x 649: end 650: end 651: 652: add_trailer_slash = !tmp.empty? 653: if base_path.empty? 654: base_path = [''] # keep '/' for root directory 655: elsif add_trailer_slash 656: base_path.pop 657: end 658: while x = tmp.shift 659: if x == '..' 660: # RFC2396, Section 4 661: # a .. or . in an absolute path has no special meaning 662: base_path.pop if base_path.size > 1 663: else 664: # if x == '..' 665: # valid absolute (but abnormal) path "/../..." 666: # else 667: # valid absolute path 668: # end 669: base_path << x 670: tmp.each {|t| base_path << t} 671: add_trailer_slash = false 672: break 673: end 674: end 675: base_path.push('') if add_trailer_slash 676: 677: return base_path.join('/') 678: end
# File lib/uri/generic.rb, line 984 984: def path_query 985: str = @path 986: if @query 987: str += '?' + @query 988: end 989: str 990: end
# File lib/uri/generic.rb, line 838 838: def route_from0(oth) 839: case oth 840: when Generic 841: when String 842: oth = URI.parse(oth) 843: else 844: raise ArgumentError, 845: "bad argument(expected URI object or URI string)" 846: end 847: 848: if self.relative? 849: raise BadURIError, 850: "relative URI: #{self}" 851: end 852: if oth.relative? 853: raise BadURIError, 854: "relative URI: #{oth}" 855: end 856: 857: if self.scheme != oth.scheme 858: return self, self.dup 859: end 860: rel = URI::Generic.new(nil, # it is relative URI 861: self.userinfo, self.host, self.port, 862: self.registry, self.path, self.opaque, 863: self.query, self.fragment) 864: 865: if rel.userinfo != oth.userinfo || 866: rel.host.to_s.downcase != oth.host.to_s.downcase || 867: rel.port != oth.port 868: if self.userinfo.nil? && self.host.nil? 869: return self, self.dup 870: end 871: rel.set_port(nil) if rel.port == oth.default_port 872: return rel, rel 873: end 874: rel.set_userinfo(nil) 875: rel.set_host(nil) 876: rel.set_port(nil) 877: 878: if rel.path && rel.path == oth.path 879: rel.set_path('') 880: rel.set_query(nil) if rel.query == oth.query 881: return rel, rel 882: elsif rel.opaque && rel.opaque == oth.opaque 883: rel.set_opaque('') 884: rel.set_query(nil) if rel.query == oth.query 885: return rel, rel 886: end 887: 888: # you can modify `rel', but can not `oth'. 889: return oth, rel 890: end
# File lib/uri/generic.rb, line 801 801: def route_from_path(src, dst) 802: case dst 803: when src 804: # RFC2396, Section 4.2 805: return '' 806: when %r{(?:\A|/)\.\.?(?:/|\z)} 807: # dst has abnormal absolute path, 808: # like "/./", "/../", "/x/../", ... 809: return dst.dup 810: end 811: 812: src_path = src.scan(%r{(?:\A|[^/]+)/}) 813: dst_path = dst.scan(%r{(?:\A|[^/]+)/?}) 814: 815: # discard same parts 816: while !dst_path.empty? && dst_path.first == src_path.first 817: src_path.shift 818: dst_path.shift 819: end 820: 821: tmp = dst_path.join 822: 823: # calculate 824: if src_path.empty? 825: if tmp.empty? 826: return './' 827: elsif dst_path.first.include?(':') # (see RFC2396 Section 5) 828: return './' + tmp 829: else 830: return tmp 831: end 832: end 833: 834: return '../' * src_path.size + tmp 835: end