[前][次][番号順一覧][スレッド一覧]

ruby-changes:50613

From: naruse <ko1@a...>
Date: Fri, 16 Mar 2018 01:51:38 +0900 (JST)
Subject: [ruby-changes:50613] naruse:r62767 (trunk): Introduce URI::File to handle file URI scheme

naruse	2018-03-16 01:51:31 +0900 (Fri, 16 Mar 2018)

  New Revision: 62767

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=62767

  Log:
    Introduce URI::File to handle file URI scheme
    
    * the default value of URI::File's authority is "" (localhost).
      Both nil and "localhost" is normalized to "" by default.
    * URI::File ignores setting userinfo and port
    [Feature #14035]
    fix https://github.com/ruby/ruby/pull/1719
    fic https://github.com/ruby/ruby/pull/1832

  Added files:
    trunk/lib/uri/file.rb
    trunk/test/uri/test_file.rb
  Modified files:
    trunk/NEWS
    trunk/lib/uri.rb
Index: NEWS
===================================================================
--- NEWS	(revision 62766)
+++ NEWS	(revision 62767)
@@ -132,6 +132,10 @@ with all sufficient information, see the https://github.com/ruby/ruby/blob/trunk/NEWS#L132
 
     * Set#filter! is a new alias for Set#select! [Feature #13784]
 
+* URI
+
+  * Add URI::File to handle file URI scheme [Feature #14035]
+
 === Compatibility issues (excluding feature bug fixes)
 
 === Stdlib compatibility issues (excluding feature bug fixes)
Index: lib/uri.rb
===================================================================
--- lib/uri.rb	(revision 62766)
+++ lib/uri.rb	(revision 62767)
@@ -41,7 +41,7 @@ https://github.com/ruby/ruby/blob/trunk/lib/uri.rb#L41
 #   #=> URI::RSYNC
 #
 #   URI.scheme_list
-#   #=> {"FTP"=>URI::FTP, "HTTP"=>URI::HTTP, "HTTPS"=>URI::HTTPS,
+#   #=> {"FILE"=>URI::File, "FTP"=>URI::FTP, "HTTP"=>URI::HTTP, "HTTPS"=>URI::HTTPS,
 #        "LDAP"=>URI::LDAP, "LDAPS"=>URI::LDAPS, "MAILTO"=>URI::MailTo,
 #        "RSYNC"=>URI::RSYNC}
 #
@@ -65,6 +65,7 @@ https://github.com/ruby/ruby/blob/trunk/lib/uri.rb#L65
 # == Class tree
 #
 # - URI::Generic (in uri/generic.rb)
+#   - URI::File - (in uri/file.rb)
 #   - URI::FTP - (in uri/ftp.rb)
 #   - URI::HTTP - (in uri/http.rb)
 #     - URI::HTTPS - (in uri/https.rb)
@@ -104,6 +105,7 @@ end https://github.com/ruby/ruby/blob/trunk/lib/uri.rb#L105
 
 require 'uri/common'
 require 'uri/generic'
+require 'uri/file'
 require 'uri/ftp'
 require 'uri/http'
 require 'uri/https'
Index: lib/uri/file.rb
===================================================================
--- lib/uri/file.rb	(nonexistent)
+++ lib/uri/file.rb	(revision 62767)
@@ -0,0 +1,95 @@ https://github.com/ruby/ruby/blob/trunk/lib/uri/file.rb#L1
+# frozen_string_literal: true
+
+require 'uri/generic'
+
+module URI
+
+  #
+  # The "file" URI is defined by RFC8089
+  #
+  class File < Generic
+    # A Default port of nil for URI::File
+    DEFAULT_PORT = nil
+
+    #
+    # An Array of the available components for URI::File
+    #
+    COMPONENT = [
+      :scheme,
+      :host,
+      :path
+    ].freeze
+
+    #
+    # == Description
+    #
+    # Creates a new URI::File object from components, with syntax checking.
+    #
+    # The components accepted are +host+ and +path+.
+    #
+    # 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
+    # [host, path]
+    #
+    # If the path supplied is absolute, it will be escaped in order to
+    # make it absolute in the URI. Examples:
+    #
+    #     require 'uri'
+    #
+    #     uri = URI::File.build(['host.example.com', '/path/file.zip'])
+    #     puts uri.to_s  ->  file://host.example.com/path/file.zip
+    #
+    #     uri2 = URI::File.build({:host => 'host.example.com',
+    #       :path => 'ruby/src'})
+    #     puts uri2.to_s  ->  file://host.example.com/ruby/src
+    #
+    def self.build(args)
+      tmp = Util::make_components_hash(self, args)
+      super(tmp)
+    end
+
+    # protected setter for the host component +v+
+    #
+    # see also URI::Generic.host=
+    #
+    def set_host(v)
+      v = "" if v.nil? || v == "localhost"
+      @host = v
+    end
+
+    # do nothing
+    def set_port(v)
+    end
+
+    # raise InvalidURIError
+    def check_userinfo(user)
+      raise URI::InvalidURIError, "can not set userinfo for file URI"
+    end
+
+    # raise InvalidURIError
+    def check_user(user)
+      raise URI::InvalidURIError, "can not set user for file URI"
+    end
+
+    # raise InvalidURIError
+    def check_password(user)
+      raise URI::InvalidURIError, "can not set password for file URI"
+    end
+
+    # do nothing
+    def set_userinfo(v)
+    end
+
+    # do nothing
+    def set_user(v)
+    end
+
+    # do nothing
+    def set_password(v)
+    end
+  end
+
+  @@schemes['FILE'] = File
+end
Index: test/uri/test_file.rb
===================================================================
--- test/uri/test_file.rb	(nonexistent)
+++ test/uri/test_file.rb	(revision 62767)
@@ -0,0 +1,67 @@ https://github.com/ruby/ruby/blob/trunk/test/uri/test_file.rb#L1
+# frozen_string_literal: false
+require 'test/unit'
+require 'uri/file'
+
+class URI::TestFile < Test::Unit::TestCase
+  def test_parse
+    u = URI("file://example.com/file")
+    assert_equal "/file", u.path
+
+    u = URI("file://localhost/file")
+    assert_equal "/file", u.path
+    assert_equal "file:///file", u.to_s
+
+    u = URI("file://localhost:30/file")
+    assert_equal "", u.host
+    assert_equal nil, u.port
+    assert_equal "/file", u.path
+    assert_equal "file:///file", u.to_s
+
+    u = URI("file:///file")
+    assert_equal "/file", u.path
+    assert_equal "file:///file", u.to_s
+
+    u = URI("file:/file")
+    assert_equal "/file", u.path
+    assert_equal "file:///file", u.to_s
+
+    u = URI("file://foo:pass@e.../file")
+    assert_equal "/file", u.path
+    assert_equal nil, u.user
+    assert_equal nil, u.password
+
+    u = URI("file:///c:/path/to/file")
+    assert_equal "/c:/path/to/file", u.path
+
+    # this form is not supported
+    u = URI("file:c:/path/to/file")
+    assert_equal "c:/path/to/file", u.opaque
+
+  end
+
+  def test_build
+    u = URI::File.build(scheme: "file", host: "example.com", path:"/file")
+    assert_equal "/file", u.path
+    assert_equal "file://example.com/file", u.to_s
+    assert_raise(URI::InvalidURIError){ u.user = "foo" }
+    assert_raise(URI::InvalidURIError){ u.password = "foo" }
+    assert_raise(URI::InvalidURIError){ u.userinfo = "foo" }
+    assert_raise(URI::InvalidURIError){ URI::File.build(scheme: "file", userinfo: "foo", host: "example.com", path:"/file") }
+
+    u = URI::File.build(scheme: "file", path:"/file")
+    assert_equal "", u.host
+    assert_equal "/file", u.path
+    assert_equal "file:///file", u.to_s
+
+    u = URI::File.build(scheme: "file", host: "localhost", path:"/file")
+    assert_equal "", u.host
+    assert_equal "/file", u.path
+    assert_equal "file:///file", u.to_s
+
+    u = URI::File.build(scheme: "file", path:"/file", port: 30)
+    assert_equal "", u.host
+    assert_equal nil, u.port
+    assert_equal "/file", u.path
+    assert_equal "file:///file", u.to_s
+  end
+end

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]