diff --git a/lib/redmine_dmsf/webdav/base_resource.rb b/lib/redmine_dmsf/webdav/base_resource.rb index 3f1ff69b..517ad763 100644 --- a/lib/redmine_dmsf/webdav/base_resource.rb +++ b/lib/redmine_dmsf/webdav/base_resource.rb @@ -60,8 +60,8 @@ module RedmineDmsf @public_path.force_encoding('utf-8') end - # Generate HTML for Get requests - def html_display + # Generate HTML for Get requests, or Head requests if no_body is true + def html_display(no_body = false) @response.body = '' Confict unless collection? entities = children.map{|child| @@ -80,7 +80,7 @@ module RedmineDmsf '', '', ] + entities if parent - @response.body << index_page % [ path.empty? ? '/' : path, path.empty? ? '/' : path, entities ] + @response.body << index_page % [ path.empty? ? '/' : path, path.empty? ? '/' : path, entities ] unless no_body end # Run method through proxy class - ensuring always compatible child is generated @@ -170,4 +170,4 @@ module RedmineDmsf end end end -end \ No newline at end of file +end diff --git a/lib/redmine_dmsf/webdav/controller.rb b/lib/redmine_dmsf/webdav/controller.rb index 26a07b13..9d52032c 100644 --- a/lib/redmine_dmsf/webdav/controller.rb +++ b/lib/redmine_dmsf/webdav/controller.rb @@ -26,6 +26,20 @@ module RedmineDmsf class Controller < DAV4Rack::Controller include DAV4Rack::Utils + # Return response to OPTIONS + def options + # Always return MethodNotAllowed(405) because how MsOffice uses anonymous OPTIONS request. + # See https://support.microsoft.com/en-us/kb/2019105 + MethodNotAllowed + end + + # Return response to HEAD + def head + # Don't check resource.exist? because it returns false for anonymous requests and MsOffice's uses anonymous HEAD requests. + # See https://support.microsoft.com/en-us/kb/2019105 + resource.head(request, response) + end + # Return response to PROPFIND def propfind unless(resource.exist?) diff --git a/lib/redmine_dmsf/webdav/dmsf_resource.rb b/lib/redmine_dmsf/webdav/dmsf_resource.rb index cf3c5e37..f12dde95 100644 --- a/lib/redmine_dmsf/webdav/dmsf_resource.rb +++ b/lib/redmine_dmsf/webdav/dmsf_resource.rb @@ -194,6 +194,22 @@ module RedmineDmsf OK end + # Process incoming HEAD request + # + # MsOFfice uses anonymous HEAD requests, so always return a response. + # See https://support.microsoft.com/en-us/kb/2019105 + ## + def head(request, response) + raise NotFound unless project && project.module_enabled?('dmsf') && (folder || file) + if collection? + html_display(true) + response['Content-Length'] = response.body.bytesize.to_s + else + response.body = '' + end + OK + end + # Process incoming MKCOL request # # Create a DmsfFolder at location requested, only if parent is a folder (or root) diff --git a/lib/redmine_dmsf/webdav/index_resource.rb b/lib/redmine_dmsf/webdav/index_resource.rb index bc39e8b4..0acf48e0 100644 --- a/lib/redmine_dmsf/webdav/index_resource.rb +++ b/lib/redmine_dmsf/webdav/index_resource.rb @@ -68,6 +68,12 @@ module RedmineDmsf 4096 end + def head(request, response) + html_display(true) + response['Content-Length'] = response.body.bytesize.to_s + OK + end + def get(request, response) html_display response['Content-Length'] = response.body.bytesize.to_s diff --git a/lib/redmine_dmsf/webdav/project_resource.rb b/lib/redmine_dmsf/webdav/project_resource.rb index 459f0d96..36a9588b 100644 --- a/lib/redmine_dmsf/webdav/project_resource.rb +++ b/lib/redmine_dmsf/webdav/project_resource.rb @@ -80,6 +80,12 @@ module RedmineDmsf 4096 end + def head(request, response) + html_display(true) + response['Content-Length'] = response.body.bytesize.to_s + OK + end + def get(request, response) html_display response['Content-Length'] = response.body.bytesize.to_s @@ -95,4 +101,4 @@ module RedmineDmsf end end -end \ No newline at end of file +end diff --git a/lib/redmine_dmsf/webdav/resource_proxy.rb b/lib/redmine_dmsf/webdav/resource_proxy.rb index 15b933d4..782ff67d 100644 --- a/lib/redmine_dmsf/webdav/resource_proxy.rb +++ b/lib/redmine_dmsf/webdav/resource_proxy.rb @@ -51,7 +51,10 @@ module RedmineDmsf # going to fork it to ensure compliance, checking the request method in the authentication # seems the next best step, if the request method is OPTIONS return true, controller will simply # call the options method within, which accesses nothing, just returns headers about dav env. - return true if @request.request_method.downcase == 'options' && (path == '/' || path.empty?) + #return true if @request.request_method.downcase == 'options' && (path == '/' || path.empty?) + # MsOffice does anonymous OPTIONS and HEAD requests. + return true if @request.request_method.downcase == 'options' + return true if @request.request_method.downcase == 'head' return false unless username && password User.current = User.try_to_login(username, password) return User.current && !User.current.anonymous? @@ -97,6 +100,10 @@ module RedmineDmsf @resource_c.content_length end + def head(request,response) + @resource_c.head(request, response) + end + def get(request, response) @resource_c.get(request, response) end