Menu

[patch] https-support and authentication bug

2008-05-29
2013-04-24
  • Stephan Schuster

    hi jason,

    we've already been in contact a few weeks ago on the apache commons mailing list. the topic was "[vfs] webdav, jackrabbit and fileObject.exists()". as i said "i would even consider helping you" someday, you answered "well, if you run into any problems with webdavclient4j, you may want to step up to the plate". so i did!

    in my current project i needed a secure webdav connection. the standard webdav provider, however, always used http and never https. so i copied webdavclient4j v0.91 and did some changes and refactorings in the "org.apache.commons.vfs.provider.webdav"-package. the exact patchfile is attached below. based on these changes it was very easy to add a new package named "org.apache.commons.vfs.provider.webdav-->s<--" which provides support for webdav over https. there are only two classes in it, "WebdavsFileProvider" and "WebdavsClientFactory", each of which is extended from its non-httpS-pendant. the sourcecode of both classes is attached below as well.

    furthermore there was a bug in WebdavFileObject.setDavResource() which didn't respect the user's credentials (needed when a webdav resource is protected by the server via e.g. Basic Authentication) that have previously been set by means of DefaultFileSystemConfigBuilder. the fix for this issue is contained in the patchfile below as well.

    for the sake of completeness i'll pack the whole sources (webdav and webdavs package) and send it to you via email.

    it would be great if you could apply these changes to webdavclient4j library. by the way, thank you so much for your efforts!

    best regards,
    stephan

    PS: one question: is there a special reason why webdavclient4j uses commons-httpclient-3.0.1 instead of commons-httpclient-3.1??? does it already work with commons-httpclient-3.1???

    --- and now the patch file and the two java classes mentioned above ---

    --- apache/commons/vfs/provider/webdav/WebdavClientFactory.java    Thu May 29 15:44:43 2008
    +++ apache/commons/vfs/provider/webdav/WebdavClientFactory.java    Tue May 06 11:53:43 2008
    @@ -21 +20,0 @@
    -import org.apache.commons.httpclient.URIException;
    @@ -41 +40 @@
    -    public WebdavClientFactory()
    +    private WebdavClientFactory()
    @@ -48 +47 @@
    -    public HttpClient createConnection(String hostname, int port, char[] username, char[] password, FileSystemOptions fileSystemOptions) throws FileSystemException
    +    public static HttpClient createConnection(String hostname, int port, char[] username, char[] password, FileSystemOptions fileSystemOptions) throws FileSystemException
    @@ -54 +53,6 @@
    -            final HttpURL url = createURL(hostname, port, username, password);
    +            final HttpURL url = new HttpURL(
    +                UserAuthenticatorUtils.toString(username),
    +                UserAuthenticatorUtils.toString(password),
    +                hostname,
    +                port,
    +                "/");
    @@ -112,10 +115,0 @@
    -
    -    protected HttpURL createURL(String hostname, int port, char[] username, char[] password)
    -            throws URIException {
    -        return new HttpURL(
    -            UserAuthenticatorUtils.toString(username),
    -            UserAuthenticatorUtils.toString(password),
    -            hostname,
    -            port,
    -            "/");
    -    }
    --- apache/commons/vfs/provider/webdav/WebdavFileObject.java    Thu May 29 15:45:04 2008
    +++ apache/commons/vfs/provider/webdav/WebdavFileObject.java    Mon May 05 14:06:41 2008
    @@ -49 +48,0 @@
    -import org.apache.commons.vfs.UserAuthenticationData;
    @@ -57 +55,0 @@
    -import org.apache.commons.vfs.util.UserAuthenticatorUtils;
    @@ -132,0 +131 @@
    +            // HttpURL url = new HttpURL(name.getHostName(), name.getPort(), name.getPath());
    @@ -134,18 +133 @@
    -           
    -            UserAuthenticationData authData = null;
    -            HttpURL url;
    -            try
    -            {
    -                authData = UserAuthenticatorUtils.authenticate(fileSystem.getFileSystemOptions(), WebdavFileProvider.AUTHENTICATOR_TYPES);
    -           
    -                url = fileSystem.getFactory().createURL(
    -                    name.getHostName(),
    -                    name.getPort(),
    -                    UserAuthenticatorUtils.getData(authData, UserAuthenticationData.USERNAME, UserAuthenticatorUtils.toChar(name.getUserName())),
    -                    UserAuthenticatorUtils.getData(authData, UserAuthenticationData.PASSWORD, UserAuthenticatorUtils.toChar(name.getPassword())));
    -            }
    -            finally
    -            {
    -                UserAuthenticatorUtils.cleanup(authData);
    -            }
    -           
    +            HttpURL url = new HttpURL(name.getUserName(), name.getPassword(), name.getHostName(), name.getPort());
    --- apache/commons/vfs/provider/webdav/WebdavFileProvider.java    Thu May 29 15:45:13 2008
    +++ apache/commons/vfs/provider/webdav/WebdavFileProvider.java    Mon May 05 14:06:41 2008
    @@ -18,0 +19 @@
    +import org.apache.commons.httpclient.HttpClient;
    @@ -24,0 +26 @@
    +import org.apache.commons.vfs.util.UserAuthenticatorUtils;
    @@ -26 +27,0 @@
    -import org.apache.commons.vfs.provider.FileNameParser;
    @@ -62,2 +62,0 @@
    -   
    -    private WebdavClientFactory clientFactory;
    @@ -68,2 +67,2 @@
    -        setFileNameParser(getParser());
    -        clientFactory = getFactory();
    +
    +        setFileNameParser(HttpFileNameParser.getInstance());
    @@ -71,8 +69,0 @@
    -   
    -    protected FileNameParser getParser() {
    -        return HttpFileNameParser.getInstance();
    -    }
    -   
    -    protected WebdavClientFactory getFactory() {
    -        return new WebdavClientFactory();
    -    }
    @@ -87 +78,21 @@
    -        return new WebDavFileSystem(clientFactory, (GenericFileName) name, fileSystemOptions);
    +        final GenericFileName rootName = (GenericFileName) name;
    +
    +        UserAuthenticationData authData = null;
    +        HttpClient httpClient;
    +        try
    +        {
    +            authData = UserAuthenticatorUtils.authenticate(fileSystemOptions, AUTHENTICATOR_TYPES);
    +
    +            httpClient = WebdavClientFactory.createConnection(
    +                rootName.getHostName(),
    +                rootName.getPort(),
    +                UserAuthenticatorUtils.getData(authData, UserAuthenticationData.USERNAME, UserAuthenticatorUtils.toChar(rootName.getUserName())),
    +                UserAuthenticatorUtils.getData(authData, UserAuthenticationData.PASSWORD, UserAuthenticatorUtils.toChar(rootName.getPassword())),
    +                fileSystemOptions);
    +        }
    +        finally
    +        {
    +            UserAuthenticatorUtils.cleanup(authData);
    +        }
    +
    +        return new WebDavFileSystem(rootName, httpClient, fileSystemOptions);
    --- apache/commons/vfs/provider/webdav/WebDavFileSystem.java    Thu May 29 15:45:21 2008
    +++ apache/commons/vfs/provider/webdav/WebDavFileSystem.java    Mon May 05 14:06:41 2008
    @@ -24 +23,0 @@
    -import org.apache.commons.vfs.FileSystemException;
    @@ -26 +24,0 @@
    -import org.apache.commons.vfs.UserAuthenticationData;
    @@ -30 +27,0 @@
    -import org.apache.commons.vfs.util.UserAuthenticatorUtils;
    @@ -45,3 +42,2 @@
    -    private final WebdavClientFactory factory;
    -   
    -    protected WebDavFileSystem(final WebdavClientFactory factory, final GenericFileName rootName, final FileSystemOptions fileSystemOptions) throws FileSystemException
    +
    +    protected WebDavFileSystem(final GenericFileName rootName, final HttpClient client, final FileSystemOptions fileSystemOptions)
    @@ -50,3 +46,2 @@
    -       
    -        this.factory = factory;
    -        this.client = createClient(rootName, fileSystemOptions);
    +
    +        this.client = client;
    @@ -54,21 +48,0 @@
    -   
    -    private HttpClient createClient(final GenericFileName rootName, final FileSystemOptions fileSystemOptions) throws FileSystemException {
    -        UserAuthenticationData authData = null;
    -        HttpClient httpClient;
    -        try
    -        {
    -            authData = UserAuthenticatorUtils.authenticate(fileSystemOptions, WebdavFileProvider.AUTHENTICATOR_TYPES);
    -       
    -            httpClient = factory.createConnection(
    -                rootName.getHostName(),
    -                rootName.getPort(),
    -                UserAuthenticatorUtils.getData(authData, UserAuthenticationData.USERNAME, UserAuthenticatorUtils.toChar(rootName.getUserName())),
    -                UserAuthenticatorUtils.getData(authData, UserAuthenticationData.PASSWORD, UserAuthenticatorUtils.toChar(rootName.getPassword())),
    -                fileSystemOptions);
    -        }
    -        finally
    -        {
    -            UserAuthenticatorUtils.cleanup(authData);
    -        }
    -        return httpClient;
    -    }
    @@ -82,8 +55,0 @@
    -    }
    -   
    -    /**
    -     * Returns the factory for this file system.
    -     */
    -    protected WebdavClientFactory getFactory()
    -    {
    -        return factory;
    --- apache/commons/vfs/provider/webdav/WebdavFileSystemConfigBuilder.java    Thu May 29 15:45:27 2008
    +++ apache/commons/vfs/provider/webdav/WebdavFileSystemConfigBuilder.java    Mon May 05 14:06:41 2008
    @@ -21,0 +22 @@
    +import org.apache.commons.httpclient.Cookie;
    --- apache/commons/vfs/provider/webdav/WebdavMethodRetryHandler.java    Thu May 29 15:47:05 2008
    +++ apache/commons/vfs/provider/webdav/WebdavMethodRetryHandler.java    Mon May 05 14:06:41 2008
    @@ -19 +19,4 @@
    -import org.apache.commons.httpclient.HttpConnection;
    +import org.apache.commons.httpclient.HttpClient;
    +import org.apache.commons.httpclient.HttpURL;
    +import org.apache.commons.httpclient.UsernamePasswordCredentials;
    +import org.apache.commons.httpclient.MethodRetryHandler;
    @@ -20,0 +24 @@
    +import org.apache.commons.httpclient.HttpConnection;
    @@ -22 +26,8 @@
    -import org.apache.commons.httpclient.MethodRetryHandler;
    +import org.apache.commons.vfs.FileSystemOptions;
    +import org.apache.commons.vfs.FileSystemException;
    +import org.apache.commons.vfs.UserAuthenticator;
    +import org.apache.commons.vfs.UserAuthenticationData;
    +import org.apache.commons.vfs.util.UserAuthenticatorUtils;
    +import org.apache.webdav.lib.WebdavResource;
    +
    +import java.io.IOException;

    ---------------------------------------------------------------------

    package org.apache.commons.vfs.provider.webdavs;

    import org.apache.commons.vfs.provider.FileNameParser;
    import org.apache.commons.vfs.provider.https.HttpsFileNameParser;

    import com.wilken.utilities.vfs.provider.webdav.WebdavClientFactory;
    import com.wilken.utilities.vfs.provider.webdav.WebdavFileProvider;

    /**
    * A provider for WebDAV based on HTTPS.
    *
    * @author Stephan Schuster
    */
    public class WebdavsFileProvider extends WebdavFileProvider {

        protected FileNameParser getParser() {
            return HttpsFileNameParser.getInstance();
        }
       
        protected WebdavClientFactory getFactory() {
            return new WebdavsClientFactory();
        }
       
    }

    ---------------------------------------------------------------------

    package org.apache.commons.vfs.provider.webdavs;

    import org.apache.commons.httpclient.HttpURL;
    import org.apache.commons.httpclient.HttpsURL;
    import org.apache.commons.httpclient.URIException;
    import org.apache.commons.vfs.util.UserAuthenticatorUtils;

    import com.wilken.utilities.vfs.provider.webdav.WebdavClientFactory;

    /**
    * A factory for HttpClient based on HTTPS.
    *
    * @author Stephan Schuster
    */
    public class WebdavsClientFactory extends WebdavClientFactory {

        protected HttpURL createURL(String hostname, int port, char[] username, char[] password)
                throws URIException {
            return new HttpsURL(
                UserAuthenticatorUtils.toString(username),
                UserAuthenticatorUtils.toString(password),
                hostname,
                port,
                "/");
        }

    }

     
    • Jason Harrop

      Jason Harrop - 2008-05-30

      Hi Stephan

      Thanks very much for your patch, which I have applied.  Several people had been after this in the past - see https://issues.apache.org/jira/browse/VFS-180

      I guess I need to think about licensing of contributions.  It seems to me that if each person who contributes says they are making their contribution available under the Apache Software License version 2, then we are covered.  So could you please confirm your contribution is made on that basis?

      As to HC 3.1, there has been a report that webdavclient4j works with it. I haven't confirmed this myself yet.

      kind regards

      Jason

       
    • Stephan Schuster

      hi jason,

      of course my contribution is available under the Apache Software License version 2, or whatever license you need or want to use. otherwise it wouldn't make sense!

      regarding hc 3.1: i've read the post but i wanted to ask you - the main developer - what your experiences are. i thought if your intention was to "make slide working with a hc version higher than 2.0.2" (as it was originally the case) then why did you use hc 3.0.1 instead of 3.1? anyway, if there was no special reason and you don't say "oh, you've got to be aware of this and that", i'll try it myself.

      cheers,
      stephan

       

Log in to post a comment.