rack_dav 0.4.1 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/Dockerfile +13 -0
- data/README.md +7 -47
- data/config.ru +14 -0
- data/lib/rack_dav/controller.rb +21 -13
- data/lib/rack_dav/file_resource.rb +2 -24
- data/lib/rack_dav/handler.rb +9 -1
- data/lib/rack_dav/version.rb +1 -1
- data/lib/rack_dav.rb +0 -1
- data/rack_dav.gemspec +6 -4
- data/spec/controller_spec.rb +166 -151
- metadata +69 -29
- data/Gemfile.lock +0 -39
- data/bin/rack_dav +0 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3f5efaaf9d78cffb9459cce4b8ff84610ae9a480303d23e0266cbd8ec351603b
|
4
|
+
data.tar.gz: 817e1db4fcb91c2fa26e8be1e32074c466c8aa6c7631237b73bd9e61c6316804
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b827c9616a9c8a106bdd0bb2dce19e944f9a21932f0686b6ce51a58307094c88d449e1673d611769c1dce28e1fdb460770eeff4351b235aa30718bf7d0cad665
|
7
|
+
data.tar.gz: 33c156ccecb968a88d8d38435b9d95a65245de4abce448dc0d987f83cf5f355ec4289c823be5340bf5e333bcf99622bd908be9f9dee1fafab79e82cd0cf21289
|
data/Dockerfile
ADDED
data/README.md
CHANGED
@@ -2,30 +2,17 @@
|
|
2
2
|
RackDAV - Web Authoring for Rack
|
3
3
|
---
|
4
4
|
|
5
|
-
RackDAV is
|
6
|
-
HTTP. RackDAV brings its own file backend, but other backends are
|
7
|
-
possible by subclassing RackDAV::Resource.
|
8
|
-
|
9
|
-
## Install
|
10
|
-
|
11
|
-
Just install the gem from RubyGems:
|
12
|
-
|
13
|
-
$ gem install rack_dav
|
5
|
+
RackDAV is a Ruby gem that allows you to use the WebDAV protocol to edit and manage files over HTTP. It comes with its own file backend, but you can also create your own backend by subclassing RackDAV::Resource.
|
14
6
|
|
15
7
|
## Quickstart
|
16
8
|
|
17
|
-
|
18
|
-
simple server with:
|
19
|
-
|
20
|
-
$ rack_dav
|
9
|
+
To install the gem, run `gem install rack_dav`.
|
21
10
|
|
22
|
-
This will start a
|
23
|
-
to without authentication.
|
11
|
+
To quickly test out RackDAV, copy the config.ru file from this repository and run `bundle exec rackup`. This will start a web server on a default port that you can connect to without any authentication.
|
24
12
|
|
25
13
|
## Rack Handler
|
26
14
|
|
27
|
-
|
28
|
-
script looks like this:
|
15
|
+
To use RackDAV in your own rack application, include the following in your config.ru file:
|
29
16
|
|
30
17
|
require 'rubygems'
|
31
18
|
require 'rack_dav'
|
@@ -36,18 +23,7 @@ script looks like this:
|
|
36
23
|
|
37
24
|
## Implementing your own WebDAV resource
|
38
25
|
|
39
|
-
|
40
|
-
for accessing resources.
|
41
|
-
|
42
|
-
Each resource will be initialized with a path, which should be used to
|
43
|
-
find the real resource.
|
44
|
-
|
45
|
-
RackDAV::Handler needs to be initialized with the actual resource class:
|
46
|
-
|
47
|
-
RackDAV::Handler.new(:resource_class => MyResource)
|
48
|
-
|
49
|
-
RackDAV needs some information about the resources, so you have to
|
50
|
-
implement following methods:
|
26
|
+
If you want to create your own WebDAV resource, you will need to subclass RackDAV::Resource and implement the following methods:
|
51
27
|
|
52
28
|
* __children__: If this is a collection, return the child resources.
|
53
29
|
|
@@ -67,10 +43,6 @@ implement following methods:
|
|
67
43
|
|
68
44
|
* __content\_length__: Return the size in bytes for this resource.
|
69
45
|
|
70
|
-
|
71
|
-
Most importantly you have to implement the actions, which are called
|
72
|
-
to retrieve and change the resources:
|
73
|
-
|
74
46
|
* __get(request, response)__: Write the content of the resource to the response.body.
|
75
47
|
|
76
48
|
* __put(request, response)__: Save the content of the request.body.
|
@@ -94,18 +66,6 @@ to retrieve and change the resources:
|
|
94
66
|
|
95
67
|
* __unlock(token)__: Unlock this resource
|
96
68
|
|
97
|
-
Note
|
98
|
-
instantiated for a not yet existing resource.
|
99
|
-
|
100
|
-
For inspiration you should have a look at the FileResource
|
101
|
-
implementation. Please let me now, if you are going to implement a new
|
102
|
-
type of resource.
|
103
|
-
|
104
|
-
|
105
|
-
### RackDAV on GitHub
|
106
|
-
|
107
|
-
Download or fork the project on its [Github page][2]
|
108
|
-
|
69
|
+
Note that it is possible that a resource object may be instantiated for a resource that does not yet exist.
|
109
70
|
|
110
|
-
|
111
|
-
[2]: http://github.com/georgi/rack_dav
|
71
|
+
For more examples and inspiration, you can look at the FileResource implementation.
|
data/config.ru
ADDED
data/lib/rack_dav/controller.rb
CHANGED
@@ -9,6 +9,8 @@ module RackDAV
|
|
9
9
|
|
10
10
|
attr_reader :request, :response, :resource
|
11
11
|
|
12
|
+
@@uri = URI::RFC2396_Parser.new
|
13
|
+
|
12
14
|
def initialize(request, response, options)
|
13
15
|
@request = request
|
14
16
|
@response = response
|
@@ -18,11 +20,11 @@ module RackDAV
|
|
18
20
|
end
|
19
21
|
|
20
22
|
def url_escape(s)
|
21
|
-
|
23
|
+
@@uri.escape(s)
|
22
24
|
end
|
23
25
|
|
24
26
|
def url_unescape(s)
|
25
|
-
|
27
|
+
@@uri.unescape(s).force_valid_encoding
|
26
28
|
end
|
27
29
|
|
28
30
|
def options
|
@@ -61,7 +63,7 @@ module RackDAV
|
|
61
63
|
map_exceptions do
|
62
64
|
resource.put
|
63
65
|
end
|
64
|
-
response.status = Created
|
66
|
+
response.status = Created.to_i
|
65
67
|
end
|
66
68
|
|
67
69
|
def post
|
@@ -76,7 +78,7 @@ module RackDAV
|
|
76
78
|
delete_recursive(resource, errors = [])
|
77
79
|
|
78
80
|
if errors.empty?
|
79
|
-
response.status = NoContent
|
81
|
+
response.status = NoContent.to_i
|
80
82
|
else
|
81
83
|
multistatus do |xml|
|
82
84
|
response_errors(xml, errors)
|
@@ -92,14 +94,14 @@ module RackDAV
|
|
92
94
|
map_exceptions do
|
93
95
|
resource.make_collection
|
94
96
|
end
|
95
|
-
response.status = Created
|
97
|
+
response.status = Created.to_i
|
96
98
|
end
|
97
99
|
|
98
100
|
def copy
|
99
101
|
raise NotFound if not resource.exist?
|
100
102
|
|
101
103
|
dest_uri = URI.parse(env['HTTP_DESTINATION'])
|
102
|
-
destination =
|
104
|
+
destination = parse_destination(dest_uri)
|
103
105
|
|
104
106
|
raise BadGateway if dest_uri.host and dest_uri.host != request.host
|
105
107
|
raise Forbidden if destination == resource.path
|
@@ -114,7 +116,7 @@ module RackDAV
|
|
114
116
|
copy_recursive(resource, dest, depth, errors = [])
|
115
117
|
|
116
118
|
if errors.empty?
|
117
|
-
response.status = dest_existed ? NoContent : Created
|
119
|
+
response.status = dest_existed ? NoContent.to_i : Created.to_i
|
118
120
|
else
|
119
121
|
multistatus do |xml|
|
120
122
|
response_errors(xml, errors)
|
@@ -128,7 +130,7 @@ module RackDAV
|
|
128
130
|
raise NotFound if not resource.exist?
|
129
131
|
|
130
132
|
dest_uri = URI.parse(env['HTTP_DESTINATION'])
|
131
|
-
destination =
|
133
|
+
destination = parse_destination(dest_uri)
|
132
134
|
|
133
135
|
raise BadGateway if dest_uri.host and dest_uri.host != request.host
|
134
136
|
raise Forbidden if destination == resource.path
|
@@ -145,7 +147,7 @@ module RackDAV
|
|
145
147
|
delete_recursive(resource, errors)
|
146
148
|
|
147
149
|
if errors.empty?
|
148
|
-
response.status = dest_existed ? NoContent : Created
|
150
|
+
response.status = dest_existed ? NoContent.to_i : Created.to_i
|
149
151
|
else
|
150
152
|
multistatus do |xml|
|
151
153
|
response_errors(xml, errors)
|
@@ -185,7 +187,7 @@ module RackDAV
|
|
185
187
|
for resource in find_resources
|
186
188
|
resource.path.gsub!(/\/\//, '/')
|
187
189
|
xml.response do
|
188
|
-
xml.href "http://#{host}#{url_escape resource.path}"
|
190
|
+
xml.href "http://#{host}#{@request.script_name}#{url_escape resource.path}"
|
189
191
|
propstats xml, get_properties(resource, nodes)
|
190
192
|
end
|
191
193
|
end
|
@@ -212,7 +214,7 @@ module RackDAV
|
|
212
214
|
multistatus do |xml|
|
213
215
|
for resource in find_resources
|
214
216
|
xml.response do
|
215
|
-
xml.href "http://#{host}#{resource.path}"
|
217
|
+
xml.href "http://#{host}#{@request.script_name}#{resource.path}"
|
216
218
|
propstats xml, set_properties(resource, nodes)
|
217
219
|
end
|
218
220
|
end
|
@@ -241,7 +243,7 @@ module RackDAV
|
|
241
243
|
locktoken = request_locktoken('LOCK_TOKEN')
|
242
244
|
raise BadRequest if locktoken.nil?
|
243
245
|
|
244
|
-
response.status = resource.unlock(locktoken) ? NoContent : Forbidden
|
246
|
+
response.status = resource.unlock(locktoken) ? NoContent.to_i : Forbidden.to_i
|
245
247
|
end
|
246
248
|
|
247
249
|
private
|
@@ -251,7 +253,7 @@ module RackDAV
|
|
251
253
|
end
|
252
254
|
|
253
255
|
def host
|
254
|
-
|
256
|
+
@request.host
|
255
257
|
end
|
256
258
|
|
257
259
|
def resource_class
|
@@ -552,6 +554,12 @@ module RackDAV
|
|
552
554
|
end
|
553
555
|
end
|
554
556
|
|
557
|
+
def parse_destination dest_uri
|
558
|
+
destination = url_unescape(dest_uri.path)
|
559
|
+
destination.slice!(1..@request.script_name.length) if @request.script_name.length > 0
|
560
|
+
destination
|
561
|
+
end
|
562
|
+
|
555
563
|
end
|
556
564
|
|
557
565
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'digest'
|
2
|
-
require '
|
2
|
+
require 'webrick/httputils'
|
3
3
|
|
4
4
|
module RackDAV
|
5
5
|
|
@@ -66,26 +66,8 @@ module RackDAV
|
|
66
66
|
stat.size
|
67
67
|
end
|
68
68
|
|
69
|
-
def set_custom_property(name, value)
|
70
|
-
if value.nil? || value.empty?
|
71
|
-
begin
|
72
|
-
xattr.remove("rack_dav:#{name}")
|
73
|
-
rescue Errno::ENOATTR
|
74
|
-
# If the attribute being deleted doesn't exist, just do nothing
|
75
|
-
end
|
76
|
-
else
|
77
|
-
xattr["rack_dav:#{name}"] = value
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def get_custom_property(name)
|
82
|
-
value = xattr["rack_dav:#{name}"]
|
83
|
-
raise HTTPStatus::NotFound if value.nil?
|
84
|
-
value
|
85
|
-
end
|
86
|
-
|
87
69
|
def list_custom_properties
|
88
|
-
|
70
|
+
[]
|
89
71
|
end
|
90
72
|
|
91
73
|
# HTTP GET request.
|
@@ -194,10 +176,6 @@ module RackDAV
|
|
194
176
|
@stat ||= File.stat(file_path)
|
195
177
|
end
|
196
178
|
|
197
|
-
def xattr
|
198
|
-
@xattr ||= Xattr.new(file_path)
|
199
|
-
end
|
200
|
-
|
201
179
|
def content_md5_pass?(env)
|
202
180
|
expected = env['HTTP_CONTENT_MD5'] or return true
|
203
181
|
|
data/lib/rack_dav/handler.rb
CHANGED
@@ -6,6 +6,9 @@ module RackDAV
|
|
6
6
|
attr_reader :options
|
7
7
|
|
8
8
|
|
9
|
+
ALLOWED_METHODS = %w(GET PUT POST DELETE PROPFIND PROPPATCH MKCOL COPY MOVE OPTIONS HEAD LOCK UNLOCK)
|
10
|
+
|
11
|
+
|
9
12
|
# Initializes a new instance with given options.
|
10
13
|
#
|
11
14
|
# @param [Hash] options Hash of options to customize the handler behavior.
|
@@ -27,7 +30,12 @@ module RackDAV
|
|
27
30
|
|
28
31
|
begin
|
29
32
|
controller = Controller.new(request, response, @options)
|
30
|
-
|
33
|
+
if ALLOWED_METHODS.include?(request.request_method)
|
34
|
+
controller.send(request.request_method.downcase)
|
35
|
+
else
|
36
|
+
response.status = 405
|
37
|
+
response['Allow'] = ALLOWED_METHODS.join(', ')
|
38
|
+
end
|
31
39
|
|
32
40
|
rescue HTTPStatus::Status => status
|
33
41
|
response.status = status.code
|
data/lib/rack_dav/version.rb
CHANGED
data/lib/rack_dav.rb
CHANGED
data/rack_dav.gemspec
CHANGED
@@ -13,14 +13,16 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.license = "MIT"
|
14
14
|
|
15
15
|
s.files = `git ls-files`.split("\n")
|
16
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
16
|
s.require_paths = ["lib"]
|
18
17
|
|
19
18
|
s.extra_rdoc_files = ["README.md"]
|
20
19
|
|
21
|
-
s.add_dependency("rack", "~>
|
20
|
+
s.add_dependency("rack", "~> 3.0.0")
|
21
|
+
s.add_dependency("rackup", "~> 0.2.3")
|
22
|
+
s.add_dependency("rexml", "~> 3.2.4")
|
22
23
|
s.add_dependency('nokogiri', "~> 1.5")
|
23
|
-
s.add_dependency(
|
24
|
+
s.add_dependency('webrick', "~> 1.3")
|
25
|
+
s.add_dependency('puma', "~> 6.0")
|
24
26
|
s.add_development_dependency("rspec", "~> 2.11")
|
25
|
-
s.add_development_dependency("rake","~> 0
|
27
|
+
s.add_development_dependency("rake","~> 13.0")
|
26
28
|
end
|
data/spec/controller_spec.rb
CHANGED
@@ -40,30 +40,25 @@ describe RackDAV::Handler do
|
|
40
40
|
CLASS_1 = CLASS_2 - %w(LOCK UNLOCK)
|
41
41
|
|
42
42
|
before do
|
43
|
-
FileUtils.mkdir(DOC_ROOT) unless File.
|
43
|
+
FileUtils.mkdir(DOC_ROOT) unless File.exist?(DOC_ROOT)
|
44
44
|
end
|
45
45
|
|
46
46
|
after do
|
47
|
-
FileUtils.rm_rf(DOC_ROOT) if File.
|
47
|
+
FileUtils.rm_rf(DOC_ROOT) if File.exist?(DOC_ROOT)
|
48
48
|
end
|
49
49
|
|
50
50
|
attr_reader :response
|
51
51
|
|
52
|
-
|
53
|
-
|
54
|
-
@controller = RackDAV::Handler.new(
|
55
|
-
:root => DOC_ROOT,
|
56
|
-
:resource_class => RackDAV::LockableFileResource
|
57
|
-
)
|
58
|
-
end
|
52
|
+
shared_examples :lockable_resource do
|
53
|
+
|
59
54
|
|
60
55
|
describe "OPTIONS" do
|
61
56
|
it "is successful" do
|
62
|
-
options(
|
57
|
+
options(url_root).should be_ok
|
63
58
|
end
|
64
59
|
|
65
60
|
it "sets the allow header with class 2 methods" do
|
66
|
-
options(
|
61
|
+
options(url_root)
|
67
62
|
CLASS_2.each do |method|
|
68
63
|
response.headers['allow'].should include(method)
|
69
64
|
end
|
@@ -72,8 +67,8 @@ describe RackDAV::Handler do
|
|
72
67
|
|
73
68
|
describe "LOCK" do
|
74
69
|
before(:each) do
|
75
|
-
put(
|
76
|
-
lock(
|
70
|
+
put(url_root + 'test', :input => "body").should be_created
|
71
|
+
lock(url_root + 'test', :input => File.read(fixture("requests/lock.xml")))
|
77
72
|
end
|
78
73
|
|
79
74
|
describe "creation" do
|
@@ -96,26 +91,26 @@ describe RackDAV::Handler do
|
|
96
91
|
context "a valid locktoken" do
|
97
92
|
it "prints the lockdiscovery" do
|
98
93
|
token = response_locktoken
|
99
|
-
lock(
|
94
|
+
lock(url_root + 'test', 'HTTP_IF' => "(#{token})").should be_ok
|
100
95
|
lockdiscovery_response token
|
101
96
|
end
|
102
97
|
|
103
98
|
it "accepts it without parenthesis" do
|
104
99
|
token = response_locktoken
|
105
|
-
lock(
|
100
|
+
lock(url_root + 'test', 'HTTP_IF' => token).should be_ok
|
106
101
|
lockdiscovery_response token
|
107
102
|
end
|
108
103
|
|
109
104
|
it "accepts it with excess angular braces (office 2003)" do
|
110
105
|
token = response_locktoken
|
111
|
-
lock(
|
106
|
+
lock(url_root + 'test', 'HTTP_IF' => "(<#{token}>)").should be_ok
|
112
107
|
lockdiscovery_response token
|
113
108
|
end
|
114
109
|
end
|
115
110
|
|
116
111
|
context "an invalid locktoken" do
|
117
112
|
it "bails out" do
|
118
|
-
lock(
|
113
|
+
lock(url_root + 'test', 'HTTP_IF' => '123')
|
119
114
|
response.should be_forbidden
|
120
115
|
response.body.should be_empty
|
121
116
|
end
|
@@ -123,7 +118,7 @@ describe RackDAV::Handler do
|
|
123
118
|
|
124
119
|
context "no locktoken" do
|
125
120
|
it "bails out" do
|
126
|
-
lock(
|
121
|
+
lock(url_root + 'test')
|
127
122
|
response.should be_bad_request
|
128
123
|
response.body.should be_empty
|
129
124
|
end
|
@@ -134,14 +129,14 @@ describe RackDAV::Handler do
|
|
134
129
|
|
135
130
|
describe "UNLOCK" do
|
136
131
|
before(:each) do
|
137
|
-
put(
|
138
|
-
lock(
|
132
|
+
put(url_root + 'test', :input => "body").should be_created
|
133
|
+
lock(url_root + 'test', :input => File.read(fixture("requests/lock.xml"))).should be_ok
|
139
134
|
end
|
140
135
|
|
141
136
|
context "given a valid token" do
|
142
137
|
before(:each) do
|
143
138
|
token = response_locktoken
|
144
|
-
unlock(
|
139
|
+
unlock(url_root + 'test', 'HTTP_LOCK_TOKEN' => "(#{token})")
|
145
140
|
end
|
146
141
|
|
147
142
|
it "unlocks the resource" do
|
@@ -151,7 +146,7 @@ describe RackDAV::Handler do
|
|
151
146
|
|
152
147
|
context "given an invalid token" do
|
153
148
|
before(:each) do
|
154
|
-
unlock(
|
149
|
+
unlock(url_root + 'test', 'HTTP_LOCK_TOKEN' => '(123)')
|
155
150
|
end
|
156
151
|
|
157
152
|
it "bails out" do
|
@@ -161,7 +156,7 @@ describe RackDAV::Handler do
|
|
161
156
|
|
162
157
|
context "given no token" do
|
163
158
|
before(:each) do
|
164
|
-
unlock(
|
159
|
+
unlock(url_root + 'test')
|
165
160
|
end
|
166
161
|
|
167
162
|
it "bails out" do
|
@@ -172,33 +167,55 @@ describe RackDAV::Handler do
|
|
172
167
|
end
|
173
168
|
end
|
174
169
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
170
|
+
|
171
|
+
context "Given a Lockable resource" do
|
172
|
+
context "when mounted directly" do
|
173
|
+
before do
|
174
|
+
@controller = RackDAV::Handler.new(
|
175
|
+
:root => DOC_ROOT,
|
176
|
+
:resource_class => RackDAV::LockableFileResource
|
177
|
+
)
|
178
|
+
end
|
179
|
+
|
180
|
+
let(:url_root){ '/' }
|
181
|
+
include_examples :lockable_resource
|
181
182
|
end
|
182
183
|
|
184
|
+
context "When mounted via a URLMap" do
|
185
|
+
before do
|
186
|
+
@controller = Rack::URLMap.new(
|
187
|
+
"/dav" => RackDAV::Handler.new(
|
188
|
+
:root => DOC_ROOT,
|
189
|
+
:resource_class => RackDAV::LockableFileResource
|
190
|
+
)
|
191
|
+
)
|
192
|
+
end
|
193
|
+
|
194
|
+
let(:url_root){ '/dav/' }
|
195
|
+
include_examples :lockable_resource
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
shared_examples :not_lockable_resource do
|
183
200
|
describe "uri escaping" do
|
184
201
|
it "allows url escaped utf-8" do
|
185
|
-
put('
|
186
|
-
get('
|
202
|
+
put(url_root + 'D%C3%B6ner').should be_created
|
203
|
+
get(url_root + 'D%C3%B6ner').should be_ok
|
187
204
|
end
|
188
205
|
|
189
206
|
it "allows url escaped iso-8859" do
|
190
|
-
put('
|
191
|
-
get('
|
207
|
+
put(url_root + 'D%F6ner').should be_created
|
208
|
+
get(url_root + 'D%F6ner').should be_ok
|
192
209
|
end
|
193
210
|
end
|
194
211
|
|
195
212
|
describe "OPTIONS" do
|
196
213
|
it "is successful" do
|
197
|
-
options(
|
214
|
+
options(url_root).should be_ok
|
198
215
|
end
|
199
216
|
|
200
217
|
it "sets the allow header with class 2 methods" do
|
201
|
-
options(
|
218
|
+
options(url_root)
|
202
219
|
CLASS_1.each do |method|
|
203
220
|
response.headers['allow'].should include(method)
|
204
221
|
end
|
@@ -208,8 +225,8 @@ describe RackDAV::Handler do
|
|
208
225
|
describe "CONTENT-MD5 header exists" do
|
209
226
|
context "doesn't match with body's checksum" do
|
210
227
|
before do
|
211
|
-
put('
|
212
|
-
|
228
|
+
put(url_root + 'foo', :input => 'bar',
|
229
|
+
'HTTP_CONTENT_MD5' => 'baz')
|
213
230
|
end
|
214
231
|
|
215
232
|
it 'should return a Bad Request response' do
|
@@ -217,14 +234,14 @@ describe RackDAV::Handler do
|
|
217
234
|
end
|
218
235
|
|
219
236
|
it 'should not create the resource' do
|
220
|
-
get('
|
237
|
+
get(url_root + 'foo').should be_not_found
|
221
238
|
end
|
222
239
|
end
|
223
240
|
|
224
241
|
context "matches with body's checksum" do
|
225
242
|
before do
|
226
|
-
put('
|
227
|
-
|
243
|
+
put(url_root + 'foo', :input => 'bar',
|
244
|
+
'HTTP_CONTENT_MD5' => 'N7UdGUp1E+RbVvZSTy1R8g==')
|
228
245
|
end
|
229
246
|
|
230
247
|
it 'should be successful' do
|
@@ -232,15 +249,15 @@ describe RackDAV::Handler do
|
|
232
249
|
end
|
233
250
|
|
234
251
|
it 'should create the resource' do
|
235
|
-
get('
|
252
|
+
get(url_root + 'foo').should be_ok
|
236
253
|
response.body.should == 'bar'
|
237
254
|
end
|
238
255
|
end
|
239
256
|
end
|
240
257
|
|
241
258
|
it 'should return headers' do
|
242
|
-
put('
|
243
|
-
head('
|
259
|
+
put(url_root + 'test.html', :input => '<html/>').should be_created
|
260
|
+
head(url_root + 'test.html').should be_ok
|
244
261
|
|
245
262
|
response.headers['etag'].should_not be_nil
|
246
263
|
response.headers['content-type'].should match(/html/)
|
@@ -249,147 +266,148 @@ describe RackDAV::Handler do
|
|
249
266
|
|
250
267
|
|
251
268
|
it 'should not find a nonexistent resource' do
|
252
|
-
get('
|
269
|
+
get(url_root + 'not_found').should be_not_found
|
253
270
|
end
|
254
271
|
|
255
272
|
it 'should not allow directory traversal' do
|
256
|
-
get('
|
273
|
+
get(url_root + '../htdocs').should be_forbidden
|
257
274
|
end
|
258
275
|
|
259
276
|
it 'should create a resource and allow its retrieval' do
|
260
|
-
put('
|
261
|
-
get('
|
277
|
+
put(url_root + 'test', :input => 'body').should be_created
|
278
|
+
get(url_root + 'test').should be_ok
|
262
279
|
response.body.should == 'body'
|
263
280
|
end
|
281
|
+
|
264
282
|
it 'should create and find a url with escaped characters' do
|
265
|
-
put(url_escape('/a b'), :input => 'body').should be_created
|
266
|
-
get(url_escape('/a b')).should be_ok
|
283
|
+
put(url_root + url_escape('/a b'), :input => 'body').should be_created
|
284
|
+
get(url_root + url_escape('/a b')).should be_ok
|
267
285
|
response.body.should == 'body'
|
268
286
|
end
|
269
287
|
|
270
288
|
it 'should delete a single resource' do
|
271
|
-
put('
|
272
|
-
delete('
|
289
|
+
put(url_root + 'test', :input => 'body').should be_created
|
290
|
+
delete(url_root + 'test').should be_no_content
|
273
291
|
end
|
274
292
|
|
275
293
|
it 'should delete recursively' do
|
276
|
-
mkcol('
|
277
|
-
put('
|
278
|
-
put('
|
294
|
+
mkcol(url_root + 'folder').should be_created
|
295
|
+
put(url_root + 'folder/a', :input => 'body').should be_created
|
296
|
+
put(url_root + 'folder/b', :input => 'body').should be_created
|
279
297
|
|
280
|
-
delete('
|
281
|
-
get('
|
282
|
-
get('
|
283
|
-
get('
|
298
|
+
delete(url_root + 'folder').should be_no_content
|
299
|
+
get(url_root + 'folder').should be_not_found
|
300
|
+
get(url_root + 'folder/a').should be_not_found
|
301
|
+
get(url_root + 'folder/b').should be_not_found
|
284
302
|
end
|
285
303
|
|
286
304
|
it 'should return not found when deleting a non-existent resource' do
|
287
|
-
delete('
|
305
|
+
delete(url_root + 'not_found').should be_not_found
|
288
306
|
end
|
289
307
|
|
290
308
|
it 'should not allow copy to another domain' do
|
291
|
-
put('
|
292
|
-
copy('http://
|
309
|
+
put(url_root + 'test', :input => 'body').should be_created
|
310
|
+
copy('http://example.org' + url_root, 'HTTP_DESTINATION' => 'http://another/').should be_bad_gateway
|
293
311
|
end
|
294
312
|
|
295
313
|
it 'should not allow copy to the same resource' do
|
296
|
-
put('
|
297
|
-
copy('
|
314
|
+
put(url_root + 'test', :input => 'body').should be_created
|
315
|
+
copy(url_root + 'test', 'HTTP_DESTINATION' => url_root + 'test').should be_forbidden
|
298
316
|
end
|
299
317
|
|
300
318
|
it 'should not allow an invalid destination uri' do
|
301
|
-
put('
|
302
|
-
copy('
|
319
|
+
put(url_root + 'test', :input => 'body').should be_created
|
320
|
+
copy(url_root + 'test', 'HTTP_DESTINATION' => '%').should be_bad_request
|
303
321
|
end
|
304
322
|
|
305
323
|
it 'should copy a single resource' do
|
306
|
-
put('
|
307
|
-
copy('
|
308
|
-
get('
|
324
|
+
put(url_root + 'test', :input => 'body').should be_created
|
325
|
+
copy(url_root + 'test', 'HTTP_DESTINATION' => url_root + 'copy').should be_created
|
326
|
+
get(url_root + 'copy').body.should == 'body'
|
309
327
|
end
|
310
328
|
|
311
329
|
it 'should copy a resource with escaped characters' do
|
312
|
-
put(url_escape('/a b'), :input => 'body').should be_created
|
313
|
-
copy(url_escape('/a b'), 'HTTP_DESTINATION' => url_escape('/a c')).should be_created
|
314
|
-
get(url_escape('/a c')).should be_ok
|
330
|
+
put(url_root + url_escape('/a b'), :input => 'body').should be_created
|
331
|
+
copy(url_root + url_escape('/a b'), 'HTTP_DESTINATION' => url_root + url_escape('/a c')).should be_created
|
332
|
+
get(url_root + url_escape('/a c')).should be_ok
|
315
333
|
response.body.should == 'body'
|
316
334
|
end
|
317
335
|
|
318
336
|
it 'should deny a copy without overwrite' do
|
319
|
-
put('
|
320
|
-
put('
|
321
|
-
copy('
|
337
|
+
put(url_root + 'test', :input => 'body').should be_created
|
338
|
+
put(url_root + 'copy', :input => 'copy').should be_created
|
339
|
+
copy(url_root + 'test', 'HTTP_DESTINATION' => url_root + 'copy', 'HTTP_OVERWRITE' => 'F').should be_precondition_failed
|
322
340
|
|
323
|
-
get('
|
341
|
+
get(url_root + 'copy').body.should == 'copy'
|
324
342
|
end
|
325
343
|
|
326
344
|
it 'should allow a copy with overwrite' do
|
327
|
-
put('
|
328
|
-
put('
|
329
|
-
copy('
|
330
|
-
get('
|
345
|
+
put(url_root + 'test', :input => 'body').should be_created
|
346
|
+
put(url_root + 'copy', :input => 'copy').should be_created
|
347
|
+
copy(url_root + 'test', 'HTTP_DESTINATION' => url_root + 'copy', 'HTTP_OVERWRITE' => 'T').should be_no_content
|
348
|
+
get(url_root + 'copy').body.should == 'body'
|
331
349
|
end
|
332
350
|
|
333
351
|
it 'should deny a move to an existing resource without overwrite' do
|
334
|
-
put('
|
335
|
-
put('
|
336
|
-
move('
|
352
|
+
put(url_root + 'test', :input => 'body').should be_created
|
353
|
+
put(url_root + 'copy', :input => 'copy').should be_created
|
354
|
+
move(url_root + 'test', 'HTTP_DESTINATION' => url_root + 'copy', 'HTTP_OVERWRITE' => 'F').should be_precondition_failed
|
337
355
|
end
|
338
356
|
|
339
357
|
it 'should copy a collection' do
|
340
|
-
mkcol('
|
341
|
-
copy('
|
342
|
-
propfind('
|
358
|
+
mkcol(url_root + 'folder').should be_created
|
359
|
+
copy(url_root + 'folder', 'HTTP_DESTINATION' => url_root + 'copy').should be_created
|
360
|
+
propfind(url_root + 'copy', :input => propfind_xml(:resourcetype))
|
343
361
|
multistatus_response('/d:propstat/d:prop/d:resourcetype/d:collection').should_not be_empty
|
344
362
|
end
|
345
363
|
|
346
364
|
it 'should copy a collection resursively' do
|
347
|
-
mkcol('
|
348
|
-
put('
|
349
|
-
put('
|
365
|
+
mkcol(url_root + 'folder').should be_created
|
366
|
+
put(url_root + 'folder/a', :input => 'A').should be_created
|
367
|
+
put(url_root + 'folder/b', :input => 'B').should be_created
|
350
368
|
|
351
|
-
copy('
|
352
|
-
propfind('
|
369
|
+
copy(url_root + 'folder', 'HTTP_DESTINATION' => url_root + 'copy').should be_created
|
370
|
+
propfind(url_root + 'copy', :input => propfind_xml(:resourcetype))
|
353
371
|
multistatus_response('/d:propstat/d:prop/d:resourcetype/d:collection').should_not be_empty
|
354
372
|
|
355
|
-
get('
|
356
|
-
get('
|
373
|
+
get(url_root + 'copy/a').body.should == 'A'
|
374
|
+
get(url_root + 'copy/b').body.should == 'B'
|
357
375
|
end
|
358
376
|
|
359
377
|
it 'should move a collection recursively' do
|
360
|
-
mkcol('
|
361
|
-
put('
|
362
|
-
put('
|
378
|
+
mkcol(url_root + 'folder').should be_created
|
379
|
+
put(url_root + 'folder/a', :input => 'A').should be_created
|
380
|
+
put(url_root + 'folder/b', :input => 'B').should be_created
|
363
381
|
|
364
|
-
move('
|
365
|
-
propfind('
|
382
|
+
move(url_root + 'folder', 'HTTP_DESTINATION' => url_root + 'move').should be_created
|
383
|
+
propfind(url_root + 'move', :input => propfind_xml(:resourcetype))
|
366
384
|
multistatus_response('/d:propstat/d:prop/d:resourcetype/d:collection').should_not be_empty
|
367
385
|
|
368
|
-
get('
|
369
|
-
get('
|
370
|
-
get('
|
371
|
-
get('
|
386
|
+
get(url_root + 'move/a').body.should == 'A'
|
387
|
+
get(url_root + 'move/b').body.should == 'B'
|
388
|
+
get(url_root + 'folder/a').should be_not_found
|
389
|
+
get(url_root + 'folder/b').should be_not_found
|
372
390
|
end
|
373
391
|
|
374
392
|
it 'should not move a collection onto an existing collection without overwrite' do
|
375
|
-
mkcol('
|
376
|
-
mkcol('
|
393
|
+
mkcol(url_root + 'folder').should be_created
|
394
|
+
mkcol(url_root + 'dest').should be_created
|
377
395
|
|
378
|
-
move('
|
396
|
+
move(url_root + 'folder', 'HTTP_DESTINATION' => url_root + 'dest', 'HTTP_OVERWRITE' => 'F').should be_precondition_failed
|
379
397
|
end
|
380
398
|
|
381
399
|
it 'should create a collection' do
|
382
|
-
mkcol('
|
383
|
-
propfind('
|
400
|
+
mkcol(url_root + 'folder').should be_created
|
401
|
+
propfind(url_root + 'folder', :input => propfind_xml(:resourcetype))
|
384
402
|
multistatus_response('/d:propstat/d:prop/d:resourcetype/d:collection').should_not be_empty
|
385
403
|
end
|
386
404
|
|
387
405
|
it 'should not create a collection with a body' do
|
388
|
-
mkcol('
|
406
|
+
mkcol(url_root + 'folder', :input => 'body').should be_unsupported_media_type
|
389
407
|
end
|
390
408
|
|
391
409
|
it 'should not find properties for nonexistent resources' do
|
392
|
-
propfind('
|
410
|
+
propfind(url_root + 'non').should be_not_found
|
393
411
|
end
|
394
412
|
|
395
413
|
it 'should find all properties' do
|
@@ -399,9 +417,9 @@ describe RackDAV::Handler do
|
|
399
417
|
end
|
400
418
|
end
|
401
419
|
|
402
|
-
propfind('http://
|
420
|
+
propfind('http://example.org' + url_root, :input => xml)
|
403
421
|
|
404
|
-
multistatus_response('/d:href').first.text.strip.should == 'http://
|
422
|
+
multistatus_response('/d:href').first.text.strip.should == 'http://example.org' + url_root
|
405
423
|
|
406
424
|
props = %w(creationdate displayname getlastmodified getetag resourcetype getcontenttype getcontentlength)
|
407
425
|
props.each do |prop|
|
@@ -410,61 +428,31 @@ describe RackDAV::Handler do
|
|
410
428
|
end
|
411
429
|
|
412
430
|
it 'should find named properties' do
|
413
|
-
put('
|
414
|
-
propfind('
|
431
|
+
put(url_root + 'test.html', :input => '<html/>').should be_created
|
432
|
+
propfind(url_root + 'test.html', :input => propfind_xml(:getcontenttype, :getcontentlength))
|
415
433
|
|
416
434
|
multistatus_response('/d:propstat/d:prop/d:getcontenttype').first.text.should == 'text/html'
|
417
435
|
multistatus_response('/d:propstat/d:prop/d:getcontentlength').first.text.should == '7'
|
418
436
|
end
|
419
437
|
|
420
|
-
it 'should set custom properties in the dav namespace', :has_xattr_support => true do
|
421
|
-
put('/prop', :input => 'A').should be_created
|
422
|
-
proppatch('/prop', :input => propset_xml([:foo, 'testing']))
|
423
|
-
multistatus_response('/d:propstat/d:prop/d:foo').should_not be_empty
|
424
|
-
|
425
|
-
propfind('/prop', :input => propfind_xml(:foo))
|
426
|
-
multistatus_response('/d:propstat/d:prop/d:foo').first.text.should == 'testing'
|
427
|
-
end
|
428
|
-
|
429
|
-
it 'should set custom properties in custom namespaces', :has_xattr_support => true do
|
430
|
-
xmlns = { 'xmlns:s' => 'SPEC:' }
|
431
|
-
put('/prop', :input => 'A').should be_created
|
432
|
-
proppatch('/prop', :input => propset_xml(['s:foo'.to_sym, 'testing', xmlns]))
|
433
|
-
multistatus_response('/d:propstat/d:prop/s:foo', xmlns).should_not be_empty
|
434
|
-
|
435
|
-
propfind('/prop', :input => propfind_xml(['s:foo'.to_sym, xmlns]))
|
436
|
-
multistatus_response('/d:propstat/d:prop/s:foo', xmlns).first.text.should == 'testing'
|
437
|
-
end
|
438
|
-
|
439
|
-
it 'should copy custom properties', :has_xattr_support => true do
|
440
|
-
xmlns = { 'xmlns:s' => 'SPEC:' }
|
441
|
-
put('/prop', :input => 'A').should be_created
|
442
|
-
proppatch('/prop', :input => propset_xml(['s:foo'.to_sym, 'testing', xmlns]))
|
443
|
-
multistatus_response('/d:propstat/d:prop/s:foo', xmlns).should_not be_empty
|
444
|
-
|
445
|
-
copy('/prop', 'HTTP_DESTINATION' => '/propcopy').should be_created
|
446
|
-
propfind('/propcopy', :input => propfind_xml(['s:foo'.to_sym, xmlns]))
|
447
|
-
multistatus_response('/d:propstat/d:prop/s:foo', xmlns).first.text.should == 'testing'
|
448
|
-
end
|
449
|
-
|
450
438
|
it 'should not set properties for a non-existent resource' do
|
451
|
-
proppatch('
|
439
|
+
proppatch(url_root + 'not_found', :input => propset_xml([:foo, 'testing'])).should be_not_found
|
452
440
|
end
|
453
441
|
|
454
442
|
it 'should not return properties for non-existent resource' do
|
455
|
-
propfind('
|
443
|
+
propfind(url_root + 'prop', :input => propfind_xml(:foo)).should be_not_found
|
456
444
|
end
|
457
445
|
|
458
446
|
it 'should return the correct charset (utf-8)' do
|
459
|
-
put('
|
460
|
-
propfind('
|
447
|
+
put(url_root + 'test.html', :input => '<html/>').should be_created
|
448
|
+
propfind(url_root + 'test.html', :input => propfind_xml(:getcontenttype, :getcontentlength))
|
461
449
|
|
462
450
|
charset = @response.media_type_params['charset']
|
463
451
|
charset.should eql 'utf-8'
|
464
452
|
end
|
465
453
|
|
466
454
|
it 'should not support LOCK' do
|
467
|
-
put('
|
455
|
+
put(url_root + 'test', :input => 'body').should be_created
|
468
456
|
|
469
457
|
xml = render do |xml|
|
470
458
|
xml.lockinfo('xmlns:d' => "DAV:") do
|
@@ -474,22 +462,49 @@ describe RackDAV::Handler do
|
|
474
462
|
end
|
475
463
|
end
|
476
464
|
|
477
|
-
lock('
|
465
|
+
lock(url_root + 'test', :input => xml).should be_method_not_allowed
|
478
466
|
end
|
479
467
|
|
480
468
|
it 'should not support UNLOCK' do
|
481
|
-
put('
|
482
|
-
unlock('
|
469
|
+
put(url_root + 'test', :input => 'body').should be_created
|
470
|
+
unlock(url_root + 'test', :input => '').should be_method_not_allowed
|
483
471
|
end
|
484
472
|
|
485
473
|
end
|
486
474
|
|
475
|
+
context "Given a not lockable resource" do
|
476
|
+
context "when mounted directly" do
|
477
|
+
before do
|
478
|
+
@controller = RackDAV::Handler.new(
|
479
|
+
:root => DOC_ROOT,
|
480
|
+
:resource_class => RackDAV::FileResource
|
481
|
+
)
|
482
|
+
end
|
483
|
+
|
484
|
+
let(:url_root){ '/' }
|
485
|
+
include_examples :not_lockable_resource
|
486
|
+
end
|
487
|
+
|
488
|
+
context "When mounted via a URLMap" do
|
489
|
+
let(:url_root){ '/dav/' }
|
490
|
+
|
491
|
+
before do
|
492
|
+
@controller = Rack::URLMap.new(
|
493
|
+
"/dav" => RackDAV::Handler.new(
|
494
|
+
:root => DOC_ROOT,
|
495
|
+
:resource_class => RackDAV::FileResource
|
496
|
+
)
|
497
|
+
)
|
498
|
+
end
|
499
|
+
|
500
|
+
include_examples :not_lockable_resource
|
501
|
+
end
|
502
|
+
end
|
487
503
|
|
488
504
|
private
|
489
505
|
|
490
506
|
def request(method, uri, options={})
|
491
507
|
options = {
|
492
|
-
'HTTP_HOST' => 'localhost',
|
493
508
|
'REMOTE_USER' => 'manni'
|
494
509
|
}.merge(options)
|
495
510
|
request = Rack::MockRequest.new(@controller)
|
metadata
CHANGED
@@ -1,102 +1,143 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack_dav
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthias Georgi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-01-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 3.0.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 3.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rackup
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.2.3
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.2.3
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rexml
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 3.2.4
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 3.2.4
|
27
55
|
- !ruby/object:Gem::Dependency
|
28
56
|
name: nokogiri
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
30
58
|
requirements:
|
31
|
-
- - ~>
|
59
|
+
- - "~>"
|
32
60
|
- !ruby/object:Gem::Version
|
33
61
|
version: '1.5'
|
34
62
|
type: :runtime
|
35
63
|
prerelease: false
|
36
64
|
version_requirements: !ruby/object:Gem::Requirement
|
37
65
|
requirements:
|
38
|
-
- - ~>
|
66
|
+
- - "~>"
|
39
67
|
- !ruby/object:Gem::Version
|
40
68
|
version: '1.5'
|
41
69
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
70
|
+
name: webrick
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.3'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.3'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: puma
|
43
85
|
requirement: !ruby/object:Gem::Requirement
|
44
86
|
requirements:
|
45
|
-
- - ~>
|
87
|
+
- - "~>"
|
46
88
|
- !ruby/object:Gem::Version
|
47
|
-
version: '0
|
89
|
+
version: '6.0'
|
48
90
|
type: :runtime
|
49
91
|
prerelease: false
|
50
92
|
version_requirements: !ruby/object:Gem::Requirement
|
51
93
|
requirements:
|
52
|
-
- - ~>
|
94
|
+
- - "~>"
|
53
95
|
- !ruby/object:Gem::Version
|
54
|
-
version: '0
|
96
|
+
version: '6.0'
|
55
97
|
- !ruby/object:Gem::Dependency
|
56
98
|
name: rspec
|
57
99
|
requirement: !ruby/object:Gem::Requirement
|
58
100
|
requirements:
|
59
|
-
- - ~>
|
101
|
+
- - "~>"
|
60
102
|
- !ruby/object:Gem::Version
|
61
103
|
version: '2.11'
|
62
104
|
type: :development
|
63
105
|
prerelease: false
|
64
106
|
version_requirements: !ruby/object:Gem::Requirement
|
65
107
|
requirements:
|
66
|
-
- - ~>
|
108
|
+
- - "~>"
|
67
109
|
- !ruby/object:Gem::Version
|
68
110
|
version: '2.11'
|
69
111
|
- !ruby/object:Gem::Dependency
|
70
112
|
name: rake
|
71
113
|
requirement: !ruby/object:Gem::Requirement
|
72
114
|
requirements:
|
73
|
-
- - ~>
|
115
|
+
- - "~>"
|
74
116
|
- !ruby/object:Gem::Version
|
75
|
-
version: '0
|
117
|
+
version: '13.0'
|
76
118
|
type: :development
|
77
119
|
prerelease: false
|
78
120
|
version_requirements: !ruby/object:Gem::Requirement
|
79
121
|
requirements:
|
80
|
-
- - ~>
|
122
|
+
- - "~>"
|
81
123
|
- !ruby/object:Gem::Version
|
82
|
-
version: '0
|
124
|
+
version: '13.0'
|
83
125
|
description: WebDAV handler for Rack.
|
84
126
|
email: matti.georgi@gmail.com
|
85
|
-
executables:
|
86
|
-
- rack_dav
|
127
|
+
executables: []
|
87
128
|
extensions: []
|
88
129
|
extra_rdoc_files:
|
89
130
|
- README.md
|
90
131
|
files:
|
91
|
-
- .gitignore
|
92
|
-
- .travis.yml
|
132
|
+
- ".gitignore"
|
133
|
+
- ".travis.yml"
|
93
134
|
- CHANGELOG.md
|
135
|
+
- Dockerfile
|
94
136
|
- Gemfile
|
95
|
-
- Gemfile.lock
|
96
137
|
- LICENSE
|
97
138
|
- README.md
|
98
139
|
- Rakefile
|
99
|
-
-
|
140
|
+
- config.ru
|
100
141
|
- lib/rack_dav.rb
|
101
142
|
- lib/rack_dav/controller.rb
|
102
143
|
- lib/rack_dav/file_resource.rb
|
@@ -124,17 +165,16 @@ require_paths:
|
|
124
165
|
- lib
|
125
166
|
required_ruby_version: !ruby/object:Gem::Requirement
|
126
167
|
requirements:
|
127
|
-
- -
|
168
|
+
- - ">="
|
128
169
|
- !ruby/object:Gem::Version
|
129
170
|
version: '0'
|
130
171
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
172
|
requirements:
|
132
|
-
- -
|
173
|
+
- - ">="
|
133
174
|
- !ruby/object:Gem::Version
|
134
175
|
version: '0'
|
135
176
|
requirements: []
|
136
|
-
|
137
|
-
rubygems_version: 2.0.14
|
177
|
+
rubygems_version: 3.4.1
|
138
178
|
signing_key:
|
139
179
|
specification_version: 4
|
140
180
|
summary: WebDAV handler for Rack.
|
data/Gemfile.lock
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
rack_dav (0.4.0)
|
5
|
-
ffi-xattr (~> 0.1)
|
6
|
-
nokogiri (~> 1.5)
|
7
|
-
rack (~> 1.4)
|
8
|
-
|
9
|
-
GEM
|
10
|
-
remote: http://rubygems.org/
|
11
|
-
specs:
|
12
|
-
diff-lcs (1.2.5)
|
13
|
-
ffi (1.9.10)
|
14
|
-
ffi (1.9.10-java)
|
15
|
-
ffi-xattr (0.1.2)
|
16
|
-
ffi
|
17
|
-
mini_portile (0.6.2)
|
18
|
-
nokogiri (1.6.6.2)
|
19
|
-
mini_portile (~> 0.6.0)
|
20
|
-
nokogiri (1.6.6.2-java)
|
21
|
-
rack (1.6.4)
|
22
|
-
rake (0.9.6)
|
23
|
-
rspec (2.99.0)
|
24
|
-
rspec-core (~> 2.99.0)
|
25
|
-
rspec-expectations (~> 2.99.0)
|
26
|
-
rspec-mocks (~> 2.99.0)
|
27
|
-
rspec-core (2.99.2)
|
28
|
-
rspec-expectations (2.99.2)
|
29
|
-
diff-lcs (>= 1.1.3, < 2.0)
|
30
|
-
rspec-mocks (2.99.3)
|
31
|
-
|
32
|
-
PLATFORMS
|
33
|
-
java
|
34
|
-
ruby
|
35
|
-
|
36
|
-
DEPENDENCIES
|
37
|
-
rack_dav!
|
38
|
-
rake (~> 0.9)
|
39
|
-
rspec (~> 2.11)
|
data/bin/rack_dav
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
$:.unshift(File.expand_path("../../lib", __FILE__))
|
4
|
-
|
5
|
-
require 'rack_dav'
|
6
|
-
|
7
|
-
root=ARGV[1] || Dir.pwd
|
8
|
-
port = ARGV[0] || 3000
|
9
|
-
|
10
|
-
app = Rack::Builder.new do
|
11
|
-
use Rack::ShowExceptions
|
12
|
-
use Rack::CommonLogger
|
13
|
-
use Rack::Reloader
|
14
|
-
use Rack::Lint
|
15
|
-
|
16
|
-
run RackDAV::Handler.new(:root => root)
|
17
|
-
|
18
|
-
end.to_app
|
19
|
-
|
20
|
-
begin
|
21
|
-
Rack::Handler::Mongrel.run(app, :Port => port)
|
22
|
-
rescue LoadError
|
23
|
-
Rack::Handler::WEBrick.run(app, :Port => port)
|
24
|
-
end
|