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 2007/03/02 22:49:06 UTC

DO NOT REPLY [Bug 41750] New: - WebdavResource.exists() throws exception if resource does not exist

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=41750>.
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=41750

           Summary: WebdavResource.exists() throws exception if resource
                    does not exist
           Product: Slide
           Version: 2.1
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: WebDAV client
        AssignedTo: slide-dev@jakarta.apache.org
        ReportedBy: dmx_dawg@hotmail.com


Issue:
If one attempts to create a org.apache.webdav.lib.WebdavResource object for a 
resource that does not exist, the WebdavResource constructor will throw an 
exception and hence one can never even call exists().  So if one can even 
successfully call exists() it implies the resource DOES exist making the method 
of limited use.

Why it is occuring:
What's happening is that WebdavResource is using PROPFIND to get properties for 
a resource that does not exist which--according to the Webdav spec--is an 
error.  Hence a correct WebDAV server must return a 404 (Not Found) response. 
The code in propFindMethod (see snippet below) checks the response status and 
throws an exception if it doesn't recieve an XML multistatus response or an 
HTTP 200 (OK) response.

        if (status != HttpStatus.SC_MULTI_STATUS
            && status != HttpStatus.SC_OK) {
            HttpException ex = new HttpException();
            ex.setReasonCode(status);
            throw ex;
        }

///////////////////////////////////////
        
Solution idea:
Here is one I thought of.  We simply add the following to this conditional:

        if (status != HttpStatus.SC_MULTI_STATUS
            && status != HttpStatus.SC_OK
            
            && status != HttpStatus.SC_NOT_FOUND // <---
            
            ) {
            HttpException ex = new HttpException();
            ex.setReasonCode(status);
            throw ex;
        }

What this essentially says is "if the property does not exist, we simply won't 
add it to the Enumeration of properties, but we won't throw an exception unless 
there is a server error".  So if the user loops through the Enumeration without 
finding the requested property, the client must assume it doesn't exist.


///////////////////////////////////////
 FIX BELOW (3 methods)
///////////////////////////////////////

The three methods of org.apache.webdav.lib.WebdavResource where this change 
needs to be made are:

	propfindMethod(String, int)
	propfindMethod(String, int, Vector)
	propfindMethod(String, Vector)

The code with the updates is below.  For what its worth, my Slide-client based 
code is working without a hitch with the changes.  Also, once I re-code 
sections of my app to take advantage of the now-working exists() function, my 
code should also run faster (since I can determine whether a file exists or not 
without possibly incurring exception throw/catch overhead).

//---------------


    /**
     * Execute PROPFIND method with allprop for the given path.
     * Get list of all WebDAV properties on the given resource.
     *
     * <p>Once used this method, the the status code in the 207
     * reponse is need to be set for the method of WebdavResource.
     *
     * <p>The values of DepthSupport.DEPTH_0, DepthSupport.DEPTH_1,
     * DepthSupport.DEPTH_INFINITY is possbile for the depth.
     *
     * @param path the server relative path of the resource to request
     * @param depth
     * @return an enumeration of <code>ResponseEntity</code>
     * @exception HttpException
     * @exception IOException
     */
    public Enumeration propfindMethod(String path, int depth)
        throws HttpException, IOException {

        setClient();
        // Change the depth for allprop
        PropFindMethod method = new PropFindMethod(URIUtil.encodePath(path),
                                                   depth);

        method.setDebug(debug);

        // Default depth=infinity, type=allprop
        generateTransactionHeader(method);
        int status = client.executeMethod(method);

        // Set status code for this resource.
        if (thisResource == true) {
            setStatusCode(status);
        }
        // Also accept OK sent by buggy servers.
        
        /**
         * OLD CODE
        if (status != HttpStatus.SC_MULTI_STATUS
            && status != HttpStatus.SC_OK) {
            HttpException ex = new HttpException();
            ex.setReasonCode(status);
            throw ex;
        }
        */

        // FIX
        if (status != HttpStatus.SC_MULTI_STATUS
            
            && status != HttpStatus.SC_NOT_FOUND    // <---
            
            && status != HttpStatus.SC_OK
            ) {
            HttpException ex = new HttpException();
            ex.setReasonCode(status);
            throw ex;
        }        
       // END FIX
        
        thisResource = false;

        return method.getResponses();
    }
    
    
