ssl support for syncing
authorBartek Przybylski <bart.p.pl@gmail.com>
Sat, 4 Feb 2012 18:49:33 +0000 (19:49 +0100)
committerBartek Przybylski <bart.p.pl@gmail.com>
Sat, 4 Feb 2012 18:49:33 +0000 (19:49 +0100)
src/eu/alefzero/owncloud/syncadapter/AbstractOwnCloudSyncAdapter.java
src/eu/alefzero/owncloud/ui/activity/LandingActivity.java
src/eu/alefzero/owncloud/ui/adapter/LandingScreenAdapter.java
src/eu/alefzero/owncloud/ui/fragment/LandingPageFragment.java
src/eu/alefzero/webdav/WebdavClient.java

index 3c1caf9..e4bacf2 100644 (file)
@@ -15,8 +15,9 @@
  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
  *\r
  */\r
-package eu.alefzero.owncloud.syncadapter;\r
-\r
+
+package eu.alefzero.owncloud.syncadapter;
+
 import java.io.IOException;\r
 import java.net.UnknownHostException;\r
 import java.util.Date;\r
@@ -25,8 +26,6 @@ import java.util.LinkedList;
 import org.apache.http.HttpHost;\r
 import org.apache.http.HttpRequest;\r
 import org.apache.http.HttpResponse;\r
-import org.apache.http.auth.AuthScope;\r
-import org.apache.http.auth.UsernamePasswordCredentials;\r
 import org.apache.http.client.ClientProtocolException;\r
 import org.apache.http.conn.ConnectionKeepAliveStrategy;\r
 import org.apache.http.impl.auth.BasicScheme;\r
@@ -46,143 +45,139 @@ import android.text.TextUtils;
 import eu.alefzero.owncloud.authenticator.AccountAuthenticator;\r
 import eu.alefzero.webdav.HttpPropFind;\r
 import eu.alefzero.webdav.TreeNode;\r
-import eu.alefzero.webdav.TreeNode.NodeProperty;\r
+import eu.alefzero.webdav.WebdavClient;\r
 import eu.alefzero.webdav.WebdavUtils;\r
-\r
-/**\r
- * Base SyncAdapter for OwnCloud\r
- * Designed to be subclassed for the concreete SyncAdapter, like ConcatsSync, CalendarSync, FileSync etc..\r
- * \r
- * @author sassman\r
- *\r
- */\r
-public abstract class AbstractOwnCloudSyncAdapter extends AbstractThreadedSyncAdapter {\r
-\r
-       private AccountManager accountManager;\r
-       private Account account;\r
-       private ContentProviderClient contentProvider;\r
-       private Date lastUpdated;\r
-       \r
-       private DefaultHttpClient client = null;\r
-       private HttpHost host;\r
-\r
-       public AbstractOwnCloudSyncAdapter(Context context, boolean autoInitialize) {\r
-               super(context, autoInitialize);\r
-               this.setAccountManager(AccountManager.get(context));\r
-       }\r
-\r
-       public AccountManager getAccountManager() {\r
-               return accountManager;\r
-       }\r
-\r
-       public void setAccountManager(AccountManager accountManager) {\r
-               this.accountManager = accountManager;\r
-       }\r
-\r
-       public Account getAccount() {\r
-               return account;\r
-       }\r
-\r
-       public void setAccount(Account account) {\r
-               this.account = account;\r
-       }\r
-\r
-       public ContentProviderClient getContentProvider() {\r
-               return contentProvider;\r
-       }\r
-\r
-       public void setContentProvider(ContentProviderClient contentProvider) {\r
-               this.contentProvider = contentProvider;\r
-       }\r
-\r
-       public Date getLastUpdated() {\r
-               return lastUpdated;\r
-       }\r
-\r
-       public void setLastUpdated(Date lastUpdated) {\r
-               this.lastUpdated = lastUpdated;\r
-       }\r
-       \r
-       protected ConnectionKeepAliveStrategy getKeepAliveStrategy() {\r
-               return new ConnectionKeepAliveStrategy() {\r
-                       public long getKeepAliveDuration(HttpResponse response, HttpContext context) {\r
-                               // TODO: change keep alive straategy basing on response: ie forbidden/not found/etc\r
-                               // should have keep alive 0\r
-                               // default return: 5s\r
-                               return 5 * 1000;\r
-                       }\r
-               };\r
-       }\r
-       \r
-       protected HttpPropFind getPropFindQuery() throws OperationCanceledException, AuthenticatorException, IOException {\r
-               HttpPropFind query = new HttpPropFind(getUri().toString());\r
-               query.setHeader("Content-type", "text/xml");\r
-               query.setHeader("User-Agent", "Android-ownCloud");\r
-               return query;\r
-       }\r
-       \r
-       protected HttpResponse fireRawRequest(HttpRequest query) throws ClientProtocolException, OperationCanceledException, AuthenticatorException, IOException {\r
-           BasicHttpContext httpContext = new BasicHttpContext();\r
-        BasicScheme basicAuth = new BasicScheme();\r
-        httpContext.setAttribute("preemptive-auth", basicAuth);\r
-        \r
-        HttpResponse response = getClient().execute(this.host, query, httpContext);\r
-        return response;\r
-       }\r
-       \r
-       protected TreeNode fireRequest(HttpRequest query) throws ClientProtocolException, OperationCanceledException, AuthenticatorException, IOException {\r
-               HttpResponse response = fireRawRequest(query);\r
-               \r
-               TreeNode root = new TreeNode();\r
-               root.setProperty(TreeNode.NodeProperty.NAME, "/");\r
-               this.parseResponse(response, getUri(), getClient(), this.host, root.getChildList());\r
-               return root;\r
-       }\r
-       \r
-       protected Uri getUri() {\r
-               return Uri.parse(this.getAccountManager().getUserData(getAccount(), AccountAuthenticator.KEY_OC_URL));\r
-       }\r
-       \r
-       private DefaultHttpClient getClient() throws OperationCanceledException, AuthenticatorException, IOException {\r
-               if(this.client == null) {\r
-                       String username = getAccount().name.split("@")[0];\r
-                       String password = this.getAccountManager().blockingGetAuthToken(getAccount(), AccountAuthenticator.AUTH_TOKEN_TYPE, true);\r
-                       if (this.getAccountManager().getUserData(getAccount(), AccountAuthenticator.KEY_OC_URL) == null) {\r
-                               throw new UnknownHostException();\r
-                       }\r
-                       Uri uri = getUri();\r
-       \r
-                       int port = (uri.getPort() == -1) ? 80 : uri.getPort();\r
-                       this.client = new DefaultHttpClient();\r
-                       this.client.getCredentialsProvider().setCredentials(\r
-                               new AuthScope(uri.getHost(), port),\r
-                               new UsernamePasswordCredentials(username, password)\r
-                       );\r
-                       this.client.setKeepAliveStrategy(this.getKeepAliveStrategy());\r
-                       this.host = new HttpHost(uri.getHost(), port, (uri.getScheme() == "https") ? "https" : "http");\r
-               }\r
-               \r
-               return this.client;\r
-       }\r
-       \r
-       private void parseResponse(HttpResponse resp, Uri uri, DefaultHttpClient client, HttpHost targetHost, LinkedList<TreeNode> insertList) throws IOException, OperationCanceledException, AuthenticatorException {\r
-               boolean skipFirst = true;\r
-               for (TreeNode n :WebdavUtils.parseResponseToNodes(resp.getEntity().getContent())) {\r
-                       String path = n.stripPathFromFilename(uri.getPath());\r
-                       if (skipFirst) {\r
-                               skipFirst = false;\r
-                               continue;\r
-                       }\r
-                       insertList.add(n);\r
-\r
-                       if (!TextUtils.isEmpty(n.getProperty(NodeProperty.NAME)) &&\r
-                                       n.getProperty(NodeProperty.RESOURCE_TYPE).equals("DIR")) {\r
-                           \r
-                           HttpPropFind method = new HttpPropFind(uri.getPath() + path + n.getProperty(NodeProperty.NAME).replace(" ", "%20") + "/");\r
-                               HttpResponse response = fireRawRequest(method);\r
-                               parseResponse(response, uri, client, targetHost, n.getChildList());\r
-                       }\r
-               }\r
-       }\r
-       \r
+import eu.alefzero.webdav.TreeNode.NodeProperty;\r
+
+/**
+ * Base SyncAdapter for OwnCloud
+ * Designed to be subclassed for the concreete SyncAdapter, like ConcatsSync, CalendarSync, FileSync etc..
+ * 
+ * @author sassman
+ *
+ */
+public abstract class AbstractOwnCloudSyncAdapter extends AbstractThreadedSyncAdapter {
+
+       private AccountManager accountManager;
+       private Account account;
+       private ContentProviderClient contentProvider;
+       private Date lastUpdated;
+       
+       private HttpHost mHost;
+       private WebdavClient mClient = null;
+
+       public AbstractOwnCloudSyncAdapter(Context context, boolean autoInitialize) {
+               super(context, autoInitialize);
+               this.setAccountManager(AccountManager.get(context));
+       }
+
+       public AccountManager getAccountManager() {
+               return accountManager;
+       }
+
+       public void setAccountManager(AccountManager accountManager) {
+               this.accountManager = accountManager;
+       }
+
+       public Account getAccount() {
+               return account;
+       }
+
+       public void setAccount(Account account) {
+               this.account = account;
+       }
+
+       public ContentProviderClient getContentProvider() {
+               return contentProvider;
+       }
+
+       public void setContentProvider(ContentProviderClient contentProvider) {
+               this.contentProvider = contentProvider;
+       }
+
+       public Date getLastUpdated() {
+               return lastUpdated;
+       }
+
+       public void setLastUpdated(Date lastUpdated) {
+               this.lastUpdated = lastUpdated;
+       }
+       
+       protected ConnectionKeepAliveStrategy getKeepAliveStrategy() {
+               return new ConnectionKeepAliveStrategy() {
+                       public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
+                               // TODO: change keep alive straategy basing on response: ie forbidden/not found/etc
+                               // should have keep alive 0
+                               // default return: 5s
+                               return 5 * 1000;
+                       }
+               };
+       }
+       
+       protected HttpPropFind getPropFindQuery() throws OperationCanceledException, AuthenticatorException, IOException {
+               HttpPropFind query = new HttpPropFind(getUri().toString());
+               query.setHeader("Content-type", "text/xml");
+               query.setHeader("User-Agent", "Android-ownCloud");
+               return query;
+       }
+       
+       protected HttpResponse fireRawRequest(HttpRequest query) throws ClientProtocolException, OperationCanceledException, AuthenticatorException, IOException {
+           BasicHttpContext httpContext = new BasicHttpContext();
+        BasicScheme basicAuth = new BasicScheme();
+        httpContext.setAttribute("preemptive-auth", basicAuth);
+        
+        HttpResponse response = getClient().execute(mHost, query, httpContext);
+        return response;
+       }
+       
+       protected TreeNode fireRequest(HttpRequest query) throws ClientProtocolException, OperationCanceledException, AuthenticatorException, IOException {
+               HttpResponse response = fireRawRequest(query);
+               
+               TreeNode root = new TreeNode();
+               root.setProperty(TreeNode.NodeProperty.NAME, "/");
+               this.parseResponse(response, getUri(), getClient(), mHost, root.getChildList());
+               return root;
+       }
+       
+       protected Uri getUri() {
+               return Uri.parse(this.getAccountManager().getUserData(getAccount(), AccountAuthenticator.KEY_OC_URL));
+       }
+       
+       private DefaultHttpClient getClient() throws OperationCanceledException, AuthenticatorException, IOException {
+               if(mClient == null) {
+                       String username = getAccount().name.split("@")[0];
+                       String password = this.getAccountManager().blockingGetAuthToken(getAccount(), AccountAuthenticator.AUTH_TOKEN_TYPE, true);
+                       if (this.getAccountManager().getUserData(getAccount(), AccountAuthenticator.KEY_OC_URL) == null) {
+                               throw new UnknownHostException();
+                       }
+                       Uri uri = getUri();
+       
+                       mClient = new WebdavClient(uri);
+                       mClient.setCredentials(username, password);
+                       mClient.allowUnsignedCertificates();
+                       mHost = mClient.getTargetHost();
+               }
+               
+               return mClient.getHttpClient();
+       }
+       
+       private void parseResponse(HttpResponse resp, Uri uri, DefaultHttpClient client, HttpHost targetHost, LinkedList<TreeNode> insertList) throws IOException, OperationCanceledException, AuthenticatorException {
+               boolean skipFirst = true;
+               for (TreeNode n :WebdavUtils.parseResponseToNodes(resp.getEntity().getContent())) {
+                       String path = n.stripPathFromFilename(uri.getPath());
+                       if (skipFirst) {
+                               skipFirst = false;
+                               continue;
+                       }
+                       insertList.add(n);
+
+                       if (!TextUtils.isEmpty(n.getProperty(NodeProperty.NAME)) &&
+                                       n.getProperty(NodeProperty.RESOURCE_TYPE).equals("DIR")) {
+                           
+                           HttpPropFind method = new HttpPropFind(uri.getPath() + path + n.getProperty(NodeProperty.NAME).replace(" ", "%20") + "/");
+                               HttpResponse response = fireRawRequest(method);
+                               parseResponse(response, uri, client, targetHost, n.getChildList());
+                       }
+               }
+       }
 }
\ No newline at end of file
index b8f1878..2080790 100644 (file)
@@ -70,7 +70,6 @@ public class LandingActivity extends FragmentActivity implements OnClickListener
                return dialog;\r
        }\r
 \r
-       @Override\r
        public void onClick(DialogInterface dialog, int which) {\r
                // In any case - we won't need it anymore\r
                dialog.dismiss();\r
index 694225d..e31c65f 100644 (file)
@@ -53,12 +53,10 @@ public class LandingScreenAdapter extends BaseAdapter {
                mContext = context;\r
        }\r
 \r
-       @Override\r
        public int getCount() {\r
                return mLandingScreenIcons.length;\r
        }\r
 \r
-       @Override\r
        /**\r
         * Returns the Intent associated with this object\r
         * or null if the functionality is not yet implemented\r
@@ -78,12 +76,10 @@ public class LandingScreenAdapter extends BaseAdapter {
                return intent;\r
        }\r
 \r
-       @Override\r
        public long getItemId(int position) {\r
                return position;\r
        }\r
 \r
-       @Override\r
        public View getView(int position, View convertView, ViewGroup parent) {\r
                if (convertView == null) {\r
                        LayoutInflater inflator = LayoutInflater.from(mContext);\r
index dd7ca31..d431a4f 100644 (file)
@@ -17,6 +17,7 @@
  */\r
 package eu.alefzero.owncloud.ui.fragment;\r
 \r
+import android.content.Context;\r
 import android.content.Intent;\r
 import android.os.Bundle;\r
 import android.support.v4.app.Fragment;\r
@@ -24,11 +25,15 @@ import android.view.LayoutInflater;
 import android.view.View;\r
 import android.view.ViewGroup;\r
 import android.widget.AdapterView;\r
-import android.widget.AdapterView.OnItemClickListener;\r
+import android.widget.BaseAdapter;\r
 import android.widget.GridView;\r
+import android.widget.ImageView;\r
+import android.widget.TextView;\r
 import android.widget.Toast;\r
+import android.widget.AdapterView.OnItemClickListener;\r
 import eu.alefzero.owncloud.R;\r
-import eu.alefzero.owncloud.ui.adapter.LandingScreenAdapter;\r
+import eu.alefzero.owncloud.ui.activity.FileDisplayActivity;\r
+import eu.alefzero.owncloud.ui.activity.Preferences;\r
 \r
 /**\r
  * Used on the Landing page to display what Components of \r
@@ -55,7 +60,6 @@ public class LandingPageFragment extends Fragment implements OnItemClickListener
                grid.setOnItemClickListener(this);\r
        }\r
        \r
-       @Override\r
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {\r
                /*\r
                 * Start an activity based on the selection\r
@@ -64,10 +68,83 @@ public class LandingPageFragment extends Fragment implements OnItemClickListener
                Intent intent;\r
                intent = (Intent) parent.getAdapter().getItem(position);\r
                if(intent != null ){\r
-                       startActivity(intent);\r
+                       startActivity(intent);
                } else {\r
                        Toast toast = Toast.makeText(getActivity(), "Not yet implemented!", Toast.LENGTH_SHORT);\r
                        toast.show();\r
+               } \r
+       }\r
+\r
+       /**\r
+        * Used to populate the landing page grid.\r
+        * Defined this one right in here as private class\r
+        * as it is unlikely that this Adapter can be useful\r
+        * anywhere else.\r
+        *  \r
+        * @author Lennart Rosam\r
+        *\r
+        */\r
+       private class LandingScreenAdapter extends BaseAdapter {\r
+\r
+               private Context mContext;\r
+\r
+               private final Integer[] mLandingScreenIcons = { R.drawable.home,\r
+                               R.drawable.music, R.drawable.contacts,\r
+                               android.R.drawable.ic_menu_today,\r
+                               android.R.drawable.ic_menu_agenda,\r
+                               android.R.drawable.ic_menu_preferences };\r
+\r
+               private final Integer[] mLandingScreenTexts = { R.string.main_files,\r
+                               R.string.main_music, R.string.main_contacts,\r
+                               R.string.main_calendar, R.string.main_bookmarks,\r
+                               R.string.main_settings };\r
+\r
+               public LandingScreenAdapter(Context context) {\r
+                       mContext = context;\r
+               }\r
+\r
+               public int getCount() {\r
+                       return mLandingScreenIcons.length;\r
+               }\r
+\r
+               /**\r
+                * Returns the Intent associated with this object\r
+                * or null if the functionality is not yet implemented\r
+                */\r
+               public Object getItem(int position) {\r
+                       Intent intent = new Intent();\r
+                       switch (position) {\r
+                       case 0:\r
+                               intent.setClass(mContext, FileDisplayActivity.class);\r
+                               break;\r
+                       case 5:\r
+                               intent.setClass(mContext, Preferences.class);\r
+                               break;\r
+                       default:\r
+                               intent = null;\r
+                       }\r
+                       return intent;\r
+               }\r
+\r
+               public long getItemId(int position) {\r
+                       return position;\r
+               }\r
+\r
+               public View getView(int position, View convertView, ViewGroup parent) {\r
+                       if (convertView == null) {\r
+                               LayoutInflater inflator = LayoutInflater.from(mContext);\r
+                               convertView = inflator\r
+                                               .inflate(R.layout.landing_page_item, null);\r
+\r
+                               ImageView icon = (ImageView) convertView\r
+                                               .findViewById(R.id.gridImage);\r
+                               TextView iconText = (TextView) convertView\r
+                                               .findViewById(R.id.gridText);\r
+\r
+                               icon.setImageResource(mLandingScreenIcons[position]);\r
+                               iconText.setText(mLandingScreenTexts[position]);\r
+                       }\r
+                       return convertView;
                }\r
        }\r
 \r
index 4d97ceb..722614e 100644 (file)
  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
  *\r
  */\r
-package eu.alefzero.webdav;\r
-\r
-import java.io.BufferedInputStream;\r
-import java.io.BufferedOutputStream;\r
-import java.io.File;\r
-import java.io.FileOutputStream;\r
-import java.io.IOException;\r
-import java.io.InputStreamReader;\r
-import java.io.OutputStreamWriter;\r
-\r
-import org.apache.http.HttpHost;\r
-import org.apache.http.HttpResponse;\r
-import org.apache.http.HttpStatus;\r
-import org.apache.http.HttpVersion;\r
-import org.apache.http.auth.AuthScope;\r
-import org.apache.http.auth.UsernamePasswordCredentials;\r
-import org.apache.http.client.methods.HttpGet;\r
-import org.apache.http.client.methods.HttpPut;\r
-import org.apache.http.conn.ClientConnectionManager;\r
-import org.apache.http.conn.params.ConnManagerPNames;\r
-import org.apache.http.conn.params.ConnPerRouteBean;\r
-import org.apache.http.conn.scheme.PlainSocketFactory;\r
-import org.apache.http.conn.scheme.Scheme;\r
-import org.apache.http.conn.scheme.SchemeRegistry;\r
-import org.apache.http.conn.ssl.SSLSocketFactory;\r
-import org.apache.http.entity.FileEntity;\r
-import org.apache.http.entity.mime.content.FileBody;\r
-import org.apache.http.impl.auth.BasicScheme;\r
-import org.apache.http.impl.client.DefaultHttpClient;\r
-import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;\r
-import org.apache.http.params.BasicHttpParams;\r
-import org.apache.http.params.HttpParams;\r
-import org.apache.http.params.HttpProtocolParams;\r
-import org.apache.http.protocol.BasicHttpContext;\r
-\r
-import eu.alefzero.owncloud.authenticator.EasySSLSocketFactory;\r
-\r
-import android.net.Uri;\r
-import android.util.Log;\r
-\r
-/**\r
- * A basic WebDAV-Client\r
- * @author Bartek Przybylski\r
- *\r
- */\r
-public class WebdavClient {\r
-  private DefaultHttpClient mHttpClient;\r
-  private BasicHttpContext mHttpContext;\r
-  private HttpHost mTargetHost;\r
-  private SchemeRegistry mSchemeRegistry;\r
-  private Uri mUri;\r
-  final private static String TAG = "WebdavClient";\r
-  \r
-  public WebdavClient(Uri uri) {\r
-    mUri = uri;\r
-    mSchemeRegistry = new SchemeRegistry();\r
-    setupHttpClient();\r
-  }\r
-  \r
-  public void setCredentials(String username, String password) {\r
-    // determine default port for http or https\r
-    int targetPort = mTargetHost.getPort() == -1 ? \r
-                        ( mUri.getScheme().equals("https") ? 443 : 80)\r
-                        : mUri.getPort();\r
-\r
-    mHttpClient.getCredentialsProvider().setCredentials(\r
-        new AuthScope(mUri.getHost(), targetPort), \r
-        new UsernamePasswordCredentials(username, password));\r
-    BasicScheme basicAuth = new BasicScheme();\r
-    mHttpContext.setAttribute("preemptive-auth", basicAuth);\r
-  }\r
-  \r
-  public void allowUnsignedCertificates() {\r
-    // https\r
-    mSchemeRegistry.register(new Scheme("https", new EasySSLSocketFactory(), 443));\r
-  }\r
-  \r
-  public boolean downloadFile(String filepath, File targetPath) {\r
-    HttpGet get = new HttpGet(mUri.toString() + filepath.replace(" ", "%20"));\r
-    get.setHeader("Host", mUri.getHost());\r
-    get.setHeader("User-Agent", "Android-ownCloud");\r
-    \r
-    try {\r
-      HttpResponse response = mHttpClient.execute(mTargetHost, get, mHttpContext);\r
-      if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {\r
-        return false;\r
-      }\r
-      BufferedInputStream bis = new BufferedInputStream(response.getEntity().getContent());\r
-      FileOutputStream fos = new FileOutputStream(targetPath);\r
-      \r
-      byte[] bytes = new byte[512];\r
-      int readResult;\r
-      while ((readResult = bis.read(bytes)) != -1) fos.write(bytes, 0, readResult);\r
-      \r
-    } catch (IOException e) {\r
-      e.printStackTrace();\r
-      return false;\r
-    }\r
-    return true;\r
-  }\r
-  \r
-  void getFileList(String dirPath) {\r
-    \r
-  }\r
-  \r
-  public boolean putFile(String localFile,\r
-                  String remoteTarget,\r
-                  String contentType) {\r
-    boolean result = true;\r
-    HttpPut method = new HttpPut(mUri.toString() + remoteTarget.replace(" ", "%20"));\r
-    method.setHeader("Content-type", contentType);\r
-    method.setHeader("Host", mUri.getHost());\r
-    method.setHeader("User-Agent", "Android-ownCloud");\r
-\r
-    try {\r
-      FileBody fb = new FileBody(new File(localFile, contentType));\r
-      final FileEntity fileEntity = new FileEntity(new File(localFile), contentType);\r
-\r
-      method.setEntity(fileEntity);\r
-      Log.i(TAG, "executing:" + method.getRequestLine().toString());\r
-\r
-      mHttpClient.execute(mTargetHost, method, mHttpContext);\r
-      /*mHandler.post(new Runnable() {\r
-      public void run() {\r
-        Uploader.this.PartialupdateUpload(c.getString(c.getColumnIndex(Media.DATA)),\r
-                                                  c.getString(c.getColumnIndex(Media.DISPLAY_NAME)),\r
-                                                  mUploadPath + (mUploadPath.equals("/")?"":"/"),\r
-                                                  fileEntity.getContentType().getValue(),\r
-                                                  fileEntity.getContentLength()+"");\r
-      }\r
-    });\r
-    Log.i(TAG, "Uploading, done");\r
-*/\r
-      Log.i(TAG, "Uploading, done");\r
-    } catch (final Exception e) {\r
-      Log.i(TAG, ""+e.getMessage());\r
-      result = false;\r
-    }\r
-    \r
-    return result;\r
-  }\r
-  \r
-  public boolean createDirectory(String path) {\r
-    HttpMkCol method = new HttpMkCol(mUri.toString() + path + "/");\r
-    method.setHeader("User-Agent", "Android-ownCloud");\r
-    \r
-    try {\r
-      mHttpClient.execute(mTargetHost, method, mHttpContext);\r
-      Log.i(TAG, "Creating dir completed");\r
-    } catch (final Exception e) {\r
-      e.printStackTrace();\r
-      return false;\r
-    }\r
-    return true;\r
-  }\r
-  \r
-  private void setupHttpClient() {\r
-    // http scheme\r
-    mSchemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));\r
-    mSchemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));\r
-    \r
-    HttpParams params = new BasicHttpParams();\r
-    params.setParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 30);\r
-    params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(30));\r
-    params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false);\r
-    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);\r
-\r
-    mHttpContext = new BasicHttpContext();\r
-    ClientConnectionManager cm = new ThreadSafeClientConnManager(params, mSchemeRegistry);\r
-\r
-    int port = mUri.getPort() == -1 ? \r
-                 mUri.getScheme().equals("https") ? 443 : 80\r
-               : mUri.getPort();\r
-    \r
-    mTargetHost = new HttpHost(mUri.getHost(), port, mUri.getScheme());\r
-    \r
-    mHttpClient = new DefaultHttpClient(cm, params);\r
-  }\r
-}\r
+package eu.alefzero.webdav;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+
+import org.apache.http.HttpHost;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.HttpVersion;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.params.ConnManagerPNames;
+import org.apache.http.conn.params.ConnPerRouteBean;
+import org.apache.http.conn.scheme.PlainSocketFactory;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeRegistry;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.entity.FileEntity;
+import org.apache.http.entity.mime.content.FileBody;
+import org.apache.http.impl.auth.BasicScheme;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.HttpParams;
+import org.apache.http.params.HttpProtocolParams;
+import org.apache.http.protocol.BasicHttpContext;
+
+import eu.alefzero.owncloud.authenticator.EasySSLSocketFactory;
+import eu.alefzero.webdav.HttpMkCol;
+
+import android.net.Uri;
+import android.util.Log;
+
+public class WebdavClient {
+  private DefaultHttpClient mHttpClient;
+  private BasicHttpContext mHttpContext;
+  private HttpHost mTargetHost;
+  private SchemeRegistry mSchemeRegistry;
+  private Uri mUri;
+  final private static String TAG = "WebdavClient";
+  
+  public DefaultHttpClient getHttpClient() {
+    return mHttpClient;
+  }
+  public HttpHost getTargetHost() {
+    return mTargetHost;
+  }
+  
+  public WebdavClient(Uri uri) {
+    mUri = uri;
+    mSchemeRegistry = new SchemeRegistry();
+    setupHttpClient();
+  }
+  
+  public void setCredentials(String username, String password) {
+    // determine default port for http or https
+    int targetPort = mTargetHost.getPort() == -1 ? 
+                        ( mUri.getScheme().equals("https") ? 443 : 80)
+                        : mUri.getPort();
+
+    mHttpClient.getCredentialsProvider().setCredentials(
+        new AuthScope(mUri.getHost(), targetPort), 
+        new UsernamePasswordCredentials(username, password));
+    BasicScheme basicAuth = new BasicScheme();
+    mHttpContext.setAttribute("preemptive-auth", basicAuth);
+  }
+  
+  public void allowUnsignedCertificates() {
+    // https
+    mSchemeRegistry.register(new Scheme("https", new EasySSLSocketFactory(), 443));
+  }
+  
+  public boolean downloadFile(String filepath, File targetPath) {
+    HttpGet get = new HttpGet(mUri.toString() + filepath.replace(" ", "%20"));
+    get.setHeader("Host", mUri.getHost());
+    get.setHeader("User-Agent", "Android-ownCloud");
+    
+    try {
+      HttpResponse response = mHttpClient.execute(mTargetHost, get, mHttpContext);
+      if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
+        return false;
+      }
+      BufferedInputStream bis = new BufferedInputStream(response.getEntity().getContent());
+      FileOutputStream fos = new FileOutputStream(targetPath);
+      
+      byte[] bytes = new byte[512];
+      int readResult;
+      while ((readResult = bis.read(bytes)) != -1) fos.write(bytes, 0, readResult);
+      
+    } catch (IOException e) {
+      e.printStackTrace();
+      return false;
+    }
+    return true;
+  }
+  
+  public boolean putFile(String localFile,
+                  String remoteTarget,
+                  String contentType) {
+    boolean result = true;
+    HttpPut method = new HttpPut(mUri.toString() + remoteTarget.replace(" ", "%20"));
+    method.setHeader("Content-type", contentType);
+    method.setHeader("Host", mUri.getHost());
+    method.setHeader("User-Agent", "Android-ownCloud");
+
+    try {
+      FileBody fb = new FileBody(new File(localFile, contentType));
+      final FileEntity fileEntity = new FileEntity(new File(localFile), contentType);
+
+      method.setEntity(fileEntity);
+      Log.i(TAG, "executing:" + method.getRequestLine().toString());
+
+      mHttpClient.execute(mTargetHost, method, mHttpContext);
+      /*mHandler.post(new Runnable() {
+      public void run() {
+        Uploader.this.PartialupdateUpload(c.getString(c.getColumnIndex(Media.DATA)),
+                                                  c.getString(c.getColumnIndex(Media.DISPLAY_NAME)),
+                                                  mUploadPath + (mUploadPath.equals("/")?"":"/"),
+                                                  fileEntity.getContentType().getValue(),
+                                                  fileEntity.getContentLength()+"");
+      }
+    });
+    Log.i(TAG, "Uploading, done");
+*/
+      Log.i(TAG, "Uploading, done");
+    } catch (final Exception e) {
+      Log.i(TAG, ""+e.getMessage());
+      result = false;
+    }
+    
+    return result;
+  }
+  
+  public boolean createDirectory(String path) {
+    HttpMkCol method = new HttpMkCol(mUri.toString() + path + "/");
+    method.setHeader("User-Agent", "Android-ownCloud");
+    
+    try {
+      mHttpClient.execute(mTargetHost, method, mHttpContext);
+      Log.i(TAG, "Creating dir completed");
+    } catch (final Exception e) {
+      e.printStackTrace();
+      return false;
+    }
+    return true;
+  }
+  
+  private void setupHttpClient() {
+    // http scheme
+    mSchemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
+    mSchemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
+    
+    HttpParams params = new BasicHttpParams();
+    params.setParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 30);
+    params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(30));
+    params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false);
+    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
+
+    mHttpContext = new BasicHttpContext();
+    ClientConnectionManager cm = new ThreadSafeClientConnManager(params, mSchemeRegistry);
+
+    int port = mUri.getPort() == -1 ? 
+                 mUri.getScheme().equals("https") ? 443 : 80
+               : mUri.getPort();
+    
+    mTargetHost = new HttpHost(mUri.getHost(), port, mUri.getScheme());
+    
+    mHttpClient = new DefaultHttpClient(cm, params);
+  }
+}