Class: DAV4Rack::FileResource

Inherits:
Resource
  • Object
show all
Includes:
Utils, WEBrick::HTTPUtils
Defined in:
lib/dav4rack/resources/file_resource.rb

Constant Summary

Constants included from HTTPStatus

HTTPStatus::StatusMessage

Instance Attribute Summary

Attributes inherited from Resource

#options, #path, #propstat_relative_path, #public_path, #request, #response, #root_xml_attributes, #user

Instance Method Summary collapse

Methods included from Utils

#to_element_hash, #to_element_key

Methods inherited from Resource

#==, #allows_redirect?, #child, #descendants, #display_name, #index_page, #initialize, #is_ms_client?, method_missing, #method_missing, #name, #parent, #parent_collection?, #parent_exists?, #properties, #resource_type, #supports_locking?, #use_compat_mkcol_response?, #use_ms_compat_creationdate?

Constructor Details

This class inherits a constructor from DAV4Rack::Resource

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class DAV4Rack::Resource

Instance Method Details

#childrenObject

If this is a collection, return the child resources.



15
16
17
18
19
# File 'lib/dav4rack/resources/file_resource.rb', line 15

def children
  Dir[file_path + '/*'].map do |path|
    child ::File.basename(path)
  end
end

#collection?Boolean

Is this resource a collection?

Returns:

  • (Boolean)


22
23
24
# File 'lib/dav4rack/resources/file_resource.rb', line 22

def collection?
  ::File.directory?(file_path)
end

#content_lengthObject

Return the size in bytes for this resource.



61
62
63
# File 'lib/dav4rack/resources/file_resource.rb', line 61

def content_length
  stat.size
end

#content_typeObject

Return the mime type of this resource.



52
53
54
55
56
57
58
# File 'lib/dav4rack/resources/file_resource.rb', line 52

def content_type
  if stat.directory?
    "text/html"
  else
    mime_type(file_path, DefaultMimeTypes)
  end
end

#copy(dest, overwrite) ⇒ Object

HTTP COPY request.

Copy this resource to given destination resource. Copy this resource to given destination resource.



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/dav4rack/resources/file_resource.rb', line 116

def copy(dest, overwrite)
  if(collection?)
    if(dest.exist?)
      if(dest.collection? && overwrite)
        FileUtils.cp_r(file_path, dest.send(:file_path))
        Created
      else
        if(overwrite)
          FileUtils.rm(dest.send(:file_path))
          FileUtils.cp_r(file_path, dest.send(:file_path))
          NoContent
        else
          PreconditionFailed
        end
      end
    else
      FileUtils.cp_r(file_path, dest.send(:file_path))
      Created
    end
  else
    if(dest.exist? && !overwrite)
      PreconditionFailed
    else
      if(::File.directory?(::File.dirname(dest.send(:file_path))))
        new = !dest.exist?
        if(dest.collection? && dest.exist?)
          FileUtils.rm_rf(dest.send(:file_path))
        end
        FileUtils.cp(file_path, dest.send(:file_path).sub(/\/$/, ''))
        FileUtils.cp(prop_path, dest.prop_path) if ::File.exist? prop_path
        new ? Created : NoContent
      else
        Conflict
      end
    end
  end
end

#creation_dateObject

Return the creation time.



32
33
34
# File 'lib/dav4rack/resources/file_resource.rb', line 32

def creation_date
  stat.ctime
end

#deleteObject

HTTP DELETE request.

Delete this resource.



101
102
103
104
105
106
107
108
109
110
# File 'lib/dav4rack/resources/file_resource.rb', line 101

def delete
  if stat.directory?
    FileUtils.rm_rf(file_path)
  else
    ::File.unlink(file_path)
  end
  ::File.unlink(prop_path) if ::File.exists?(prop_path)
  @_prop_hash = nil
  NoContent
end

#etagObject

Return an Etag, an unique hash value for this resource.



47
48
49
# File 'lib/dav4rack/resources/file_resource.rb', line 47

def etag
  sprintf('%x-%x-%x', stat.ino, stat.size, stat.mtime.to_i)
end

#exist?Boolean

Does this recource exist?

Returns:

  • (Boolean)


27
28
29
# File 'lib/dav4rack/resources/file_resource.rb', line 27

def exist?
  ::File.exist?(file_path)
end

#get(request, response) ⇒ Object

HTTP GET request.

Write the content of the resource to the response.body.

Raises:

  • (NotFound)


68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/dav4rack/resources/file_resource.rb', line 68

def get(request, response)
  raise NotFound unless exist?
  if stat.directory?
    response.body = ""
    Rack::Directory.new(root).call(request.env)[2].each do |line|
      response.body << line
    end
    response['Content-Length'] = response.body.bytesize.to_s
  else
    file = Rack::File.new(root)
    response.body = file
  end
  OK
