Class: Tilia::Dav::TemporaryFileFilterPlugin
- Inherits:
-
ServerPlugin
- Object
- ServerPlugin
- Tilia::Dav::TemporaryFileFilterPlugin
- Defined in:
- lib/tilia/dav/temporary_file_filter_plugin.rb
Overview
Temporary File Filter Plugin
The purpose of this filter is to intercept some of the garbage files operation systems and applications tend to generate when mounting a WebDAV share as a disk.
It will intercept these files and place them in a separate directory. these files are not deleted automatically, so it is adviceable to delete these after they are not accessed for 24 hours.
Currently it supports:
* OS/X style resource forks and .DS_Store
* desktop.ini and Thumbs.db (windows)
* .*.swp (vim temporary files)
* .dat.* (smultron temporary files)
Additional patterns can be added, by adding on to the temporaryFilePatterns property.
Instance Attribute Summary collapse
-
#temporary_file_patterns ⇒ Object
This is the list of patterns we intercept.
Instance Method Summary collapse
-
#before_create_file(uri, data, _parent, _modified) ⇒ Object
This method is invoked if some subsystem creates a new file.
-
#before_method(request, response) ⇒ Object
This method is called before any HTTP method handler.
-
#http_delete(_request, h_r, temp_location) ⇒ Object
This method handles the DELETE method.
-
#http_get(_request, h_r, temp_location) ⇒ Object
This method handles the GET method for temporary files.
-
#http_propfind(request, h_r, temp_location) ⇒ Object
This method handles the PROPFIND method.
-
#http_put(_request, h_r, temp_location) ⇒ Object
This method handles the PUT method.
-
#initialize(data_dir = nil) ⇒ TemporaryFileFilterPlugin
constructor
Creates the plugin.
-
#setup(server) ⇒ Object
Initialize the plugin.
Methods inherited from ServerPlugin
#features, #http_methods, #plugin_info, #plugin_name, #supported_report_set
Constructor Details
#initialize(data_dir = nil) ⇒ TemporaryFileFilterPlugin
Creates the plugin.
Make sure you specify a directory for your files. If you don’t, we will use PHP’s directory for session-storage instead, and you might not want that.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/tilia/dav/temporary_file_filter_plugin.rb', line 48 def initialize(data_dir = nil) @temporary_file_patterns = [ /^\._(.*)$/, # OS/X resource forks /^.DS_Store$/, # OS/X custom folder settings /^desktop.ini$/, # Windows custom folder settings /^Thumbs.db$/, # Windows thumbnail cache /^.(.*).swp$/, # ViM temporary files /^\.dat(.*)$/, # Smultron seems to create these /^~lock.(.*)\#$/ # Windows 7 lockfiles ] data_dir = ::File.join(Dir.tmpdir, 'tiliadav', '') unless data_dir Dir.mkdir(data_dir) unless ::File.directory?(data_dir) @data_dir = data_dir end |
Instance Attribute Details
#temporary_file_patterns ⇒ Object
This is the list of patterns we intercept. If new patterns are added, they must be valid patterns for preg_match.
28 29 30 |
# File 'lib/tilia/dav/temporary_file_filter_plugin.rb', line 28 def temporary_file_patterns @temporary_file_patterns end |
Instance Method Details
#before_create_file(uri, data, _parent, _modified) ⇒ Object
This method is invoked if some subsystem creates a new file.
This is used to deal with HTTP LOCK requests which create a new file.
114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/tilia/dav/temporary_file_filter_plugin.rb', line 114 def before_create_file(uri, data, _parent, _modified) temp_path = temp_file?(uri) if temp_path h_r = @server.http_response h_r.update_header('X-Sabre-Temp', 'true') ::File.open(temp_path, 'w') do |file| file.write(data) end return false end nil end |
#before_method(request, response) ⇒ Object
This method is called before any HTTP method handler
This method intercepts any GET, DELETE, PUT and PROPFIND calls to filenames that are known to match the ‘temporary file’ regex.
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/tilia/dav/temporary_file_filter_plugin.rb', line 85 def before_method(request, response) temp_location = temp_file?(request.path) return true unless temp_location case request.method when 'GET' http_get(request, response, temp_location) when 'PUT' http_put(request, response, temp_location) when 'PROPFIND' http_propfind(request, response, temp_location) when 'DELETE' http_delete(request, response, temp_location) else true end end |
#http_delete(_request, h_r, temp_location) ⇒ Object
This method handles the DELETE method.
If the file didn’t exist, it will return false, which will make the standard HTTP DELETE handler kick in.
202 203 204 205 206 207 208 209 |
# File 'lib/tilia/dav/temporary_file_filter_plugin.rb', line 202 def http_delete(_request, h_r, temp_location) return nil unless ::File.exist?(temp_location) ::File.unlink(temp_location) h_r.update_header('X-Sabre-Temp', 'true') h_r.status = 204 false end |
#http_get(_request, h_r, temp_location) ⇒ Object
This method handles the GET method for temporary files. If the file doesn’t exist, it will return false which will kick in the regular system for the GET method.
159 160 161 162 163 164 165 166 167 168 |
# File 'lib/tilia/dav/temporary_file_filter_plugin.rb', line 159 def http_get(_request, h_r, temp_location) return nil unless ::File.exist?(temp_location) h_r.update_header('Content-Type', 'application/octet-stream') h_r.update_header('Content-Length', ::File.size(temp_location)) h_r.update_header('X-Sabre-Temp', 'true') h_r.status = 200 h_r.body = ::File.open(temp_location, 'r') false end |
#http_propfind(request, h_r, temp_location) ⇒ Object
This method handles the PROPFIND method.
It’s a very lazy method, it won’t bother checking the request body for which properties were requested, and just sends back a default set of properties.
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/tilia/dav/temporary_file_filter_plugin.rb', line 221 def http_propfind(request, h_r, temp_location) return false unless ::File.exist?(temp_location) h_r.update_header('X-Sabre-Temp', 'true') h_r.status = 207 h_r.update_header('Content-Type', 'application/xml; charset=utf-8') properties = { 'href' => request.path, 200 => { '{DAV:}getlastmodified' => Xml::Property::GetLastModified.new(::File.mtime(temp_location)), '{DAV:}getcontentlength' => ::File.size(temp_location), '{DAV:}resourcetype' => Xml::Property::ResourceType.new(nil), "{#{Server::NS_SABREDAV}}tempFile" => true } } data = @server.generate_multi_status([properties]) h_r.body = data false end |
#http_put(_request, h_r, temp_location) ⇒ Object
This method handles the PUT method.
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/tilia/dav/temporary_file_filter_plugin.rb', line 176 def http_put(_request, h_r, temp_location) h_r.update_header('X-Sabre-Temp', 'true') new_file = !::File.exist?(temp_location) if !new_file && @server.http_request.header('If-None-Match') fail Exception::PreconditionFailed, 'The resource already exists, and an If-None-Match header was supplied' end ::File.open(temp_location, 'w') do |file| file.write(@server.http_request.body) end h_r.status = new_file ? 201 : 200 false end |
#setup(server) ⇒ Object
Initialize the plugin
This is called automatically be the Server class after this plugin is added with SabreDAVServer::add_plugin
71 72 73 74 75 |
# File 'lib/tilia/dav/temporary_file_filter_plugin.rb', line 71 def setup(server) @server = server @server.on('beforeMethod', method(:before_method)) @server.on('beforeCreateFile', method(:before_create_file)) end |