andig / carddav2fb

Download CardDAV VCards and upload as phonebook to AVM FRITZ!Box
63 stars 19 forks source link

Dav Server reports: The input element to parse is empty. #196

Closed altheeagle closed 3 years ago

altheeagle commented 4 years ago

I have upgraded to baikal 0.6.1 and get a 500 error while using carddav2fb, the apache error log of baikal says [Thu Feb 13 13:01:20.650491 2020] [php7:notice] [pid 17226] [client 10.10.10.10:41862] Sabre\\Xml\\ParseException: The input element to parse is empty. Do not attempt to parse in /var/www/example.com/vendor/sabre/xml/lib/Service.php:114\nStack trace:\n#0 /var/www/example.com/vendor/sabre/dav/lib/DAV/CorePlugin.php(715): Sabre\\Xml\\Service->parse()\n#1 /var/www/example.com/vendor/sabre/event/lib/WildcardEmitterTrait.php(96): Sabre\\DAV\\CorePlugin->httpReport()\n#2 /var/www/example.com/vendor/sabre/dav/lib/DAV/Server.php(464): Sabre\\DAV\\Server->emit()\n#3 /var/www/example.com/vendor/sabre/dav/lib/DAV/Server.php(241): Sabre\\DAV\\Server->invokeMethod()\n#4 /var/www/example.com/vendor/sabre/dav/lib/DAV/Server.php(309): Sabre\\DAV\\Server->start()\n#5 /var/www/example.com/Core/Frameworks/Baikal/Core/Server.php(123): Sabre\\DAV\\Server->exec()\n#6 /var/www/example.com/html/dav.php(61): Baikal\\Core\\Server->start()\n#7 {main}

baikal is working fine with Thunderbird TBsync , also the iOS Contacts App is working

andig commented 4 years ago

Looks like something has changed in Baikal and it was working before? You could check https://github.com/andig/carddav2fb/pull/192 which allows to select the query method and see if any of these variants work. Otherwise I'd suggest to open an issue with Baikal.

blacksenator commented 4 years ago

@altheeagle Please check with the current version whether the last imported PR #205 solves your problem

altheeagle commented 4 years ago

Thank you that you mentioned me. Unfortunatly it didn't helped - or made somethin wrong. I've just updated carddav2fb with "git fetch" and "composer update" and still getting same error.

mstilkerich commented 3 years ago

Just surfing by here I think I can give a few helpful pointers.

Please see here for the issue: sabre-io/dav#932

You may be interested in this for inspiration on how to fix it: https://github.com/mstilkerich/carddavclient/commit/106a1df68b784c6e47f425c41af8a485e63018b7

andig commented 3 years ago

Interesting. I‘m by no means a curl expert. As I understand it you‘re retrying the request in the dreaded HTTP 500 response with different curl auth options? Sabre won‘t fix it as its due to http client behavior. We could try applying your fix here, thank you very much!

mstilkerich commented 3 years ago

There is different ways to work around this:

  1. Don't use REPORT at all, because the issue specifically only affects the REPORT request method. Downside: Many GET requests is slower than addressbook-multiget REPORT.
    • Discover the cards in an addressbook using PROPFIND
    • Download the cards individually with GET requests
  2. If you only care about BASIC authentication, you can send the authentication headers with the first request, i.e. skip the negotiation of the AUTH scheme. Downside: Baïkal by default uses DIGEST authentication, so this won't work out of the box for many users. With digest, this does not work, because a 401 response is needed to get the parameters for the digest auth scheme.
  3. Always force CURL to negotiate the authentication (CURLAUTH_ANY). This is what you can see in the commit I referenced. Downside: Each request will be sent twice. The first without Authentication header will get a 401, then another one with the proper auth info will be sent.

If you don't care about performance, 1 or 3 are the easy way to go.

For me, 1 and 2 was not an option, because I want the library to interoperate with any CardDAV server in the most efficient supported way. 3 was also not an option because I don't want to slow down communication with other CardDAV servers because of a workaround for sabre. So I chose to try the normal way, and specifically detect the issue (500 reply and some other conditions you can see in my commit's code comment). Only if I detect the issue I then use option 3.

andig commented 3 years ago

Thank you @mstilkerich for the in-depth explanation. As performance is not my primary concern due to the batch-oriented nature of what we're doing 3. sounds like a good option. It would still be considerable better in performance than 1.

