dav4rack 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -21,6 +21,10 @@ a pull request with your modifications. If you are just here to use the library,
21
21
  === Via RubyGems
22
22
 
23
23
  gem install dav4rack
24
+
25
+ == Documentation
26
+
27
+ * {DAV4Rack documentation}[http://chrisroberts.github.com/dav4rack]
24
28
 
25
29
  == Quickstart
26
30
 
@@ -90,9 +94,9 @@ lets continue with the last example but this time include the interceptor:
90
94
  end
91
95
  map '/' do
92
96
  use DAV4Rack::Interceptor, :mappings => {
93
- '/webdav/share/' => {:resource_class => FileResource, :custom => 'option'},
94
- '/webdav/share2/' => {:resource_class => CustomResource}
95
- }
97
+ '/webdav/share/' => {:resource_class => FileResource, :custom => 'option'},
98
+ '/webdav/share2/' => {:resource_class => CustomResource}
99
+ }
96
100
  use Rails::Rack::Static
97
101
  run ActionController::Dispatcher.new
98
102
  end
@@ -202,7 +206,7 @@ And if you don't have the X-Sendfile-Type header set, you can fix that by changi
202
206
 
203
207
  response.body = DAV4Rack::RemoteFile.new(item[:url], :size => content_length, :mime_type => content_type, :sendfile => 'X-Accel-Redirect', :sendfile_prefix => 'webdav_redirect')
204
208
 
205
- And if you have none of the above because your server hasn't been configured for sendfile support, your out of luck until it's configured.
209
+ And if you have none of the above because your server hasn't been configured for sendfile support, you're out of luck until it's configured.
206
210
 
207
211
  == Authentication
208
212
 
@@ -295,6 +299,13 @@ without getting stuck in a loop.
295
299
 
296
300
  Please use the issues at github: http://github.com/chrisroberts/dav4rack/issues
297
301
 
