davclient icon indicating copy to clipboard operation
davclient copied to clipboard

propFind method with empty properties returns 400

Open d70rr3s opened this issue 10 years ago • 2 comments

Hi, I'm using DAV Client as adapter with Gaufrette and when I make a PROPFIND request with no properties the server send a 400 response. This happens with functions like this one:

       private function isDir($directory) {
        if ('/' === $directory) {
            return true;
        }

        $data = $this->getClient()->propFind($directory, [], 0);

        return !empty($data) && $data['{DAV:}resourcetype']->is('{DAV:}collection');
    }

I've been testing the resulting request and because the prop tags are empty the server returns a 400 response. In the other hand if we replace the prop tag with allprop tag it goes as expected. I make a work around and patch the code in the mean time like this:

       public function propFind($url, array $properties, $depth = 0) {

        $dom = new \DOMDocument('1.0', 'UTF-8');
        $dom->formatOutput = true;
        $root = $dom->createElementNS('DAV:', 'd:propfind');

       // My code
      // -----------
        if (count($properties) > 0) {
            $prop = $dom->createElement('d:prop');

            foreach($properties as $property) {

                list(
                    $namespace,
                    $elementName
                    ) = XMLUtil::parseClarkNotation($property);

                if ($namespace === 'DAV:') {
                    $element = $dom->createElement('d:'.$elementName);
                } else {
                    $element = $dom->createElementNS($namespace, 'x:'.$elementName);
                }

                $prop->appendChild( $element );
            }
        } else {
            $prop = $dom->createElement('d:allprop');
        }
        // -------

        $dom->appendChild($root)->appendChild( $prop );
        $body = $dom->saveXML();

        $url = $this->getAbsoluteUrl($url);

        $request = new HTTP\Request('PROPFIND', $url, [
            'Depth' => $depth,
            'Content-Type' => 'application/xml'
        ], $body);

        $response = $this->send($request);

        if ((int)$response->getStatus() >= 400) {
            throw new Exception('HTTP error: ' . $response->getStatus());
        }

        $result = $this->parseMultiStatus($response->getBodyAsString());

        // If depth was 0, we only return the top item
        if ($depth===0) {
            reset($result);
            $result = current($result);
            return isset($result[200])?$result[200]:[];
        }

        $newResult = [];
        foreach($result as $href => $statusList) {

            $newResult[$href] = isset($statusList[200])?$statusList[200]:[];

        }

        return $newResult;

    }

I don't like this solution and looking a way round to solve this issue.

Thanks!

d70rr3s avatar Oct 01 '15 16:10 d70rr3s

I agree that this is a bug, but I want to warn you that this project has not really been maintained for a long while. I want to pick it up again in the future, but I will probably solve this by modifying the method signatures a bit.

The recommendation I would have for you is to simply never do an 'empty properties' request or allprop request. You probably already know exactly which properties you want, so why not specify those exact properties?

evert avatar Oct 01 '15 16:10 evert

Thanks for the quick response, it's true as in all WebDAV examples they request for specific properties. I'll follow your advice and make my way thru. Thanks!

d70rr3s avatar Oct 02 '15 09:10 d70rr3s