notroj / cadaver

Command-line WebDAV client
GNU General Public License v2.0
87 stars 8 forks source link

Cannot access WebDAV share / terminates with `207 Multi-Status` #4

Open igsz opened 2 years ago

igsz commented 2 years ago

Describe the bug

When I try to access a WebDAV share on my bitrix24.de server, libneon terminates the connection with the message 207 Multi-Status. Other WebDAV servers work fine, so it must be specific to bitrix24.de.

Environment

To Reproduce

Happens everytime when connecting to a bitrix24 WebDAV server. The error also occurs with earlier versions of libneon.

Debugging output

This is the debug output with debugging of HTTP and XML enabled. Potentially sensitive info was masked by xxxxxx....

Running pre_send hooks
Sending request headers:
OPTIONS /company/personal/user/1/disk/path/ HTTP/1.1
User-Agent: cadaver/0.23.3 neon/0.32.2
Keep-Alive: 
Connection: TE, Keep-Alive
TE: trailers
Host: xxxxxxxxxx.bitrix24.de

Sending request-line and headers:
Doing DNS lookup on xxxxxxxxxx.bitrix24.de...
req: Connecting to xxx.xxx.xxx.xxx:443
Request sent; retry is 0.
[status-line] < HTTP/1.1 401 Unauthorized
[hdr] Date: Fri, 15 Jul 2022 00:44:59 GMT
Header Name: [date], Value: [Fri, 15 Jul 2022 00:44:59 GMT]
[hdr] Content-Type: text/html; charset=UTF-8
Header Name: [content-type], Value: [text/html; charset=UTF-8]
[hdr] Transfer-Encoding: chunked
Header Name: [transfer-encoding], Value: [chunked]
[hdr] Connection: keep-alive
Header Name: [connection], Value: [keep-alive]
[hdr] Server: nginx
Header Name: [server], Value: [nginx]
[hdr] P3P: policyref="/bitrix/p3p.xml", CP="NON DSP COR CUR ADM DEV PSA PSD OUR UNR BUS UNI COM NAV INT DEM STA"
Header Name: [p3p], Value: [policyref="/bitrix/p3p.xml", CP="NON DSP COR CUR ADM DEV PSA PSD OUR UNR BUS UNI COM NAV INT DEM STA"]
[hdr] X-Powered-CMS: Bitrix Site Manager (xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)
Header Name: [x-powered-cms], Value: [Bitrix Site Manager (xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)]
[hdr] X-Dav-Powered-By: Bitrix Site Manager
Header Name: [x-dav-powered-by], Value: [Bitrix Site Manager]
[hdr] WWW-Authenticate: Digest realm="Bitrix Site Manager", nonce="xxxxxxxxxxxxxx"
Header Name: [www-authenticate], Value: [Digest realm="Bitrix Site Manager", nonce="xxxxxxxxxxxxxx"]
[hdr] X-WebDAV-Status: 401 Unauthorized
Header Name: [x-webdav-status], Value: [401 Unauthorized]
[hdr] 
End of headers.
Running post_headers hooks
ne_begin_request 0
[chunk] < 0
Got chunk size: 0
ne_discard_response 0
[hdr] 
End of headers.
Running post_send hooks
Authentication required for Bitrix Site Manager on server `xxxxxxxxxx.bitrix24.de':
Username: xxxxxxxxxxxx@xxxxxxx.xxx
Password: 
ne_end_request 8
Running pre_send hooks
Sending request headers:
OPTIONS /company/personal/user/1/disk/path/ HTTP/1.1
User-Agent: cadaver/0.23.3 neon/0.32.2
Keep-Alive: 
Connection: TE, Keep-Alive
TE: trailers
Host: xxxxxxxxxx.bitrix24.de
Authorization: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Sending request-line and headers:
Request sent; retry is 1.
[status-line] < HTTP/1.1 200 OK
[hdr] Date: Fri, 15 Jul 2022 00:45:18 GMT
Header Name: [date], Value: [Fri, 15 Jul 2022 00:45:18 GMT]
[hdr] Content-Type: text/html; charset=UTF-8
Header Name: [content-type], Value: [text/html; charset=UTF-8]
[hdr] Content-Length: 0
Header Name: [content-length], Value: [0]
[hdr] Connection: keep-alive
Header Name: [connection], Value: [keep-alive]
[hdr] Server: nginx
Header Name: [server], Value: [nginx]
[hdr] P3P: policyref="/bitrix/p3p.xml", CP="NON DSP COR CUR ADM DEV PSA PSD OUR UNR BUS UNI COM NAV INT DEM STA"
Header Name: [p3p], Value: [policyref="/bitrix/p3p.xml", CP="NON DSP COR CUR ADM DEV PSA PSD OUR UNR BUS UNI COM NAV INT DEM STA"]
[hdr] X-Powered-CMS: Bitrix Site Manager (xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)
Header Name: [x-powered-cms], Value: [Bitrix Site Manager (xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)]
[hdr] Set-Cookie: PHPSESSID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; path=/; secure; HttpOnly
Header Name: [set-cookie], Value: [PHPSESSID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; path=/; secure; HttpOnly]
[hdr] Expires: Thu, 19 Nov 1981 08:52:00 GMT
Header Name: [expires], Value: [Thu, 19 Nov 1981 08:52:00 GMT]
[hdr] Cache-Control: no-store, no-cache, must-revalidate
Header Name: [cache-control], Value: [no-store, no-cache, must-revalidate]
[hdr] Pragma: no-cache
Header Name: [pragma], Value: [no-cache]
[hdr] Set-Cookie: BITRIX_SM_PK=%2F1%2Fxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; path=/; HttpOnly
Header Name: [set-cookie], Value: [BITRIX_SM_PK=%2F1%2Fxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; path=/; HttpOnly]
[hdr] X-Dav-Powered-By: Bitrix Site Manager
Header Name: [x-dav-powered-by], Value: [Bitrix Site Manager]
[hdr] MS-Author-Via: DAV
Header Name: [ms-author-via], Value: [DAV]
[hdr] DAV: 1,2
Header Name: [dav], Value: [1,2]
[hdr] Allow: OPTIONS,CHECKAUTH,PROPFIND,PROPPATCH,MKCOL,GET,POST,PUT,DELETE,COPY,MOVE,LOCK,UNLOCK,HEAD
Header Name: [allow], Value: [OPTIONS,CHECKAUTH,PROPFIND,PROPPATCH,MKCOL,GET,POST,PUT,DELETE,COPY,MOVE,LOCK,UNLOCK,HEAD]
[hdr] X-WebDAV-Status: 200 OK
Header Name: [x-webdav-status], Value: [200 OK]
[hdr] X-Frame-Options: SAMEORIGIN
Header Name: [x-frame-options], Value: [SAMEORIGIN]
[hdr] X-Content-Type-Options: nosniff
Header Name: [x-content-type-options], Value: [nosniff]
[hdr] Strict-Transport-Security: max-age=31536000; includeSubdomains
Header Name: [strict-transport-security], Value: [max-age=31536000; includeSubdomains]
[hdr] Server-Timing: t1;dur=0.261, t2;dur=0.262, t3;dur=0.000
Header Name: [server-timing], Value: [t1;dur=0.261, t2;dur=0.262, t3;dur=0.000]
[hdr] Server-Timing: tc1;dur=496, tc2;dur=795, tc3;dur=34
Header Name: [server-timing], Value: [tc1;dur=496, tc2;dur=795, tc3;dur=34]
[hdr] X-Bitrix-RI: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Header Name: [x-bitrix-ri], Value: [xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx]
[hdr] X-Bitrix-LB: lb-de-01
Header Name: [x-bitrix-lb], Value: [lb-de-01]
[hdr] 
End of headers.
Running post_headers hooks
ne_begin_request 0
ne_discard_response 0
Running post_send hooks
ne_end_request 0
Request ends, status 200 class 2xx, error line:
200 OK
Running destroy hooks.
Request ends.
Running pre_send hooks
Sending request headers:
PROPFIND /company/personal/user/1/disk/path/ HTTP/1.1
User-Agent: cadaver/0.23.3 neon/0.32.2
Connection: TE
TE: trailers
Host: xxxxxxxxxx.bitrix24.de
Depth: 0
Content-Length: 288
Content-Type: application/xml
Authorization: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Sending request-line and headers:
Sending request body:
Request sent; retry is 1.
[status-line] < HTTP/1.1 207 Multi-Status
[hdr] Date: Fri, 15 Jul 2022 00:45:18 GMT
Header Name: [date], Value: [Fri, 15 Jul 2022 00:45:18 GMT]
[hdr] Content-Type: text/xml; charset="utf-8"
Header Name: [content-type], Value: [text/xml; charset="utf-8"]
[hdr] Transfer-Encoding: chunked
Header Name: [transfer-encoding], Value: [chunked]
[hdr] Connection: keep-alive
Header Name: [connection], Value: [keep-alive]
[hdr] Server: nginx
Header Name: [server], Value: [nginx]
[hdr] P3P: policyref="/bitrix/p3p.xml", CP="NON DSP COR CUR ADM DEV PSA PSD OUR UNR BUS UNI COM NAV INT DEM STA"
Header Name: [p3p], Value: [policyref="/bitrix/p3p.xml", CP="NON DSP COR CUR ADM DEV PSA PSD OUR UNR BUS UNI COM NAV INT DEM STA"]
[hdr] X-Powered-CMS: Bitrix Site Manager (xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)
Header Name: [x-powered-cms], Value: [Bitrix Site Manager (xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)]
[hdr] Set-Cookie: PHPSESSID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; path=/; secure; HttpOnly
Header Name: [set-cookie], Value: [PHPSESSID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; path=/; secure; HttpOnly]
[hdr] Expires: Thu, 19 Nov 1981 08:52:00 GMT
Header Name: [expires], Value: [Thu, 19 Nov 1981 08:52:00 GMT]
[hdr] Cache-Control: no-store, no-cache, must-revalidate
Header Name: [cache-control], Value: [no-store, no-cache, must-revalidate]
[hdr] Pragma: no-cache
Header Name: [pragma], Value: [no-cache]
[hdr] Set-Cookie: BITRIX_SM_PK=%2F1%2Fxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; path=/; HttpOnly
Header Name: [set-cookie], Value: [BITRIX_SM_PK=%2F1%2Fxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; path=/; HttpOnly]
[hdr] X-Dav-Powered-By: Bitrix Site Manager
Header Name: [x-dav-powered-by], Value: [Bitrix Site Manager]
[hdr] DAV: 1
Header Name: [dav], Value: [1]
[hdr] X-WebDAV-Status: 207 Multi-Status
Header Name: [x-webdav-status], Value: [207 Multi-Status]
[hdr] 
End of headers.
Running post_headers hooks
ne_begin_request 0
[chunk] < 459
Got chunk size: 1113
Reading 1113 bytes of response body.
Got 1113 bytes.
XML: start-element (0, {DAV:, multistatus}) => 1
XML: char-data (1) returns 0
XML: start-element (1, {DAV:, response}) => 2
XML: char-data (2) returns 0
XML: start-element (2, {DAV:, href}) => 4
XML: char-data (4) returns 0
XML: end-element (4, {DAV:, href})
XML: char-data (2) returns 0
XML: start-element (2, {DAV:, propstat}) => 7
XML: char-data (7) returns 0
XML: start-element (7, {DAV:, prop}) => 50
XML: char-data (50) returns 0
Got property #0: {DAV:}name.
XML: start-element (50, {DAV:, name}) => 99
XML: char-data (99) returns 0
XML: end-element (99, {DAV:, name})
XML: char-data (50) returns 0
Got property notroj/neon#1: {DAV:}creationdate.
XML: start-element (50, {DAV:, creationdate}) => 99
XML: char-data (99) returns 0
XML: end-element (99, {DAV:, creationdate})
XML: char-data (50) returns 0
Got property notroj/neon#2: {DAV:}getlastmodified.
XML: start-element (50, {DAV:, getlastmodified}) => 99
XML: char-data (99) returns 0
XML: end-element (99, {DAV:, getlastmodified})
XML: char-data (50) returns 0
Got property notroj/neon#3: {DAV:}iscollection.
XML: start-element (50, {DAV:, iscollection}) => 99
XML: char-data (99) returns 0
XML: end-element (99, {DAV:, iscollection})
XML: char-data (50) returns 0
XML: start-element (50, {DAV:, resourcetype}) => 201
XML: start-element (201, {, collection}) => 0
XML: end-element (0, {, collection})
XML: end-element (201, {DAV:, resourcetype})
XML: char-data (50) returns 0
Got property notroj/neon#4: {DAV:}getcontenttype.
XML: start-element (50, {DAV:, getcontenttype}) => 99
XML: char-data (99) returns 0
XML: end-element (99, {DAV:, getcontenttype})
XML: char-data (50) returns 0
Got property notroj/neon#5: {DAV:}supportedlock.
XML: start-element (50, {DAV:, supportedlock}) => 99
XML: start-element (99, {DAV:, lockentry}) => 99
XML: start-element (99, {DAV:, lockscope}) => 99
XML: start-element (99, {DAV:, exclusive}) => 99
XML: end-element (99, {DAV:, exclusive})
XML: end-element (99, {DAV:, lockscope})
XML: start-element (99, {DAV:, locktype}) => 99
XML: start-element (99, {DAV:, write}) => 99
XML: end-element (99, {DAV:, write})
XML: end-element (99, {DAV:, locktype})
XML: end-element (99, {DAV:, lockentry})
XML: start-element (99, {DAV:, lockentry}) => 99
XML: start-element (99, {DAV:, lockscope}) => 99
XML: start-element (99, {DAV:, shared}) => 99
XML: end-element (99, {DAV:, shared})
XML: end-element (99, {DAV:, lockscope})
XML: start-element (99, {DAV:, locktype}) => 99
XML: start-element (99, {DAV:, write}) => 99
XML: end-element (99, {DAV:, write})
XML: end-element (99, {DAV:, locktype})
XML: end-element (99, {DAV:, lockentry})
XML: end-element (99, {DAV:, supportedlock})
XML: char-data (50) returns 0
XML: end-element (50, {DAV:, prop})
XML: char-data (7) returns 0
XML: start-element (7, {DAV:, status}) => 6
XML: char-data (6) returns 0
Decoded status line: HTTP/1.1 200 OK
XML: end-element (6, {DAV:, status})
XML: char-data (7) returns 0
XML: end-element (7, {DAV:, propstat})
XML: char-data (2) returns 0
End resource /company/personal/user/1/disk/path/
XML: end-element (2, {DAV:, response})
XML: char-data (1) returns 0
XML: end-element (1, {DAV:, multistatus})
[chunk] < 0
Got chunk size: 0
ne_discard_response 0
[hdr] 
End of headers.
Running post_send hooks
ne_end_request 0
Request ends, status 207 class 2xx, error line:
207 Multi-Status
Running destroy hooks.
Request ends.
Could not access /company/personal/user/1/disk/path/ (not WebDAV-enabled?):
207 Multi-Status
sess: Destroying session.
Connection to `xxxxxxxxxx.bitrix24.de' closed.
notroj commented 2 years ago

