From 23ebe39031eff118b9748f096ea7d464d316731d Mon Sep 17 00:00:00 2001 From: themanifold Date: Mon, 17 Aug 2020 08:54:16 +0100 Subject: [PATCH] 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 --- frontend/apps/cloudstorage/webdavapi.lua | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/frontend/apps/cloudstorage/webdavapi.lua b/frontend/apps/cloudstorage/webdavapi.lua index 7086ed0ca..57b782317 100644 --- a/frontend/apps/cloudstorage/webdavapi.lua +++ b/frontend/apps/cloudstorage/webdavapi.lua @@ -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 tags, each containing an entry - for item in res_data:gmatch("(.-)") do + for item in res_data:gmatch("<[^:]*:response[^>]*>(.-)") do --logger.dbg("WebDav catalog item=", item) -- is the path and filename of the entry. - local item_fullpath = item:match("(.*)") + local item_fullpath = item:match("<[^:]*: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("") 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("") 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,