Class: RackWebDAV::FileResource
- Includes:
- WEBrick::HTTPUtils
- Defined in:
- lib/rack-webdav/file_resource.rb
Constant Summary collapse
- @@locks =
{}
Instance Attribute Summary
Attributes inherited from Resource
Instance Method Summary collapse
-
#children ⇒ Object
If this is a collection, return the child resources.
-
#collection? ⇒ Boolean
Is this resource a collection?.
-
#content_length ⇒ Object
Return the size in bytes for this resource.
-
#content_type ⇒ Object
Return the mime type of this resource.
-
#copy(dest) ⇒ Object
HTTP COPY request.
-
#creation_date ⇒ Object
Return the creation time.
-
#delete ⇒ Object
HTTP DELETE request.
-
#etag ⇒ Object
Return an Etag, an unique hash value for this resource.
-
#exist? ⇒ Boolean
Does this recource exist?.
-
#get ⇒ Object
HTTP GET request.
- #get_custom_property(name) ⇒ Object
-
#last_modified ⇒ Object
Return the time of last modification.
-
#last_modified=(time) ⇒ Object
Set the time of last modification.
- #list_custom_properties ⇒ Object
- #lock(token, timeout, scope = nil, type = nil, owner = nil) ⇒ Object
- #locked?(token, etag = nil) ⇒ Boolean
- #locks ⇒ Object
-
#make_collection ⇒ Object
HTTP MKCOL request.
-
#move(dest) ⇒ Object
HTTP MOVE request.
- #other_owner_locked?(token, owner) ⇒ Boolean
-
#post ⇒ Object
HTTP POST request.
-
#put ⇒ Object
HTTP PUT request.
-
#resource_type ⇒ Object
Return the resource type.
- #set_custom_property(name, value) ⇒ Object
- #unlock(token) ⇒ Object
-
#write(io) ⇒ Object
Write to this resource from given IO.
Methods inherited from Resource
#==, #child, #descendants, #display_name, #get_property, #initialize, #lockable?, #name, #parent, #property_names, #remove_property, #set_property
Constructor Details
This class inherits a constructor from RackWebDAV::Resource
Instance Method Details
#children ⇒ Object
If this is a collection, return the child resources.
9 10 11 12 13 |
# File 'lib/rack-webdav/file_resource.rb', line 9 def children Dir[file_path + '/*'].map do |path| child File.basename(path) end end |
#collection? ⇒ Boolean
Is this resource a collection?
16 17 18 |
# File 'lib/rack-webdav/file_resource.rb', line 16 def collection? File.directory?(file_path) end |
#content_length ⇒ Object
Return the size in bytes for this resource.
64 65 66 |
# File 'lib/rack-webdav/file_resource.rb', line 64 def content_length stat.size end |
#content_type ⇒ Object
Return the mime type of this resource.
55 56 57 58 59 60 61 |
# File 'lib/rack-webdav/file_resource.rb', line 55 def content_type if stat.directory? "text/html" else mime_type(file_path, DefaultMimeTypes) end end |
#copy(dest) ⇒ Object
HTTP COPY request.
Copy this resource to given destination resource.
141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/rack-webdav/file_resource.rb', line 141 def copy(dest) if stat.directory? dest.make_collection else open(file_path, "rb") do |file| dest.write(file) end list_custom_properties.each do |prop| dest.set_custom_property(prop, get_custom_property(prop)) end end end |
#creation_date ⇒ Object
Return the creation time.
26 27 28 |
# File 'lib/rack-webdav/file_resource.rb', line 26 def creation_date stat.ctime end |
#delete ⇒ Object
HTTP DELETE request.
Delete this resource.
130 131 132 133 134 135 136 |
# File 'lib/rack-webdav/file_resource.rb', line 130 def delete if stat.directory? Dir.rmdir(file_path) else File.unlink(file_path) end end |
#etag ⇒ Object
Return an Etag, an unique hash value for this resource.
41 42 43 |
# File 'lib/rack-webdav/file_resource.rb', line 41 def etag sprintf('%x-%x-%x', stat.ino, stat.size, stat.mtime.to_i) end |
#exist? ⇒ Boolean
Does this recource exist?
21 22 23 |
# File 'lib/rack-webdav/file_resource.rb', line 21 def exist? File.exist?(file_path) end |
#get ⇒ Object
HTTP GET request.
Write the content of the resource to the response.body.
93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/rack-webdav/file_resource.rb', line 93 def get if stat.directory? content = "" Rack::Directory.new(root).call(@request.env)[2].each { |line| content << line } @response.body = [content] @response['Content-Length'] = (content.respond_to?(:bytesize) ? content.bytesize : content.size).to_s else file = File.open(file_path) @response.body = file end end |
#get_custom_property(name) ⇒ Object
80 81 82 83 84 |
# File 'lib/rack-webdav/file_resource.rb', line 80 def get_custom_property(name) value = xattr["rack-webdav:#{name}"] raise HTTPStatus::NotFound if value.nil? value end |
#last_modified ⇒ Object
Return the time of last modification.
31 32 33 |
# File 'lib/rack-webdav/file_resource.rb', line 31 def last_modified stat.mtime end |
#last_modified=(time) ⇒ Object
Set the time of last modification.
36 37 38 |
# File 'lib/rack-webdav/file_resource.rb', line 36 def last_modified=(time) File.utime(Time.now, time, file_path) end |
#list_custom_properties ⇒ Object
86 87 88 |
# File 'lib/rack-webdav/file_resource.rb', line 86 def list_custom_properties xattr.list.select { |a| a.start_with?('rack-webdav') }.map { |a| a.sub(/^rack-webdav:/, '') } end |
#lock(token, timeout, scope = nil, type = nil, owner = nil) ⇒ Object
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/rack-webdav/file_resource.rb', line 187 def lock(token, timeout, scope = nil, type = nil, owner = nil) if scope && type # Create lock @@locks[token] = { :timeout => timeout, :scope => scope, :type => type, :owner => owner, :path => self.path } return true else # Refresh lock lock = @@locks[token] return false unless lock return [ lock[:timeout], lock[:scope], lock[:type], lock[:owner] ] end end |
#locked?(token, etag = nil) ⇒ Boolean
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/rack-webdav/file_resource.rb', line 210 def locked?(token, etag = nil) if token.nil? # check parent directory match already_locks = @@locks.select { |lock_token, lock| found = false Pathname.new(self.path).ascend { |v| found = lock[:path].gsub(/\/$/, '') == v.to_s break if found } lock if found } return !already_locks.empty? else lock_paths = @@locks.select { |lock_token, lock| lock[:path] == self.path } self.exist? && @@locks.key?(token) == false && !lock_paths.empty? end end |
#locks ⇒ Object
239 240 241 |
# File 'lib/rack-webdav/file_resource.rb', line 239 def locks @@locks end |
#make_collection ⇒ Object
HTTP MKCOL request.
Create this resource as collection.
166 167 168 |
# File 'lib/rack-webdav/file_resource.rb', line 166 def make_collection Dir.mkdir(file_path) end |
#move(dest) ⇒ Object
HTTP MOVE request.
Move this resource to given destination resource.
158 159 160 161 |
# File 'lib/rack-webdav/file_resource.rb', line 158 def move(dest) copy(dest) delete end |
#other_owner_locked?(token, owner) ⇒ Boolean
228 229 230 231 232 233 234 235 236 237 |
# File 'lib/rack-webdav/file_resource.rb', line 228 def other_owner_locked?(token, owner) return false if token.nil? return false if @@locks.key?(token) && owner.nil? other_owner = @@locks.select { |lock_token, lock| lock[:path] == self.path }.select { |lock_token, lock| !lock[:owner].nil? && lock[:owner] != owner } !other_owner.empty? end |
#post ⇒ Object
HTTP POST request.
Usually forbidden.
123 124 125 |
# File 'lib/rack-webdav/file_resource.rb', line 123 def post raise HTTPStatus::Forbidden end |
#put ⇒ Object
HTTP PUT request.
Save the content of the request.body.
108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/rack-webdav/file_resource.rb', line 108 def put if @request.env['HTTP_CONTENT_MD5'] content_md5_pass?(@request.env) or raise HTTPStatus::BadRequest.new('Content-MD5 mismatch') end if content_continue_pass?(@request.env) raise HTTPStatus::Continue.new() end write(@request.body) end |
#resource_type ⇒ Object
Return the resource type.
If this is a collection, return a collection element
48 49 50 51 52 |
# File 'lib/rack-webdav/file_resource.rb', line 48 def resource_type if collection? Nokogiri::XML::fragment('<D:collection xmlns:D="DAV:"/>').children.first end end |
#set_custom_property(name, value) ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/rack-webdav/file_resource.rb', line 68 def set_custom_property(name, value) if value.nil? || value.empty? begin xattr.remove("rack-webdav:#{name}") rescue Errno::ENOATTR # If the attribute being deleted doesn't exist, just do nothing end else xattr["rack-webdav:#{name}"] = value end end |
#unlock(token) ⇒ Object
206 207 208 |
# File 'lib/rack-webdav/file_resource.rb', line 206 def unlock(token) !!@@locks.delete(token) end |
#write(io) ⇒ Object
Write to this resource from given IO.
171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/rack-webdav/file_resource.rb', line 171 def write(io) tempfile = "#{file_path}.#{Process.pid}.#{object_id}" open(tempfile, "wb") do |file| while part = io.read(8192) file << part end end File.rename(tempfile, file_path) ensure File.unlink(tempfile) rescue nil end |