summaryrefslogtreecommitdiff
path: root/ruby_1_9_3/lib/uri/generic.rb
diff options
context:
space:
mode:
Diffstat (limited to 'ruby_1_9_3/lib/uri/generic.rb')
-rw-r--r--ruby_1_9_3/lib/uri/generic.rb1599
1 files changed, 0 insertions, 1599 deletions
diff --git a/ruby_1_9_3/lib/uri/generic.rb b/ruby_1_9_3/lib/uri/generic.rb
deleted file mode 100644
index 1056cfe3bc..0000000000
--- a/ruby_1_9_3/lib/uri/generic.rb
+++ /dev/null
@@ -1,1599 +0,0 @@
-# = uri/generic.rb
-#
-# Author:: Akira Yamada <akira@ruby-lang.org>
-# License:: You can redistribute it and/or modify it under the same term as Ruby.
-# Revision:: $Id$
-#
-# See URI for general documentation
-#
-
-require 'uri/common'
-
-module URI
-
- #
- # Base class for all URI classes.
- # Implements generic URI syntax as per RFC 2396.
- #
- class Generic
- include URI
-
- #
- # A Default port of nil for URI::Generic
- #
- DEFAULT_PORT = nil
-
- #
- # Returns default port
- #
- def self.default_port
- self::DEFAULT_PORT
- end
-
- #
- # Returns default port
- #
- def default_port
- self.class.default_port
- end
-
- #
- # An Array of the available components for URI::Generic
- #
- COMPONENT = [
- :scheme,
- :userinfo, :host, :port, :registry,
- :path, :opaque,
- :query,
- :fragment
- ].freeze
-
- #
- # Components of the URI in the order.
- #
- def self.component
- self::COMPONENT
- end
-
- #
- # Default to not use the registry for a URI::Generic
- #
- USE_REGISTRY = false
-
- #
- # Returns whether a registry of naming
- # authorities are being used.
- #
- def self.use_registry
- self::USE_REGISTRY
- end
-
- #
- # == Synopsis
- #
- # See #new
- #
- # == Description
- #
- # 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.
- #
- #
- def self.build2(args)
- begin
- return self.build(args)
- rescue InvalidComponentError
- if args.kind_of?(Array)
- return self.build(args.collect{|x|
- if x
- parser.escape(x)
- else
- x
- end
- })
- elsif args.kind_of?(Hash)
- tmp = {}
- args.each do |key, value|
- tmp[key] = if value
- parser.escape(value)
- else
- value
- end
- end
- return self.build(tmp)
- end
- end
- end
-
- #
- # == Synopsis
- #
- # See #new
- #
- # == Description
- #
- # 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.
- #
- def self.build(args)
- if args.kind_of?(Array) &&
- args.size == ::URI::Generic::COMPONENT.size
- tmp = args
- elsif args.kind_of?(Hash)
- tmp = ::URI::Generic::COMPONENT.collect do |c|
- if args.include?(c)
- args[c]
- else
- nil
- end
- end
- else
- raise ArgumentError,
- "expected Array of or Hash of components of #{self.class} (#{self.class.component.join(', ')})"
- end
-
- tmp << nil
- tmp << true
- return self.new(*tmp)
- end
- #
- # == Args
- #
- # +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+::
- # Registry of naming authorities.
- # +path+::
- # Path on server
- # +opaque+::
- # Opaque part
- # +query+::
- # Query data
- # +fragment+::
- # A part of URI after '#' sign
- # +parser+::
- # Parser for internal use [URI::DEFAULT_PARSER by default]
- # +arg_check+::
- # Check arguments [false by default]
- #
- # == Description
- #
- # Creates a new URI::Generic instance from ``generic'' components without check.
- #
- def initialize(scheme,
- userinfo, host, port, registry,
- path, opaque,
- query,
- fragment,
- parser = DEFAULT_PARSER,
- arg_check = false)
- @scheme = nil
- @user = nil
- @password = nil
- @host = nil
- @port = nil
- @path = nil
- @query = nil
- @opaque = nil
- @registry = nil
- @fragment = nil
- @parser = parser == DEFAULT_PARSER ? nil : parser
-
- if arg_check
- self.scheme = scheme
- self.userinfo = userinfo
- self.host = host
- self.port = port
- self.path = path
- self.query = query
- self.opaque = opaque
- self.registry = registry
- self.fragment = fragment
- else
- self.set_scheme(scheme)
- self.set_userinfo(userinfo)
- self.set_host(host)
- self.set_port(port)
- self.set_path(path)
- self.set_query(query)
- self.set_opaque(opaque)
- self.set_registry(registry)
- self.set_fragment(fragment)
- end
- if @registry && !self.class.use_registry
- raise InvalidURIError,
- "the scheme #{@scheme} does not accept registry part: #{@registry} (or bad hostname?)"
- end
-
- @scheme.freeze if @scheme
- self.set_path('') if !@path && !@opaque # (see RFC2396 Section 5.2)
- self.set_port(self.default_port) if self.default_port && !@port
- end
-
- #
- # returns the scheme component of the URI.
- #
- # URI("http://foo/bar/baz").scheme #=> "http"
- #
- attr_reader :scheme
-
- # returns the host component of the URI.
- #
- # URI("http://foo/bar/baz").host #=> "foo"
- #
- # It returns nil if no host component.
- #
- # URI("mailto:foo@example.org").host #=> nil
- #
- # The component doesn't contains the port number.
- #
- # URI("http://foo:8080/bar/baz").host #=> "foo"
- #
- # Since IPv6 addresses are wrapped by brackets in URIs,
- # this method returns IPv6 addresses wrapped by brackets.
- # This form is not appropriate to pass socket methods such as TCPSocket.open.
- # If unwrapped host names are required, use "hostname" method.
- #
- # URI("http://[::1]/bar/baz").host #=> "[::1]"
- # URI("http://[::1]/bar/baz").hostname #=> "::1"
- #
- attr_reader :host
-
- # returns the port component of the URI.
- #
- # URI("http://foo/bar/baz").port #=> "80"
- #
- # URI("http://foo:8080/bar/baz").port #=> "8080"
- #
- attr_reader :port
-
- # returns the registry component of the URI.
- #
- # (see RFC2396 Section 3.2)
- #
- attr_reader :registry
-
- # returns the path component of the URI.
- #
- # URI("http://foo/bar/baz").path #=> "/bar/baz"
- #
- attr_reader :path
-
- # returns the query component of the URI.
- #
- # URI("http://foo/bar/baz?search=FooBar").query #=> "search=FooBar"
- #
- attr_reader :query
-
- # returns the opaque part of the URI.
- #
- # URI("mailto:foo@example.org").opaque #=> "foo@example.org"
- #
- # Portion of the path that does make use of the slash '/'.
- # The path typically refers to the absolute path and the opaque part.
- # (see RFC2396 Section 3 and 5.2)
- #
- attr_reader :opaque
-
- # returns the fragment component of the URI.
- #
- # URI("http://foo/bar/baz?search=FooBar#ponies").fragment #=> "ponies"
- #
- attr_reader :fragment
-
- # returns the parser to be used.
- #
- # Unless a URI::Parser is defined, then DEFAULT_PARSER is used.
- #
- def parser
- if !defined?(@parser) || !@parser
- DEFAULT_PARSER
- else
- @parser || DEFAULT_PARSER
- end
- end
-
- # replace self by other URI object
- def replace!(oth)
- if self.class != oth.class
- raise ArgumentError, "expected #{self.class} object"
- end
-
- component.each do |c|
- self.__send__("#{c}=", oth.__send__(c))
- end
- end
- private :replace!
-
- #
- # Components of the URI in the order.
- #
- def component
- self.class.component
- end
-
- #
- # check the scheme +v+ component against the URI::Parser Regexp for :SCHEME
- #
- def check_scheme(v)
- if v && parser.regexp[:SCHEME] !~ v
- raise InvalidComponentError,
- "bad component(expected scheme component): #{v}"
- end
-
- return true
- end
- private :check_scheme
-
- # protected setter for the scheme component +v+
- #
- # see also URI::Generic.scheme=
- #
- def set_scheme(v)
- @scheme = v
- end
- protected :set_scheme
-
- #
- # == Args
- #
- # +v+::
- # String
- #
- # == Description
- #
- # public setter for the scheme component +v+.
- # (with validation)
- #
- # see also URI::Generic.check_scheme
- #
- # == Usage
- #
- # require 'uri'
- #
- # uri = URI.parse("http://my.example.com")
- # uri.scheme = "https"
- # # => "https"
- # uri
- # #=> #<URI::HTTP:0x000000008e89e8 URL:https://my.example.com>
- #
- def scheme=(v)
- check_scheme(v)
- set_scheme(v)
- v
- end
-
- #
- # check the +user+ and +password+.
- #
- # If +password+ is not provided, then +user+ is
- # split, using URI::Generic.split_userinfo, to
- # pull +user+ and +password.
- #
- # see also URI::Generic.check_user, URI::Generic.check_password
- #
- def check_userinfo(user, password = nil)
- if !password
- user, password = split_userinfo(user)
- end
- check_user(user)
- check_password(password, user)
-
- return true
- end
- private :check_userinfo
-
- #
- # check the user +v+ component for RFC2396 compliance
- # and against the URI::Parser Regexp for :USERINFO
- #
- # Can not have a registry or opaque component defined,
- # with a user component defined.
- #
- def check_user(v)
- if @registry || @opaque
- raise InvalidURIError,
- "can not set user with registry or opaque"
- end
-
- return v unless v
-
- if parser.regexp[:USERINFO] !~ v
- raise InvalidComponentError,
- "bad component(expected userinfo component or user component): #{v}"
- end
-
- return true
- end
- private :check_user
-
- #
- # check the password +v+ component for RFC2396 compliance
- # and against the URI::Parser Regexp for :USERINFO
- #
- # Can not have a registry or opaque component defined,
- # with a user component defined.
- #
- def check_password(v, user = @user)
- if @registry || @opaque
- raise InvalidURIError,
- "can not set password with registry or opaque"
- end
- return v unless v
-
- if !user
- raise InvalidURIError,
- "password component depends user component"
- end
-
- if parser.regexp[:USERINFO] !~ v
- raise InvalidComponentError,
- "bad component(expected user component): #{v}"
- end
-
- return true
- end
- private :check_password
-
- #
- # Sets userinfo, argument is string like 'name:pass'
- #
- def userinfo=(userinfo)
- if userinfo.nil?
- return nil
- end
- check_userinfo(*userinfo)
- set_userinfo(*userinfo)
- # returns userinfo
- end
-
- #
- # == Args
- #
- # +v+::
- # String
- #
- # == Description
- #
- # public setter for the +user+ component.
- # (with validation)
- #
- # see also URI::Generic.check_user
- #
- # == Usage
- #
- # require 'uri'
- #
- # uri = URI.parse("http://john:S3nsit1ve@my.example.com")
- # uri.user = "sam"
- # # => "sam"
- # uri
- # #=> #<URI::HTTP:0x00000000881d90 URL:http://sam:V3ry_S3nsit1ve@my.example.com>
- #
- def user=(user)
- check_user(user)
- set_user(user)
- # returns user
- end
-
- #
- # == Args
- #
- # +v+::
- # String
- #
- # == Description
- #
- # public setter for the +password+ component.
- # (with validation)
- #
- # see also URI::Generic.check_password
- #
- # == Usage
- #
- # require 'uri'
- #
- # uri = URI.parse("http://john:S3nsit1ve@my.example.com")
- # uri.password = "V3ry_S3nsit1ve"
- # # => "V3ry_S3nsit1ve"
- # uri
- # #=> #<URI::HTTP:0x00000000881d90 URL:http://john:V3ry_S3nsit1ve@my.example.com>
- #
- def password=(password)
- check_password(password)
- set_password(password)
- # returns password
- end
-
- # protect setter for the +user+ component, and +password+ if available.
- # (with validation)
- #
- # see also URI::Generic.userinfo=
- #
- def set_userinfo(user, password = nil)
- unless password
- user, password = split_userinfo(user)
- end
- @user = user
- @password = password if password
-
- [@user, @password]
- end
- protected :set_userinfo
-
- # protected setter for the user component +v+
- #
- # see also URI::Generic.user=
- #
- def set_user(v)
- set_userinfo(v, @password)
- v
- end
- protected :set_user
-
- # protected setter for the password component +v+
- #
- # see also URI::Generic.password=
- #
- def set_password(v)
- @password = v
- # returns v
- end
- protected :set_password
-
- # returns the userinfo +ui+ as user, password
- # if properly formated as 'user:password'
- def split_userinfo(ui)
- return nil, nil unless ui
- user, password = ui.split(/:/, 2)
-
- return user, password
- end
- private :split_userinfo
-
- # escapes 'user:password' +v+ based on RFC 1738 section 3.1
- def escape_userpass(v)
- v = parser.escape(v, /[@:\/]/o) # RFC 1738 section 3.1 #/
- end
- private :escape_userpass
-
- # returns the userinfo, either as 'user' or 'user:password'
- def userinfo
- if @user.nil?
- nil
- elsif @password.nil?
- @user
- else
- @user + ':' + @password
- end
- end
-
- # returns the user component
- def user
- @user
- end
-
- # returns the password component
- def password
- @password
- end
-
- #
- # check the host +v+ component for RFC2396 compliance
- # and against the URI::Parser Regexp for :HOST
- #
- # Can not have a registry or opaque component defined,
- # with a host component defined.
- #
- def check_host(v)
- return v unless v
-
- if @registry || @opaque
- raise InvalidURIError,
- "can not set host with registry or opaque"
- elsif parser.regexp[:HOST] !~ v
- raise InvalidComponentError,
- "bad component(expected host component): #{v}"
- end
-
- return true
- end
- private :check_host
-
- # protected setter for the host component +v+
- #
- # see also URI::Generic.host=
- #
- def set_host(v)
- @host = v
- end
- protected :set_host
-
- #
- # == Args
- #
- # +v+::
- # String
- #
- # == Description
- #
- # public setter for the host component +v+.
- # (with validation)
- #
- # see also URI::Generic.check_host
- #
- # == Usage
- #
- # require 'uri'
- #
- # uri = URI.parse("http://my.example.com")
- # uri.host = "foo.com"
- # # => "foo.com"
- # uri
- # #=> #<URI::HTTP:0x000000008e89e8 URL:http://foo.com>
- #
- def host=(v)
- check_host(v)
- set_host(v)
- v
- end
-
- # extract the host part of the URI and unwrap brackets for IPv6 addresses.
- #
- # This method is same as URI::Generic#host except
- # brackets for IPv6 (andn future IP) addresses are removed.
- #
- # u = URI("http://[::1]/bar")
- # p u.hostname #=> "::1"
- # p u.host #=> "[::1]"
- #
- def hostname
- v = self.host
- /\A\[(.*)\]\z/ =~ v ? $1 : v
- end
-
- # set the host part of the URI as the argument with brackets for IPv6 addresses.
- #
- # This method is same as URI::Generic#host= except
- # the argument can be bare IPv6 address.
- #
- # u = URI("http://foo/bar")
- # p u.to_s #=> "http://foo/bar"
- # u.hostname = "::1"
- # p u.to_s #=> "http://[::1]/bar"
- #
- # If the arugument seems IPv6 address,
- # it is wrapped by brackets.
- #
- def hostname=(v)
- v = "[#{v}]" if /\A\[.*\]\z/ !~ v && /:/ =~ v
- self.host = v
- end
-
- #
- # check the port +v+ component for RFC2396 compliance
- # and against the URI::Parser Regexp for :PORT
- #
- # Can not have a registry or opaque component defined,
- # with a port component defined.
- #
- def check_port(v)
- return v unless v
-
- if @registry || @opaque
- raise InvalidURIError,
- "can not set port with registry or opaque"
- elsif !v.kind_of?(Fixnum) && parser.regexp[:PORT] !~ v
- raise InvalidComponentError,
- "bad component(expected port component): #{v}"
- end
-
- return true
- end
- private :check_port
-
- # protected setter for the port component +v+
- #
- # see also URI::Generic.port=
- #
- def set_port(v)
- unless !v || v.kind_of?(Fixnum)
- if v.empty?
- v = nil
- else
- v = v.to_i
- end
- end
- @port = v
- end
- protected :set_port
-
- #
- # == Args
- #
- # +v+::
- # String
- #
- # == Description
- #
- # public setter for the port component +v+.
- # (with validation)
- #
- # see also URI::Generic.check_port
- #
- # == Usage
- #
- # require 'uri'
- #
- # uri = URI.parse("http://my.example.com")
- # uri.port = 8080
- # # => 8080
- # uri
- # #=> #<URI::HTTP:0x000000008e89e8 URL:http://my.example.com:8080>
- #
- def port=(v)
- check_port(v)
- set_port(v)
- port
- end
-
- #
- # check the registry +v+ component for RFC2396 compliance
- # and against the URI::Parser Regexp for :REGISTRY
- #
- # Can not have a host, port or user component defined,
- # with a registry component defined.
- #
- def check_registry(v)
- return v unless v
-
- # raise if both server and registry are not nil, because:
- # authority = server | reg_name
- # server = [ [ userinfo "@" ] hostport ]
- if @host || @port || @user # userinfo = @user + ':' + @password
- raise InvalidURIError,
- "can not set registry with host, port, or userinfo"
- elsif v && parser.regexp[:REGISTRY] !~ v
- raise InvalidComponentError,
- "bad component(expected registry component): #{v}"
- end
-
- return true
- end
- private :check_registry
-
- # protected setter for the registry component +v+
- #
- # see also URI::Generic.registry=
- #
- def set_registry(v)
- @registry = v
- end
- protected :set_registry
-
- #
- # == Args
- #
- # +v+::
- # String
- #
- # == Description
- #
- # public setter for the registry component +v+.
- # (with validation)
- #
- # see also URI::Generic.check_registry
- #
- def registry=(v)
- check_registry(v)
- set_registry(v)
- v
- end
-
- #
- # check the path +v+ component for RFC2396 compliance
- # and against the URI::Parser Regexp
- # for :ABS_PATH and :REL_PATH
- #
- # Can not have a opaque component defined,
- # with a path component defined.
- #
- def check_path(v)
- # raise if both hier and opaque are not nil, because:
- # absoluteURI = scheme ":" ( hier_part | opaque_part )
- # hier_part = ( net_path | abs_path ) [ "?" query ]
- if v && @opaque
- raise InvalidURIError,
- "path conflicts with opaque"
- end
-
- # If scheme is ftp, path may be relative.
- # See RFC 1738 section 3.2.2, and RFC 2396.
- if @scheme && @scheme != "ftp"
- if v && v != '' && parser.regexp[:ABS_PATH] !~ v
- raise InvalidComponentError,
- "bad component(expected absolute path component): #{v}"
- end
- else
- if v && v != '' && parser.regexp[:ABS_PATH] !~ v && parser.regexp[:REL_PATH] !~ v
- raise InvalidComponentError,
- "bad component(expected relative path component): #{v}"
- end
- end
-
- return true
- end
- private :check_path
-
- # protected setter for the path component +v+
- #
- # see also URI::Generic.path=
- #
- def set_path(v)
- @path = v
- end
- protected :set_path
-
- #
- # == Args
- #
- # +v+::
- # String
- #
- # == Description
- #
- # public setter for the path component +v+.
- # (with validation)
- #
- # see also URI::Generic.check_path
- #
- # == Usage
- #
- # require 'uri'
- #
- # uri = URI.parse("http://my.example.com/pub/files")
- # uri.path = "/faq/"
- # # => "/faq/"
- # uri
- # #=> #<URI::HTTP:0x000000008e89e8 URL:http://my.example.com/faq/>
- #
- def path=(v)
- check_path(v)
- set_path(v)
- v
- end
-
- #
- # check the query +v+ component for RFC2396 compliance
- # and against the URI::Parser Regexp for :QUERY
- #
- # Can not have a opaque component defined,
- # with a query component defined.
- #
- def check_query(v)
- return v unless v
-
- # raise if both hier and opaque are not nil, because:
- # absoluteURI = scheme ":" ( hier_part | opaque_part )
- # hier_part = ( net_path | abs_path ) [ "?" query ]
- if @opaque
- raise InvalidURIError,
- "query conflicts with opaque"
- end
-
- if v && v != '' && parser.regexp[:QUERY] !~ v
- raise InvalidComponentError,
- "bad component(expected query component): #{v}"
- end
-
- return true
- end
- private :check_query
-
- # protected setter for the query component +v+
- #
- # see also URI::Generic.query=
- #
- def set_query(v)
- @query = v
- end
- protected :set_query
-
- #
- # == Args
- #
- # +v+::
- # String
- #
- # == Description
- #
- # public setter for the query component +v+.
- # (with validation)
- #
- # see also URI::Generic.check_query
- #
- # == Usage
- #
- # require 'uri'
- #
- # uri = URI.parse("http://my.example.com/?id=25")
- # uri.query = "id=1"
- # # => "id=1"
- # uri
- # #=> #<URI::HTTP:0x000000008e89e8 URL:http://my.example.com/?id=1>
- #
- def query=(v)
- check_query(v)
- set_query(v)
- v
- end
-
- #
- # check the opaque +v+ component for RFC2396 compliance and
- # against the URI::Parser Regexp for :OPAQUE
- #
- # Can not have a host, port, user or path component defined,
- # with an opaque component defined.
- #
- def check_opaque(v)
- return v unless v
-
- # raise if both hier and opaque are not nil, because:
- # absoluteURI = scheme ":" ( hier_part | opaque_part )
- # hier_part = ( net_path | abs_path ) [ "?" query ]
- if @host || @port || @user || @path # userinfo = @user + ':' + @password
- raise InvalidURIError,
- "can not set opaque with host, port, userinfo or path"
- elsif v && parser.regexp[:OPAQUE] !~ v
- raise InvalidComponentError,
- "bad component(expected opaque component): #{v}"
- end
-
- return true
- end
- private :check_opaque
-
- # protected setter for the opaque component +v+
- #
- # see also URI::Generic.opaque=
- #
- def set_opaque(v)
- @opaque = v
- end
- protected :set_opaque
-
- #
- # == Args
- #
- # +v+::
- # String
- #
- # == Description
- #
- # public setter for the opaque component +v+.
- # (with validation)
- #
- # see also URI::Generic.check_opaque
- #
- def opaque=(v)
- check_opaque(v)
- set_opaque(v)
- v
- end
-
- #
- # check the fragment +v+ component against the URI::Parser Regexp for :FRAGMENT
- #
- def check_fragment(v)
- return v unless v
-
- if v && v != '' && parser.regexp[:FRAGMENT] !~ v
- raise InvalidComponentError,
- "bad component(expected fragment component): #{v}"
- end
-
- return true
- end
- private :check_fragment
-
- # protected setter for the fragment component +v+
- #
- # see also URI::Generic.fragment=
- #
- def set_fragment(v)
- @fragment = v
- end
- protected :set_fragment
-
- #
- # == Args
- #
- # +v+::
- # String
- #
- # == Description
- #
- # public setter for the fragment component +v+.
- # (with validation)
- #
- # see also URI::Generic.check_fragment
- #
- # == Usage
- #
- # require 'uri'
- #
- # uri = URI.parse("http://my.example.com/?id=25#time=1305212049")
- # uri.fragment = "time=1305212086"
- # # => "time=1305212086"
- # uri
- # #=> #<URI::HTTP:0x000000007a81f8 URL:http://my.example.com/?id=25#time=1305212086>
- #
- def fragment=(v)
- check_fragment(v)
- set_fragment(v)
- v
- end
-
- #
- # Checks if URI has a path
- #
- def hierarchical?
- if @path
- true
- else
- false
- end
- end
-
- #
- # Checks if URI is an absolute one
- #
- def absolute?
- if @scheme
- true
- else
- false
- end
- end
- alias absolute absolute?
-
- #
- # Checks if URI is relative
- #
- def relative?
- !absolute?
- end
-
- #
- # returns an Array of the path split on '/'
- #
- def split_path(path)
- path.split(%r{/+}, -1)
- end
- private :split_path
-
- #
- # Merges a base path +base+, with relative path +rel+,
- # returns a modified base path.
- #
- def merge_path(base, rel)
-
- # RFC2396, Section 5.2, 5)
- # RFC2396, Section 5.2, 6)
- base_path = split_path(base)
- rel_path = split_path(rel)
-
- # RFC2396, Section 5.2, 6), a)
- base_path << '' if base_path.last == '..'
- while i = base_path.index('..')
- base_path.slice!(i - 1, 2)
- end
-
- if (first = rel_path.first) and first.empty?
- base_path.clear
- rel_path.shift
- end
-
- # RFC2396, Section 5.2, 6), c)
- # RFC2396, Section 5.2, 6), d)
- rel_path.push('') if rel_path.last == '.' || rel_path.last == '..'
- rel_path.delete('.')
-
- # RFC2396, Section 5.2, 6), e)
- tmp = []
- rel_path.each do |x|
- if x == '..' &&
- !(tmp.empty? || tmp.last == '..')
- tmp.pop
- else
- tmp << x
- end
- end
-
- add_trailer_slash = !tmp.empty?
- if base_path.empty?
- base_path = [''] # keep '/' for root directory
- elsif add_trailer_slash
- base_path.pop
- end
- while x = tmp.shift
- if x == '..'
- # RFC2396, Section 4
- # a .. or . in an absolute path has no special meaning
- base_path.pop if base_path.size > 1
- else
- # if x == '..'
- # valid absolute (but abnormal) path "/../..."
- # else
- # valid absolute path
- # end
- base_path << x
- tmp.each {|t| base_path << t}
- add_trailer_slash = false
- break
- end
- end
- base_path.push('') if add_trailer_slash
-
- return base_path.join('/')
- end
- private :merge_path
-
- #
- # == Args
- #
- # +oth+::
- # URI or String
- #
- # == Description
- #
- # Destructive form of #merge
- #
- # == Usage
- #
- # 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>
- #
- def merge!(oth)
- t = merge(oth)
- if self == t
- nil
- else
- replace!(t)
- self
- end
- end
-
- #
- # == Args
- #
- # +oth+::
- # URI or String
- #
- # == Description
- #
- # Merges two URI's.
- #
- # == Usage
- #
- # 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>
- #
- def merge(oth)
- begin
- base, rel = merge0(oth)
- rescue
- raise $!.class, $!.message
- end
-
- if base == rel
- return base
- end
-
- authority = rel.userinfo || rel.host || rel.port
-
- # RFC2396, Section 5.2, 2)
- if (rel.path.nil? || rel.path.empty?) && !authority && !rel.query
- base.set_fragment(rel.fragment) if rel.fragment
- return base
- end
-
- base.set_query(nil)
- base.set_fragment(nil)
-
- # RFC2396, Section 5.2, 4)
- if !authority
- base.set_path(merge_path(base.path, rel.path)) if base.path && rel.path
- else
- # RFC2396, Section 5.2, 4)
- base.set_path(rel.path) if rel.path
- end
-
- # RFC2396, Section 5.2, 7)
- base.set_userinfo(rel.userinfo) if rel.userinfo
- base.set_host(rel.host) if rel.host
- base.set_port(rel.port) if rel.port
- base.set_query(rel.query) if rel.query
- base.set_fragment(rel.fragment) if rel.fragment
-
- return base
- end # merge
- alias + merge
-
- # return base and rel.
- # you can modify `base', but can not `rel'.
- def merge0(oth)
- oth = parser.send(:convert_to_uri, oth)
-
- if self.relative? && oth.relative?
- raise BadURIError,
- "both URI are relative"
- end
-
- if self.absolute? && oth.absolute?
- #raise BadURIError,
- # "both URI are absolute"
- # hmm... should return oth for usability?
- return oth, oth
- end
-
- if self.absolute?
- return self.dup, oth
- else
- return oth, oth
- end
- end
- private :merge0
-
- # :stopdoc:
- def route_from_path(src, dst)
- case dst
- when src
- # RFC2396, Section 4.2
- return ''
- when %r{(?:\A|/)\.\.?(?:/|\z)}
- # dst has abnormal absolute path,
- # like "/./", "/../", "/x/../", ...
- return dst.dup
- end
-
- src_path = src.scan(%r{(?:\A|[^/]+)/})
- dst_path = dst.scan(%r{(?:\A|[^/]+)/?})
-
- # discard same parts
- while !dst_path.empty? && dst_path.first == src_path.first
- src_path.shift
- dst_path.shift
- end
-
- tmp = dst_path.join
-
- # calculate
- if src_path.empty?
- if tmp.empty?
- return './'
- elsif dst_path.first.include?(':') # (see RFC2396 Section 5)
- return './' + tmp
- else
- return tmp
- end
- end
-
- return '../' * src_path.size + tmp
- end
- private :route_from_path
- # :startdoc:
-
- # :stopdoc:
- def route_from0(oth)
- oth = parser.send(:convert_to_uri, oth)
- if self.relative?
- raise BadURIError,
- "relative URI: #{self}"
- end
- if oth.relative?
- raise BadURIError,
- "relative URI: #{oth}"
- end
-
- if self.scheme != oth.scheme
- return self, self.dup
- end
- rel = URI::Generic.new(nil, # it is relative URI
- self.userinfo, self.host, self.port,
- self.registry, self.path, self.opaque,
- self.query, self.fragment, parser)
-
- if rel.userinfo != oth.userinfo ||
- rel.host.to_s.downcase != oth.host.to_s.downcase ||
- rel.port != oth.port
-
- if self.userinfo.nil? && self.host.nil?
- return self, self.dup
- end
-
- rel.set_port(nil) if rel.port == oth.default_port
- return rel, rel
- end
- rel.set_userinfo(nil)
- rel.set_host(nil)
- rel.set_port(nil)
-
- if rel.path && rel.path == oth.path
- rel.set_path('')
- rel.set_query(nil) if rel.query == oth.query
- return rel, rel
- elsif rel.opaque && rel.opaque == oth.opaque
- rel.set_opaque('')
- rel.set_query(nil) if rel.query == oth.query
- return rel, rel
- end
-
- # you can modify `rel', but can not `oth'.
- return oth, rel
- end
- private :route_from0
- # :startdoc:
-
- #
- # == Args
- #
- # +oth+::
- # URI or String
- #
- # == Description
- #
- # Calculates relative path from oth to self
- #
- # == Usage
- #
- # 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>
- #
- def route_from(oth)
- # you can modify `rel', but can not `oth'.
- begin
- oth, rel = route_from0(oth)
- rescue
- raise $!.class, $!.message
- end
- if oth == rel
- return rel
- end
-
- rel.set_path(route_from_path(oth.path, self.path))
- if rel.path == './' && self.query
- # "./?foo" -> "?foo"
- rel.set_path('')
- end
-
- return rel
- end
-
- alias - route_from
-
- #
- # == Args
- #
- # +oth+::
- # URI or String
- #
- # == Description
- #
- # Calculates relative path to oth from self
- #
- # == Usage
- #
- # 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>
- #
- def route_to(oth)
- parser.send(:convert_to_uri, oth).route_from(self)
- end
-
- #
- # Returns normalized URI
- #
- def normalize
- uri = dup
- uri.normalize!
- uri
- end
-
- #
- # Destructive version of #normalize
- #
- def normalize!
- if path && path == ''
- set_path('/')
- end
- if scheme && scheme != scheme.downcase
- set_scheme(self.scheme.downcase)
- end
- if host && host != host.downcase
- set_host(self.host.downcase)
- end
- end
-
- # returns the assemble String with path and query components
- def path_query
- str = @path
- if @query
- str += '?' + @query
- end
- str
- end
- private :path_query
-
- #
- # Constructs String from URI
- #
- def to_s
- str = ''
- if @scheme
- str << @scheme
- str << ':'
- end
-
- if @opaque
- str << @opaque
-
- else
- if @registry
- str << @registry
- else
- if @host
- str << '//'
- end
- if self.userinfo
- str << self.userinfo
- str << '@'
- end
- if @host
- str << @host
- end
- if @port && @port != self.default_port
- str << ':'
- str << @port.to_s
- end
- end
-
- str << path_query
- end
-
- if @fragment
- str << '#'
- str << @fragment
- end
-
- str
- end
-
- #
- # Compares to URI's
- #
- def ==(oth)
- if self.class == oth.class
- self.normalize.component_ary == oth.normalize.component_ary
- else
- false
- end
- end
-
- def hash
- self.component_ary.hash
- end
-
- def eql?(oth)
- self.class == oth.class &&
- parser == oth.parser &&
- self.component_ary.eql?(oth.component_ary)
- end
-
-=begin
-
---- URI::Generic#===(oth)
-
-=end
-# def ===(oth)
-# raise NotImplementedError
-# end
-
-=begin
-=end
-
-
- # returns an Array of the components defined from the COMPONENT Array
- def component_ary
- component.collect do |x|
- self.send(x)
- end
- end
- protected :component_ary
-
- # == Args
- #
- # +components+::
- # Multiple Symbol arguments defined in URI::HTTP
- #
- # == Description
- #
- # Selects specified components from URI
- #
- # == Usage
- #
- # 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"]
- #
- def select(*components)
- components.collect do |c|
- if component.include?(c)
- self.send(c)
- else
- raise ArgumentError,
- "expected of components of #{self.class} (#{self.class.component.join(', ')})"
- end
- end
- end
-
- @@to_s = Kernel.instance_method(:to_s)
- def inspect
- @@to_s.bind(self).call.sub!(/>\z/) {" URL:#{self}>"}
- end
-
- #
- # == Args
- #
- # +v+::
- # URI or String
- #
- # == Description
- #
- # attempt to parse other URI +oth+
- # return [parsed_oth, self]
- #
- # == Usage
- #
- # require 'uri'
- #
- # uri = URI.parse("http://my.example.com")
- # uri.coerce("http://foo.com")
- # #=> [#<URI::HTTP:0x00000000bcb028 URL:http://foo.com/>, #<URI::HTTP:0x00000000d92178 URL:http://my.example.com>]
- #
- def coerce(oth)
- case oth
- when String
- oth = parser.parse(oth)
- else
- super
- end
-
- return oth, self
- end
- end
-end