end

#get_property(name) ⇒ Object

name

String - Property name

Returns the value of the given property



198
199
200
201
202
203
204
# File 'lib/dav4rack/resources/file_resource.rb', line 198

def get_property(name)
  begin
    super
  rescue NotImplemented
    custom_props(name)
  end
end

#last_modifiedObject

Return the time of last modification.



37
38
39
# File 'lib/dav4rack/resources/file_resource.rb', line 37

def last_modified
  stat.mtime
end

#last_modified=(time) ⇒ Object

Set the time of last modification.



42
43
44
# File 'lib/dav4rack/resources/file_resource.rb', line 42

def last_modified=(time)
  ::File.utime(Time.now, time, file_path)
end

#lock(args) ⇒ Object



225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
# File 'lib/dav4rack/resources/file_resource.rb', line 225

def lock(args)
  unless(parent_exists?)
    Conflict
  else
    lock_check(args[:type])
    lock = FileResourceLock.explicit_locks(@path, root, :scope => args[:scope], :kind => args[:type], :user => @user)
    unless(lock)
      token = UUIDTools::UUID.random_create.to_s
      lock = FileResourceLock.generate(@path, @user, token, root)
      lock.scope = args[:scope]
      lock.kind = args[:type]
      lock.owner = args[:owner]
      lock.depth = args[:depth]
      if(args[:timeout])
        lock.timeout = args[:timeout] <= @max_timeout && args[:timeout] > 0 ? args[:timeout] : @max_timeout
      else
        lock.timeout = @default_timeout
      end
      lock.save
    end
    begin
      lock_check(args[:type])
    rescue DAV4Rack::LockFailure => lock_failure
      lock.destroy
      raise lock_failure
    rescue HTTPStatus::Status => status
      status
    end
    [lock.remaining_timeout, lock.token]
  end
end

#make_collectionObject

HTTP MKCOL request.

Create this resource as collection.



166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/dav4rack/resources/file_resource.rb', line 166

def make_collection
  if(request.body.read.to_s == '')
    if(::File.directory?(file_path))
      MethodNotAllowed
    else
      if(::File.directory?(::File.dirname(file_path)) && !::File.exists?(file_path))
        Dir.mkdir(file_path)
        Created
      else
        Conflict
      end
    end
  else
    UnsupportedMediaType
  end
end

#move(*args) ⇒ Object

HTTP MOVE request.

Move this resource to given destination resource.



157
158
159
160
161
# File 'lib/dav4rack/resources/file_resource.rb', line 157

def move(*args)
  result = copy(*args)
  delete if [Created, NoContent].include?(result)
  result
end

#post(request, response) ⇒ Object

HTTP POST request.

Usually forbidden.

Raises:

  • (HTTPStatus::Forbidden)


94
95
96
# File 'lib/dav4rack/resources/file_resource.rb', line 94

def post(request, response)
  raise HTTPStatus::Forbidden
end

#put(request, response) ⇒ Object

HTTP PUT request.

Save the content of the request.body.



86
87
88
89
# File 'lib/dav4rack/resources/file_resource.rb', line 86

def put(request, response)
  write(request.body)
  Created
end

#remove_property(element) ⇒ Object



217
218
219
220
221
222
223
# File 'lib/dav4rack/resources/file_resource.rb', line 217

def remove_property(element)
  prop_hash.transaction do
    prop_hash.delete(to_element_key(element))
    prop_hash.commit
  end
  val = prop_hash.transaction{ prop_hash[to_element_key(element)] }
end

#set_property(name, value) ⇒ Object

name

String - Property name

value

New value

Set the property to the given value



209
210
211
212
213
214
215
# File 'lib/dav4rack/resources/file_resource.rb', line 209

def set_property(name, value)
  begin
    super
  rescue NotImplemented
    set_custom_props(name,value)
  end
end

#unlock(token) ⇒ Object



257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
# File 'lib/dav4rack/resources/file_resource.rb', line 257

def unlock(token)
  token = token.slice(1, token.length - 2)
  if(token.nil? || token.empty?)
    BadRequest
  else
    lock = FileResourceLock.find_by_token(token)
    if(lock.nil? || lock.user_id != @user.id)
      Forbidden
    elsif(lock.path !~ /^#{Regexp.escape(@path)}.*$/)
      Conflict
    else
      lock.destroy
      NoContent
    end
  end
end

#write(io) ⇒ Object

Write to this resource from given IO.



184
185
186
187
188
189
190
191
192
193
194
# File 'lib/dav4rack/resources/file_resource.rb', line 184

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