Skip to content
thorek edited this page Mar 2, 2013 · 19 revisions

Rails 3 Integration

A basic example

Minimal integration application at: http://github.com/clyfe/rails3-dav4rack-example
NOTE. People reported that for maximum compatibility (with all kinds of webdav clients) webdav is to be mounted in the root ‘/’ and run on port 80, so a subdomain is perfect in that regard. Also by using a subdomain we don’t need a DAV4Rack::Interceptor.

This is a step by step tutorial based on the sample application

Install

Add dav4rack to your Gemfile gem 'dav4rack'
Run bundle install to install it.

Fix Rails < 3.0.2

Issue here
Patch Rails’s HTTP method validation to allow WebDAV HTTP extension verbs in an initializer.

# config/initializers/rails_webdav_patch.rb
%w(propfind proppatch mkcol copy move lock unlock).each do |method|
  ActionDispatch::Request::HTTP_METHODS << method.upcase
  ActionDispatch::Request::HTTP_METHOD_LOOKUP[method.upcase] = method.to_sym
end

Load your resources

Create a webdav initializer at config/initializers/webdav.rb.
In this file you will load your custom resources (A resource is a class that implements DAV4Rack::Resource).
For the time being we will just use the bundled FileResource to serve files from our Rails.root directory for ilustrative purpouses.

# config/initializers/webdav.rb
require 'dav4rack/file_resource'

For dav4rack-0.3.0, Rails 3.2.11 and ruby-1.9.3 and I found you need to require

# config/initializers/webdav.rb
require 'dav4rack/resources/file_resource'

Mount your handlers

Mount your dav4rack handlers in routes.rb. In this example we mount our handler on the webdav.domain.com subdomain.
Note that mount is a special case of match, it takes the parameters backwards and is not anchored by default (matches all paths that start with the given path, see http://inductor.induktiv.at/blog/2010/05/23/mount-rack-apps-in-rails-3/).

# config/routes.rb
HelloDav::Application.routes.draw do
  mount DAV4Rack::Handler.new( :root => Rails.root.to_s, :root_uri_path => '/',
    :resource_class => ::DAV4Rack::FileResource
  ), :at => '/', :constraints => {:subdomain => "webdav"}
end

You can also mount a handler on a path segment on the main domain, say ‘/webdav’:

# config/routes.rb
HelloDav::Application.routes.draw do
  mount DAV4Rack::Handler.new( :root => Rails.root.to_s, :root_uri_path => '/webdav',
    :resource_class => ::DAV4Rack::FileResource
  ), :at => '/webdav/'
end

Understand that mounting the handler on a path segment will limit the number of WebDAV clients that can talk to your handler successfully. You find a some hints on striving for compatibility at Milton’s site: Server implementation requirements. Understand that some of these issues are partially addressed by DAV4Rack::Interceptor, see this comment .

We could also use match:

# config/routes.rb
HelloDav::Application.routes.draw do
  match '/webdav' => DAV4Rack::Handler.new( :root => Rails.root.to_s, :root_uri_path => '/webdav',
    :resource_class => ::DAV4Rack::FileResource
  ), :anchor => false
end
Enable upstream paths with Interceptors

:TBD

Advanced example