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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 849a36645773dd942cbf87d7e41a685ff5814157
4
- data.tar.gz: 5269572bc9f41e2c6fa73eb23f1e31a7ac17aa58
2
+ SHA256:
3
+ metadata.gz: 3f5efaaf9d78cffb9459cce4b8ff84610ae9a480303d23e0266cbd8ec351603b
4
+ data.tar.gz: 817e1db4fcb91c2fa26e8be1e32074c466c8aa6c7631237b73bd9e61c6316804
5
5
  SHA512:
6
- metadata.gz: b6e6183c272dbd1c9c292c2de86fda4afef9282db0e190cc9fa31f1d7d0af7d3d175e917442f83d11c53231bf07f676fa4990bf722781a385f29d2dfcbdab299
7
- data.tar.gz: c591239bce9cff7162639b6bf1b24b28b4e1d193a87eafda61c1aa0477085f491683270622cdd78eaeaa9855fb2c1a039b0816bfa0da7b66e986b11c0c15b25c
6
+ metadata.gz: b827c9616a9c8a106bdd0bb2dce19e944f9a21932f0686b6ce51a58307094c88d449e1673d611769c1dce28e1fdb460770eeff4351b235aa30718bf7d0cad665
7
+ data.tar.gz: 33c156ccecb968a88d8d38435b9d95a65245de4abce448dc0d987f83cf5f355ec4289c823be5340bf5e333bcf99622bd908be9f9dee1fafab79e82cd0cf21289
data/Dockerfile ADDED
@@ -0,0 +1,13 @@
1
+ FROM ruby:latest
2
+
3
+ RUN mkdir /app
4
+ WORKDIR /app
5
+
6
+ ADD Gemfile /app
7
+ ADD rack_dav.gemspec /app
8
+ ADD lib/rack_dav/version.rb /app/lib/rack_dav/version.rb
9
+
10
+ RUN bundle install
11
+
12
+ ADD . /app
13
+
data/README.md CHANGED
@@ -2,30 +2,17 @@
2
2
  RackDAV - Web Authoring for Rack
3
3
  ---
4
4
 
5
- RackDAV is Handler for [Rack][1], which allows content authoring over
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
- If you just want to share a folder over WebDAV, you can just start a
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 WEBrick server on port 3000, which you can connect
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
- Using RackDAV inside a rack application is quite easy. A simple rackup
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
- RackDAV::Resource is an abstract base class and defines an interface
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, that it is generally possible, that a resource object is
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
- [1]: http://github.com/chneukirchen/rack
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
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rack_dav'
3
+
4
+ app = Rack::Builder.new do
5
+ use Rack::ShowExceptions
6
+ use Rack::CommonLogger
7
+ use Rack::Reloader
8
+ # use Rack::Lint
9
+
10
+ run RackDAV::Handler.new(:root => ".")
11
+
12
+ end.to_app
13
+
14
+ run app
@@ -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
- URI.escape(s)
23
+ @@uri.escape(s)
22
24
  end
23
25
 
24
26
  def url_unescape(s)
25
- URI.unescape(s).force_valid_encoding
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 = url_unescape(dest_uri.path)
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 = url_unescape(dest_uri.path)
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
- env['HTTP_HOST']
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 'ffi-xattr'
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
- xattr.list.select { |a| a.start_with?('rack_dav') }.map { |a| a.sub(/^rack_dav:/, '') }
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
 
@@ -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
- controller.send(request.request_method.downcase)
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
@@ -3,7 +3,7 @@ module RackDAV
3
3
  # Holds information about library version.
4
4
  module Version
5
5
  MAJOR = 0
6
- MINOR = 4
6
+ MINOR = 5
7
7
  PATCH = 1
8
8
  BUILD = nil
9
9
 
data/lib/rack_dav.rb CHANGED
@@ -3,7 +3,6 @@ require 'time'
3
3
  require 'uri'
4
4
  require 'rexml/document'
5
5
  require 'nokogiri'
6
- require 'webrick/httputils'
7
6
 
8
7
  require 'rack'
9
8
  require 'rack_dav/http_status'
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", "~> 1.4")
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("ffi-xattr", "~> 0.1")
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.9")
27
+ s.add_development_dependency("rake","~> 13.0")
26
28
  end
@@ -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.exists?(DOC_ROOT)
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.exists?(DOC_ROOT)
47
+ FileUtils.rm_rf(DOC_ROOT) if File.exist?(DOC_ROOT)
48
48
  end
49
49
 
50
50
  attr_reader :response
51
51
 
