Support for Apache WebDAV module (#6510)

This change to the parser in `cloudstorage.lua` adds support for the [Apache WebDAV module][1]

It was manually tested using the [bytemark/webdav][2] docker container.

I developed this in Windows, with a docker container that hosted an extracted AppImage and a VNC server that I viewed using a VNC client.

I will write up my work flow at a later point.

Changes have not been tested against other webdav servers (what was this originally tested against?). Please could someone test against other webdav servers?

I also noticed a logic inversion error where we were looking for a slash at the end of the URL and if it exists, then we explicitly set `has_trailing_slash=false` - so I fixed it to set to `true`. I had to do this so that we weren't visiting the URL without a trailing slash - apache sends back a 301 redirect with a `location` header with a trailing slash, if you don't put a trailing slash.

As a side note, I think we should consider replacing this regexp pattern matching parser with the [XML parser in the newsreader plugin[3]

[1]: https://httpd.apache.org/docs/2.4/mod/mod_dav.html
[2]: https://github.com/BytemarkHosting/docker-webdav
[3]: https://github.com/koreader/koreader/blob/master/plugins/newsdownloader.koplugin/lib/xml.lua
reviewable/pr6514/r1
themanifold 4 years ago committed by GitHub
parent b3f64dc73b
commit 23ebe39031
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -59,7 +59,7 @@ function WebDavApi:listFolder(address, user, pass, folder_path)
local has_trailing_slash = false
local has_leading_slash = false
if string.sub( address, -1 ) ~= "/" then has_trailing_slash = true end
if string.sub( address, -1 ) == "/" then has_trailing_slash = true end
if path == nil or path == "/" then
path = ""
elseif string.sub( path, 1, 2 ) == "/" then
@ -73,6 +73,9 @@ function WebDavApi:listFolder(address, user, pass, folder_path)
address = address .. "/"
end
local webdav_url = address .. path
if not has_trailing_slash then
webdav_url = webdav_url .. "/"
end
local request, sink = {}, {}
local parsed = url.parse(webdav_url)
@ -96,19 +99,20 @@ function WebDavApi:listFolder(address, user, pass, folder_path)
end
local res_data = table.concat(sink)
if res_data ~= "" then
-- iterate through the <d:response> tags, each containing an entry
for item in res_data:gmatch("<d:response>(.-)</d:response>") do
for item in res_data:gmatch("<[^:]*:response[^>]*>(.-)</[^:]*:response>") do
--logger.dbg("WebDav catalog item=", item)
-- <d:href> is the path and filename of the entry.
local item_fullpath = item:match("<d:href>(.*)</d:href>")
local item_fullpath = item:match("<[^:]*:href[^>]*>(.*)</[^:]*:href>")
if string.sub( item_fullpath, -1 ) == "/" then
item_fullpath = string.sub( item_fullpath, 1, -2 )
end
local is_current_dir = self:isCurrentDirectory( item_fullpath, address, path )
local item_name = util.urlDecode( FFIUtil.basename( item_fullpath ) )
local item_path = path .. "/" .. item_name
if item:find("<d:collection/>") then
if item:find("<[^:]*:collection/>") then
item_name = item_name .. "/"
if not is_current_dir then
table.insert(webdav_list, {
@ -117,7 +121,7 @@ function WebDavApi:listFolder(address, user, pass, folder_path)
type = "folder",
})
end
elseif item:find("<d:resourcetype/>") and (DocumentRegistry:hasProvider(item_name)
elseif item:find("<[^:]*:resourcetype/>") and (DocumentRegistry:hasProvider(item_name)
or G_reader_settings:isTrue("show_unsupported")) then
table.insert(webdav_file, {
text = item_name,

Loading…
Cancel
Save