2

I'm trying to create a SabreDAV-Server in a Laravel Route. The following Code shows that I tried:

Illuminate\Routing\Router::$verbs = [
    'GET',
    'HEAD',
    'POST',
    'PUT',
    'PATCH',
    'DELETE', 
    'PROPFIND',
    'PROPPATCH',
    'MKCOL',
    'COPY',
    'MOVE',
    'LOCK',
    'UNLOCK'
];


    Route::match(['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'PATCH', 'PROPFIND', 'PROPPATCH', 'MKCOL', 'COPY', 'MOVE', 'LOCK', 'UNLOCK'], 'carddav{test}', function()
{
        date_default_timezone_set('Europe/Berlin');

        $baseUri = '/carddav';

        $pdo = new PDO('mysql:host=localhost;dbname=dav', 'root', 'root');
        $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);

        $authBackend = new \Sabre\DAV\Auth\Backend\PDO($pdo);
        $principalBackend = new \Sabre\DAVACL\PrincipalBackend\PDO($pdo);
        $carddavBackend = new \Sabre\CardDAV\Backend\PDO($pdo);

        $nodes = [
                new \Sabre\DAVACL\PrincipalCollection($principalBackend),
                new \Sabre\CardDAV\AddressBookRoot($principalBackend, $carddavBackend)
        ];

        $server = new \Sabre\DAV\Server($nodes);
        $server->setBaseUri($baseUri);

        $server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend, 'SabreDAV'));
        $server->addPlugin(new \Sabre\DAV\Browser\Plugin());
        $server->addPlugin(new \Sabre\CardDAV\Plugin());
        $server->addPlugin(new \Sabre\DAVACL\Plugin());
        $server->addPlugin(new \Sabre\DAV\Sync\Plugin());

        $server->exec();
})->where('path', '(.)*';

But if I try to call it in the Browser there is an error:

<?xml version="1.0" encoding="utf-8"?>
<d:error xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns">
  <s:sabredav-version>2.0.4</s:sabredav-version>
  <s:exception>Sabre\DAV\Exception\NotAuthenticated</s:exception>
  <s:message>No digest authentication headers were found</s:message>
</d:error>

There was no authentication prompt.

If I try to connect from Evolution there was the message: "Method Not Allowed".

Has someone any idea what the problem is?

Thanks, pepe

pepe84
  • 21
  • 2

1 Answers1

1

The problem is the sent HTTP status code. No matter the response from SabreDAV, the Laravel router always sets the HTTP status code to 200, so no CardDAV client will ever know they have to authorize requests – ignoring the Basic Auth Challenge.

My solution might not be the most elegant one, but it is working. Just wrap the $server->exec() in ob_start() and ob_end() tags and output the content with a real Laravel response:

ob_start();
$server->exec();

$status = $server->httpResponse->getStatus();
$content = ob_get_contents();
ob_end_clean();

return response($content, $status);

General guidance:

  • Use "postman" (Google Chrome App) to test requests, you'll see they are working when sending authorization headers upfront
  • Use a web debugging proxy like "Charles" to monitor actual request and response bodies
DanielPHP
  • 11
  • 3