52
- context "Given a Lockable resource" do
53
- before do
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('/').should be_ok
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("/test", :input => "body").should be_created
76
- lock("/test", :input => File.read(fixture("requests/lock.xml")))
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("/test", 'HTTP_IF' => "(#{token})").should be_ok
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("/test", 'HTTP_IF' => token).should be_ok
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("/test", 'HTTP_IF' => "(<#{token}>)").should be_ok
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("/test", 'HTTP_IF' => '123')
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("/test")
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("/test", :input => "body").should be_created
138
- lock("/test", :input => File.read(fixture("requests/lock.xml"))).should be_ok
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("/test", 'HTTP_LOCK_TOKEN' => "(#{token})")
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("/test", 'HTTP_LOCK_TOKEN' => '(123)')
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("/test")
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
- context "Given a not lockable resource" do
176
- before do
177
- @controller = RackDAV::Handler.new(
178
- :root => DOC_ROOT,
179
- :resource_class => RackDAV::FileResource
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('/D%C3%B6ner').should be_created
186
- get('/D%C3%B6ner').should be_ok
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('/D%F6ner').should be_created
191
- get('/D%F6ner').should be_ok
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('/').should be_ok
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('/foo', :input => 'bar',
212
- 'HTTP_CONTENT_MD5' => 'baz')
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('/foo').should be_not_found
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('/foo', :input => 'bar',
227
- 'HTTP_CONTENT_MD5' => 'N7UdGUp1E+RbVvZSTy1R8g==')
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('/foo').should be_ok
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('/test.html', :input => '<html/>').should be_created
243
- head('/test.html').should be_ok
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('/not_found').should be_not_found
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('/../htdocs').should be_forbidden
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('/test', :input => 'body').should be_created
261
- get('/test').should be_ok
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('/test', :input => 'body').should be_created
272
- delete('/test').should be_no_content
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('/folder').should be_created
277
- put('/folder/a', :input => 'body').should be_created
278
- put('/folder/b', :input => 'body').should be_created
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('/folder').should be_no_content
281
- get('/folder').should be_not_found
282
- get('/folder/a').should be_not_found
283
- get('/folder/b').should be_not_found
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('/not_found').should be_not_found
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('/test', :input => 'body').should be_created
292
- copy('http://localhost/', 'HTTP_DESTINATION' => 'http://another/').should be_bad_gateway
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('/test', :input => 'body').should be_created
297
- copy('/test', 'HTTP_DESTINATION' => '/test').should be_forbidden
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('/test', :input => 'body').should be_created
302
- copy('/test', 'HTTP_DESTINATION' => '%').should be_bad_request
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('/test', :input => 'body').should be_created
307
- copy('/test', 'HTTP_DESTINATION' => '/copy').should be_created
308
- get('/copy').body.should == 'body'
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('/test', :input => 'body').should be_created
320
- put('/copy', :input => 'copy').should be_created
321
- copy('/test', 'HTTP_DESTINATION' => '/copy', 'HTTP_OVERWRITE' => 'F').should be_precondition_failed
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('/copy').body.should == 'copy'
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('/test', :input => 'body').should be_created
328
- put('/copy', :input => 'copy').should be_created
329
- copy('/test', 'HTTP_DESTINATION' => '/copy', 'HTTP_OVERWRITE' => 'T').should be_no_content
330
- get('/copy').body.should == 'body'
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('/test', :input => 'body').should be_created
335
- put('/copy', :input => 'copy').should be_created
336
- move('/test', 'HTTP_DESTINATION' => '/copy', 'HTTP_OVERWRITE' => 'F').should be_precondition_failed
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('/folder').should be_created
341
- copy('/folder', 'HTTP_DESTINATION' => '/copy').should be_created
342
- propfind('/copy', :input => propfind_xml(:resourcetype))
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('/folder').should be_created
348
- put('/folder/a', :input => 'A').should be_created
349
- put('/folder/b', :input => 'B').should be_created
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('/folder', 'HTTP_DESTINATION' => '/copy').should be_created
352
- propfind('/copy', :input => propfind_xml(:resourcetype))
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('/copy/a').body.should == 'A'
356
- get('/copy/b').body.should == 'B'
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('/folder').should be_created
361
- put('/folder/a', :input => 'A').should be_created
362
- put('/folder/b', :input => 'B').should be_created
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('/folder', 'HTTP_DESTINATION' => '/move').should be_created
365
- propfind('/move', :input => propfind_xml(:resourcetype))
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('/move/a').body.should == 'A'
369
- get('/move/b').body.should == 'B'
370
- get('/folder/a').should be_not_found
371
- get('/folder/b').should be_not_found
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('/folder').should be_created
376
- mkcol('/dest').should be_created
393
+ mkcol(url_root + 'folder').should be_created
394
+ mkcol(url_root + 'dest').should be_created
377
395
 
378
- move('/folder', 'HTTP_DESTINATION' => '/dest', 'HTTP_OVERWRITE' => 'F').should be_precondition_failed
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('/folder').should be_created
383
- propfind('/folder', :input => propfind_xml(:resourcetype))
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('/folder', :input => 'body').should be_unsupported_media_type
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('/non').should be_not_found
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://localhost/', :input => xml)
420
+ propfind('http://example.org' + url_root, :input => xml)
403
421
 
404
- multistatus_response('/d:href').first.text.strip.should == 'http://localhost/'
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('/test.html', :input => '<html/>').should be_created
414
- propfind('/test.html', :input => propfind_xml(:getcontenttype, :getcontentlength))
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('/not_found', :input => propset_xml([:foo, 'testing'])).should be_not_found
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('/prop', :input => propfind_xml(:foo)).should be_not_found
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('/test.html', :input => '<html/>').should be_created
460
- propfind('/test.html', :input => propfind_xml(:getcontenttype, :getcontentlength))
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('/test', :input => 'body').should be_created
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('/test', :input => xml).should be_method_not_allowed
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('/test', :input => 'body').should be_created
482
- unlock('/test', :input => '').should be_method_not_allowed
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.1
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: 2015-08-27 00:00:00.000000000 Z
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: '1.4'
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: '1.4'
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: ffi-xattr
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.1'
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.1'
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.9'
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.9'
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
- - bin/rack_dav
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
- rubyforge_project:
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