302
+ == Contributors
303
+
304
+ A big thanks to everyone contributing to help make this project better.
305
+
306
+ * {clyfe}[http://github.com/clyfe]
307
+ * {antiloopgmbh}[http://github.com/antiloopgmbh]
308
+
298
309
  == License
299
310
 
300
311
  Just like RackDAV before it, this software is distributed under the MIT license.
@@ -39,7 +39,7 @@
39
39
  response["Allow"] = 'OPTIONS,HEAD,GET,PUT,POST,DELETE,PROPFIND,PROPPATCH,MKCOL,COPY,MOVE,LOCK,UNLOCK'
40
40
  response["Dav"] = "2"
41
41
  response["Ms-Author-Via"] = "DAV"
42
- NoContent
42
+ OK
43
43
  end
44
44
 
45
45
  # Return response to HEAD
@@ -48,7 +48,7 @@
48
48
  response['Etag'] = resource.etag
49
49
  response['Content-Type'] = resource.content_type
50
50
  response['Last-Modified'] = resource.last_modified.httpdate
51
- NoContent
51
+ OK
52
52
  end
53
53
 
54
54
  # Return response to GET
@@ -127,8 +127,8 @@
127
127
  response['Location'] = "#{scheme}://#{host}:#{port}#{dest.public_path}" if status == Created
128
128
  multistatus do |xml|
129
129
  xml.response do
130
- xml.href "#{scheme}://#{host}:#{port}#{dest.public_path}"
131
- xml.status = "#{http_version} #{status.status_line}"
130
+ xml.href "#{scheme}://#{host}:#{port}#{status == Created ? dest.public_path : resource.public_path}"
131
+ xml.status "#{http_version} #{status.status_line}"
132
132
  end
133
133
  end
134
134
  end
@@ -202,6 +202,9 @@
202
202
  xml.locktoken do
203
203
  xml.href locktoken
204
204
  end
205
+ if(asked[:owner])
206
+ xml.owner asked[:owner]
207
+ end
205
208
  end
206
209
  end
207
210
  end
@@ -228,14 +231,18 @@
228
231
  # has defined an #authenticate method
229
232
  def authenticate
230
233
  authed = true
231
- if(resource.respond_to?(:authenticate))
234
+ if(resource.respond_to?(:authenticate, true))
232
235
  authed = false
236
+ uname = nil
237
+ password = nil
233
238
  if(request.env['HTTP_AUTHORIZATION'])
234
239
  auth = Rack::Auth::Basic::Request.new(request.env)
235
240
  if(auth.basic? && auth.credentials)
236
- authed = resource.authenticate(auth.credentials[0], auth.credentials[1])
241
+ uname = auth.credentials[0]
242
+ password = auth.credentials[1]
237
243
  end
238
244
  end
245
+ authed = resource.send(:authenticate, uname, password)
239
246
  end
240
247
  raise Unauthorized unless authed
241
248
  end
@@ -320,17 +327,17 @@
320
327
  end
321
328
 
322
329
  # Find resources at depth requested
323
- def find_resources
330
+ def find_resources(with_current_resource=true)
324
331
  ary = nil
325
332
  case depth
326
333
  when 0
327
- ary = [resource]
334
+ ary = []
328
335
  when 1
329
336
  ary = resource.children
330
337
  else
331
338
  ary = resource.descendants
332
339
  end
333
- ary ? ary : []
340
+ with_current_resource ? [resource] + ary : ary
334
341
  end
335
342
 
336
343
  # XML parsed request
@@ -6,10 +6,6 @@ module DAV4Rack
6
6
 
7
7
  include WEBrick::HTTPUtils
8
8
 
9
- before do |resource, method_name|
10
- resource.send(:check_authentication)
11
- end
12
-
13
9
  # If this is a collection, return the child resources.
14
10
  def children
15
11
  Dir[file_path + '/*'].map do |path|
@@ -84,7 +80,7 @@ module DAV4Rack
84
80
  # Save the content of the request.body.
85
81
  def put(request, response)
86
82
  write(request.body)
87
- Created
83
+ OK
88
84
  end
89
85
 
90
86
  # HTTP POST request.
@@ -99,7 +95,7 @@ module DAV4Rack
99
95
  # Delete this resource.
100
96
  def delete
101
97
  if stat.directory?
102
- Dir.rmdir(file_path)
98
+ FileUtils.rm_rf(file_path)
103
99
  else
104
100
  File.unlink(file_path)
105
101
  end
@@ -109,22 +105,31 @@ module DAV4Rack
109
105
  # HTTP COPY request.
110
106
  #
111
107
  # Copy this resource to given destination resource.
112
- def copy(dest)
113
- if stat.directory?
108
+ def copy(dest, overwrite = false)
109
+ if(dest.path == path)
110
+ Conflict
111
+ elsif(stat.directory?)
114
112
  dest.make_collection
113
+ FileUtils.cp_r("#{file_path}/.", "#{dest.send(:file_path)}/")
114
+ OK
115
115
  else
116
- open(file_path, "rb") do |file|
117
- dest.write(file)
116
+ exists = File.exists?(file_path)
117
+ if(exists && !overwrite)
118
+ PreconditionFailed
119
+ else
120
+ open(file_path, "rb") do |file|
121
+ dest.write(file)
122
+ end
123
+ exists ? NoContent : Created
118
124
  end
119
125
  end
120
- OK
121
126
  end
122
127
 
123
128
  # HTTP MOVE request.
124
129
  #
125
130
  # Move this resource to given destination resource.
126
- def move(dest)
127
- copy(dest)
131
+ def move(*args)
132
+ copy(*args)
128
133
  delete
129
134
  OK
130
135
  end
@@ -134,7 +139,7 @@ module DAV4Rack
134
139
  # Create this resource as collection.
135
140
  def make_collection
136
141
  Dir.mkdir(file_path)
137
- NoContent
142
+ Created
138
143
  end
139
144
 
140
145
  # Write to this resource from given IO.
@@ -154,21 +159,6 @@ module DAV4Rack
154
159
 
155
160
  private
156
161
 
157
- def check_authentication
158
- valid = true
159
- if(options[:username])
160
- valid = false
161
- if(request.env['HTTP_AUTHORIZATION'])
162
- auth = Rack::Auth::Basic::Request.new(request.env)
163
- if(auth.basic? && auth.credentials)
164
- valid = options[:username] == auth.credentials[0] && options[:password] == auth.credentials[1]
165
- end
166
- end
167
- end
168
- raise Unauthorized unless valid
169
- valid
170
- end
171
-
172
162
  def authenticate(user, pass)
173
163
  if(options[:username])
174
164
  options[:username] == user && options[:password] == pass
@@ -5,13 +5,15 @@ module DAV4Rack
5
5
  @roots = args[:mappings].keys
6
6
  @args = args
7
7
  @app = app
8
+ @intercept_methods = %w(OPTIONS PROPFIND PROPPATCH MKCOL COPY MOVE LOCK UNLOCK)
9
+ @intercept_methods -= args[:ignore_methods] if args[:ignore_methods]
8
10
  end
9
11
 
10
12
  def call(env)
11
13
  path = env['PATH_INFO'].downcase
12
14
  method = env['REQUEST_METHOD'].upcase
13
15
  app = nil
14
- if(@roots.detect{|x| path =~ /^#{Regexp.escape(x.downcase)}\/?/}.nil? && %w(OPTIONS PUT PROPFIND PROPPATCH MKCOL COPY MOVE LOCK UNLOCK).include?(method))
16
+ if(@roots.detect{|x| path =~ /^#{Regexp.escape(x.downcase)}\/?/}.nil? && @intercept_methods.include?(method))
15
17
  app = DAV4Rack::Handler.new(:resource_class => InterceptorResource, :mappings => @args[:mappings], :log_to => @args[:log_to])
16
18
  end
17
19
  app ? app.call(env) : @app.call(env)
@@ -196,14 +196,14 @@ module DAV4Rack
196
196
  # HTTP COPY request.
197
197
  #
198
198
  # Copy this resource to given destination resource.
199
- def copy(dest)
199
+ def copy(dest, overwrite=false)
200
200
  raise NotImplementedError
201
201
  end
202
202
 
203
203
  # HTTP MOVE request.
204
204
  #
205
205
  # Move this resource to given destination resource.
206
- def move(dest)
206
+ def move(dest, overwrite=false)
207
207
  raise NotImplemented
208
208
  end
209
209
 
@@ -287,7 +287,6 @@ module DAV4Rack
287
287
  raise Forbidden unless lock && lock.user == @user
288
288
  raise Conflict unless lock.path =~ /^#{Regexp.escape(@path)}.*$/
289
289
  lock.destroy
290
- delete if name[0,1] == '.' && @options[:delete_dotfiles]
291
290
  NoContent
292
291
  end
293
292
 
@@ -394,6 +393,7 @@ module DAV4Rack
394
393
  end
395
394
 
396
395
  # Does client allow GET redirection
396
+ # TODO: Get a comprehensive list in here. Especially now that trasmit added support
397
397
  def allows_redirect?
398
398
  %w(cyberduck konqueror).any?{|x| (request.respond_to?(:user_agent) ? request.user_agent.to_s.downcase : request.env['HTTP_USER_AGENT'].to_s.downcase) =~ /#{Regexp.escape(x)}/}
399
399
  end
@@ -1,3 +1,3 @@
1
1
  module DAV4Rack
2
- VERSION = '0.1.4'
2
+ VERSION = '0.1.5'
3
3
  end
data/spec/handler_spec.rb CHANGED
@@ -1,16 +1,17 @@
1
1
  $:.unshift(File.expand_path(File.dirname(__FILE__) + '/../lib'))
2
2
 
3
3
  require 'rubygems'
4
- require 'rack_dav'
4
+ require 'dav4rack'
5
5
  require 'fileutils'
6
+ require 'nokogiri'
6
7
 
7
- describe RackDAV::Handler do
8
+ describe DAV4Rack::Handler do
8
9
  DOC_ROOT = File.expand_path(File.dirname(__FILE__) + '/htdocs')
9
10
  METHODS = %w(GET PUT POST DELETE PROPFIND PROPPATCH MKCOL COPY MOVE OPTIONS HEAD LOCK UNLOCK)
10
11
 
11
12
  before do
12
13
  FileUtils.mkdir(DOC_ROOT) unless File.exists?(DOC_ROOT)
13
- @controller = RackDAV::Handler.new(:root => DOC_ROOT)
14
+ @controller = DAV4Rack::Handler.new(:root => DOC_ROOT)
14
15
  end
15
16
 
16
17
  after do
@@ -22,7 +23,7 @@ describe RackDAV::Handler do
22
23
  def request(method, uri, options={})
23
24
  options = {
24
25
  'HTTP_HOST' => 'localhost',
25
- 'REMOTE_USER' => 'manni'
26
+ 'REMOTE_USER' => 'user'
26
27
  }.merge(options)
27
28
  request = Rack::MockRequest.new(@controller)
28
29
  @response = request.request(method, uri, options)
@@ -34,13 +35,16 @@ describe RackDAV::Handler do
34
35
  end
35
36
  end
36
37
 
37
- def render
38
- xml = Builder::XmlMarkup.new
39
- xml.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
40
- xml.namespace('d') do
41
- yield xml
38
+ def render(root_type)
39
+ raise ArgumentError.new 'Expecting block' unless block_given?
40
+ doc = Nokogiri::XML::Builder.new do |xml_base|
41
+ xml_base.send(root_type.to_s, 'xmlns:D' => 'D:') do
42
+ xml_base.parent.namespace = xml_base.parent.namespace_definitions.first
43
+ xml = xml_base['D']
44
+ yield xml
45
+ end
42
46
  end
43
- xml.target!
47
+ doc.to_xml
44
48
  end
45
49
 
46
50
  def url_escape(string)
@@ -50,22 +54,35 @@ describe RackDAV::Handler do
50
54
  end
51
55
 
52
56
  def response_xml
53
- REXML::Document.new(@response.body)
57
+ Nokogiri.XML(@response.body)
54
58
  end
55
59
 
56
60
  def multistatus_response(pattern)
57
61
  @response.should be_multi_status
58
- REXML::XPath::match(response_xml, "/multistatus/response", '' => 'DAV:').should_not be_empty
59
- REXML::XPath::match(response_xml, "/multistatus/response" + pattern, '' => 'DAV:')
62
+ response_xml.xpath('//D:multistatus/D:response', response_xml.root.namespaces).should_not be_empty
63
+ response_xml.xpath("//D:multistatus/D:response#{pattern}", response_xml.root.namespaces)
60
64
  end
61
65
 
66
+ def multi_status_created
67
+ response_xml.xpath('//D:multistatus/D:response/D:status').should_not be_empty
68
+ response_xml.xpath('//D:multistatus/D:response/D:status').text.should =~ /Created/
69
+ end
70
+
71
+ def multi_status_ok
72
+ response_xml.xpath('//D:multistatus/D:response/D:status').should_not be_empty
73
+ response_xml.xpath('//D:multistatus/D:response/D:status').text.should =~ /OK/
74
+ end
75
+
76
+ def multi_status_no_content
77
+ response_xml.xpath('//D:multistatus/D:response/D:status').should_not be_empty
78
+ response_xml.xpath('//D:multistatus/D:response/D:status').text.should =~ /No Content/
79
+ end
80
+
62
81
  def propfind_xml(*props)
63
- render do |xml|
64
- xml.propfind('xmlns:d' => "DAV:") do
65
- xml.prop do
66
- props.each do |prop|
67
- xml.tag! prop
68
- end
82
+ render(:propfind) do |xml|
83
+ xml.prop do
84
+ props.each do |prop|
85
+ xml.send(prop.to_sym)
69
86
  end
70
87
  end
71
88
  end
@@ -80,7 +97,8 @@ describe RackDAV::Handler do
80
97
  end
81
98
 
82
99
  it 'should return headers' do
83
- put('/test.html', :input => '<html/>').should be_ok
100
+ put('/test.html', :input => '<html/>')
101
+ multi_status_ok.should eq true
84
102
  head('/test.html').should be_ok
85
103
 
86
104
  response.headers['etag'].should_not be_nil
@@ -97,25 +115,31 @@ describe RackDAV::Handler do
97
115
  end
98
116
 
99
117
  it 'should create a resource and allow its retrieval' do
100
- put('/test', :input => 'body').should be_ok
118
+ put('/test', :input => 'body')
119
+ multi_status_ok.should eq true
101
120
  get('/test').should be_ok
102
121
  response.body.should == 'body'
103
122
  end
104
123
  it 'should create and find a url with escaped characters' do
105
- put(url_escape('/a b'), :input => 'body').should be_ok
124
+ put(url_escape('/a b'), :input => 'body')
125
+ multi_status_ok.should eq true
106
126
  get(url_escape('/a b')).should be_ok
107
127
  response.body.should == 'body'
108
128
  end
109
129
 
110
130
  it 'should delete a single resource' do
111
- put('/test', :input => 'body').should be_ok
131
+ put('/test', :input => 'body')
132
+ multi_status_ok.should eq true
112
133
  delete('/test').should be_no_content
113
134
  end
114
135
 
115
136
  it 'should delete recursively' do
116
- mkcol('/folder').should be_created
117
- put('/folder/a', :input => 'body').should be_ok
118
- put('/folder/b', :input => 'body').should be_ok
137
+ mkcol('/folder')
138
+ multi_status_created.should eq true
139
+ put('/folder/a', :input => 'body')
140
+ multi_status_ok.should eq true
141
+ put('/folder/b', :input => 'body')
142
+ multi_status_ok.should eq true
119
143
 
120
144
  delete('/folder').should be_no_content
121
145
  get('/folder').should be_not_found
@@ -124,79 +148,94 @@ describe RackDAV::Handler do
124
148
  end
125
149
 
126
150
  it 'should not allow copy to another domain' do
127
- put('/test', :input => 'body').should be_ok
151
+ put('/test', :input => 'body')
152
+ multi_status_ok.should eq true
128
153
  copy('http://localhost/', 'HTTP_DESTINATION' => 'http://another/').should be_bad_gateway
129
154
  end
130
155
 
131
156
  it 'should not allow copy to the same resource' do
132
- put('/test', :input => 'body').should be_ok
157
+ put('/test', :input => 'body')
158
+ multi_status_ok.should eq true
133
159
  copy('/test', 'HTTP_DESTINATION' => '/test').should be_forbidden
134
160
  end
135
161
 
136
- it 'should not allow an invalid destination uri' do
137
- put('/test', :input => 'body').should be_ok
138
- copy('/test', 'HTTP_DESTINATION' => '%').should be_bad_request
139
- end
140
-
141
162
  it 'should copy a single resource' do
142
- put('/test', :input => 'body').should be_ok
143
- copy('/test', 'HTTP_DESTINATION' => '/copy').should be_created
163
+ put('/test', :input => 'body')
164
+ multi_status_ok.should eq true
165
+ copy('/test', 'HTTP_DESTINATION' => '/copy')
166
+ multi_status_no_content.should eq true
144
167
  get('/copy').body.should == 'body'
145
168
  end
146
169
 
147
170
  it 'should copy a resource with escaped characters' do
148
- put(url_escape('/a b'), :input => 'body').should be_ok
149
- copy(url_escape('/a b'), 'HTTP_DESTINATION' => url_escape('/a c')).should be_created
171
+ put(url_escape('/a b'), :input => 'body')
172
+ multi_status_ok.should eq true
173
+ copy(url_escape('/a b'), 'HTTP_DESTINATION' => url_escape('/a c'))
174
+ multi_status_no_content.should eq true
150
175
  get(url_escape('/a c')).should be_ok
151
176
  response.body.should == 'body'
152
177
  end
153
178
 
154
179
  it 'should deny a copy without overwrite' do
155
- put('/test', :input => 'body').should be_ok
156
- put('/copy', :input => 'copy').should be_ok
180
+ put('/test', :input => 'body')
181
+ multi_status_ok.should eq true
182
+ put('/copy', :input => 'copy')
183
+ multi_status_ok.should eq true
157
184
  copy('/test', 'HTTP_DESTINATION' => '/copy', 'HTTP_OVERWRITE' => 'F')
158
185
 
159
- multistatus_response('/href').first.text.should == 'http://localhost/test'
160
- multistatus_response('/status').first.text.should match(/412 Precondition Failed/)
186
+ multistatus_response('/D:href').first.text.should =~ /http:\/\/localhost(:\d+)?\/test/
187
+ multistatus_response('/D:status').first.text.should match(/412 Precondition Failed/)
161
188
 
162
189
  get('/copy').body.should == 'copy'
163
190
  end
164
191
 
165
192
  it 'should allow a copy with overwrite' do
166
- put('/test', :input => 'body').should be_ok
167
- put('/copy', :input => 'copy').should be_ok
168
- copy('/test', 'HTTP_DESTINATION' => '/copy', 'HTTP_OVERWRITE' => 'T').should be_no_content
193
+ put('/test', :input => 'body')
194
+ multi_status_ok.should eq true
195
+ put('/copy', :input => 'copy')
196
+ multi_status_ok.should eq true
197
+ copy('/test', 'HTTP_DESTINATION' => '/copy', 'HTTP_OVERWRITE' => 'T')
198
+ multi_status_no_content.should eq true
169
199
  get('/copy').body.should == 'body'
170
200
  end
171
201
 
172
- it 'should copy a collection' do
173
- mkcol('/folder').should be_created
174
- copy('/folder', 'HTTP_DESTINATION' => '/copy').should be_created
202
+ it 'should copy a collection' do
203
+ mkcol('/folder')
204
+ multi_status_created.should eq true
205
+ copy('/folder', 'HTTP_DESTINATION' => '/copy')
206
+ multi_status_ok.should eq true
175
207
  propfind('/copy', :input => propfind_xml(:resourcetype))
176
- multistatus_response('/propstat/prop/resourcetype/collection').should_not be_empty
208
+ multistatus_response('/D:propstat/D:prop/D:resourcetype/D:collection').should_not be_empty
177
209
  end
178
210
 
179
211
  it 'should copy a collection resursively' do
180
- mkcol('/folder').should be_created
181
- put('/folder/a', :input => 'A').should be_ok
182
- put('/folder/b', :input => 'B').should be_ok
212
+ mkcol('/folder')
213
+ multi_status_created.should eq true
214
+ put('/folder/a', :input => 'A')
215
+ multi_status_ok.should eq true
216
+ put('/folder/b', :input => 'B')
217
+ multi_status_ok.should eq true
183
218
 
184
- copy('/folder', 'HTTP_DESTINATION' => '/copy').should be_created
219
+ copy('/folder', 'HTTP_DESTINATION' => '/copy')
220
+ multi_status_ok.should eq true
185
221
  propfind('/copy', :input => propfind_xml(:resourcetype))
186
- multistatus_response('/propstat/prop/resourcetype/collection').should_not be_empty
187
-
222
+ multistatus_response('/D:propstat/D:prop/D:resourcetype/D:collection').should_not be_empty
188
223
  get('/copy/a').body.should == 'A'
189
224
  get('/copy/b').body.should == 'B'
190
225
  end
191
226
 
192
227
  it 'should move a collection recursively' do
193
- mkcol('/folder').should be_created
194
- put('/folder/a', :input => 'A').should be_ok
195
- put('/folder/b', :input => 'B').should be_ok
228
+ mkcol('/folder')
229
+ multi_status_created.should eq true
230
+ put('/folder/a', :input => 'A')
231
+ multi_status_ok.should eq true
232
+ put('/folder/b', :input => 'B')
233
+ multi_status_ok.should eq true
196
234
 
197
- move('/folder', 'HTTP_DESTINATION' => '/move').should be_created
235
+ move('/folder', 'HTTP_DESTINATION' => '/move')
236
+ multi_status_ok.should eq true
198
237
  propfind('/move', :input => propfind_xml(:resourcetype))
199
- multistatus_response('/propstat/prop/resourcetype/collection').should_not be_empty
238
+ multistatus_response('/D:propstat/D:prop/D:resourcetype/D:collection').should_not be_empty
200
239
 
201
240
  get('/move/a').body.should == 'A'
202
241
  get('/move/b').body.should == 'B'
@@ -205,9 +244,10 @@ describe RackDAV::Handler do
205
244
  end
206
245
 
207
246
  it 'should create a collection' do
208
- mkcol('/folder').should be_created
247
+ mkcol('/folder')
248
+ multi_status_created.should eq true
209
249
  propfind('/folder', :input => propfind_xml(:resourcetype))
210
- multistatus_response('/propstat/prop/resourcetype/collection').should_not be_empty
250
+ multistatus_response('/D:propstat/D:prop/D:resourcetype/D:collection').should_not be_empty
211
251
  end
212
252
 
213
253
  it 'should not find properties for nonexistent resources' do
@@ -215,56 +255,54 @@ describe RackDAV::Handler do
215
255
  end
216
256
 
217
257
  it 'should find all properties' do
218
- xml = render do |xml|
219
- xml.propfind('xmlns:d' => "DAV:") do
220
- xml.allprop
221
- end
258
+ xml = render(:propfind) do |xml|
259
+ xml.allprop
222
260
  end
223
261
 
224
262
  propfind('http://localhost/', :input => xml)
225
263
 
226
- multistatus_response('/href').first.text.strip.should == 'http://localhost/'
264
+ multistatus_response('/D:href').first.text.strip.should =~ /http:\/\/localhost(:\d+)?\//
227
265
 
228
266
  props = %w(creationdate displayname getlastmodified getetag resourcetype getcontenttype getcontentlength)
229
267
  props.each do |prop|
230
- multistatus_response('/propstat/prop/' + prop).should_not be_empty
268
+ multistatus_response("/D:propstat/D:prop/D:#{prop}").should_not be_empty
231
269
  end
232
270
  end
233
271
 
234
272
  it 'should find named properties' do
235
- put('/test.html', :input => '<html/>').should be_ok
273
+ put('/test.html', :input => '<html/>')
274
+ multi_status_ok.should eq true
236
275
  propfind('/test.html', :input => propfind_xml(:getcontenttype, :getcontentlength))
237
276
 
238
- multistatus_response('/propstat/prop/getcontenttype').first.text.should == 'text/html'
239
- multistatus_response('/propstat/prop/getcontentlength').first.text.should == '7'
277
+ multistatus_response('/D:propstat/D:prop/D:getcontenttype').first.text.should == 'text/html'
278
+ multistatus_response('/D:propstat/D:prop/D:getcontentlength').first.text.should == '7'
240
279
  end
241
280
 
242
281
  it 'should lock a resource' do
243
- put('/test', :input => 'body').should be_ok
282
+ put('/test', :input => 'body')
283
+ multi_status_ok.should eq true
244
284
 
245
- xml = render do |xml|
246
- xml.lockinfo('xmlns:d' => "DAV:") do
247
- xml.lockscope { xml.exclusive }
248
- xml.locktype { xml.write }
249
- xml.owner { xml.href "http://test.de/" }
250
- end
285
+ xml = render(:lockinfo) do |xml|
286
+ xml.lockscope { xml.exclusive }
287
+ xml.locktype { xml.write }
288
+ xml.owner { xml.href "http://test.de/" }
251
289
  end
252
290
 
253
291
  lock('/test', :input => xml)
254
292
 
255
293
  response.should be_ok
256
-
294
+
257
295
  match = lambda do |pattern|
258
- REXML::XPath::match(response_xml, "/prop/lockdiscovery/activelock" + pattern, '' => 'DAV:')
296
+ response_xml.xpath "/D:prop/D:lockdiscovery/D:activelock#{pattern}"
259
297
  end
260
298
 
261
299
  match[''].should_not be_empty
262
300
 
263
- match['/locktype'].should_not be_empty
264
- match['/lockscope'].should_not be_empty
265
- match['/depth'].should_not be_empty
266
- match['/owner'].should_not be_empty
267
- match['/timeout'].should_not be_empty
268
- match['/locktoken'].should_not be_empty
301
+ match['/D:locktype'].should_not be_empty
302
+ match['/D:lockscope'].should_not be_empty
303
+ match['/D:depth'].should_not be_empty
304
+ match['/D:timeout'].should_not be_empty
305
+ match['/D:locktoken'].should_not be_empty
306
+ match['/D:owner'].should_not be_empty
269
307
  end
270
308
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dav4rack
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 17
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 4
10
- version: 0.1.4
9
+ - 5
10
+ version: 0.1.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - Chris Roberts
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-10-22 00:00:00 -07:00
18
+ date: 2010-11-04 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency