1 /* ownCloud Android client application 
   2  *   Copyright (C) 2011  Bartek Przybylski 
   4  *   This program is free software: you can redistribute it and/or modify 
   5  *   it under the terms of the GNU General Public License as published by 
   6  *   the Free Software Foundation, either version 3 of the License, or 
   7  *   (at your option) any later version. 
   9  *   This program is distributed in the hope that it will be useful, 
  10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of 
  11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  12  *   GNU General Public License for more details. 
  14  *   You should have received a copy of the GNU General Public License 
  15  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. 
  18 package eu
.alefzero
.webdav
; 
  20 import java
.io
.BufferedInputStream
; 
  22 import java
.io
.FileOutputStream
; 
  23 import java
.io
.IOException
; 
  25 import org
.apache
.commons
.httpclient
.Credentials
; 
  26 import org
.apache
.commons
.httpclient
.HttpClient
; 
  27 import org
.apache
.commons
.httpclient
.HttpConnectionManager
; 
  28 import org
.apache
.commons
.httpclient
.HttpVersion
; 
  29 import org
.apache
.commons
.httpclient
.MultiThreadedHttpConnectionManager
; 
  30 import org
.apache
.commons
.httpclient
.UsernamePasswordCredentials
; 
  31 import org
.apache
.commons
.httpclient
.auth
.AuthScope
; 
  32 import org
.apache
.commons
.httpclient
.methods
.GetMethod
; 
  33 import org
.apache
.commons
.httpclient
.methods
.HeadMethod
; 
  34 import org
.apache
.commons
.httpclient
.methods
.PutMethod
; 
  35 import org
.apache
.commons
.httpclient
.params
.HttpMethodParams
; 
  36 import org
.apache
.commons
.httpclient
.protocol
.Protocol
; 
  37 import org
.apache
.http
.HttpStatus
; 
  38 import org
.apache
.http
.params
.CoreProtocolPNames
; 
  39 import org
.apache
.jackrabbit
.webdav
.client
.methods
.DavMethod
; 
  40 import org
.apache
.jackrabbit
.webdav
.client
.methods
.DeleteMethod
; 
  41 import org
.apache
.jackrabbit
.webdav
.client
.methods
.MkColMethod
; 
  43 import android
.accounts
.Account
; 
  44 import android
.accounts
.AccountManager
; 
  45 import android
.content
.Context
; 
  46 import android
.net
.Uri
; 
  47 import android
.util
.Log
; 
  48 import eu
.alefzero
.owncloud
.AccountUtils
; 
  49 import eu
.alefzero
.owncloud
.authenticator
.AccountAuthenticator
; 
  50 import eu
.alefzero
.owncloud
.authenticator
.EasySSLSocketFactory
; 
  51 import eu
.alefzero
.owncloud
.files
.interfaces
.OnDatatransferProgressListener
; 
  52 import eu
.alefzero
.owncloud
.utils
.OwnCloudVersion
; 
  54 public class WebdavClient 
extends HttpClient 
{ 
  56     private Credentials mCredentials
; 
  57     final private static String TAG 
= "WebdavClient"; 
  58     private static final String USER_AGENT 
= "Android-ownCloud"; 
  59     private OnDatatransferProgressListener mDataTransferListener
; 
  60     static private MultiThreadedHttpConnectionManager mConnManager 
= null
; 
  62     static public MultiThreadedHttpConnectionManager 
getMultiThreadedConnManager() { 
  63         if (mConnManager 
== null
) { 
  64             mConnManager 
= new MultiThreadedHttpConnectionManager(); 
  65             mConnManager
.setMaxConnectionsPerHost(5); 
  66             mConnManager
.setMaxTotalConnections(5); 
  72      * Creates a WebdavClient setup for the current account 
  73      * @param account The client accout 
  74      * @param context The application context 
  77     public WebdavClient (Account account
, Context context
) { 
  78         OwnCloudVersion ownCloudVersion 
= new OwnCloudVersion(AccountManager
.get(context
).getUserData(account
, 
  79                 AccountAuthenticator
.KEY_OC_VERSION
)); 
  80         String baseUrl 
= AccountManager
.get(context
).getUserData(account
, AccountAuthenticator
.KEY_OC_BASE_URL
); 
  81         String webDavPath 
= AccountUtils
.getWebdavPath(ownCloudVersion
);         
  82         String username 
= account
.name
.substring(0, account
.name
.indexOf('@')); 
  83         String password 
= AccountManager
.get(context
).getPassword(account
); 
  85         mUri 
= Uri
.parse(baseUrl 
+ webDavPath
); 
  87         setCredentials(username
, password
); 
  90     public WebdavClient() { 
  91         super(getMultiThreadedConnManager()); 
  93         getParams().setParameter(HttpMethodParams
.USER_AGENT
, USER_AGENT
); 
  94         getParams().setParameter(CoreProtocolPNames
.PROTOCOL_VERSION
, HttpVersion
.HTTP_1_1
); 
  95         allowSelfsignedCertificates(); 
  98     public void setCredentials(String username
, String password
) { 
  99         //getParams().setAuthenticationPreemptive(true); 
 100         getState().setCredentials(AuthScope
.ANY
, 
 101                 getCredentials(username
, password
)); 
 104     private Credentials 
getCredentials(String username
, String password
) { 
 105         if (mCredentials 
== null
) 
 106             mCredentials 
= new UsernamePasswordCredentials(username
, password
); 
 110     public void allowSelfsignedCertificates() { 
 112         Protocol
.registerProtocol("https", new Protocol("https", 
 113                 new EasySSLSocketFactory(), 443)); 
 117      * Downloads a file in remoteFilepath to the local targetPath. 
 119      * @param remoteFilepath    Path to the file in the remote server, URL DECODED.  
 120      * @param targetPath        Local path to save the downloaded file. 
 121      * @return                  'True' when the file is successfully downloaded. 
 123     public boolean downloadFile(String remoteFilepath
, File targetPath
) { 
 125         GetMethod get 
= new GetMethod(mUri
.toString() + WebdavUtils
.encodePath(remoteFilepath
)); 
 126         HttpMethodParams params 
= get
.getParams(); 
 127         params
.setSoTimeout(0); // that means "infinite timeout"; it's the default value, but let's make it explicit 
 128         get
.setParams(params
); 
 130         // get.setHeader("Host", mUri.getHost()); 
 131         // get.setHeader("User-Agent", "Android-ownCloud"); 
 134             int status 
= executeMethod(get
); 
 135             Log
.e(TAG
, "status return: " + status
); 
 136             if (status 
== HttpStatus
.SC_OK
) { 
 137                 targetPath
.createNewFile(); 
 138                 BufferedInputStream bis 
= new BufferedInputStream( 
 139                         get
.getResponseBodyAsStream()); 
 140                 FileOutputStream fos 
= new FileOutputStream(targetPath
); 
 142                 byte[] bytes 
= new byte[4096]; 
 144                 while ((readResult 
= bis
.read(bytes
)) != -1) { 
 145                     if (mDataTransferListener 
!= null
) 
 146                         mDataTransferListener
.transferProgress(readResult
); 
 147                     fos
.write(bytes
, 0, readResult
); 
 152         } catch (Throwable e
) { 
 161      * Deletes a remote file via webdav 
 162      * @param remoteFilePath       Remote file path of the file to delete, in URL DECODED format. 
 165     public boolean deleteFile(String remoteFilePath
){ 
 166         DavMethod delete 
= new DeleteMethod(mUri
.toString() + WebdavUtils
.encodePath(remoteFilePath
)); 
 168             executeMethod(delete
); 
 169         }  catch (Throwable e
) { 
 170             Log
.e(TAG
, "Deleting failed with error: " + e
.getMessage(), e
); 
 176     public void setDataTransferProgressListener(OnDatatransferProgressListener listener
) { 
 177         mDataTransferListener 
= listener
; 
 181      * Creates or update a file in the remote server with the contents of a local file. 
 184      * @param localFile         Path to the local file to upload. 
 185      * @param remoteTarget      Remote path to the file to create or update, URL DECODED 
 186      * @param contentType       MIME type of the file. 
 187      * @return                  'True' then the upload was successfully completed 
 189     public boolean putFile(String localFile
, String remoteTarget
, 
 190             String contentType
) { 
 191         boolean result 
= true
; 
 194             Log
.e("ASD", contentType 
+ ""); 
 195             File f 
= new File(localFile
); 
 196             FileRequestEntity entity 
= new FileRequestEntity(f
, contentType
); 
 197             entity
.setOnDatatransferProgressListener(mDataTransferListener
); 
 198             Log
.e("ASD", f
.exists() + " " + entity
.getContentLength()); 
 199             PutMethod put 
= new PutMethod(mUri
.toString() + WebdavUtils
.encodePath(remoteTarget
)); 
 200             HttpMethodParams params 
= put
.getParams(); 
 201             params
.setSoTimeout(0); // that means "infinite timeout"; it's the default value, but let's make it explicit 
 202             put
.setParams(params
); 
 203             put
.setRequestEntity(entity
); 
 204             Log
.d(TAG
, "" + put
.getURI().toString()); 
 205             int status 
= executeMethod(put
); 
 206             Log
.d(TAG
, "PUT method return with status " + status
); 
 208             Log
.i(TAG
, "Uploading, done"); 
 209         } catch (final Exception e
) { 
 210             Log
.i(TAG
, "" + e
.getMessage()); 
 218      * Tries to log in to the given WedDavURI, with the given credentials 
 220      * @param username Username to check 
 221      * @param password Password to verify 
 222      * @return A {@link HttpStatus}-Code of the result. SC_OK is good. 
 224     public static int tryToLogin(Uri uri
, String username
, String password
) { 
 226         WebdavClient client 
= new WebdavClient(); 
 227         client
.setCredentials(username
, password
); 
 228         HeadMethod head 
= new HeadMethod(uri
.toString()); 
 230             returnCode 
= client
.executeMethod(head
); 
 231         } catch (Exception e
) { 
 232             Log
.e(TAG
, "Error: " + e
.getMessage()); 
 238      * Creates a remote directory with the received path. 
 240      * @param path      Path of the directory to create, URL DECODED 
 241      * @return          'True' when the directory is successfully created 
 243     public boolean createDirectory(String path
) { 
 245             MkColMethod mkcol 
= new MkColMethod(mUri
.toString() + WebdavUtils
.encodePath(path
)); 
 246             int status 
= executeMethod(mkcol
); 
 247             Log
.d(TAG
, "Status returned " + status
); 
 248             Log
.d(TAG
, "uri: " + mkcol
.getURI().toString()); 
 249             Log
.i(TAG
, "Creating dir completed"); 
 250         } catch (final Exception e
) {