При попытке перечислить каталог, содержащий неработающую ссылку, я получаю неинформативную ошибку:
$ cadaver webdav://localhost:5555/api/v1/content
dav:/api/v1/content/> ls etc
Listing collection `/api/v1/content/etc/': failed:
XML parse error at line 1: junk after document element
Вот что я получаю от сервера webdav:
2016/06/27 14:52:42 http: multiple response.WriteHeader calls
Ошибка возникает из файла file.go [1], где он вызывает stat для файла неработающей ссылки, но я думаю, что, возможно, ее следует обрабатывать в webdav.go walkFn [2].
Я сам не уверен, что следует печатать/возвращать, но я ожидаю получить полный список каталогов (т.е., по моему мнению, webdav не должен разбиваться на этом) с этой ссылкой, помеченной как-то неработающей.
[1] https://github.com/golang/net/blob/master/webdav/file.go#L779
[2] https://github.com/golang/net/blob/master/webdav/webdav.go#L527
/cc @simon3z
Я просто столкнулся с этой проблемой. Я исправил это локально, просто вернув nil при получении ошибки здесь https://github.com/golang/net/blob/master/webdav/webdav.go#L557.
Я протестировал тот же вариант использования с реализацией Apache, и в случае неработающей символической ссылки он молча отбрасывался.
Я не знаю, достаточно ли это хорошее решение, но сегодняшнее поведение тоже неверно.
Вот трассировка ошибочного ответа wireshark
Host: 10.21.59.204
Depth: 1
Content-Type: application/xml
Apply-To-Redirect-Ref: T
Accept-Encoding: gzip, deflate
User-Agent: gvfs/1.28.2
Accept-Language: en-us, en;q=0.9
Connection: Keep-Alive
Content-Length: 235
<?xml version="1.0" encoding="utf-8" ?>
<D:propfind xmlns:D="DAV:">
<D:prop>
<D:creationdate/>
<D:displayname/>
<D:getcontentlength/>
<D:getcontenttype/>
<D:getetag/>
<D:getlastmodified/>
<D:resourcetype/>
</D:prop>
</D:propfind>HTTP/1.1 207 status code 207
Content-Type: text/xml; charset=utf-8
Date: Wed, 15 Mar 2017 09:00:40 GMT
Content-Length: 610
<?xml version="1.0" encoding="UTF-8"?><D:multistatus xmlns:D="DAV:"><D:response><D:href>/dav</D:href><D:propstat><D:prop><D:displayname></D:displayname><D:getlastmodified>Wed, 15 Mar 2017 08:59:55 GMT</D:getlastmodified><D:resourcetype><D:collection xmlns:D="DAV:"/></D:resourcetype></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat><D:propstat><D:prop><D:creationdate></D:creationdate><D:getcontentlength></D:getcontentlength><D:getcontenttype></D:getcontenttype><D:getetag></D:getetag></D:prop><D:status>HTTP/1.1 404 Not Found</D:status></D:propstat></D:response></D:multistatus>Internal Server Error
В спецификации Webdav сказано, что
В случае allprop и propname, если у принципала нет
право знать, существует ли конкретное имущество, тогда это свойство
следует молча исключить из ответа.
Я не знаю, применимо ли это в нашем случае использования
Я думаю, что код состояния 4XX
должен быть возвращен в случае доступа к неработающим ссылкам, в частности, 403 Forbidden
для ссылок, связанных с недопустимыми целями, и 404 Not Found
для связанных ссылок. к несуществующим целям.
В настоящее время ошибки, возвращаемые FileSystem.OpenFile
или File.Stat
переносятся в http.StatusInternalServerError
и вызывают «http: избыточный ответ.Вызов WriteHeader с golang.org/x/net/webdav.(*Handler) .ServeHTTP (webdav.go:74)"
Изменение https://golang.org/cl/249797 упоминает эту проблему: webdav: ignore os.PathError in PROPFIND
Самый полезный комментарий
Я просто столкнулся с этой проблемой. Я исправил это локально, просто вернув nil при получении ошибки здесь https://github.com/golang/net/blob/master/webdav/webdav.go#L557.
Я протестировал тот же вариант использования с реализацией Apache, и в случае неработающей символической ссылки он молча отбрасывался.
Я не знаю, достаточно ли это хорошее решение, но сегодняшнее поведение тоже неверно.
Вот трассировка ошибочного ответа wireshark
В спецификации Webdav сказано, что
Я не знаю, применимо ли это в нашем случае использования