@blacksenator do you want to give it a try? It should also only be necessary to use this approach if user/password are specified, but not with open servers.

blacksenator commented 3 years ago

@andig I just followed the discussion out of the corner of my eye. If I understand correctly, the request method should be cascaded? If you code the PR, I can willingly test it - if you explain to me again how or what to test.

andig commented 3 years ago

PR attached please let me know if this works and solves the problem with Sabre.

altheeagle commented 3 years ago

Hi, I've just updated the program and now I get a different Error: `./carddav2fb run -vvv Downloading recent FRITZ!Box phonebook No special attributes are saved! Downloading vCard(s) from account 0 [>---------------------------] < 1 sec 6.0 MiB In RequestException.php line 113:

[GuzzleHttp\Exception\ServerException (500)] Server error: REPORT https://xxx/dav.php/addressbooks/<username>/default/ resulted in a 500 Internal Server Error response: <?xml version="1.0" encoding="utf-8"?>

4 (truncated...) Exception trace: at /usr/local/lib/php/carddav2fb/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php:113 GuzzleHttp\Exception\RequestException::create() at /usr/local/lib/php/carddav2fb/vendor/guzzlehttp/guzzle/src/Middleware.php:65 GuzzleHttp\Middleware::GuzzleHttp\{closure}() at /usr/local/lib/php/carddav2fb/vendor/guzzlehttp/promises/src/Promise.php:203 GuzzleHttp\Promise\Promise::callHandler() at /usr/local/lib/php/carddav2fb/vendor/guzzlehttp/promises/src/Promise.php:156 GuzzleHttp\Promise\Promise::GuzzleHttp\Promise\{closure}() at /usr/local/lib/php/carddav2fb/vendor/guzzlehttp/promises/src/TaskQueue.php:47 GuzzleHttp\Promise\TaskQueue->run() at /usr/local/lib/php/carddav2fb/vendor/guzzlehttp/promises/src/Promise.php:246 GuzzleHttp\Promise\Promise->invokeWaitFn() at /usr/local/lib/php/carddav2fb/vendor/guzzlehttp/promises/src/Promise.php:223 GuzzleHttp\Promise\Promise->waitIfPending() at /usr/local/lib/php/carddav2fb/vendor/guzzlehttp/promises/src/Promise.php:267 GuzzleHttp\Promise\Promise->invokeWaitList() at /usr/local/lib/php/carddav2fb/vendor/guzzlehttp/promises/src/Promise.php:225 GuzzleHttp\Promise\Promise->waitIfPending() at /usr/local/lib/php/carddav2fb/vendor/guzzlehttp/promises/src/Promise.php:62 GuzzleHttp\Promise\Promise->wait() at /usr/local/lib/php/carddav2fb/vendor/guzzlehttp/guzzle/src/Client.php:183 GuzzleHttp\Client->request() at /usr/local/lib/php/carddav2fb/src/CardDav/Backend.php:171 Andig\CardDav\Backend->getVcards() at /usr/local/lib/php/carddav2fb/src/functions.php:51 Andig\download() at /usr/local/lib/php/carddav2fb/src/DownloadTrait.php:35 Andig\RunCommand->downloadProvider() at /usr/local/lib/php/carddav2fb/src/DownloadTrait.php:70 Andig\RunCommand->downloadAllProviders() at /usr/local/lib/php/carddav2fb/src/RunCommand.php:56 Andig\RunCommand->execute() at /usr/local/lib/php/carddav2fb/vendor/symfony/console/Command/Command.php:255 Symfony\Component\Console\Command\Command->run() at /usr/local/lib/php/carddav2fb/vendor/symfony/console/Application.php:1001 Symfony\Component\Console\Application->doRunCommand() at /usr/local/lib/php/carddav2fb/vendor/symfony/console/Application.php:271 Symfony\Component\Console\Application->doRun() at /usr/local/lib/php/carddav2fb/vendor/symfony/console/Application.php:147 Symfony\Component\Console\Application->run() at /usr/local/lib/php/carddav2fb/carddav2fb:20 run [-i|--image] [-l|--local [LOCAL]] [-c|--config CONFIG] `
blacksenator commented 3 years ago

@altheeagle Just to be sure - and according to your message from May 13 and the first error you mentioned: have you tried it with an configuration like in this example?

altheeagle commented 3 years ago

@blacksenator No I did not have tried a configuration like in your example. But now I did and it works! Thank you for mentioning this! This Issue can now be closed.