# class URI::FTP

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. tools.ietf.org/html/draft-hoffman-ftp-uri-04

### Constants

COMPONENT

  An Array of the available components for URI::FTP

DEFAULT_PORT

  A Default port of 21 for URI::FTP

TYPECODE

  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_PREFIX

  Typecode prefix

      ';type='

### Attributes

typecode[R]

typecode accessor

see URI::FTP::COMPONENT

### Public Class Methods

build(args) click to toggle source

## 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=i

      uri2 = URI::FTP.build({:host => 'ftp.example.com',
        :path => 'ruby/src'})
      puts uri2.to_s  ->  ftp://ftp.example.com/ruby/src

Calls superclass method

    # File lib/uri/ftp.rb, line 95
    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

new(scheme, userinfo, host, port, registry, path, opaque, query, fragment, parser = nil, arg_check = false) click to toggle source

## 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.

Calls superclass method

    # File lib/uri/ftp.rb, line 132
    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

### Public Instance Methods

path() click to toggle source

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.example.com/%2Fpub/ruby+

This method will then return “/pub/ruby”

    # File lib/uri/ftp.rb, line 240
    def path
      return @path.sub(/^\//,'').sub(/^%2F/,'/')
    end

to_s() click to toggle source

Returns a String representation of the URI::FTP

Calls superclass method

    # File lib/uri/ftp.rb, line 251
    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

typecode=(typecode) click to toggle source

## Args¶ ↑

`v`

  String

## Description¶ ↑

public setter for the typecode `v`. (with validation)

see also #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>

    # File lib/uri/ftp.rb, line 208
    def typecode=(typecode)
      check_typecode(typecode)
      set_typecode(typecode)
      typecode
    end

### Protected Instance Methods

set_path(v) click to toggle source

Private setter for the path of the URI::FTP

Calls superclass method

    # File lib/uri/ftp.rb, line 245
    def set_path(v)
      super("/" + v.sub(/^\//, "%2F"))
    end

set_typecode(v) click to toggle source

Private setter for the typecode `v`

see also #typecode=

    # File lib/uri/ftp.rb, line 179
    def set_typecode(v)
      @typecode = v
    end

### Private Instance Methods

check_typecode(v) click to toggle source

validates typecode `v`, returns a `true` or `false` boolean

    # File lib/uri/ftp.rb, line 165
    def check_typecode(v)
      if TYPECODE.include?(v)
        return true
      else
        raise InvalidComponentError,
          "bad typecode(expected #{TYPECODE.join(', ')}): #{v}"
      end
    end