| 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 1111
1111: def coerce(oth)
1112: case oth
1113: when String
1114: oth = URI.parse(oth)
1115: else
1116: super
1117: end
1118:
1119: return oth, self
1120: end
# File lib/uri/generic.rb, line 1056
1056: def eql?(oth)
1057: self.component_ary.eql?(oth.component_ary)
1058: 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 1107
1107: def inspect
1108: @@to_s.bind(self).call.sub!(/>\z/) {" URL:#{self}>"}
1109: 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 914
914: def route_from(oth)
915: # you can modify `rel', but can not `oth'.
916: begin
917: oth, rel = route_from0(oth)
918: rescue
919: raise $!.class, $!.message
920: end
921: if oth == rel
922: return rel
923: end
924:
925: rel.set_path(route_from_path(oth.path, self.path))
926: if rel.path == './' && self.query
927: # "./?foo" -> "?foo"
928: rel.set_path('')
929: end
930:
931: return rel
932: 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 954
954: def route_to(oth)
955: case oth
956: when Generic
957: when String
958: oth = URI.parse(oth)
959: else
960: raise ArgumentError,
961: "bad argument(expected URI object or URI string)"
962: end
963:
964: oth.route_from(self)
965: 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 1095
1095: def select(*components)
1096: components.collect do |c|
1097: if component.include?(c)
1098: self.send(c)
1099: else
1100: raise ArgumentError,
1101: "expected of components of #{self.class} (#{self.class.component.join(', ')})"
1102: end
1103: end
1104: end
# File lib/uri/generic.rb, line 1000
1000: def to_s
1001: str = ''
1002: if @scheme
1003: str << @scheme
1004: str << ':'
1005: end
1006:
1007: if @opaque
1008: str << @opaque
1009:
1010: else
1011: if @registry
1012: str << @registry
1013: else
1014: if @host
1015: str << '//'
1016: end
1017: if self.userinfo
1018: str << self.userinfo
1019: str << '@'
1020: end
1021: if @host
1022: str << @host
1023: end
1024: if @port && @port != self.default_port
1025: str << ':'
1026: str << @port.to_s
1027: end
1028: end
1029:
1030: str << path_query
1031: end
1032:
1033: if @fragment
1034: str << '#'
1035: str << @fragment
1036: end
1037:
1038: str
1039: 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 1071
1071: def component_ary
1072: component.collect do |x|
1073: self.send(x)
1074: end
1075: 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 988
988: def path_query
989: str = @path
990: if @query
991: str += '?' + @query
992: end
993: str
994: end
# File lib/uri/generic.rb, line 842
842: def route_from0(oth)
843: case oth
844: when Generic
845: when String
846: oth = URI.parse(oth)
847: else
848: raise ArgumentError,
849: "bad argument(expected URI object or URI string)"
850: end
851:
852: if self.relative?
853: raise BadURIError,
854: "relative URI: #{self}"
855: end
856: if oth.relative?
857: raise BadURIError,
858: "relative URI: #{oth}"
859: end
860:
861: if self.scheme != oth.scheme
862: return self, self.dup
863: end
864: rel = URI::Generic.new(nil, # it is relative URI
865: self.userinfo, self.host, self.port,
866: self.registry, self.path, self.opaque,
867: self.query, self.fragment)
868:
869: if rel.userinfo != oth.userinfo ||
870: rel.host.to_s.downcase != oth.host.to_s.downcase ||
871: rel.port != oth.port
872: if self.userinfo.nil? && self.host.nil?
873: return self, self.dup
874: end
875: rel.set_port(nil) if rel.port == oth.default_port
876: return rel, rel
877: end
878: rel.set_userinfo(nil)
879: rel.set_host(nil)
880: rel.set_port(nil)
881:
882: if rel.path && rel.path == oth.path
883: rel.set_path('')
884: rel.set_query(nil) if rel.query == oth.query
885: return rel, rel
886: elsif rel.opaque && rel.opaque == oth.opaque
887: rel.set_opaque('')
888: rel.set_query(nil) if rel.query == oth.query
889: return rel, rel
890: end
891:
892: # you can modify `rel', but can not `oth'.
893: return oth, rel
894: end
# File lib/uri/generic.rb, line 801
801: def route_from_path(src, dst)
802: # RFC2396, Section 4.2
803: return '' if src == dst
804:
805: src_path = split_path(src)
806: dst_path = split_path(dst)
807:
808: # hmm... dst has abnormal absolute path,
809: # like "/./", "/../", "/x/../", ...
810: if dst_path.include?('..') ||
811: dst_path.include?('.')
812: return dst.dup
813: end
814:
815: src_path.pop
816:
817: # discard same parts
818: while dst_path.first == src_path.first
819: break if dst_path.empty?
820:
821: src_path.shift
822: dst_path.shift
823: end
824:
825: tmp = dst_path.join('/')
826:
827: # calculate
828: if src_path.empty?
829: if tmp.empty?
830: return './'
831: elsif dst_path.first.include?(':') # (see RFC2396 Section 5)
832: return './' + tmp
833: else
834: return tmp
835: end
836: end
837:
838: return '../' * src_path.size + tmp
839: end