//---------------    

    
    public Enumeration propfindMethod(String path, int depth,
                                      Vector properties)
        throws HttpException, IOException {

        setClient();
        // Change the depth for prop
        PropFindMethod method = new PropFindMethod(URIUtil.encodePath(path),
                                                   depth,
                                                   properties.elements());

        method.setDebug(debug);
        method.setFollowRedirects(this.followRedirects);
        generateTransactionHeader(method);
        int status = client.executeMethod(method);

        // Set status code for this resource.
        if (thisResource == true) {
            // Set the status code.
            setStatusCode(method.getStatusLine().getStatusCode());
        }
        // Also accept OK sent by buggy servers.
        
        /*
         * OLD CODE
         *
        if (status != HttpStatus.SC_MULTI_STATUS
            && status != HttpStatus.SC_OK) {
            HttpException ex = new HttpException();
            ex.setReasonCode(status);
            throw ex;
        }
        */
        
        // FIX
        if (status != HttpStatus.SC_MULTI_STATUS
            
            && status != HttpStatus.SC_NOT_FOUND // <---
            
            && status != HttpStatus.SC_OK) {
            HttpException ex = new HttpException();
            ex.setReasonCode(status);
            throw ex;
        }
        // END FIX
        

        thisResource = false;

        return method.getResponses();
    }
    
    
//---------------    
    
    
    /**
     * Execute PROPFIND method for the given path and properties.
     * Get list of given WebDAV properties on the given resource.
     *
     * @param path the server relative path of the resource to request
     * @param properties the WebDAV properties to find.
     * @return Enumeration list of WebDAV properties on a resource.
     * @exception HttpException
     * @exception IOException
     */
    public Enumeration propfindMethod(String path, Vector properties)
        throws HttpException, IOException {

        setClient();
        // Default depth=0, type=by_name
        PropFindMethod method = new PropFindMethod(URIUtil.encodePath(path),
                                                   DepthSupport.DEPTH_0,
                                                   properties.elements());
        method.setDebug(debug);
        method.setFollowRedirects(this.followRedirects);
        generateTransactionHeader(method);
        int status = client.executeMethod(method);

        // Also accept OK sent by buggy servers.
        /*
         * OLD CODE
         *        
        if (status != HttpStatus.SC_MULTI_STATUS
            && status != HttpStatus.SC_OK) {
            HttpException ex = new HttpException();
            ex.setReasonCode(status);
            throw ex;
        }
        */
        
        // FIX
        if (status != HttpStatus.SC_MULTI_STATUS
            
            && status != HttpStatus.SC_NOT_FOUND	// <---
            
            && status != HttpStatus.SC_OK) {
            HttpException ex = new HttpException();
            ex.setReasonCode(status);
            throw ex;
        }
        // END FIX
        

        // It contains the results.
        Vector results = new Vector();

        Enumeration responses = method.getResponses();
        if (responses.hasMoreElements()) {
            ResponseEntity response =
                (ResponseEntity) responses.nextElement();
            String href = response.getHref();

            // Set status code for this resource.
            if ((thisResource == true) && (response.getStatusCode() > 0))
                setStatusCode(response.getStatusCode());
            thisResource = false;

            Enumeration responseProperties =
                method.getResponseProperties(href);
            while (responseProperties.hasMoreElements()) {
                Property property =
                    (Property) responseProperties.nextElement();
                results.addElement(property.getPropertyAsString());
            }
        }

        return results.elements();
    }    

///////////////////////////////////////
///////////////////////////////////////


For more detailed information on this issue, please the following message in 
the Slide client dev mailing list archive.

Possible solutions to WebdavResource.exists() method
http://mail-archives.apache.org/mod_mbox/jakarta-slide-dev/200702.mbox/%
3c2FCCD448BA412B4FB9039AF8DDC103BC052B3FAB@camhems-1.camh.ca%3e

Possible side-effects of proposed fix
http://mail-archives.apache.org/mod_mbox/jakarta-slide-dev/200702.mbox/%
3c2FCCD448BA412B4FB9039AF8DDC103BC052B3FE3@camhems-1.camh.ca%3e




Cheers!



Michael N. Christoff
dmx_dawg@hotmail.com



///////////////////////////////////////


Michael N. Christoff
Site Administrator
Continuing Professional Education Online
Centre for Addiction and Mental Health
33 Russell Street
Toronto, Ontario M5S 2S1

-- 
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


DO NOT REPLY [Bug 41750] - WebdavResource.exists() throws exception if resource does not exist

Posted by bu...@apache.org.
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=41750>.
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=41750


antoine@apache.org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |DUPLICATE




------- Additional Comments From antoine@apache.org  2007-03-30 11:21 -------


*** This bug has been marked as a duplicate of 16642 ***

-- 
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