dav4rack 0.2.7 → 0.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -308,6 +308,7 @@ A big thanks to everyone contributing to help make this project better.
308
308
  * {teefax}[http://github.com/teefax]
309
309
  * {buffym}[https://github.com/buffym]
310
310
  * {jbangert}[https://github.com/jbangert]
311
+ * {doxavore}[https://github.com/doxavore]
311
312
 
312
313
  == License
313
314
 
@@ -44,35 +44,45 @@ module DAV4Rack
44
44
 
45
45
  # Return response to HEAD
46
46
  def head
47
- raise NotFound unless resource.exist?
48
- response['Etag'] = resource.etag
49
- response['Content-Type'] = resource.content_type
50
- response['Last-Modified'] = resource.last_modified.httpdate
51
- OK
47
+ if(resource.exist?)
48
+ response['Etag'] = resource.etag
49
+ response['Content-Type'] = resource.content_type
50
+ response['Last-Modified'] = resource.last_modified.httpdate
51
+ OK
52
+ else
53
+ NotFound
54
+ end
52
55
  end
53
56
 
54
57
  # Return response to GET
55
58
  def get
56
- raise NotFound unless resource.exist?
57
- res = resource.get(request, response)
58
- if(res == OK && !resource.collection?)
59
- response['Etag'] = resource.etag
60
- response['Content-Type'] = resource.content_type
61
- response['Content-Length'] = resource.content_length.to_s
62
- response['Last-Modified'] = resource.last_modified.httpdate
59
+ if(resource.exist?)
60
+ res = resource.get(request, response)
61
+ if(res == OK && !resource.collection?)
62
+ response['Etag'] = resource.etag
63
+ response['Content-Type'] = resource.content_type
64
+ response['Content-Length'] = resource.content_length.to_s
65
+ response['Last-Modified'] = resource.last_modified.httpdate
66
+ end
67
+ res
68
+ else
69
+ NotFound
63
70
  end
64
- res
65
71
  end
66
72
 
67
73
  # Return response to PUT
68
74
  def put
69
- raise Forbidden if resource.collection?
70
- raise Conflict unless resource.parent_exists? && resource.parent.collection?
71
- resource.lock_check
72
- status = resource.put(request, response)
73
- response['Location'] = "#{scheme}://#{host}:#{port}#{resource.public_path}" if status == Created
74
- response.body = response['Location']
75
- status
75
+ if(resource.collection?)
76
+ Forbidden
77
+ elsif(!resource.parent_exists? || !resource.parent.collection?)
78
+ Conflict
79
+ else
80
+ resource.lock_check
81
+ status = resource.put(request, response)
82
+ response['Location'] = "#{scheme}://#{host}:#{port}#{resource.public_path}" if status == Created
83
+ response.body = response['Location']
84
+ status
85
+ end
76
86
  end
77
87
 
78
88
  # Return response to POST
@@ -82,9 +92,12 @@ module DAV4Rack
82
92
 
83
93
  # Return response to DELETE
84
94
  def delete
85
- raise NotFound unless resource.exist?
86
- resource.lock_check
87
- resource.delete
95
+ if(resource.exist?)
96
+ resource.lock_check
97
+ resource.delete
98
+ else
99
+ NotFound
100
+ end
88
101
  end
89
102
 
90
103
  # Return response to MKCOL
@@ -108,43 +121,53 @@ module DAV4Rack
108
121
  # Move Resource to new location. If :copy is provided,
109
122
  # Resource will be copied (implementation ease)
110
123
  def move(*args)
111
- raise NotFound unless resource.exist?
112
- resource.lock_check unless args.include?(:copy)
113
- destination = url_unescape(env['HTTP_DESTINATION'].sub(%r{https?://([^/]+)}, ''))
114
- dest_host = $1
115
- raise BadGateway if dest_host and dest_host.gsub(/:\d{2,5}$/,'') != request.host
116
- raise Forbidden if destination == resource.public_path
117
- dest = resource_class.new(destination, clean_path(destination), @request, @response, @options.merge(:user => resource.user))
118
- status = nil
119
- if(args.include?(:copy))
120
- status = resource.copy(dest, overwrite)
124
+ unless(resource.exist?)
125
+ NotFound
121
126
  else
122
- raise Conflict unless depth.is_a?(Symbol) || depth > 1
123
- status = resource.move(dest, overwrite)
124
- end
125
- response['Location'] = "#{scheme}://#{host}:#{port}#{dest.public_path}" if status == Created
126
- multistatus do |xml|
127
- xml.response do
128
- xml.href "#{scheme}://#{host}:#{port}#{status == Created ? dest.public_path : resource.public_path}"
129
- xml.status "#{http_version} #{status.status_line}"
127
+ resource.lock_check unless args.include?(:copy)
128
+ destination = url_unescape(env['HTTP_DESTINATION'].sub(%r{https?://([^/]+)}, ''))
129
+ dest_host = $1
130
+ if(dest_host && dest_host.gsub(/:\d{2,5}$/, '') != request.host)
131
+ BadGateway
132
+ elsif(destination == resource.public_path)
133
+ Forbidden
134
+ else
135
+ dest = resource_class.new(destination, clean_path(destination), @request, @response, @options.merge(:user => resource.user))
136
+ status = nil
137
+ if(args.include?(:copy))
138
+ status = resource.copy(dest, overwrite)
139
+ else
140
+ return Conflict unless depth.is_a?(Symbol) || depth > 1
141
+ status = resource.move(dest, overwrite)
142
+ end
143
+ response['Location'] = "#{scheme}://#{host}:#{port}#{dest.public_path}" if status == Created
144
+ multistatus do |xml|
145
+ xml.response do
146
+ xml.href "#{scheme}://#{host}:#{port}#{status == Created ? dest.public_path : resource.public_path}"
147
+ xml.status "#{http_version} #{status.status_line}"
148
+ end
149
+ end
130
150
  end
131
151
  end
132
152
  end
133
153
 
134
154
  # Return respoonse to PROPFIND
135
155
  def propfind
136
- raise NotFound unless resource.exist?
137
- unless(request_document.xpath("//#{ns}propfind/#{ns}allprop").empty?)
138
- names = resource.property_names
156
+ unless(resource.exist?)
157
+ NotFound
139
158
  else
140
- names = request_document.xpath("//#{ns}propfind/#{ns}prop").children.find_all{|n|n.element?}.map{|n|n.name}
141
- names = resource.property_names if names.empty?
142
- end
143
- multistatus do |xml|
144
- find_resources.each do |resource|
145
- xml.response do
146
- xml.href "#{scheme}://#{host}:#{port}#{url_escape(resource.public_path)}"
147
- propstats(xml, get_properties(resource, names))
159
+ unless(request_document.xpath("//#{ns}propfind/#{ns}allprop").empty?)
160
+ names = resource.property_names
161
+ else
162
+ names = request_document.xpath("//#{ns}propfind/#{ns}prop").children.find_all{|n|n.element?}.map{|n|n.name}
163
+ names = resource.property_names if names.empty?
164
+ end
165
+ multistatus do |xml|
166
+ find_resources.each do |resource|
167
+ xml.response do
168
+ xml.href "#{scheme}://#{host}:#{port}#{url_escape(resource.public_path)}"
169
+ propstats(xml, get_properties(resource, names))
170
+ end
148
171
  end
149
172
  end
150
173
  end
@@ -152,15 +175,18 @@ module DAV4Rack
152
175
 
153
176
  # Return response to PROPPATCH
154
177
  def proppatch
155
- raise NotFound unless resource.exist?
156
- resource.lock_check
157
- prop_rem = request_match('/propertyupdate/remove/prop').children.map{|n| [n.name] }
158
- prop_set = request_match('/propertyupdate/set/prop').children.map{|n| [n.name, n.text] }
159
- multistatus do |xml|
160
- find_resources.each do |resource|
161
- xml.response do
162
- xml.href "#{scheme}://#{host}:#{port}#{url_escape(resource.public_path)}"
163
- propstats(xml, set_properties(resource, prop_set))
178
+ unless(resource.exist?)
179
+ NotFound
180
+ else
181
+ resource.lock_check
182
+ prop_rem = request_match('/propertyupdate/remove/prop').children.map{|n| [n.name] }
183
+ prop_set = request_match('/propertyupdate/set/prop').children.map{|n| [n.name, n.text] }
184
+ multistatus do |xml|
185
+ find_resources.each do |resource|
186
+ xml.response do
187
+ xml.href "#{scheme}://#{host}:#{port}#{url_escape(resource.public_path)}"
188
+ propstats(xml, set_properties(resource, prop_set))
189
+ end
164
190
  end
165
191
  end
166
192
  end
@@ -171,48 +197,50 @@ module DAV4Rack
171
197
  # NOTE: This will pass an argument hash to Resource#lock and
172
198
  # wait for a success/failure response.
173
199
  def lock
174
- raise NotFound unless resource.exist?
175
200
  lockinfo = request_document.xpath("//#{ns}lockinfo")
176
201
  asked = {}
177
202
  asked[:timeout] = request.env['Timeout'].split(',').map{|x|x.strip} if request.env['Timeout']
178
203
  asked[:depth] = depth
179
- raise BadRequest unless [0, :infinity].include?(asked[:depth])
180
- asked[:scope] = lockinfo.xpath("//#{ns}lockscope").children.find_all{|n|n.element?}.map{|n|n.name}.first
181
- asked[:type] = lockinfo.xpath("#{ns}locktype").children.find_all{|n|n.element?}.map{|n|n.name}.first
182
- asked[:owner] = lockinfo.xpath("//#{ns}owner/#{ns}href").children.map{|n|n.text}.first
183
- begin
184
- lock_time, locktoken = resource.lock(asked)
185
- render_xml(:prop) do |xml|
186
- xml.lockdiscovery do
187
- xml.activelock do
188
- if(asked[:scope])
189
- xml.lockscope do
190
- xml.send(asked[:scope])
204
+ unless([0, :infinity].include?(asked[:depth]))
205
+ BadRequest
206
+ else
207
+ asked[:scope] = lockinfo.xpath("//#{ns}lockscope").children.find_all{|n|n.element?}.map{|n|n.name}.first
208
+ asked[:type] = lockinfo.xpath("#{ns}locktype").children.find_all{|n|n.element?}.map{|n|n.name}.first
209
+ asked[:owner] = lockinfo.xpath("//#{ns}owner/#{ns}href").children.map{|n|n.text}.first
210
+ begin
211
+ lock_time, locktoken = resource.lock(asked)
212
+ render_xml(:prop) do |xml|
213
+ xml.lockdiscovery do
214
+ xml.activelock do
215
+ if(asked[:scope])
216
+ xml.lockscope do
217
+ xml.send(asked[:scope])
218
+ end
191
219
  end
192
- end
193
- if(asked[:type])
194
- xml.locktype do
195
- xml.send(asked[:type])
220
+ if(asked[:type])
221
+ xml.locktype do
222
+ xml.send(asked[:type])
223
+ end
224
+ end
225
+ xml.depth asked[:depth].to_s
226
+ xml.timeout lock_time ? "Second-#{lock_time}" : 'infinity'
227
+ xml.locktoken do
228
+ xml.href locktoken
229
+ end
230
+ if(asked[:owner])
231
+ xml.owner asked[:owner]
196
232
  end
197
- end
198
- xml.depth asked[:depth].to_s
199
- xml.timeout lock_time ? "Second-#{lock_time}" : 'infinity'
200
- xml.locktoken do
201
- xml.href locktoken
202
- end
203
- if(asked[:owner])
204
- xml.owner asked[:owner]
205
233
  end
206
234
  end
207
235
  end
208
- end
209
- response.status = resource.exist? ? OK : Created
210
- rescue LockFailure => e
211
- multistatus do |xml|
212
- e.path_status.each_pair do |path, status|
213
- xml.response do
214
- xml.href path
215
- xml.status "#{http_version} #{status.status_line}"
236
+ response.status = resource.exist? ? OK : Created
237
+ rescue LockFailure => e
238
+ multistatus do |xml|
239
+ e.path_status.each_pair do |path, status|
240
+ xml.response do
241
+ xml.href path
242
+ xml.status "#{http_version} #{status.status_line}"
243
+ end
216
244
  end
217
245
  end
218
246
  end
@@ -8,10 +8,12 @@ module DAV4Rack
8
8
  # args:: Arguments for Logger -> [path, level] (level is optional) or a Logger instance
9
9
  # Set the path to the log file.
10
10
  def set(*args)
11
- if(args.first.is_a?(Logger))
11
+ if(%w(info debug warn fatal).all?{|meth| args.first.respond_to?(meth)})
12
12
  @@logger = args.first
13
- else
14
- @@logger = ::Logger.new(args.first, 'weekly')
13
+ elsif(args.first.respond_to?(:to_s) && !args.first.to_s.empty?)
14
+ @@logger = ::Logger.new(args.first.to_s, 'weekly')
15
+ elsif(args.first)
16
+ raise 'Invalid type specified for logger'
15
17
  end
16
18
  if(args.size > 1)
17
19
  @@logger.level = args[1]
@@ -117,17 +117,17 @@ module DAV4Rack
117
117
 
118
118
  # If this is a collection, return the child resources.
119
119
  def children
120
- raise NotImplementedError
120
+ NotImplemented
121
121
  end
122
122
 
123
123
  # Is this resource a collection?
124
124
  def collection?
125
- raise NotImplementedError
125
+ NotImplemented
126
126
  end
127
127
 
128
128
  # Does this resource exist?
129
129
  def exist?
130
- raise NotImplementedError
130
+ NotImplemented
131
131
  end
132
132
 
133
133
  # Does the parent resource exist?
@@ -137,22 +137,22 @@ module DAV4Rack
137
137
 
138
138
  # Return the creation time.
139
139
  def creation_date
140
- raise NotImplementedError
140
+ NotImplemented
141
141
  end
142
142
 
143
143
  # Return the time of last modification.
144
144
  def last_modified
145
- raise NotImplementedError
145
+ NotImplemented
146
146
  end
147
147
 
148
148
  # Set the time of last modification.
149
149
  def last_modified=(time)
150
- raise NotImplementedError
150
+ NotImplemented
151
151
  end
152
152
 
153
153
  # Return an Etag, an unique hash value for this resource.
154
154
  def etag
155
- raise NotImplementedError
155
+ NotImplemented
156
156
  end
157
157
 
158
158
  # Return the resource type. Generally only used to specify
@@ -163,54 +163,54 @@ module DAV4Rack
163
163
 
164
164
  # Return the mime type of this resource.
165
165
  def content_type
166
- raise NotImplementedError
166
+ NotImplemented
167
167
  end
168
168
 
169
169
  # Return the size in bytes for this resource.
170
170
  def content_length
171
- raise NotImplementedError
171
+ NotImplemented
172
172
  end
173
173
 
174
174
  # HTTP GET request.
175
175
  #
176
176
  # Write the content of the resource to the response.body.
177
177
  def get(request, response)
178
- raise NotImplementedError
178
+ NotImplemented
179
179
  end
180
180
 
181
181
  # HTTP PUT request.
182
182
  #
183
183
  # Save the content of the request.body.
184
184
  def put(request, response)
185
- raise NotImplementedError
185
+ NotImplemented
186
186
  end
187
187
 
188
188
  # HTTP POST request.
189
189
  #
190
190
  # Usually forbidden.
191
191
  def post(request, response)
192
- raise NotImplementedError
192
+ NotImplemented
193
193
  end
194
194
 
195
195
  # HTTP DELETE request.
196
196
  #
197
197
  # Delete this resource.
198
198
  def delete
199
- raise NotImplementedError
199
+ NotImplemented
200
200
  end
201
201
 
202
202
  # HTTP COPY request.
203
203
  #
204
204
  # Copy this resource to given destination resource.
205
205
  def copy(dest, overwrite=false)
206
- raise NotImplementedError
206
+ NotImplemented
207
207
  end
208
208
 
209
209
  # HTTP MOVE request.
210
210
  #
211
211
  # Move this resource to given destination resource.
212
212
  def move(dest, overwrite=false)
213
- raise NotImplemented
213
+ NotImplemented
214
214
  end
215
215
 
216
216
  # args:: Hash of lock arguments
@@ -229,31 +229,39 @@ module DAV4Rack
229
229
  # (http://www.webdav.org/specs/rfc4918.html#rfc.section.9.10)
230
230
 
231
231
  def lock(args)
232
- raise NotImplemented if @lock_class.nil?
233
- raise Conflict unless parent_exists?
234
- lock_check(args[:scope])
235
- lock = @lock_class.explicit_locks(@path).find{|l| l.scope == args[:scope] && l.kind == args[:type] && l.user == @user}
236
- unless(lock)
237
- token = UUIDTools::UUID.random_create.to_s
238
- lock = @lock_class.generate(@path, @user, token)
239
- lock.scope = args[:scope]
240
- lock.kind = args[:type]
241
- lock.owner = args[:owner]
242
- lock.depth = args[:depth].is_a?(Symbol) ? args[:depth] : args[:depth].to_i
243
- if(args[:timeout])
244
- lock.timeout = args[:timeout] <= @max_timeout && args[:timeout] > 0 ? args[:timeout] : @max_timeout
232
+ unless(@lock_class)
233
+ NotImplemented
234
+ else
235
+ unless(parent_exists?)
236
+ Conflict
245
237
  else
246
- lock.timeout = @default_timeout
238
+ lock_check(args[:scope])
239
+ lock = @lock_class.explicit_locks(@path).find{|l| l.scope == args[:scope] && l.kind == args[:type] && l.user == @user}
240
+ unless(lock)
241
+ token = UUIDTools::UUID.random_create.to_s
242
+ lock = @lock_class.generate(@path, @user, token)
243
+ lock.scope = args[:scope]
244
+ lock.kind = args[:type]
245
+ lock.owner = args[:owner]
246
+ lock.depth = args[:depth].is_a?(Symbol) ? args[:depth] : args[:depth].to_i
247
+ if(args[:timeout])
248
+ lock.timeout = args[:timeout] <= @max_timeout && args[:timeout] > 0 ? args[:timeout] : @max_timeout
249
+ else
250
+ lock.timeout = @default_timeout
251
+ end
252
+ lock.save if lock.respond_to? :save
253
+ end
254
+ begin
255
+ lock_check(args[:type])
256
+ rescue DAV4Rack::LockFailure => lock_failure
257
+ lock.destroy
258
+ raise lock_failure
259
+ rescue HTTPStatus::Status => status
260
+ status
261
+ end
262
+ [lock.remaining_timeout, lock.token]
247
263
  end
248
- lock.save if lock.respond_to? :save
249
- end
250
- begin
251
- lock_check(args[:type])
252
- rescue DAV4Rack::LockFailure => e
253
- lock.destroy
254
- raise e
255
264
  end
256
- [lock.remaining_timeout, lock.token]
257
265
  end
258
266
 
259
267
  # lock_scope:: scope of lock
@@ -286,20 +294,30 @@ module DAV4Rack
286
294
  # token:: Lock token
287
295
  # Remove the given lock
288
296
  def unlock(token)
289
- raise NotImplemented if @lock_class.nil?
290
- token = token.slice(1, token.length - 2)
291
- raise BadRequest if token.nil? || token.empty?
292
- lock = @lock_class.find_by_token(token)
293
- raise Forbidden unless lock && lock.user == @user
294
- raise Conflict unless lock.path =~ /^#{Regexp.escape(@path)}.*$/
295
- lock.destroy
296
- NoContent
297
+ unless(@lock_class)
298
+ NotImplemented
299
+ else
300
+ token = token.slice(1, token.length - 2)
301
+ if(token.nil? || token.empty?)
302
+ BadRequest
303
+ else
304
+ lock = @lock_class.find_by_token(token)
305
+ if(lock.nil? || lock.user != @user)
306
+ Forbidden
307
+ elsif(lock.path !~ /^#{Regexp.escape(@path)}.*$/)
308
+ Conflict
309
+ else
310
+ lock.destroy
311
+ NoContent
312
+ end
313
+ end
314
+ end
297
315
  end
298
316
 
299
317
 
300
318
  # Create this resource as collection.
301
319
  def make_collection
302
- raise NotImplementedError
320
+ NotImplemented
303
321
  end
304
322
 
305
323
  # other:: Resource
@@ -348,13 +366,13 @@ module DAV4Rack
348
366
  when 'getlastmodified' then self.last_modified = Time.httpdate(value)
349
367
  end
350
368
  rescue ArgumentError
351
- raise HTTPStatus::Conflict
369
+ Conflict
352
370
  end
353
371
 
354
372
  # name:: Property name
355
373
  # Remove the property from the resource
356
374
  def remove_property(name)
357
- raise HTTPStatus::Forbidden
375
+ Forbidden
358
376
  end
359
377
 
360
378
  # name:: Name of child
@@ -13,5 +13,5 @@ module DAV4Rack
13
13
  end
14
14
  end
15
15
 
16
- VERSION = Version.new('0.2.7')
16
+ VERSION = Version.new('0.2.8')
17
17
  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: 25
4
+ hash: 7
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 7
10
- version: 0.2.7
9
+ - 8
10
+ version: 0.2.8
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: 2011-08-23 00:00:00 -07:00
18
+ date: 2011-08-26 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency