dav4rack 0.2.7 → 0.2.8

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