| Class | URI::Generic |
| In: |
lib/open-uri.rb
lib/uri/generic.rb |
| Parent: | Object |
Base class for all URI classes.
| 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 107
107: def self.build(args)
108: if args.kind_of?(Array) &&
109: args.size == ::URI::Generic::COMPONENT.size
110: tmp = args
111: elsif args.kind_of?(Hash)
112: tmp = ::URI::Generic::COMPONENT.collect do |c|
113: if args.include?(c)
114: args[c]
115: else
116: nil
117: end
118: end
119: else
120: raise ArgumentError,
121: "expected Array of or Hash of components of #{self.class} (#{self.class.component.join(', ')})"
122: end
123:
124: tmp << true
125: return self.new(*tmp)
126: 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 69
69: def self.build2(args)
70: begin
71: return self.build(args)
72: rescue InvalidComponentError
73: if args.kind_of?(Array)
74: return self.build(args.collect{|x|
75: if x
76: URI.escape(x)
77: else
78: x
79: end
80: })
81: elsif args.kind_of?(Hash)
82: tmp = {}
83: args.each do |key, value|
84: tmp[key] = if value
85: URI.escape(value)
86: else
87: value
88: end
89: end
90: return self.build(tmp)
91: end
92: end
93: end
Returns default port
# File lib/uri/generic.rb, line 25
25: def self.default_port
26: self::DEFAULT_PORT
27: 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 155
155: def initialize(scheme,
156: userinfo, host, port, registry,
157: path, opaque,
158: query,
159: fragment,
160: arg_check = false)
161: @scheme = nil
162: @user = nil
163: @password = nil
164: @host = nil
165: @port = nil
166: @path = nil
167: @query = nil
168: @opaque = nil
169: @registry = nil
170: @fragment = nil
171:
172: if arg_check
173: self.scheme = scheme
174: self.userinfo = userinfo
175: self.host = host
176: self.port = port
177: self.path = path
178: self.query = query
179: self.opaque = opaque
180: self.registry = registry
181: self.fragment = fragment
182: else
183: self.set_scheme(scheme)
184: self.set_userinfo(userinfo)
185: self.set_host(host)
186: self.set_port(port)
187: self.set_path(path)
188: self.set_query(query)
189: self.set_opaque(opaque)
190: self.set_registry(registry)
191: self.set_fragment(fragment)
192: end
193: if @registry && !self.class.use_registry
194: raise InvalidURIError,
195: "the scheme #{@scheme} does not accept registry part: #{@registry} (or bad hostname?)"
196: end
197:
198: @scheme.freeze if @scheme
199: self.set_path('') if !@path && !@opaque # (see RFC2396 Section 5.2)
200: self.set_port(self.default_port) if self.default_port && !@port
201: end
DOC: FIXME!
# File lib/uri/generic.rb, line 53
53: def self.use_registry
54: self::USE_REGISTRY
55: end
# File lib/uri/generic.rb, line 1107
1107: def coerce(oth)
1108: case oth
1109: when String
1110: oth = URI.parse(oth)
1111: else
1112: super
1113: end
1114:
1115: return oth, self
1116: end
# File lib/uri/generic.rb, line 1053
1053: def eql?(oth)
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 560
560: def find_proxy
561: name = self.scheme.downcase + '_proxy'
562: proxy_uri = nil
563: if name == 'http_proxy' && ENV.include?('REQUEST_METHOD') # CGI?
564: # HTTP_PROXY conflicts with *_proxy for proxy settings and
565: # HTTP_* for header information in CGI.
566: # So it should be careful to use it.
567: pairs = ENV.reject {|k, v| /\Ahttp_proxy\z/i !~ k }
568: case pairs.length
569: when 0 # no proxy setting anyway.
570: proxy_uri = nil
571: when 1
572: k, v = pairs.shift
573: if k == 'http_proxy' && ENV[k.upcase] == nil
574: # http_proxy is safe to use because ENV is case sensitive.
575: proxy_uri = ENV[name]
576: else
577: proxy_uri = nil
578: end
579: else # http_proxy is safe to use because ENV is case sensitive.
580: proxy_uri = ENV[name]
581: end
582: if !proxy_uri
583: # Use CGI_HTTP_PROXY. cf. libwww-perl.
584: proxy_uri = ENV["CGI_#{name.upcase}"]
585: end
586: elsif name == 'http_proxy'
587: unless proxy_uri = ENV[name]
588: if proxy_uri = ENV[name.upcase]
589: warn 'The environment variable HTTP_PROXY is discouraged. Use http_proxy.'
590: end
591: end
592: else
593: proxy_uri = ENV[name] || ENV[name.upcase]
594: end
595:
596: if proxy_uri && self.host
597: require 'socket'
598: begin
599: addr = IPSocket.getaddress(self.host)
600: proxy_uri = nil if /\A127\.|\A::1\z/ =~ addr
601: rescue SocketError
602: end
603: end
604:
605: if proxy_uri
606: proxy_uri = URI.parse(proxy_uri)
607: name = 'no_proxy'
608: if no_proxy = ENV[name] || ENV[name.upcase]
609: no_proxy.scan(/([^:,]*)(?::(\d+))?/) {|host, port|
610: if /(\A|\.)#{Regexp.quote host}\z/i =~ self.host &&
611: (!port || self.port == port.to_i)
612: proxy_uri = nil
613: break
614: end
615: }
616: end
617: proxy_uri
618: else
619: nil
620: end
621: end
# File lib/uri/generic.rb, line 574
574: def fragment=(v)
575: check_fragment(v)
576: set_fragment(v)
577: v
578: end
# File lib/uri/generic.rb, line 393
393: def host=(v)
394: check_host(v)
395: set_host(v)
396: v
397: end
# File lib/uri/generic.rb, line 1103
1103: def inspect
1104: sprintf("#<%s:%#0x URL:%s>", self.class.to_s, self.object_id, self.to_s)
1105: 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 725
725: def merge(oth)
726: begin
727: base, rel = merge0(oth)
728: rescue
729: raise $!.class, $!.message
730: end
731:
732: if base == rel
733: return base
734: end
735:
736: authority = rel.userinfo || rel.host || rel.port
737:
738: # RFC2396, Section 5.2, 2)
739: if (rel.path.nil? || rel.path.empty?) && !authority && !rel.query
740: base.set_fragment(rel.fragment) if rel.fragment
741: return base
742: end
743:
744: base.set_query(nil)
745: base.set_fragment(nil)
746:
747: # RFC2396, Section 5.2, 4)
748: if !authority
749: base.set_path(merge_path(base.path, rel.path)) if base.path && rel.path
750: else
751: # RFC2396, Section 5.2, 4)
752: base.set_path(rel.path) if rel.path
753: end
754:
755: # RFC2396, Section 5.2, 7)
756: base.set_userinfo(rel.userinfo) if rel.userinfo
757: base.set_host(rel.host) if rel.host
758: base.set_port(rel.port) if rel.port
759: base.set_query(rel.query) if rel.query
760: base.set_fragment(rel.fragment) if rel.fragment
761:
762: return base
763: 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 697
697: def merge!(oth)
698: t = merge(oth)
699: if self == t
700: nil
701: else
702: replace!(t)
703: self
704: end
705: end
# File lib/uri/generic.rb, line 551
551: def opaque=(v)
552: check_opaque(v)
553: set_opaque(v)
554: v
555: end
# File lib/uri/generic.rb, line 315
315: def password=(password)
316: check_password(password)
317: set_password(password)
318: password
319: end
# File lib/uri/generic.rb, line 491
491: def path=(v)
492: check_path(v)
493: set_path(v)
494: v
495: end
# File lib/uri/generic.rb, line 426
426: def port=(v)
427: check_port(v)
428: set_port(v)
429: port
430: end
# File lib/uri/generic.rb, line 522
522: def query=(v)
523: check_query(v)
524: set_query(v)
525: v
526: end
# File lib/uri/generic.rb, line 455
455: def registry=(v)
456: check_registry(v)
457: set_registry(v)
458: v
459: 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 911
911: def route_from(oth)
912: # you can modify `rel', but can not `oth'.
913: begin
914: oth, rel = route_from0(oth)
915: rescue
916: raise $!.class, $!.message
917: end
918: if oth == rel
919: return rel
920: end
921:
922: rel.set_path(route_from_path(oth.path, self.path))
923: if rel.path == './' && self.query
924: # "./?foo" -> "?foo"
925: rel.set_path('')
926: end
927:
928: return rel
929: 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 951
951: def route_to(oth)
952: case oth
953: when Generic
954: when String
955: oth = URI.parse(oth)
956: else
957: raise ArgumentError,
958: "bad argument(expected URI object or URI string)"
959: end
960:
961: oth.route_from(self)
962: end
# File lib/uri/generic.rb, line 242
242: def scheme=(v)
243: check_scheme(v)
244: set_scheme(v)
245: v
246: 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 997
997: def to_s
998: str = ''
999: if @scheme
1000: str << @scheme
1001: str << ':'
1002: end
1003:
1004: if @opaque
1005: str << @opaque
1006:
1007: else
1008: if @registry
1009: str << @registry
1010: else
1011: if @host
1012: str << '//'
1013: end
1014: if self.userinfo
1015: str << self.userinfo
1016: str << '@'
1017: end
1018: if @host
1019: str << @host
1020: end
1021: if @port && @port != self.default_port
1022: str << ':'
1023: str << @port.to_s
1024: end
1025: end
1026:
1027: str << path_query
1028: end
1029:
1030: if @fragment
1031: str << '#'
1032: str << @fragment
1033: end
1034:
1035: str
1036: end
# File lib/uri/generic.rb, line 309
309: def user=(user)
310: check_user(user)
311: set_user(user)
312: user
313: end
# File lib/uri/generic.rb, line 357
357: def userinfo
358: if !@password
359: @user
360: else
361: @user + ':' + @password
362: end
363: 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 338
338: def set_password(v)
339: set_userinfo(@user, v)
340: v
341: end
# File lib/uri/generic.rb, line 414
414: def set_port(v)
415: unless !v || v.kind_of?(Fixnum)
416: if v.empty?
417: v = nil
418: else
419: v = v.to_i
420: end
421: end
422: @port = v
423: end
# File lib/uri/generic.rb, line 332
332: def set_user(v)
333: set_userinfo(v, @password)
334: v
335: end
# File lib/uri/generic.rb, line 321
321: def set_userinfo(user, password = nil)
322: unless password
323: user, password = split_userinfo(user)
324: end
325: @user = user
326: @password = password if password
327:
328: [@user, @password]
329: end
# File lib/uri/generic.rb, line 557
557: def check_fragment(v)
558: return v unless v
559:
560: if v && v != '' && FRAGMENT !~ v
561: raise InvalidComponentError,
562: "bad component(expected fragment component): #{v}"
563: end
564:
565: return true
566: end
# File lib/uri/generic.rb, line 373
373: def check_host(v)
374: return v unless v
375:
376: if @registry || @opaque
377: raise InvalidURIError,
378: "can not set host with registry or opaque"
379: elsif HOST !~ v
380: raise InvalidComponentError,
381: "bad component(expected host component): #{v}"
382: end
383:
384: return true
385: end
# File lib/uri/generic.rb, line 528
528: def check_opaque(v)
529: return v unless v
530:
531: # raise if both hier and opaque are not nil, because:
532: # absoluteURI = scheme ":" ( hier_part | opaque_part )
533: # hier_part = ( net_path | abs_path ) [ "?" query ]
534: if @host || @port || @user || @path # userinfo = @user + ':' + @password
535: raise InvalidURIError,
536: "can not set opaque with host, port, userinfo or path"
537: elsif v && OPAQUE !~ v
538: raise InvalidComponentError,
539: "bad component(expected opaque component): #{v}"
540: end
541:
542: return true
543: end
# File lib/uri/generic.rb, line 276
276: def check_password(v, user = @user)
277: if @registry || @opaque
278: raise InvalidURIError,
279: "can not set password with registry or opaque"
280: end
281: return v unless v
282:
283: if !user
284: raise InvalidURIError,
285: "password component depends user component"
286: end
287:
288: if USERINFO !~ v
289: raise InvalidComponentError,
290: "bad component(expected user component): #{v}"
291: end
292:
293: return true
294: end
# File lib/uri/generic.rb, line 461
461: def check_path(v)
462: # raise if both hier and opaque are not nil, because:
463: # absoluteURI = scheme ":" ( hier_part | opaque_part )
464: # hier_part = ( net_path | abs_path ) [ "?" query ]
465: if v && @opaque
466: raise InvalidURIError,
467: "path conflicts with opaque"
468: end
469:
470: if @scheme
471: if v && v != '' && ABS_PATH !~ v
472: raise InvalidComponentError,
473: "bad component(expected absolute path component): #{v}"
474: end
475: else
476: if v && v != '' && ABS_PATH !~ v && REL_PATH !~ v
477: raise InvalidComponentError,
478: "bad component(expected relative path component): #{v}"
479: end
480: end
481:
482: return true
483: end
# File lib/uri/generic.rb, line 399
399: def check_port(v)
400: return v unless v
401:
402: if @registry || @opaque
403: raise InvalidURIError,
404: "can not set port with registry or opaque"
405: elsif !v.kind_of?(Fixnum) && PORT !~ v
406: raise InvalidComponentError,
407: "bad component(expected port component): #{v}"
408: end
409:
410: return true
411: end
# File lib/uri/generic.rb, line 497
497: def check_query(v)
498: return v unless v
499:
500: # raise if both hier and opaque are not nil, because:
501: # absoluteURI = scheme ":" ( hier_part | opaque_part )
502: # hier_part = ( net_path | abs_path ) [ "?" query ]
503: if @opaque
504: raise InvalidURIError,
505: "query conflicts with opaque"
506: end
507:
508: if v && v != '' && QUERY !~ v
509: raise InvalidComponentError,
510: "bad component(expected query component): #{v}"
511: end
512:
513: return true
514: end
# File lib/uri/generic.rb, line 432
432: def check_registry(v)
433: return v unless v
434:
435: # raise if both server and registry are not nil, because:
436: # authority = server | reg_name
437: # server = [ [ userinfo "@" ] hostport ]
438: if @host || @port || @user # userinfo = @user + ':' + @password
439: raise InvalidURIError,
440: "can not set registry with host, port, or userinfo"
441: elsif v && REGISTRY !~ v
442: raise InvalidComponentError,
443: "bad component(expected registry component): #{v}"
444: end
445:
446: return true
447: end
# File lib/uri/generic.rb, line 227
227: def check_scheme(v)
228: if v && SCHEME !~ v
229: raise InvalidComponentError,
230: "bad component(expected scheme component): #{v}"
231: end
232:
233: return true
234: end
# File lib/uri/generic.rb, line 259
259: def check_user(v)
260: if @registry || @opaque
261: raise InvalidURIError,
262: "can not set user with registry or opaque"
263: end
264:
265: return v unless v
266:
267: if USERINFO !~ v
268: raise InvalidComponentError,
269: "bad component(expected userinfo component or user component): #{v}"
270: end
271:
272: return true
273: end
# File lib/uri/generic.rb, line 248
248: def check_userinfo(user, password = nil)
249: if !password
250: user, password = split_userinfo(user)
251: end
252: check_user(user)
253: check_password(password, user)
254:
255: return true
256: end
# File lib/uri/generic.rb, line 352
352: def escape_userpass(v)
353: v = URI.escape(v, /[@:\/]/o) # RFC 1738 section 3.1 #/
354: end
return base and rel. you can modify `base’, but can not `rel’.
# File lib/uri/generic.rb, line 768
768: def merge0(oth)
769: case oth
770: when Generic
771: when String
772: oth = URI.parse(oth)
773: else
774: raise ArgumentError,
775: "bad argument(expected URI object or URI string)"
776: end
777:
778: if self.relative? && oth.relative?
779: raise BadURIError,
780: "both URI are relative"
781: end
782:
783: if self.absolute? && oth.absolute?
784: #raise BadURIError,
785: # "both URI are absolute"
786: # hmm... should return oth for usability?
787: return oth, oth
788: end
789:
790: if self.absolute?
791: return self.dup, oth
792: else
793: return oth, oth
794: end
795: end
# File lib/uri/generic.rb, line 615
615: def merge_path(base, rel)
616: # RFC2396, Section 5.2, 5)
617: if rel[0] == ?/ #/
618: # RFC2396, Section 5.2, 5)
619: return rel
620:
621: else
622: # RFC2396, Section 5.2, 6)
623: base_path = split_path(base)
624: rel_path = split_path(rel)
625:
626: # RFC2396, Section 5.2, 6), a)
627: base_path << '' if base_path.last == '..'
628: while i = base_path.index('..')
629: base_path.slice!(i - 1, 2)
630: end
631: if base_path.empty?
632: base_path = [''] # keep '/' for root directory
633: else
634: base_path.pop
635: end
636:
637: # RFC2396, Section 5.2, 6), c)
638: # RFC2396, Section 5.2, 6), d)
639: rel_path.push('') if rel_path.last == '.' || rel_path.last == '..'
640: rel_path.delete('.')
641:
642: # RFC2396, Section 5.2, 6), e)
643: tmp = []
644: rel_path.each do |x|
645: if x == '..' &&
646: !(tmp.empty? || tmp.last == '..')
647: tmp.pop
648: else
649: tmp << x
650: end
651: end
652:
653: add_trailer_slash = true
654: while x = tmp.shift
655: if x == '..' && base_path.size > 1
656: # RFC2396, Section 4
657: # a .. or . in an absolute path has no special meaning
658: base_path.pop
659: else
660: # if x == '..'
661: # valid absolute (but abnormal) path "/../..."
662: # else
663: # valid absolute path
664: # end
665: base_path << x
666: tmp.each {|t| base_path << t}
667: add_trailer_slash = false
668: break
669: end
670: end
671: base_path.push('') if add_trailer_slash
672:
673: return base_path.join('/')
674: end
675: end
# File lib/uri/generic.rb, line 985
985: def path_query
986: str = @path
987: if @query
988: str += '?' + @query
989: end
990: str
991: end
# File lib/uri/generic.rb, line 839
839: def route_from0(oth)
840: case oth
841: when Generic
842: when String
843: oth = URI.parse(oth)
844: else
845: raise ArgumentError,
846: "bad argument(expected URI object or URI string)"
847: end
848:
849: if self.relative?
850: raise BadURIError,
851: "relative URI: #{self}"
852: end
853: if oth.relative?
854: raise BadURIError,
855: "relative URI: #{oth}"
856: end
857:
858: if self.scheme != oth.scheme
859: return self, self.dup
860: end
861: rel = URI::Generic.new(nil, # it is relative URI
862: self.userinfo, self.host, self.port,
863: self.registry, self.path, self.opaque,
864: self.query, self.fragment)
865:
866: if rel.userinfo != oth.userinfo ||
867: rel.host.to_s.downcase != oth.host.to_s.downcase ||
868: rel.port != oth.port
869: if self.userinfo.nil? && self.host.nil?
870: return self, self.dup
871: end
872: rel.set_port(nil) if rel.port == oth.default_port
873: return rel, rel
874: end
875: rel.set_userinfo(nil)
876: rel.set_host(nil)
877: rel.set_port(nil)
878:
879: if rel.path && rel.path == oth.path
880: rel.set_path('')
881: rel.set_query(nil) if rel.query == oth.query
882: return rel, rel
883: elsif rel.opaque && rel.opaque == oth.opaque
884: rel.set_opaque('')
885: rel.set_query(nil) if rel.query == oth.query
886: return rel, rel
887: end
888:
889: # you can modify `rel', but can not `oth'.
890: return oth, rel
891: end
# File lib/uri/generic.rb, line 798
798: def route_from_path(src, dst)
799: # RFC2396, Section 4.2
800: return '' if src == dst
801:
802: src_path = split_path(src)
803: dst_path = split_path(dst)
804:
805: # hmm... dst has abnormal absolute path,
806: # like "/./", "/../", "/x/../", ...
807: if dst_path.include?('..') ||
808: dst_path.include?('.')
809: return dst.dup
810: end
811:
812: src_path.pop
813:
814: # discard same parts
815: while dst_path.first == src_path.first
816: break if dst_path.empty?
817:
818: src_path.shift
819: dst_path.shift
820: end
821:
822: tmp = dst_path.join('/')
823:
824: # calculate
825: if src_path.empty?
826: if tmp.empty?
827: return './'
828: elsif dst_path.first.include?(':') # (see RFC2396 Section 5)
829: return './' + tmp
830: else
831: return tmp
832: end
833: end
834:
835: return '../' * src_path.size + tmp
836: end