The problem is that the "resourcetype" element returned in the response is malformed. cadaver requires that when you open a resource, it is a WebDAV collection, but because the resourcetype is not recognized it fails, hence the "(not WebDAV-enabled?)" message. I could clarify that message to be better, so I'll leave this open.

Can you report this to Bitrix support please? It is a programming error in the server code. In the response:

 <D:response xmlns:ns0="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/">
  <D:href>/company/personal/user/1/disk/path/</D:href>
   <D:propstat>
    <D:prop>
     <D:name>REG_ADMIN_FIRST_NAME REG_ADMIN_LAST_NAME</D:name>
     <D:creationdate ns0:dt="dateTime.tz">2022-07-15T00:00:33Z</D:creationdate>
     <D:getlastmodified ns0:dt="dateTime.rfc1123">Fri, 15 Jul 2022 14:47:38 GMT</D:getlastmodified>
     <D:iscollection>1</D:iscollection>
     <D:resourcetype><collection/></D:resourcetype>
     <D:getcontenttype>httpd/unix-directory</D:getcontenttype>
    ....

    </D:prop>
    <D:status>HTTP/1.1 200 OK</D:status>
   </D:propstat>
 </D:response>

they are missing the D: namespace prefix on the collection element:

<D:resourcetype><collection/></D:resourcetype> should be <D:resourcetype><D:collection/></D:resourcetype>

To work around this problem you can set "tolerant" mode in cadaver. i.e. cadaver -t $URL

notroj commented 2 years ago

I've moved this issue, to track an improved error message in the cadaver repo.

igsz commented 2 years ago

Thank you for this very informative response! As it turns out, I cannot make Bitrix24 aware of their bug, because I have a free account, and only paid users can contact the support.

I understand that there is nothing you can do from your side. So feel free to close the issue when you are satisfied with your modifications. The workaround using the tolerant option is perfectly fine for me.