file-uri 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/file-uri-common.rb +73 -0
- data/lib/file-uri.rb +30 -0
- data/lib/file-uri/win.rb +68 -0
- data/test/test-file-uri.rb +100 -0
- data/test/test-win-file-uri.rb +114 -0
- metadata +56 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a6a645851a1f2159e72eafaefd02f0d740bead9e
|
4
|
+
data.tar.gz: 0aa68c3ae8150ac81653498069c7fab57693db65
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bb872d4478f27ec8c8a63e36499db67742c271e1431a34c1770bf86b96bf7a0492727a5d1ecafb656452ffaa1f1b82f50f0e2dbae1700e15b5c5bf1b2f409b54
|
7
|
+
data.tar.gz: 71ec8ecde2ea8631276db2475f3b9b3de89cec206e4c41999348c6ceb3153de322e12bcfa1a56a596547460f7e7375752a68da5c5fcb49d43486b4d244c0e547
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'uri/generic'
|
2
|
+
|
3
|
+
module URI
|
4
|
+
module File
|
5
|
+
|
6
|
+
COMPONENT = %i[
|
7
|
+
scheme
|
8
|
+
userinfo host port
|
9
|
+
path
|
10
|
+
query
|
11
|
+
fragment
|
12
|
+
]
|
13
|
+
|
14
|
+
def self.build(args)
|
15
|
+
tmp = Util.make_components_hash(self, args)
|
16
|
+
super(tmp)
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# localhost:
|
21
|
+
#
|
22
|
+
# * true => 'file://localhost/' is local, 'file://example.com/' is non-local
|
23
|
+
# * false => 'file://localhost/' is non-local
|
24
|
+
#
|
25
|
+
def local? localhost: true
|
26
|
+
if host && !host.empty?
|
27
|
+
return localhost && (host.downcase == LOCALHOST)
|
28
|
+
elsif path.start_with? DBL_SLASH
|
29
|
+
return false
|
30
|
+
end
|
31
|
+
true
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# localhost:
|
36
|
+
#
|
37
|
+
# * true => 'file://localhost/' is local, 'file://example.com/' is non-local
|
38
|
+
# * false => 'file://localhost/' is non-local
|
39
|
+
#
|
40
|
+
def to_file_path localhost: true
|
41
|
+
raise "no local path for non-local URI #{to_s}" unless local?(localhost: localhost)
|
42
|
+
path
|
43
|
+
end
|
44
|
+
|
45
|
+
##
|
46
|
+
# localhost:
|
47
|
+
#
|
48
|
+
# * true => 'file://localhost/' is local, 'file://example.com/' is non-local
|
49
|
+
# * false => 'file://localhost/' is non-local
|
50
|
+
#
|
51
|
+
def to_unc localhost: true
|
52
|
+
if host && !host.empty?
|
53
|
+
unless localhost && (host.downcase == LOCALHOST)
|
54
|
+
unc = DBL_BACKSLASH + host
|
55
|
+
unc += COLON + port if port
|
56
|
+
unc += path.gsub(%r[/], BACKSLASH)
|
57
|
+
return unc
|
58
|
+
end
|
59
|
+
elsif path.start_with? DBL_SLASH
|
60
|
+
return path.gsub(%r[/], BACKSLASH)
|
61
|
+
end
|
62
|
+
raise "no UNC conversion for local URI #{to_s}"
|
63
|
+
end
|
64
|
+
|
65
|
+
COLON = ?:.freeze
|
66
|
+
SLASH = ?/.freeze
|
67
|
+
DBL_SLASH = '//'.freeze
|
68
|
+
BACKSLASH = '\\'.freeze
|
69
|
+
DBL_BACKSLASH = '\\\\'.freeze
|
70
|
+
LOCALHOST = 'localhost'.freeze
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
data/lib/file-uri.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'uri/generic'
|
2
|
+
require_relative 'file-uri-common'
|
3
|
+
|
4
|
+
module URI
|
5
|
+
class CoreFile < Generic
|
6
|
+
include File
|
7
|
+
|
8
|
+
def initialize(scheme,
|
9
|
+
userinfo, host, port, registry,
|
10
|
+
path, opaque,
|
11
|
+
query,
|
12
|
+
fragment,
|
13
|
+
parser = DEFAULT_PARSER,
|
14
|
+
arg_check = false)
|
15
|
+
# detect UNC-type paths ("file:////server/Share/dir/file.ext")
|
16
|
+
if !host && path && path =~ %r[\A//+]
|
17
|
+
path = path.sub(%r[\A/+], DBL_SLASH)
|
18
|
+
host = ''
|
19
|
+
# ...urgh
|
20
|
+
elsif path && path =~ %r[\A/+]
|
21
|
+
path = path.sub(%r[\A/+], SLASH)
|
22
|
+
end
|
23
|
+
super(scheme, userinfo, host, port, registry, path, opaque, query, fragment, parser, arg_check)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
@@schemes['FILE'] = CoreFile
|
29
|
+
|
30
|
+
end
|
data/lib/file-uri/win.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'uri/generic'
|
4
|
+
require_relative '../file-uri-common'
|
5
|
+
|
6
|
+
module URI
|
7
|
+
class WinFile < Generic
|
8
|
+
include File
|
9
|
+
|
10
|
+
def fixup path
|
11
|
+
path.gsub(%r[\A/([A-Z]):?(?=/|\z)]i, '/\1:')
|
12
|
+
end
|
13
|
+
private :fixup
|
14
|
+
|
15
|
+
def scrub path
|
16
|
+
path.gsub(%r[\A/?([A-Z]):?(?=/|\z)|:]i) {|m| $1 ? "#{$1}:" : SPECIAL }
|
17
|
+
end
|
18
|
+
private :scrub
|
19
|
+
|
20
|
+
def initialize(scheme,
|
21
|
+
userinfo, host, port, registry,
|
22
|
+
path, opaque,
|
23
|
+
query,
|
24
|
+
fragment,
|
25
|
+
parser = DEFAULT_PARSER,
|
26
|
+
arg_check = false)
|
27
|
+
# detect Windows drive letter absolute paths ("file:c:/dir/file.ext")
|
28
|
+
if !path && opaque && opaque =~ %r[\A[A-Z]:?(?=\z|/)]i
|
29
|
+
path = fixup(SLASH + opaque)
|
30
|
+
path += SLASH if path.length == 3
|
31
|
+
opaque = nil
|
32
|
+
# detect Windows-style drive letter authorities ("file://c:/dir/file.ext")
|
33
|
+
elsif host && host =~ %r[\A[A-Z]\z]i
|
34
|
+
path = SLASH + host + COLON + fixup(path)
|
35
|
+
host = nil
|
36
|
+
# detect UNC-type paths ("file:////server/Share/dir/file.ext")
|
37
|
+
elsif !host && path && path =~ %r[\A//+]
|
38
|
+
path = path.sub(%r[\A/+], DBL_SLASH).gsub(COLON, SPECIAL)
|
39
|
+
host = ''
|
40
|
+
# ...urgh
|
41
|
+
elsif path && path =~ %r[\A//+]
|
42
|
+
path = fixup(path.sub(%r[\A//+], SLASH))
|
43
|
+
else
|
44
|
+
path = fixup(path) if path
|
45
|
+
end
|
46
|
+
super(scheme, userinfo, host, port, registry, path, opaque, query, fragment, parser, arg_check)
|
47
|
+
end
|
48
|
+
|
49
|
+
##
|
50
|
+
# localhost:
|
51
|
+
#
|
52
|
+
# * true => 'file://localhost/' is local, 'file://example.com/' is non-local
|
53
|
+
# * false => 'file://localhost/' is non-local
|
54
|
+
#
|
55
|
+
def to_file_path localhost: true
|
56
|
+
raise "no local path for non-local URI #{to_s}" unless local?(localhost: localhost)
|
57
|
+
path = scrub(@path)
|
58
|
+
#path = path.gsub(SLASH, File::SEPARATOR)
|
59
|
+
path
|
60
|
+
end
|
61
|
+
|
62
|
+
SPECIAL = "\u{F03A}".freeze
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
@@schemes['FILE'] = WinFile
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
$VERBOSE = true
|
3
|
+
|
4
|
+
|
5
|
+
require_relative '../lib/file-uri'
|
6
|
+
class Test_file_uri < Test::Unit::TestCase
|
7
|
+
|
8
|
+
# 'file' URIs that are valid and are always treated as local
|
9
|
+
def test_valid_local_uris
|
10
|
+
[
|
11
|
+
['file:///path/to/file', '/path/to/file'],
|
12
|
+
['file:/short/path/to/file', '/short/path/to/file'],
|
13
|
+
].each do |str, path|
|
14
|
+
uri = URI.parse(str)
|
15
|
+
assert_kind_of( URI::File, uri )
|
16
|
+
assert_equal( path, uri.path )
|
17
|
+
# these depend on it being a URI::File object
|
18
|
+
assert_equal( true, uri.local? )
|
19
|
+
assert_equal( path, uri.to_file_path )
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# 'file' URIs that are valid and encode UNC strings in the path
|
24
|
+
# (i.e. non-local)
|
25
|
+
def test_valid_unc_uris
|
26
|
+
[
|
27
|
+
['file:////example.com/Share/dir/file.ext', '//example.com/Share/dir/file.ext', '\\\\example.com\\Share\\dir\\file.ext'],
|
28
|
+
['file://///example.com/Share/dir/file.ext', '//example.com/Share/dir/file.ext', '\\\\example.com\\Share\\dir\\file.ext'],
|
29
|
+
|
30
|
+
['file:////localhost/Share/dir/file.ext', '//localhost/Share/dir/file.ext', '\\\\localhost\\Share\\dir\\file.ext'],
|
31
|
+
['file://///localhost/Share/dir/file.ext', '//localhost/Share/dir/file.ext', '\\\\localhost\\Share\\dir\\file.ext'],
|
32
|
+
].each do |str, path, unc|
|
33
|
+
uri = URI.parse(str)
|
34
|
+
assert_kind_of( URI::File, uri )
|
35
|
+
assert_equal( path, uri.path )
|
36
|
+
|
37
|
+
assert_equal( false, uri.local?(localhost: false) )
|
38
|
+
assert_equal( false, uri.local?(localhost: true) )
|
39
|
+
assert_equal( false, uri.local? )
|
40
|
+
|
41
|
+
assert_raise(RuntimeError) { uri.to_file_path(localhost: false) }
|
42
|
+
assert_raise(RuntimeError) { uri.to_file_path(localhost: true) }
|
43
|
+
assert_raise(RuntimeError) { uri.to_file_path }
|
44
|
+
|
45
|
+
assert_equal( unc, uri.to_unc(localhost: false) )
|
46
|
+
assert_equal( unc, uri.to_unc(localhost: true) )
|
47
|
+
assert_equal( unc, uri.to_unc )
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# 'file' URIs that are valid and non-local
|
52
|
+
def test_valid_nonlocal_uris
|
53
|
+
[
|
54
|
+
['file://example.com/Share/dir/file.ext', 'example.com', '/Share/dir/file.ext', '\\\\example.com\\Share\\dir\\file.ext'],
|
55
|
+
['file://example.com/Share/dir/file.ext', 'example.com', '/Share/dir/file.ext', '\\\\example.com\\Share\\dir\\file.ext'],
|
56
|
+
].each do |str, host, path, unc|
|
57
|
+
uri = URI.parse(str)
|
58
|
+
assert_kind_of( URI::File, uri )
|
59
|
+
assert_equal( path, uri.path )
|
60
|
+
assert_equal( host, uri.host )
|
61
|
+
|
62
|
+
assert_equal( false, uri.local?(localhost: false) )
|
63
|
+
assert_equal( false, uri.local?(localhost: true) )
|
64
|
+
assert_equal( false, uri.local? )
|
65
|
+
|
66
|
+
assert_raise(RuntimeError) { uri.to_file_path(localhost: false) }
|
67
|
+
assert_raise(RuntimeError) { uri.to_file_path(localhost: true) }
|
68
|
+
assert_raise(RuntimeError) { uri.to_file_path }
|
69
|
+
|
70
|
+
assert_equal( unc, uri.to_unc(localhost: false) )
|
71
|
+
assert_equal( unc, uri.to_unc(localhost: true) )
|
72
|
+
assert_equal( unc, uri.to_unc )
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# 'file' URIs that are valid and use the "localhost" authority
|
77
|
+
# (i.e. sometimes local, sometimes non-local)
|
78
|
+
def test_valid_localhost_uris
|
79
|
+
[
|
80
|
+
['file://localhost/path/to/file', '/path/to/file', '\\\\localhost\\path\\to\\file'],
|
81
|
+
].each do |str, path, unc|
|
82
|
+
uri = URI.parse(str)
|
83
|
+
assert_kind_of( URI::File, uri )
|
84
|
+
assert_equal( path, uri.path )
|
85
|
+
|
86
|
+
assert_equal( false, uri.local?(localhost: false) )
|
87
|
+
assert_equal( true, uri.local?(localhost: true) )
|
88
|
+
assert_equal( true, uri.local? )
|
89
|
+
|
90
|
+
assert_raise(RuntimeError) { uri.to_file_path(localhost: false) }
|
91
|
+
assert_equal( path, uri.to_file_path(localhost: true) )
|
92
|
+
assert_equal( path, uri.to_file_path )
|
93
|
+
|
94
|
+
assert_equal( unc, uri.to_unc(localhost: false) )
|
95
|
+
assert_raise(RuntimeError) { uri.to_unc(localhost: true) }
|
96
|
+
assert_raise(RuntimeError) { uri.to_unc }
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
$VERBOSE = true
|
3
|
+
|
4
|
+
|
5
|
+
require_relative '../lib/file-uri/win'
|
6
|
+
class Test_win_file_uri < Test::Unit::TestCase
|
7
|
+
|
8
|
+
# 'file' URIs that are valid and are always treated as local
|
9
|
+
def test_valid_local_uris
|
10
|
+
[
|
11
|
+
# POSIX-style
|
12
|
+
['file:///path/to/file', '/path/to/file', '/path/to/file'],
|
13
|
+
['file:/short/path/to/file', '/short/path/to/file','/short/path/to/file'],
|
14
|
+
# drive letter
|
15
|
+
['file:///c:/path/to/file', '/c:/path/to/file', 'c:/path/to/file'],
|
16
|
+
['file:///c/path/to/file', '/c:/path/to/file', 'c:/path/to/file'],
|
17
|
+
# no slash
|
18
|
+
['file:c:/path/to/file', '/c:/path/to/file', 'c:/path/to/file'],
|
19
|
+
['file:c/path/to/file', '/c:/path/to/file', 'c:/path/to/file'],
|
20
|
+
# cheeky authority
|
21
|
+
['file://c:/path/to/file', '/c:/path/to/file', 'c:/path/to/file'],
|
22
|
+
['file://c/path/to/file', '/c:/path/to/file', 'c:/path/to/file'],
|
23
|
+
# stinky colon
|
24
|
+
['file:///c:/path:to/file', '/c:/path:to/file', "c:/path\u{F03A}to/file"],
|
25
|
+
].each do |str, path, file|
|
26
|
+
uri = URI.parse(str)
|
27
|
+
assert_kind_of( URI::File, uri )
|
28
|
+
assert_equal( path, uri.path )
|
29
|
+
# these depend on it being a URI::File object
|
30
|
+
assert_equal( true, uri.local? )
|
31
|
+
assert_equal( file, uri.to_file_path )
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# 'file' URIs that are valid and encode UNC strings in the path
|
36
|
+
# (i.e. non-local)
|
37
|
+
def test_valid_unc_uris
|
38
|
+
[
|
39
|
+
['file:////example.com/Share/dir/file.ext', '//example.com/Share/dir/file.ext', '\\\\example.com\\Share\\dir\\file.ext'],
|
40
|
+
['file://///example.com/Share/dir/file.ext', '//example.com/Share/dir/file.ext', '\\\\example.com\\Share\\dir\\file.ext'],
|
41
|
+
|
42
|
+
['file:////localhost/Share/dir/file.ext', '//localhost/Share/dir/file.ext', '\\\\localhost\\Share\\dir\\file.ext'],
|
43
|
+
['file://///localhost/Share/dir/file.ext', '//localhost/Share/dir/file.ext', '\\\\localhost\\Share\\dir\\file.ext'],
|
44
|
+
].each do |str, path, unc|
|
45
|
+
uri = URI.parse(str)
|
46
|
+
assert_kind_of( URI::File, uri )
|
47
|
+
assert_equal( path, uri.path )
|
48
|
+
|
49
|
+
assert_equal( false, uri.local?(localhost: false) )
|
50
|
+
assert_equal( false, uri.local?(localhost: true) )
|
51
|
+
assert_equal( false, uri.local? )
|
52
|
+
|
53
|
+
assert_raise(RuntimeError) { uri.to_file_path(localhost: false) }
|
54
|
+
assert_raise(RuntimeError) { uri.to_file_path(localhost: true) }
|
55
|
+
assert_raise(RuntimeError) { uri.to_file_path }
|
56
|
+
|
57
|
+
assert_equal( unc, uri.to_unc(localhost: false) )
|
58
|
+
assert_equal( unc, uri.to_unc(localhost: true) )
|
59
|
+
assert_equal( unc, uri.to_unc )
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# 'file' URIs that are valid and non-local
|
64
|
+
def test_valid_nonlocal_uris
|
65
|
+
[
|
66
|
+
['file://example.com/Share/dir/file.ext', 'example.com', '/Share/dir/file.ext', '\\\\example.com\\Share\\dir\\file.ext'],
|
67
|
+
['file://example.com/Share/dir/file.ext', 'example.com', '/Share/dir/file.ext', '\\\\example.com\\Share\\dir\\file.ext'],
|
68
|
+
].each do |str, host, path, unc|
|
69
|
+
uri = URI.parse(str)
|
70
|
+
assert_kind_of( URI::File, uri )
|
71
|
+
assert_equal( path, uri.path )
|
72
|
+
assert_equal( host, uri.host )
|
73
|
+
|
74
|
+
assert_equal( false, uri.local?(localhost: false) )
|
75
|
+
assert_equal( false, uri.local?(localhost: true) )
|
76
|
+
assert_equal( false, uri.local? )
|
77
|
+
|
78
|
+
assert_raise(RuntimeError) { uri.to_file_path(localhost: false) }
|
79
|
+
assert_raise(RuntimeError) { uri.to_file_path(localhost: true) }
|
80
|
+
assert_raise(RuntimeError) { uri.to_file_path }
|
81
|
+
|
82
|
+
assert_equal( unc, uri.to_unc(localhost: false) )
|
83
|
+
assert_equal( unc, uri.to_unc(localhost: true) )
|
84
|
+
assert_equal( unc, uri.to_unc )
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# 'file' URIs that are valid and use the "localhost" authority
|
89
|
+
# (i.e. sometimes local, sometimes non-local)
|
90
|
+
def test_valid_localhost_uris
|
91
|
+
[
|
92
|
+
['file://localhost/path/to/file', '/path/to/file', '\\\\localhost\\path\\to\\file', '/path/to/file'],
|
93
|
+
['file://localhost/c:/path/to/file', '/c:/path/to/file', '\\\\localhost\\c:\\path\\to\\file', 'c:/path/to/file'], # FIXME - bad spec in UNC
|
94
|
+
['file://localhost/path/to:file', '/path/to:file', '\\\\localhost\\path\\to:file', "/path/to\u{F03A}file"],
|
95
|
+
].each do |str, path, unc, file|
|
96
|
+
uri = URI.parse(str)
|
97
|
+
assert_kind_of( URI::File, uri )
|
98
|
+
assert_equal( path, uri.path )
|
99
|
+
|
100
|
+
assert_equal( false, uri.local?(localhost: false) )
|
101
|
+
assert_equal( true, uri.local?(localhost: true) )
|
102
|
+
assert_equal( true, uri.local? )
|
103
|
+
|
104
|
+
assert_raise(RuntimeError) { uri.to_file_path(localhost: false) }
|
105
|
+
assert_equal( file, uri.to_file_path(localhost: true) )
|
106
|
+
assert_equal( file, uri.to_file_path )
|
107
|
+
|
108
|
+
assert_equal( unc, uri.to_unc(localhost: false) )
|
109
|
+
assert_raise(RuntimeError) { uri.to_unc(localhost: true) }
|
110
|
+
assert_raise(RuntimeError) { uri.to_unc }
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
metadata
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: file-uri
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Matthew Kerwin
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-12-06 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: |
|
14
|
+
== file-uri – the "file" URI Scheme
|
15
|
+
|
16
|
+
Adds explicit handling for 'file' URIs to the 'uri' library.
|
17
|
+
|
18
|
+
See the documentation at http://phluid61.github.io/file-uri/
|
19
|
+
email:
|
20
|
+
- matthew@kerwin.net.au
|
21
|
+
executables: []
|
22
|
+
extensions: []
|
23
|
+
extra_rdoc_files: []
|
24
|
+
files:
|
25
|
+
- lib/file-uri-common.rb
|
26
|
+
- lib/file-uri.rb
|
27
|
+
- lib/file-uri/win.rb
|
28
|
+
- test/test-file-uri.rb
|
29
|
+
- test/test-win-file-uri.rb
|
30
|
+
homepage: http://phluid61.github.com/file-uri
|
31
|
+
licenses:
|
32
|
+
- ISC
|
33
|
+
metadata: {}
|
34
|
+
post_install_message:
|
35
|
+
rdoc_options: []
|
36
|
+
require_paths:
|
37
|
+
- lib
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
requirements: []
|
49
|
+
rubyforge_project:
|
50
|
+
rubygems_version: 2.6.7
|
51
|
+
signing_key:
|
52
|
+
specification_version: 4
|
53
|
+
summary: 'file-uri : the "file" URI Scheme'
|
54
|
+
test_files:
|
55
|
+
- test/test-win-file-uri.rb
|
56
|
+
- test/test-file-uri.rb
|