file-uri 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|