mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	 c56dab2ceb
			
		
	
	
		c56dab2ceb
		
	
	
	
	
		
			
			* lib/uri/ftp.rb (initialize): arg[-1] was fragment, but it must be arg_check. * lib/uri/ftp.rb (initialize): explicitly specify arguments. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46489 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
		
			
				
	
	
		
			266 lines
		
	
	
	
		
			7 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			266 lines
		
	
	
	
		
			7 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| # = uri/ftp.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/generic'
 | |
| 
 | |
| module URI
 | |
| 
 | |
|   #
 | |
|   # FTP URI syntax is defined by RFC1738 section 3.2.
 | |
|   #
 | |
|   # This class will be redesigned because of difference of implementations;
 | |
|   # the structure of its path. draft-hoffman-ftp-uri-04 is a draft but it
 | |
|   # is a good summary about the de facto spec.
 | |
|   # http://tools.ietf.org/html/draft-hoffman-ftp-uri-04
 | |
|   #
 | |
|   class FTP < Generic
 | |
|     # A Default port of 21 for URI::FTP
 | |
|     DEFAULT_PORT = 21
 | |
| 
 | |
|     #
 | |
|     # An Array of the available components for URI::FTP
 | |
|     #
 | |
|     COMPONENT = [
 | |
|       :scheme,
 | |
|       :userinfo, :host, :port,
 | |
|       :path, :typecode
 | |
|     ].freeze
 | |
| 
 | |
|     #
 | |
|     # Typecode is "a", "i" or "d".
 | |
|     #
 | |
|     # * "a" indicates a text file (the FTP command was ASCII)
 | |
|     # * "i" indicates a binary file (FTP command IMAGE)
 | |
|     # * "d" indicates the contents of a directory should be displayed
 | |
|     #
 | |
|     TYPECODE = ['a', 'i', 'd'].freeze
 | |
| 
 | |
|     # Typecode prefix
 | |
|     #  ';type='
 | |
|     TYPECODE_PREFIX = ';type='.freeze
 | |
| 
 | |
|     def self.new2(user, password, host, port, path,
 | |
|                   typecode = nil, arg_check = true) # :nodoc:
 | |
|       # Do not use this method!  Not tested.  [Bug #7301]
 | |
|       # This methods remains just for compatibility,
 | |
|       # Keep it undocumented until the active maintainer is assigned.
 | |
|       typecode = nil if typecode.size == 0
 | |
|       if typecode && !TYPECODE.include?(typecode)
 | |
|         raise ArgumentError,
 | |
|           "bad typecode is specified: #{typecode}"
 | |
|       end
 | |
| 
 | |
|       # do escape
 | |
| 
 | |
|       self.new('ftp',
 | |
|                [user, password],
 | |
|                host, port, nil,
 | |
|                typecode ? path + TYPECODE_PREFIX + typecode : path,
 | |
|                nil, nil, nil, arg_check)
 | |
|     end
 | |
| 
 | |
|     #
 | |
|     # == Description
 | |
|     #
 | |
|     # Creates a new URI::FTP object from components, with syntax checking.
 | |
|     #
 | |
|     # The components accepted are +userinfo+, +host+, +port+, +path+ and
 | |
|     # +typecode+.
 | |
|     #
 | |
|     # The components should be provided either as an Array, or as a Hash
 | |
|     # with keys formed by preceding the component names with a colon.
 | |
|     #
 | |
|     # If an Array is used, the components must be passed in the order
 | |
|     # [userinfo, host, port, path, typecode]
 | |
|     #
 | |
|     # If the path supplied is absolute, it will be escaped in order to
 | |
|     # make it absolute in the URI. Examples:
 | |
|     #
 | |
|     #     require 'uri'
 | |
|     #
 | |
|     #     uri = URI::FTP.build(['user:password', 'ftp.example.com', nil,
 | |
|     #       '/path/file.> zip', 'i'])
 | |
|     #     puts uri.to_s  ->  ftp://user:password@ftp.example.com/%2Fpath/file.zip;type=a
 | |
|     #
 | |
|     #     uri2 = URI::FTP.build({:host => 'ftp.example.com',
 | |
|     #       :path => 'ruby/src'})
 | |
|     #     puts uri2.to_s  ->  ftp://ftp.example.com/ruby/src
 | |
|     #
 | |
|     def self.build(args)
 | |
| 
 | |
|       # Fix the incoming path to be generic URL syntax
 | |
|       # FTP path  ->  URL path
 | |
|       # foo/bar       /foo/bar
 | |
|       # /foo/bar      /%2Ffoo/bar
 | |
|       #
 | |
|       if args.kind_of?(Array)
 | |
