You are viewing a plain text version of this content. The canonical link for it is here.
Posted to slide-dev@jakarta.apache.org by bu...@apache.org on 2006/10/06 14:26:50 UTC
DO NOT REPLY [Bug 32886] - client webdav lib doesn't return child collections using listwebdavresources
DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG�
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://issues.apache.org/bugzilla/show_bug.cgi?id=32886>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND�
INSERTED IN THE BUG DATABASE.
http://issues.apache.org/bugzilla/show_bug.cgi?id=32886
------- Additional Comments From prileva@yahoo.com 2006-10-06 05:26 -------
I am still having problem with this solution. I now have deleted folders beeing
listed with the listWebdavResources call...
(In reply to comment #0)
> I have a mature application working with client webdavlib 2.0, with the webdav
> server that comes with tomcat 5.0.28. Client webdavlib 2.1 seams to be broken.
> Method listWebdavResources() doesn't return child collections, but the parent
> collection itself.
>
> This is the directory structure I tested:
>
> parent/
> child1/
> child2/
> file1.txt
> file2.txt
>
>
> This is my code:
>
> HttpURL url = new HttpURL("http://localhost:8080/webdav/[some-url]");
> url.setUserinfo("user", "pass");
> WebdavResource wdResource = new WebdavResource(url);
> WebdavResource[] webdavList = wdResource.listWebdavResources();
>
> System.out.println("Display Name: " + wdResource.getDisplayName());
> WebdavResource[] webdavList = null;
> webdavList = wdResource.listWebdavResources();
> System.out.println("Children returned: " + webdavList.length);
>
> for (int idx = 0; idx < webdavList.length; idx++) {
> System.out.println("\t" + webdavList[idx].getDisplayName());
> System.out.println("\t" + webdavList[idx].getHttpURL());
> }
>
> This is the output:
>
> Display Name: parent
> Children returned: 3
> file1.txt
> http://localhost:8080/webdav/parent/file1.txt
> child2
> http://localhost:8080/webdav/parent/
> file2.txt
> http://localhost:8080/webdav/parent/file2.txt
>
> The third result is the URL of the parent, with display name "child2"!
> So nothing about child1, although it comes from the server (see trace).
> And child2 URL is bad, because it shows parent URL.
>
> In general, I see that collection childs are never shown.
>
> And this is the http tracing I got. There are two requests involved, the first
> using depth 0 and the second using depth 1.
>
> FIRST REQUEST
> ===============
>
> PROPFIND /webdav/parent HTTP/1.1
> Authorization: Basic anVncmVnbzE6cGFkZW50cm8=
> Content-Type: text/xml; charset=utf-8
> User-Agent: Jakarta Commons-HttpClient/2.0final
> Host: localhost:8080
> Content-Length: 207
> Depth: 0
>
> <?xml version="1.0" encoding="utf-8"?>
> <D:propfind xmlns:D="DAV:">
> <D:prop>
> <D:displayname/>
> <D:getcontentlength/>
> <D:getcontenttype/>
> <D:resourcetype/>
> <D:getlastmodified/>
> <D:lockdiscovery/>
> </D:prop>
> </D:propfind>
>
> FIRST RESPONSE
> =================
>
> HTTP/1.1 207 Multi-Estado
> Content-Type: text/xml;charset=UTF-8
> Content-Length: 436
> Date: Thu, 30 Dec 2004 09:51:45 GMT
> Server: Apache-Coyote/1.1
>
> <?xml version="1.0" encoding="utf-8"?>
> <multistatus xmlns="DAV:">
> <response>
> <href>/webdav/parent/</href>
> <propstat>
> <prop>
> <displayname><![CDATA[parent]]></displayname>
> <resourcetype>
> <collection/>
> </resourcetype>
> </prop>
> <status>HTTP/1.1 200 OK</status>
> </propstat>
> <propstat>
> <prop>
> <getcontentlength/>
> <getcontenttype/>
> <getlastmodified/>
> <lockdiscovery/>
> </prop>
> <status>HTTP/1.1 404 Not Found</status>
> </propstat>
> </response>
> </multistatus>
>
> SECOND REQUEST
> ================
>
> PROPFIND /webdav/parent HTTP/1.1
> Authorization: Basic anVncmVnbzE6cGFkZW50cm8=
> Content-Type: text/xml; charset=utf-8
> User-Agent: Jakarta Commons-HttpClient/2.0final
> Host: localhost:8080
> Content-Length: 207
> Depth: 1
>
> <?xml version="1.0" encoding="utf-8"?>
> <D:propfind xmlns:D="DAV:">
> <D:prop>
> <D:displayname/>
> <D:getcontentlength/>
> <D:getcontenttype/>
> <D:resourcetype/>
> <D:getlastmodified/>
> <D:lockdiscovery/>
> </D:prop>
> </D:propfind>
>
> SECOND RESPONSE
> =================
>
> HTTP/1.1 207 Multi-Estado
> Content-Type: text/xml;charset=UTF-8
> Content-Length: 2028
> Date: Thu, 30 Dec 2004 09:51:45 GMT
> Server: Apache-Coyote/1.1
>
> <?xml version="1.0" encoding="utf-8"?>
> <multistatus xmlns="DAV:">
> <response>
> <href>/webdav/parent/</href>
> <propstat>
> <prop>
> <displayname><![CDATA[parent]]></displayname>
> <resourcetype>
> <collection/>
> </resourcetype>
> </prop>
> <status>HTTP/1.1 200 OK</status>
> </propstat>
> <propstat>
> <prop>
> <getcontentlength/>
> <getcontenttype/>
> <getlastmodified/>
> <lockdiscovery/>
> </prop>
> <status>HTTP/1.1 404 Not Found</status>
> </propstat>
> </response>
> <response>
> <href>/webdav/parent/file2.txt</href>
> <propstat>
> <prop>
> <displayname><![CDATA[file2.txt]]></displayname>
> <getcontentlength>10</getcontentlength>
> <getcontenttype>text/plain</getcontenttype>
> <resourcetype/>
> <getlastmodified>Mon, 27 Sep 2004 11:13:07 GMT</getlastmodified>
> </prop>
> <status>HTTP/1.1 200 OK</status>
> </propstat>
> <propstat>
> <prop>
> <lockdiscovery/>
> </prop>
> <status>HTTP/1.1 404 Not Found</status>
> </propstat>
> </response>
> <response>
> <href>/webdav/parent/file1.txt</href>
> <propstat>
> <prop>
> <displayname><![CDATA[file1.txt]]></displayname>
> <getcontentlength>10</getcontentlength>
> <getcontenttype>text/plain</getcontenttype>
> <resourcetype/>
> <getlastmodified>Mon, 27 Sep 2004 11:13:07 GMT</getlastmodified>
> </prop>
> <status>HTTP/1.1 200 OK</status>
> </propstat>
> <propstat>
> <prop>
> <lockdiscovery/>
> </prop>
> <status>HTTP/1.1 404 Not Found</status>
> </propstat>
> </response>
> <response>
> <href>/webdav/parent/child2/</href>
> <propstat>
> <prop>
> <displayname><![CDATA[child2]]></displayname>
> <resourcetype>
> <collection/>
> </resourcetype>
> </prop>
> <status>HTTP/1.1 200 OK</status>
> </propstat>
> <propstat>
> <prop>
> <getcontentlength/>
> <getcontenttype/>
> <getlastmodified/>
> <lockdiscovery/>
> </prop>
> <status>HTTP/1.1 404 Not Found</status>
> </propstat>
> </response>
> <response>
> <href>/webdav/parent/child1/</href>
> <propstat>
> <prop>
> <displayname><![CDATA[child1]]></displayname>
> <resourcetype>
> <collection/>
> </resourcetype>
> </prop>
> <status>HTTP/1.1 200 OK</status>
> </propstat>
> <propstat>
> <prop>
> <getcontentlength/>
> <getcontenttype/>
> <getlastmodified/>
> <lockdiscovery/>
> </prop>
> <status>HTTP/1.1 404 Not Found</status>
> </propstat>
> </response>
> </multistatus>
>
> As you can see from the second response, all the resources are returned
> correctly from the server.
(In reply to comment #16)
> (In reply to comment #14)
> > I bumped into the problem as well. 2.1 didn't work for me.
> > A solution was to change a part of WebdavResource.setWebdavProperties after
> >
> > if (!itself) {
> > String myURI = httpURL.getEscapedURI();
> >
> > ...
> >
> > to
> >
> > if (!itself) {
> > String myURI = httpURL.getEscapedURI();
> > final String adjustedHref = href.endsWith("/") ?
> > href.substring(0, href.length() - 1) : href;
> > final String name = URIUtil.getName(adjustedHref);
> > char[] childURI = (myURI + (myURI.endsWith("/") ? "" : "/")
> > + name).toCharArray();
> >
> > the problem is that children's hrefs can end with '/' and in this case
> > URIUtil.getName returns empty string. Because of that childURI is the same as
> > myURI (bug!!!)
>
>
> Thanks Igor! Everything works fine now. Also thanks to Robert and Philip. For
> those who want a fast cut-and-paste solution, simply replace the entire
>
> protected void setWebdavProperties(Enumeration responses)
>
> method in org.apache.webdav.lib.WebdavResource with the following code:
>
> // START: FIX /////////////////////////////////////////////////////
> /**
> * Set WebDAV properties following to the given http URL.
> * This method is fundamental for getting information of a collection.
> *
> * @param responses An enumeration over {@link ResponseEntity} items, one
> * for each resource for which information was returned via PROPFIND.
> *
> * @exception HttpException
> * @exception IOException The socket error with a server.
> */
> protected void setWebdavProperties(Enumeration responses)
> throws HttpException, IOException {
>
> // Make the resources in the collection empty.
> childResources.removeAll();
> while (responses.hasMoreElements()) {
>
> ResponseEntity response =
> (ResponseEntity) responses.nextElement();
>
> boolean itself = false;
> String href = response.getHref();
> if (!href.startsWith("/"))
> href = URIUtil.getPath(href);
> href = decodeMarks(href);
>
> /*
> * Decode URIs to common (unescaped) format for comparison
> * as HttpClient.URI.setPath() doesn't escape $ and : chars.
> */
> String httpURLPath = httpURL.getPath();
> String escapedHref = URIUtil.decode(href);
>
> // Normalize them to both have trailing slashes if they differ by
> one in length.
> int lenDiff = escapedHref.length() - httpURLPath.length();
> int compareLen = 0;
>
> if ( lenDiff == -1 && !escapedHref.endsWith("/")) {
> compareLen = escapedHref.length();
> lenDiff = 0;
> }
> else
> if ( lenDiff == 1 && !httpURLPath.endsWith("/")) {
> compareLen = httpURLPath.length();
> lenDiff = 0;
> }
>
> // if they are the same length then compare them.
> if (lenDiff == 0) {
> if ((compareLen == 0 && httpURLPath.equals(escapedHref))
> || httpURLPath.regionMatches(0, escapedHref, 0, compareLen))
> {
> // escaped href and http path are the same
> // Set the status code for this resource.
> if (response.getStatusCode() > 0)
> setStatusCode(response.getStatusCode());
> setExistence(true);
> itself = true;
> }
> }
>
> // Get to know each resource.
> WebdavResource workingResource = null;
> if (itself) {
> workingResource = this;
> }
> else {
> workingResource = createWebdavResource(client);
> workingResource.setDebug(debug);
> }
>
> // clear the current lock set
> workingResource.setLockDiscovery(null);
>
> // Process the resource's properties
> Enumeration properties = response.getProperties();
> while (properties.hasMoreElements()) {
>
> Property property = (Property) properties.nextElement();
>
> // ------------------------------ Checking WebDAV properties
> workingResource.processProperty(property);
> }
>
> String displayName = workingResource.getDisplayName();
>
> if (displayName == null || displayName.trim().equals("")) {
> displayName = getName(href);
> }
>
> /** BUGGY CODE
> if (!itself) {
> String myURI = httpURL.getEscapedURI();
> char[] childURI = (myURI + (myURI.endsWith("/") ? "" : "/")
> + URIUtil.getName(href)).toCharArray();
> HttpURL childURL = httpURL instanceof HttpsURL
> ? new HttpsURL(childURI)
> : new HttpURL(childURI);
> childURL.setRawAuthority(httpURL.getRawAuthority());
> workingResource.setHttpURL(childURL, NOACTION, defaultDepth);
> workingResource.setExistence(true);
> workingResource.setOverwrite(getOverwrite());
> }
> */
>
> /** FIX ********/
> if (!itself) {
> String myURI = httpURL.getEscapedURI();
>
> /**
> Checks if href contains trailing '/', and if so removes it.
> This ensures URIUtil.getName does not return an empty
> String when we don't want it to.
>
> See http://issues.apache.org/bugzilla/show_bug.cgi?id=32886
> for more information.
> */
> String fixedHref = href.endsWith("/") ?
> href.substring(0, href.length() - 1) : href;
>
> char[] childURI = (myURI + (myURI.endsWith("/") ? "" : "/")
> + URIUtil.getName(fixedHref)).toCharArray();
>
> HttpURL childURL = httpURL instanceof HttpsURL
> ? new HttpsURL(childURI)
> : new HttpURL(childURI);
> childURL.setRawAuthority(httpURL.getRawAuthority());
> workingResource.setHttpURL(childURL, NOACTION, defaultDepth);
> workingResource.setExistence(true);
> workingResource.setOverwrite(getOverwrite());
> }
> /**************/
>
>
> workingResource.setDisplayName(displayName);
>
> if (!itself)
> childResources.addResource(workingResource);
> }
> }
> // END: FIX /////////////////////////////////////////////////////
>
> The code is based on Igor's solution and should work fine. Please post here if
> you stumble upon any issues the fix causes. In the meantime however, its
> working perfectly for me.
>
> Cheers!
>
> Mike N. Christoff
--
Configure bugmail: http://issues.apache.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.
---------------------------------------------------------------------
To unsubscribe, e-mail: slide-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: slide-dev-help@jakarta.apache.org