allow chunked uploads, closes https://github.com/PhilippC/keepass2android/issues/2777
This commit is contained in:
		| @@ -140,6 +140,10 @@ namespace keepass2android | |||||||
|  |  | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|  |         int WebDavChunkedUploadSize | ||||||
|  |         { | ||||||
|  |             get; | ||||||
|  |         } | ||||||
| 	     | 	     | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -15,7 +15,9 @@ namespace keepass2android.Io | |||||||
| 	    { | 	    { | ||||||
| 	        get { return false; } | 	        get { return false; } | ||||||
| 	    } | 	    } | ||||||
| 	} |  | ||||||
|  |         static public bool IsConfigured => !string.IsNullOrEmpty(AppKey) && !string.IsNullOrEmpty(AppSecret); | ||||||
|  |     } | ||||||
|  |  | ||||||
| 	public partial class DropboxAppFolderFileStorage: JavaFileStorage | 	public partial class DropboxAppFolderFileStorage: JavaFileStorage | ||||||
| 	{ | 	{ | ||||||
| @@ -29,6 +31,7 @@ namespace keepass2android.Io | |||||||
| 	        get { return false; } | 	        get { return false; } | ||||||
| 	    } | 	    } | ||||||
|  |  | ||||||
|  |         static public bool IsConfigured => !string.IsNullOrEmpty(AppKey) && !string.IsNullOrEmpty(AppSecret); | ||||||
|     } |     } | ||||||
| 	 | 	 | ||||||
| } | } | ||||||
|   | |||||||
| @@ -123,7 +123,7 @@ namespace keepass2android.Io | |||||||
|  |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		public IWriteTransaction OpenWriteTransaction(IOConnectionInfo ioc, bool useFileTransaction) | 		public virtual IWriteTransaction OpenWriteTransaction(IOConnectionInfo ioc, bool useFileTransaction) | ||||||
| 		{ | 		{ | ||||||
| 			return new JavaFileStorageWriteTransaction(IocToPath(ioc), useFileTransaction, this); | 			return new JavaFileStorageWriteTransaction(IocToPath(ioc), useFileTransaction, this); | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -6,10 +6,12 @@ using System.Text; | |||||||
| using Android.App; | using Android.App; | ||||||
| using Android.Content; | using Android.Content; | ||||||
| using Android.OS; | using Android.OS; | ||||||
|  | using Android.Preferences; | ||||||
| using Android.Runtime; | using Android.Runtime; | ||||||
| using Android.Views; | using Android.Views; | ||||||
| using Android.Widget; | using Android.Widget; | ||||||
| #if !NoNet && !EXCLUDE_JAVAFILESTORAGE | #if !NoNet && !EXCLUDE_JAVAFILESTORAGE | ||||||
|  |  | ||||||
| using Keepass2android.Javafilestorage; | using Keepass2android.Javafilestorage; | ||||||
| #endif | #endif | ||||||
| using KeePassLib.Serialization; | using KeePassLib.Serialization; | ||||||
| @@ -19,9 +21,15 @@ namespace keepass2android.Io | |||||||
| #if !NoNet && !EXCLUDE_JAVAFILESTORAGE | #if !NoNet && !EXCLUDE_JAVAFILESTORAGE | ||||||
| 	public class WebDavFileStorage: JavaFileStorage | 	public class WebDavFileStorage: JavaFileStorage | ||||||
| 	{ | 	{ | ||||||
| 		public WebDavFileStorage(IKp2aApp app) : base(new Keepass2android.Javafilestorage.WebDavStorage(app.CertificateErrorHandler), app) |         private readonly IKp2aApp _app; | ||||||
| 		{ |         private readonly WebDavStorage baseWebdavStorage; | ||||||
| 		} |  | ||||||
|  |         public WebDavFileStorage(IKp2aApp app, int chunkSize) : base(new Keepass2android.Javafilestorage.WebDavStorage(app.CertificateErrorHandler, chunkSize), app) | ||||||
|  |         { | ||||||
|  |             _app = app; | ||||||
|  |             baseWebdavStorage = (WebDavStorage)Jfs; | ||||||
|  |  | ||||||
|  |         } | ||||||
|  |  | ||||||
| 		public override IEnumerable<string> SupportedProtocols | 		public override IEnumerable<string> SupportedProtocols | ||||||
| 		{ | 		{ | ||||||
| @@ -75,6 +83,15 @@ namespace keepass2android.Io | |||||||
| 			} | 			} | ||||||
| 			return base.IocToPath(ioc); | 			return base.IocToPath(ioc); | ||||||
| 		} | 		} | ||||||
| 	} |  | ||||||
|  |  | ||||||
|  |         public override IWriteTransaction OpenWriteTransaction(IOConnectionInfo ioc, bool useFileTransaction) | ||||||
|  |         { | ||||||
|  |             baseWebdavStorage.SetUploadChunkSize(_app.WebDavChunkedUploadSize); | ||||||
|  |             return base.OpenWriteTransaction(ioc, useFileTransaction); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| @@ -15,7 +15,10 @@ import com.burgstaller.okhttp.basic.BasicAuthenticator; | |||||||
| import com.burgstaller.okhttp.digest.CachingAuthenticator; | import com.burgstaller.okhttp.digest.CachingAuthenticator; | ||||||
| import com.burgstaller.okhttp.digest.DigestAuthenticator; | import com.burgstaller.okhttp.digest.DigestAuthenticator; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | import java.io.ByteArrayInputStream; | ||||||
| import java.io.FileNotFoundException; | import java.io.FileNotFoundException; | ||||||
|  | import java.io.IOException; | ||||||
| import java.io.InputStream; | import java.io.InputStream; | ||||||
| import java.io.StringReader; | import java.io.StringReader; | ||||||
| import java.io.UnsupportedEncodingException; | import java.io.UnsupportedEncodingException; | ||||||
| @@ -44,23 +47,33 @@ import keepass2android.javafilestorage.webdav.DecoratedTrustManager; | |||||||
| import keepass2android.javafilestorage.webdav.PropfindXmlParser; | import keepass2android.javafilestorage.webdav.PropfindXmlParser; | ||||||
| import keepass2android.javafilestorage.webdav.WebDavUtil; | import keepass2android.javafilestorage.webdav.WebDavUtil; | ||||||
| import okhttp3.MediaType; | import okhttp3.MediaType; | ||||||
|  | import okhttp3.MultipartBody; | ||||||
| import okhttp3.OkHttpClient; | import okhttp3.OkHttpClient; | ||||||
| import okhttp3.Request; | import okhttp3.Request; | ||||||
| import okhttp3.RequestBody; | import okhttp3.RequestBody; | ||||||
| import okhttp3.Response; | import okhttp3.Response; | ||||||
| import okhttp3.internal.tls.OkHostnameVerifier; | import okhttp3.internal.tls.OkHostnameVerifier; | ||||||
|  | import okio.BufferedSink; | ||||||
|  |  | ||||||
| public class WebDavStorage extends JavaFileStorageBase { | public class WebDavStorage extends JavaFileStorageBase { | ||||||
|  |  | ||||||
|     private final ICertificateErrorHandler mCertificateErrorHandler; |     private final ICertificateErrorHandler mCertificateErrorHandler; | ||||||
|     private Context appContext; |     private Context appContext; | ||||||
|  |  | ||||||
|     public WebDavStorage(ICertificateErrorHandler certificateErrorHandler) |     int chunkSize; | ||||||
|  |  | ||||||
|  |     public WebDavStorage(ICertificateErrorHandler certificateErrorHandler, int chunkSize) | ||||||
|     { |     { | ||||||
|  |         this.chunkSize = chunkSize; | ||||||
|  |  | ||||||
|         mCertificateErrorHandler = certificateErrorHandler; |         mCertificateErrorHandler = certificateErrorHandler; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public void setUploadChunkSize(int chunkSize) | ||||||
|  |     { | ||||||
|  |         this.chunkSize = chunkSize; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public String buildFullPath(String url, String username, String password) throws UnsupportedEncodingException { |     public String buildFullPath(String url, String username, String password) throws UnsupportedEncodingException { | ||||||
|         String scheme = url.substring(0, url.indexOf("://")); |         String scheme = url.substring(0, url.indexOf("://")); | ||||||
|         url = url.substring(scheme.length() + 3); |         url = url.substring(scheme.length() + 3); | ||||||
| @@ -189,11 +202,49 @@ public class WebDavStorage extends JavaFileStorageBase { | |||||||
|         try { |         try { | ||||||
|             ConnectionInfo ci = splitStringToConnectionInfo(path); |             ConnectionInfo ci = splitStringToConnectionInfo(path); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |             RequestBody requestBody; | ||||||
|  |             if (chunkSize > 0) | ||||||
|  |             { | ||||||
|  |                 // use chunked upload | ||||||
|  |                 requestBody = new RequestBody() { | ||||||
|  |                     @Override | ||||||
|  |                     public MediaType contentType() { | ||||||
|  |                         return MediaType.parse("application/binary"); | ||||||
|  |                     } | ||||||
|  |  | ||||||
|  |                     @Override | ||||||
|  |                     public void writeTo(BufferedSink sink) throws IOException { | ||||||
|  |                         try (InputStream in = new ByteArrayInputStream(data)) { | ||||||
|  |                             byte[] buffer = new byte[chunkSize]; | ||||||
|  |                             int read; | ||||||
|  |                             while ((read = in.read(buffer)) != -1) { | ||||||
|  |                                 sink.write(buffer, 0, read); | ||||||
|  |                                 sink.flush(); | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |  | ||||||
|  |                     @Override | ||||||
|  |                     public long contentLength() { | ||||||
|  |                         return -1; // use chunked upload | ||||||
|  |                     } | ||||||
|  |                 }; | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 requestBody = new MultipartBody.Builder() | ||||||
|  |                     .addPart(RequestBody.create(data, MediaType.parse("application/binary"))) | ||||||
|  |                     .build(); | ||||||
|  |             }             | ||||||
|  |  | ||||||
|  |  | ||||||
|             Request request = new Request.Builder() |             Request request = new Request.Builder() | ||||||
|                     .url(new URL(ci.URL)) |                     .url(new URL(ci.URL)) | ||||||
|                     .put(RequestBody.create(MediaType.parse("application/binary"), data)) |                     .put(requestBody) | ||||||
|                     .build(); |                     .build(); | ||||||
|  |  | ||||||
|  |  | ||||||
|             //TODO consider writeTransactional |             //TODO consider writeTransactional | ||||||
|             //TODO check for error |             //TODO check for error | ||||||
|  |  | ||||||
| @@ -522,3 +573,4 @@ public class WebDavStorage extends JavaFileStorageBase { | |||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -9,7 +9,9 @@ using System.Text; | |||||||
|  |  | ||||||
| using Android.App; | using Android.App; | ||||||
| using Android.Content; | using Android.Content; | ||||||
|  | using Android.Content.Res; | ||||||
| using Android.OS; | using Android.OS; | ||||||
|  | using Android.Preferences; | ||||||
| using Android.Runtime; | using Android.Runtime; | ||||||
| using Android.Views; | using Android.Views; | ||||||
| using Android.Widget; | using Android.Widget; | ||||||
| @@ -319,7 +321,7 @@ namespace keepass2android | |||||||
| 			View dlgContents = activity.LayoutInflater.Inflate(Resource.Layout.httpcredentials, null); | 			View dlgContents = activity.LayoutInflater.Inflate(Resource.Layout.httpcredentials, null); | ||||||
| 		    if (!defaultPath.EndsWith(_schemeSeparator)) | 		    if (!defaultPath.EndsWith(_schemeSeparator)) | ||||||
| 		    { | 		    { | ||||||
| 		        var webdavStorage = new Keepass2android.Javafilestorage.WebDavStorage(App.Kp2a.CertificateErrorHandler); | 		        var webdavStorage = CreateWebdavStorage(activity); | ||||||
| 		        var connInfo = webdavStorage.SplitStringToConnectionInfo(defaultPath); | 		        var connInfo = webdavStorage.SplitStringToConnectionInfo(defaultPath); | ||||||
| 		        dlgContents.FindViewById<EditText>(Resource.Id.http_url).Text = connInfo.Url; | 		        dlgContents.FindViewById<EditText>(Resource.Id.http_url).Text = connInfo.Url; | ||||||
| 		        dlgContents.FindViewById<EditText>(Resource.Id.http_user).Text = connInfo.Username; | 		        dlgContents.FindViewById<EditText>(Resource.Id.http_user).Text = connInfo.Username; | ||||||
| @@ -339,7 +341,7 @@ namespace keepass2android | |||||||
| 										  string scheme = defaultPath.Substring(0, defaultPath.IndexOf(_schemeSeparator, StringComparison.Ordinal)); | 										  string scheme = defaultPath.Substring(0, defaultPath.IndexOf(_schemeSeparator, StringComparison.Ordinal)); | ||||||
| 										  if (host.Contains(_schemeSeparator) == false) | 										  if (host.Contains(_schemeSeparator) == false) | ||||||
| 											  host = scheme + _schemeSeparator + host; | 											  host = scheme + _schemeSeparator + host; | ||||||
| 										  string httpPath = new Keepass2android.Javafilestorage.WebDavStorage(null).BuildFullPath(host, user, | 										  string httpPath = CreateWebdavStorage(activity).BuildFullPath(host, user, | ||||||
| 																										  password); | 																										  password); | ||||||
| 										  onStartBrowse(httpPath); | 										  onStartBrowse(httpPath); | ||||||
| 									  }); | 									  }); | ||||||
| @@ -353,7 +355,12 @@ namespace keepass2android | |||||||
| #endif | #endif | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		private void ShowFtpDialog(Activity activity, Util.FileSelectedHandler onStartBrowse, Action onCancel, string defaultPath) |         private static WebDavStorage CreateWebdavStorage(Activity activity) | ||||||
|  |         { | ||||||
|  |             return new WebDavStorage(App.Kp2a.CertificateErrorHandler, App.Kp2a.WebDavChunkedUploadSize); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private void ShowFtpDialog(Activity activity, Util.FileSelectedHandler onStartBrowse, Action onCancel, string defaultPath) | ||||||
| 		{ | 		{ | ||||||
| #if !NoNet | #if !NoNet | ||||||
| 			MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(activity); | 			MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(activity); | ||||||
| @@ -518,7 +525,7 @@ namespace keepass2android | |||||||
| 										  string scheme = defaultPath.Substring(0,defaultPath.IndexOf(_schemeSeparator, StringComparison.Ordinal)); | 										  string scheme = defaultPath.Substring(0,defaultPath.IndexOf(_schemeSeparator, StringComparison.Ordinal)); | ||||||
| 										  if (host.Contains(_schemeSeparator) == false) | 										  if (host.Contains(_schemeSeparator) == false) | ||||||
| 											  host = scheme + _schemeSeparator + host; | 											  host = scheme + _schemeSeparator + host; | ||||||
| 										  string httpPath = new Keepass2android.Javafilestorage.WebDavStorage(null).BuildFullPath(WebDavFileStorage.Owncloud2Webdav(host, subtype == "owncloud" ? WebDavFileStorage.owncloudPrefix : WebDavFileStorage.nextcloudPrefix), user, | 										  string httpPath = CreateWebdavStorage(activity).BuildFullPath(WebDavFileStorage.Owncloud2Webdav(host, subtype == "owncloud" ? WebDavFileStorage.owncloudPrefix : WebDavFileStorage.nextcloudPrefix), user, | ||||||
| 																										  password); | 																										  password); | ||||||
| 										  onStartBrowse(httpPath); | 										  onStartBrowse(httpPath); | ||||||
| 									  }); | 									  }); | ||||||
|   | |||||||
| @@ -209,6 +209,7 @@ | |||||||
|  |  | ||||||
| 	<string name="ShowUnlockedNotification_key">ShowUnlockedNotification</string> | 	<string name="ShowUnlockedNotification_key">ShowUnlockedNotification</string> | ||||||
| 	<bool name="ShowUnlockedNotification_default">true</bool> | 	<bool name="ShowUnlockedNotification_default">true</bool> | ||||||
|  | 	<integer name="WebDavChunkedUploadSize_default">65536</integer> | ||||||
|  |  | ||||||
| 	<string name="PreloadDatabaseEnabled_key">PreloadDatabaseEnabled</string> | 	<string name="PreloadDatabaseEnabled_key">PreloadDatabaseEnabled</string> | ||||||
| 	<bool name="PreloadDatabaseEnabled_default">true</bool> | 	<bool name="PreloadDatabaseEnabled_default">true</bool> | ||||||
|   | |||||||
| @@ -729,6 +729,9 @@ | |||||||
|   <string name="EntryChannel_desc">Notification to simplify access to the currently selected entry.</string> |   <string name="EntryChannel_desc">Notification to simplify access to the currently selected entry.</string> | ||||||
|   <string name="CloseDbAfterFailedAttempts">Close database after three failed biometric unlock attempts.</string> |   <string name="CloseDbAfterFailedAttempts">Close database after three failed biometric unlock attempts.</string> | ||||||
|   <string name="WarnFingerprintInvalidated">Warning! Biometric authentication can be invalidated by Android, e.g. after adding a new fingerprint in your device settings. Make sure you always know how to unlock with your master password!</string> |   <string name="WarnFingerprintInvalidated">Warning! Biometric authentication can be invalidated by Android, e.g. after adding a new fingerprint in your device settings. Make sure you always know how to unlock with your master password!</string> | ||||||
|  |   <string name="webdav_chunked_upload_size_title">Chunk size for WebDav upload</string> | ||||||
|  |   <string name="webdav_chunked_upload_size_summary">Size of chunks when uploading to WebDav servers in bytes. Use 0 to disable chunked upload.</string> | ||||||
|  |  | ||||||
|  |  | ||||||
|   <string-array name="ChangeLog_1_13"> |   <string-array name="ChangeLog_1_13"> | ||||||
|     <item>Improved password quality estimation by considering most popular passwords.</item> |     <item>Improved password quality estimation by considering most popular passwords.</item> | ||||||
|   | |||||||
| @@ -45,6 +45,14 @@ | |||||||
| 		android:title="@string/UseFileTransactions_title" | 		android:title="@string/UseFileTransactions_title" | ||||||
| 		android:key="@string/UseFileTransactions_key" /> | 		android:key="@string/UseFileTransactions_key" /> | ||||||
|  |  | ||||||
|  |   <EditTextPreference | ||||||
|  |     android:key="WebDavChunkedUploadSize_str" | ||||||
|  |     android:title="@string/webdav_chunked_upload_size_title" | ||||||
|  |     android:summary="@string/webdav_chunked_upload_size_title" | ||||||
|  | 		android:defaultValue="@integer/WebDavChunkedUploadSize_default" | ||||||
|  |     android:inputType="number" | ||||||
|  |      /> | ||||||
|  |  | ||||||
| 	<CheckBoxPreference | 	<CheckBoxPreference | ||||||
| 		android:enabled="true" | 		android:enabled="true" | ||||||
| 		android:persistent="true" | 		android:persistent="true" | ||||||
| @@ -80,5 +88,6 @@ | |||||||
| 		android:defaultValue="true" | 		android:defaultValue="true" | ||||||
| 		android:title="@string/CheckForDuplicateUuids_title" | 		android:title="@string/CheckForDuplicateUuids_title" | ||||||
| 		android:key="@string/CheckForDuplicateUuids_key" /> | 		android:key="@string/CheckForDuplicateUuids_key" /> | ||||||
|  | 		 | ||||||
|  |  | ||||||
| </PreferenceScreen> | </PreferenceScreen> | ||||||
| @@ -836,8 +836,8 @@ namespace keepass2android | |||||||
| 							new AndroidContentStorage(LocaleManager.LocalizedAppContext), | 							new AndroidContentStorage(LocaleManager.LocalizedAppContext), | ||||||
| #if !EXCLUDE_JAVAFILESTORAGE | #if !EXCLUDE_JAVAFILESTORAGE | ||||||
| #if !NoNet | #if !NoNet | ||||||
| 							new DropboxFileStorage(LocaleManager.LocalizedAppContext, this), | 							DropboxFileStorage.IsConfigured ? new DropboxFileStorage(LocaleManager.LocalizedAppContext, this) : null, | ||||||
| 							new DropboxAppFolderFileStorage(LocaleManager.LocalizedAppContext, this), | 							DropboxAppFolderFileStorage.IsConfigured ? new DropboxAppFolderFileStorage(LocaleManager.LocalizedAppContext, this): null, | ||||||
|                             GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(LocaleManager.LocalizedAppContext)==ConnectionResult.Success ? new GoogleDriveFileStorage(LocaleManager.LocalizedAppContext, this) : null, |                             GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(LocaleManager.LocalizedAppContext)==ConnectionResult.Success ? new GoogleDriveFileStorage(LocaleManager.LocalizedAppContext, this) : null, | ||||||
|                             GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(LocaleManager.LocalizedAppContext)==ConnectionResult.Success ? new GoogleDriveAppDataFileStorage(LocaleManager.LocalizedAppContext, this) : null, |                             GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(LocaleManager.LocalizedAppContext)==ConnectionResult.Success ? new GoogleDriveAppDataFileStorage(LocaleManager.LocalizedAppContext, this) : null, | ||||||
| 							new OneDriveFileStorage(this), | 							new OneDriveFileStorage(this), | ||||||
| @@ -846,8 +846,8 @@ namespace keepass2android | |||||||
| 						    new OneDrive2AppFolderFileStorage(), | 						    new OneDrive2AppFolderFileStorage(), | ||||||
|                             new SftpFileStorage(LocaleManager.LocalizedAppContext, this, IsFtpDebugEnabled()), |                             new SftpFileStorage(LocaleManager.LocalizedAppContext, this, IsFtpDebugEnabled()), | ||||||
| 							new NetFtpFileStorage(LocaleManager.LocalizedAppContext, this, IsFtpDebugEnabled), | 							new NetFtpFileStorage(LocaleManager.LocalizedAppContext, this, IsFtpDebugEnabled), | ||||||
| 							new WebDavFileStorage(this), |                             new WebDavFileStorage(this, WebDavChunkedUploadSize), | ||||||
| 							new PCloudFileStorage(LocaleManager.LocalizedAppContext, this), |                             new PCloudFileStorage(LocaleManager.LocalizedAppContext, this), | ||||||
|                             new PCloudFileStorageAll(LocaleManager.LocalizedAppContext, this), |                             new PCloudFileStorageAll(LocaleManager.LocalizedAppContext, this), | ||||||
|                             new MegaFileStorage(App.Context), |                             new MegaFileStorage(App.Context), | ||||||
| 							//new LegacyWebDavStorage(this), | 							//new LegacyWebDavStorage(this), | ||||||
| @@ -1333,6 +1333,18 @@ namespace keepass2android | |||||||
|             } |             } | ||||||
|              |              | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         public int WebDavChunkedUploadSize | ||||||
|  |         { | ||||||
|  |             get | ||||||
|  |             { | ||||||
|  |                 return int.Parse(PreferenceManager.GetDefaultSharedPreferences(LocaleManager.LocalizedAppContext) | ||||||
|  |                     .GetString("WebDavChunkedUploadSize_str", | ||||||
|  |                         LocaleManager.LocalizedAppContext.Resources | ||||||
|  |                             .GetInteger(Resource.Integer.WebDavChunkedUploadSize_default).ToString())); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -1458,8 +1470,7 @@ namespace keepass2android | |||||||
| 		{ | 		{ | ||||||
| 			Kp2aLog.LogUnexpectedError(e.Exception); | 			Kp2aLog.LogUnexpectedError(e.Exception); | ||||||
| 		} | 		} | ||||||
|  |     } | ||||||
| 	} |  | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Philipp Crocoll
					Philipp Crocoll