|         args[3] = '/' + args[3].sub(/^\//, '%2F')
 | |
|       else
 | |
|         args[:path] = '/' + args[:path].sub(/^\//, '%2F')
 | |
|       end
 | |
| 
 | |
|       tmp = Util::make_components_hash(self, args)
 | |
| 
 | |
|       if tmp[:typecode]
 | |
|         if tmp[:typecode].size == 1
 | |
|           tmp[:typecode] = TYPECODE_PREFIX + tmp[:typecode]
 | |
|         end
 | |
|         tmp[:path] << tmp[:typecode]
 | |
|       end
 | |
| 
 | |
|       return super(tmp)
 | |
|     end
 | |
| 
 | |
|     #
 | |
|     # == Description
 | |
|     #
 | |
|     # Creates a new URI::FTP object from generic URL components with no
 | |
|     # syntax checking.
 | |
|     #
 | |
|     # Unlike build(), this method does not escape the path component as
 | |
|     # required by RFC1738; instead it is treated as per RFC2396.
 | |
|     #
 | |
|     # Arguments are +scheme+, +userinfo+, +host+, +port+, +registry+, +path+,
 | |
|     # +opaque+, +query+ and +fragment+, in that order.
 | |
|     #
 | |
|     def initialize(scheme,
 | |
|                    userinfo, host, port, registry,
 | |
|                    path, opaque,
 | |
|                    query,
 | |
|                    fragment,
 | |
|                    parser = nil,
 | |
|                    arg_check = false)
 | |
|       raise InvalidURIError unless path
 | |
|       path = path.sub(/^\//,'')
 | |
|       path.sub!(/^%2F/,'/')
 | |
|       super(scheme, userinfo, host, port, registry, path, opaque,
 | |
|             query, fragment, parser, arg_check)
 | |
|       @typecode = nil
 | |
|       if tmp = @path.index(TYPECODE_PREFIX)
 | |
|         typecode = @path[tmp + TYPECODE_PREFIX.size..-1]
 | |
|         @path = @path[0..tmp - 1]
 | |
| 
 | |
|         if arg_check
 | |
|           self.typecode = typecode
 | |
|         else
 | |
|           self.set_typecode(typecode)
 | |
|         end
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     # typecode accessor
 | |
|     #
 | |
|     # see URI::FTP::COMPONENT
 | |
|     attr_reader :typecode
 | |
| 
 | |
|     # validates typecode +v+,
 | |
|     # returns a +true+ or +false+ boolean
 | |
|     #
 | |
|     def check_typecode(v)
 | |
|       if TYPECODE.include?(v)
 | |
|         return true
 | |
|       else
 | |
|         raise InvalidComponentError,
 | |
|           "bad typecode(expected #{TYPECODE.join(', ')}): #{v}"
 | |
|       end
 | |
|     end
 | |
|     private :check_typecode
 | |
| 
 | |
|     # Private setter for the typecode +v+
 | |
|     #
 | |
|     # see also URI::FTP.typecode=
 | |
|     #
 | |
|     def set_typecode(v)
 | |
|       @typecode = v
 | |
|     end
 | |
|     protected :set_typecode
 | |
| 
 | |
|     #
 | |
|     # == Args
 | |
|     #
 | |
|     # +v+::
 | |
|     #    String
 | |
|     #
 | |
|     # == Description
 | |
|     #
 | |
|     # public setter for the typecode +v+.
 | |
|     # (with validation)
 | |
|     #
 | |
|     # see also URI::FTP.check_typecode
 | |
|     #
 | |
|     # == Usage
 | |
|     #
 | |
|     #   require 'uri'
 | |
|     #
 | |
|     #   uri = URI.parse("ftp://john@ftp.example.com/my_file.img")
 | |
|     #   #=> #<URI::FTP:0x00000000923650 URL:ftp://john@ftp.example.com/my_file.img>
 | |
|     #   uri.typecode = "i"
 | |
|     #   # =>  "i"
 | |
|     #   uri
 | |
|     #   #=> #<URI::FTP:0x00000000923650 URL:ftp://john@ftp.example.com/my_file.img;type=i>
 | |
|     #
 | |
|     def typecode=(typecode)
 | |
|       check_typecode(typecode)
 | |
|       set_typecode(typecode)
 | |
|       typecode
 | |
|     end
 | |
| 
 | |
|     def merge(oth) # :nodoc:
 | |
|       tmp = super(oth)
 | |
|       if self != tmp
 | |
|         tmp.set_typecode(oth.typecode)
 | |
|       end
 | |
| 
 | |
|       return tmp
 | |
|     end
 | |
| 
 | |
|     # Returns the path from an FTP URI.
 | |
|     #
 | |
|     # RFC 1738 specifically states that the path for an FTP URI does not
 | |
|     # include the / which separates the URI path from the URI host. Example:
 | |
|     #
 | |
|     #     ftp://ftp.example.com/pub/ruby
 | |
|     #
 | |
|     # The above URI indicates that the client should connect to
 | |
|     # ftp.example.com then cd pub/ruby from the initial login directory.
 | |
|     #
 | |
|     # If you want to cd to an absolute directory, you must include an
 | |
|     # escaped / (%2F) in the path. Example:
 | |
|     #
 | |
|     #     ftp://ftp.example.com/%2Fpub/ruby
 | |
|     #
 | |
|     # This method will then return "/pub/ruby"
 | |
|     #
 | |
|     def path
 | |
|       return @path.sub(/^\//,'').sub(/^%2F/,'/')
 | |
|     end
 | |
| 
 | |
|     # Private setter for the path of the URI::FTP
 | |
|     def set_path(v)
 | |
|       super("/" + v.sub(/^\//, "%2F"))
 | |
|     end
 | |
|     protected :set_path
 | |
| 
 | |
|     # Returns a String representation of the URI::FTP
 | |
|     def to_s
 | |
|       save_path = nil
 | |
|       if @typecode
 | |
|         save_path = @path
 | |
|         @path = @path + TYPECODE_PREFIX + @typecode
 | |
|       end
 | |
|       str = super
 | |
|       if @typecode
 | |
|         @path = save_path
 | |
|       end
 | |
| 
 | |
|       return str
 | |
|     end
 | |
|   end
 | |
|   @@schemes['FTP'] = FTP
 | |
| end
 |