Я создал сервер webdav в своем приложении rails, используя гем rack-webdav.
Я использую базовую аутентификацию Rack в своем приложении rails.
При использовании libre office я могу: 1. увидеть файл в браузере файлов, 2. открыть файл, 3. отредактировать и 4. загрузить файл.
При использовании ms word без базовой аутентификации в стойке я могу: 1. увидеть файл в браузере файлов, 2. открыть файл, 3. отредактировать и 4. загрузить файл.
При использовании ms word WITH базовой аутентификации в стойке я могу только 1. увидеть файл в файловом браузере.
При попытке открыть файл в формате ms word с помощью обычной аутентификации в стойке на сервер делается запрос propfind, который возвращает 400 неверных запросов. Я добавил привязывающий pry в метод propfind, и он не останавливает выполнение кода, что означает, что он никогда не попадет в метод контроллера. Я знаю, что базовая аутентификация Rack выдает 400 неверных запросов, когда в запрос не включена аутентификация.
Вот как я настраиваю webdav в Windows 10 и повторяю проблему:
зайдите в каталог моего компьютера в windows
щелкните правой кнопкой мыши сеть и выберите карту сетевого диска
в поле папки, введите информацию о сервере webdav, авторизуйтесь и нажмите Готово
откройте слово MS, щелкните файл и просмотрите
перейти к сетевому диску
Я вижу файлы в каталоге сетевого диска
попытка открыть файл приводит к запросу propfind, который выдает ошибку 400 неверных запросов. Сервер имеет SSL, поэтому я не верю, что это проблема.
Любая помощь будет оценена
Я попытался установить соединение с сервером webdav из windows 10 через опцию «Подключиться к веб-сайту, который вы можете использовать для хранения ваших документов и изображений», но это не позволяет мне просматривать файлы с моего сервера webdav с Браузер файлов MS Word (когда вы нажимаете кнопку Обзор из MS Word).
# my custom webdav controller
class WebDavController < RackWebDAV::Controller
def initialize(request, response, options)
@request = request
@response = response
@options = options
@resource = resource_class.new(url_unescape(request.path_info), @request, @response, @options)
raise Forbidden if request.path_info.include?('../')
end
# this method is used to populate which file are available in the word document editor
# which is connecting to webdav server
# Note: this function should only return one file as users can only check out one file at a time
# and users can only view files which they have checked out.
def propfind
token = request.url.split("?token=")[1]
#raise NotFound if not resource.exist?
if not request_match("/d:propfind/d:allprop").empty?
nodes = all_prop_nodes
else
nodes = request_match("/d:propfind/d:prop/*")
nodes = all_prop_nodes if nodes.empty?
end
nodes.each do |n|
# Don't allow empty namespace declarations
# See litmus props test 3
raise BadRequest if n.namespace.nil? && n.namespace_definitions.empty?
# Set a blank namespace if one is included in the request
# See litmus props test 16
# <propfind xmlns="DAV:"><prop><nonamespace xmlns=""/></prop></propfind>
if n.namespace.nil?
nd = n.namespace_definitions.first
if nd.prefix.nil? && nd.href.empty?
n.add_namespace(nil, '')
end
end
end
multistatus do |xml|
for resource in find_resources
resource.path.gsub!(/\/\//, '/')
# do not show file to word document editor unless the file is checked out by logged in user
# "/."
# "/"
if resource.path != "/." and resource.path != "/"
if resource.file_locked? @options[:user_id]
# we do nothing here
else
next
end
end
# if "next" was not executed in the previous block, we allow the
# file to be visible within the file explorer when being accessed
# via web dav
xml.response do
xml.href "http://#{host}#{@request.script_name}#{url_escape resource.path}"
propstats xml, get_properties(resource, nodes)
end
end
end
end
# sends a file to the word document editor via webdav
def get
raise NotFound if not resource.exist?
response['Etag'] = resource.etag
response['Content-Type'] = resource.content_type
response['Content-Length'] = resource.content_length.to_s
response['Last-Modified'] = resource.last_modified.httpdate
map_exceptions do
resource.get @options[:user_id]
end
end
def put
map_exceptions do
resource.put
end
response.status = Created
response['Location'] = "#{request.scheme}://#{request.host}:#{request.port}#{url_format_for_response(resource)}"
end
def head
raise NotFound if not resource.exist?
response['Etag'] = resource.etag
response['Content-Type'] = resource.content_type
response['Content-Length'] = resource.content_length.to_s
response['Last-Modified'] = resource.last_modified.httpdate
end
def lock
response.status = 200
end
def unlock
response.status = 200
end
def options
response["Allow"] = 'OPTIONS,HEAD,GET,PUT,POST,DELETE,PROPFIND,PROPPATCH,MKCOL,COPY,MOVE'
response["Dav"] = "1"
if resource.exist?
response["Allow"] << ",LOCK,UNLOCK"
response["Dav"] << ",2"
end
response["Ms-Author-Via"] = "DAV"
end
end
На самом деле ошибки нет, я вижу только 400 Bad Request, когда создаю туннель через ngrok к моему серверу разработки и производственному серверу.