1
0
mirror of https://github.com/owncloud/android-library.git synced 2025-06-07 16:06:08 +00:00

prepare code for the inclusion of connection validator

This commit is contained in:
Christian Schabesberger 2021-09-06 12:09:21 +02:00
parent 0e82f983b5
commit 7e4b43e7cb
4 changed files with 67 additions and 67 deletions

View File

@ -1,12 +1,12 @@
package com.owncloud.android.lib.common package com.owncloud.android.lib.common
import com.owncloud.android.lib.common.http.methods.HttpBaseMethod
import com.owncloud.android.lib.common.http.methods.nonwebdav.HttpMethod
import timber.log.Timber import timber.log.Timber
class ConnectionValidator ( class ConnectionValidator {
private val ocClient: OwnCloudClient
) {
fun dosomething() { fun validate(method: HttpBaseMethod, client: OwnCloudClient) {
Timber.d(ocClient.toString()) Timber.d("hello world")
} }
} }

View File

@ -28,7 +28,6 @@ package com.owncloud.android.lib.common;
import android.accounts.AccountManager; import android.accounts.AccountManager;
import android.accounts.AccountsException; import android.accounts.AccountsException;
import android.net.Uri; import android.net.Uri;
import android.util.Log;
import at.bitfire.dav4jvm.exception.HttpException; import at.bitfire.dav4jvm.exception.HttpException;
import com.owncloud.android.lib.common.accounts.AccountUtils; import com.owncloud.android.lib.common.accounts.AccountUtils;
@ -38,7 +37,6 @@ import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory
import com.owncloud.android.lib.common.http.HttpClient; import com.owncloud.android.lib.common.http.HttpClient;
import com.owncloud.android.lib.common.http.HttpConstants; import com.owncloud.android.lib.common.http.HttpConstants;
import com.owncloud.android.lib.common.http.methods.HttpBaseMethod; import com.owncloud.android.lib.common.http.methods.HttpBaseMethod;
import com.owncloud.android.lib.common.http.methods.nonwebdav.HttpMethod;
import com.owncloud.android.lib.common.network.RedirectionPath; import com.owncloud.android.lib.common.network.RedirectionPath;
import com.owncloud.android.lib.common.utils.RandomUtils; import com.owncloud.android.lib.common.utils.RandomUtils;
import com.owncloud.android.lib.resources.status.OwnCloudVersion; import com.owncloud.android.lib.resources.status.OwnCloudVersion;
@ -70,26 +68,32 @@ public class OwnCloudClient extends HttpClient {
private Uri mBaseUri; private Uri mBaseUri;
private OwnCloudVersion mVersion = null; private OwnCloudVersion mVersion = null;
private OwnCloudAccount mAccount; private OwnCloudAccount mAccount;
private ConnectionValidator mConnectionValidator; private final ConnectionValidator mConnectionValidator;
private Object mRequestMutex = new Object();
private static Boolean mHoldRequests = false; // If set to true a mutex will be used to prevent parallel execution of the execute() method
// if false the execute() method can be called even though the mutex is already aquired.
// This is used for the ConnectionValidator, which has to be able to execute OperationsWhile all "normal" operations net
// to be set on hold.
private final Boolean mSynchronizeRequests;
private SingleSessionManager mSingleSessionManager = null; private SingleSessionManager mSingleSessionManager = null;
private boolean mFollowRedirects; private boolean mFollowRedirects;
public OwnCloudClient(Uri baseUri) { public OwnCloudClient(Uri baseUri, ConnectionValidator connectionValidator, boolean synchronizeRequests) {
if (baseUri == null) { if (baseUri == null) {
throw new IllegalArgumentException("Parameter 'baseUri' cannot be NULL"); throw new IllegalArgumentException("Parameter 'baseUri' cannot be NULL");
} }
mBaseUri = baseUri; mBaseUri = baseUri;
mSynchronizeRequests = synchronizeRequests;
mInstanceNumber = sIntanceCounter++; mInstanceNumber = sIntanceCounter++;
Timber.d("#" + mInstanceNumber + "Creating OwnCloudClient"); Timber.d("#" + mInstanceNumber + "Creating OwnCloudClient");
clearCredentials(); clearCredentials();
clearCookies(); clearCookies();
mConnectionValidator = new ConnectionValidator(this); mConnectionValidator = connectionValidator;
} }
public void clearCredentials() { public void clearCredentials() {
@ -99,10 +103,21 @@ public class OwnCloudClient extends HttpClient {
} }
public int executeHttpMethod(HttpBaseMethod method) throws Exception { public int executeHttpMethod(HttpBaseMethod method) throws Exception {
if(mSynchronizeRequests) {
synchronized (mRequestMutex) {
return saveExecuteHttpMethod(method);
}
} else {
return saveExecuteHttpMethod(method);
}
}
private int saveExecuteHttpMethod(HttpBaseMethod method) throws Exception {
boolean repeatWithFreshCredentials; boolean repeatWithFreshCredentials;
int repeatCounter = 0; int repeatCounter = 0;
int status; int status;
boolean retry = false;
do { do {
String requestId = RandomUtils.generateRandomUUID(); String requestId = RandomUtils.generateRandomUUID();
@ -117,44 +132,14 @@ public class OwnCloudClient extends HttpClient {
status = method.execute(); status = method.execute();
stacklog(status, method); stacklog(status, method);
/*
synchronized (mHoldRequests) {
while (mHoldRequests) {
while (true) {
try {
throw new Exception("Stack log");
} catch (Exception e) {
Timber.d( "HATL BEFORE" +
"\nThread: " + Thread.currentThread().getName() +
"\nobject: " + this.toString() +
"\nMethod: " + method.getHttpUrl() +
"\ntrace: " + ExceptionUtils.getStackTrace(e));
}
Thread.sleep(40000);
}
}
status = method.execute();
if (status == 302) {
mHoldRequests = true;
while (mHoldRequests) {
try {
throw new Exception("Stack log");
} catch (Exception e) {
Timber.d( "HALT AFTER" +
"\nresponsecode: " + Integer.toString(status) +
"\nThread: " + Thread.currentThread().getName() +
"\nobject: " + this.toString() +
"\nMethod: " + method.getHttpUrl() +
"\ntrace: " + ExceptionUtils.getStackTrace(e));
}
Thread.sleep(40000);
}
}
if (status == HttpConstants.HTTP_MOVED_TEMPORARILY) {
mConnectionValidator.validate(method, this);
retry = true;
} }
*/
if (mFollowRedirects) { if (mFollowRedirects) {
status = followRedirection(method).getLastStatus(); status = followRedirection(method).getLastStatus();
} }
@ -163,6 +148,7 @@ public class OwnCloudClient extends HttpClient {
repeatCounter++; repeatCounter++;
} }
} while (repeatWithFreshCredentials); } while (repeatWithFreshCredentials);
// } while (retry);
return status; return status;
} }
@ -384,9 +370,8 @@ public class OwnCloudClient extends HttpClient {
boolean credentialsWereRefreshed = false; boolean credentialsWereRefreshed = false;
if (shouldInvalidateAccountCredentials(status)) { if (shouldInvalidateAccountCredentials(status)) {
boolean invalidated = invalidateAccountCredentials(); invalidateAccountCredentials();
if (invalidated) {
if (getCredentials().authTokenCanBeRefreshed() && if (getCredentials().authTokenCanBeRefreshed() &&
repeatCounter < MAX_REPEAT_COUNT_WITH_FRESH_CREDENTIALS) { repeatCounter < MAX_REPEAT_COUNT_WITH_FRESH_CREDENTIALS) {
try { try {
@ -400,7 +385,6 @@ public class OwnCloudClient extends HttpClient {
mAccount.getSavedAccount().name mAccount.getSavedAccount().name
); );
} }
}
if (!credentialsWereRefreshed && mSingleSessionManager != null) { if (!credentialsWereRefreshed && mSingleSessionManager != null) {
// if credentials are not refreshed, client must be removed // if credentials are not refreshed, client must be removed
@ -441,16 +425,14 @@ public class OwnCloudClient extends HttpClient {
* <p> * <p>
* {@link #shouldInvalidateAccountCredentials(int)} should be called first. * {@link #shouldInvalidateAccountCredentials(int)} should be called first.
* *
* @return 'True' if invalidation was successful, 'false' otherwise.
*/ */
private boolean invalidateAccountCredentials() { private void invalidateAccountCredentials() {
AccountManager am = AccountManager.get(getContext()); AccountManager am = AccountManager.get(getContext());
am.invalidateAuthToken( am.invalidateAuthToken(
mAccount.getSavedAccount().type, mAccount.getSavedAccount().type,
mCredentials.getAuthToken() mCredentials.getAuthToken()
); );
am.clearPassword(mAccount.getSavedAccount()); // being strict, only needed for Basic Auth credentials am.clearPassword(mAccount.getSavedAccount()); // being strict, only needed for Basic Auth credentials
return true;
} }
public boolean followRedirects() { public boolean followRedirects() {

View File

@ -49,6 +49,7 @@ public class SingleSessionManager {
private static SingleSessionManager sDefaultSingleton; private static SingleSessionManager sDefaultSingleton;
private static String sUserAgent; private static String sUserAgent;
private static ConnectionValidator sConnectionValidator;
private ConcurrentMap<String, OwnCloudClient> mClientsWithKnownUsername = new ConcurrentHashMap<>(); private ConcurrentMap<String, OwnCloudClient> mClientsWithKnownUsername = new ConcurrentHashMap<>();
private ConcurrentMap<String, OwnCloudClient> mClientsWithUnknownUsername = new ConcurrentHashMap<>(); private ConcurrentMap<String, OwnCloudClient> mClientsWithUnknownUsername = new ConcurrentHashMap<>();
@ -60,6 +61,14 @@ public class SingleSessionManager {
return sDefaultSingleton; return sDefaultSingleton;
} }
public static void setConnectionValidator(ConnectionValidator connectionValidator) {
sConnectionValidator = connectionValidator;
}
public static ConnectionValidator getConnectionValidator() {
return sConnectionValidator;
}
public static String getUserAgent() { public static String getUserAgent() {
return sUserAgent; return sUserAgent;
} }
@ -68,15 +77,23 @@ public class SingleSessionManager {
sUserAgent = userAgent; sUserAgent = userAgent;
} }
private static OwnCloudClient createOwnCloudClient(Uri uri, Context context, boolean followRedirects) { private static OwnCloudClient createOwnCloudClient(Uri uri, Context context, boolean followRedirects, ConnectionValidator connectionValidator) {
OwnCloudClient client = new OwnCloudClient(uri); OwnCloudClient client = new OwnCloudClient(uri, connectionValidator, true);
client.setFollowRedirects(followRedirects); client.setFollowRedirects(followRedirects);
HttpClient.setContext(context); HttpClient.setContext(context);
return client; return client;
} }
public OwnCloudClient getClientFor(OwnCloudAccount account, Context context) throws OperationCanceledException, public OwnCloudClient getClientFor(OwnCloudAccount account,
Context context) throws OperationCanceledException,
AuthenticatorException, IOException {
return getClientFor(account, context, getConnectionValidator());
}
public OwnCloudClient getClientFor(OwnCloudAccount account,
Context context,
ConnectionValidator connectionValidator) throws OperationCanceledException,
AuthenticatorException, IOException { AuthenticatorException, IOException {
Timber.d("getClientFor starting "); Timber.d("getClientFor starting ");
@ -115,7 +132,8 @@ public class SingleSessionManager {
client = createOwnCloudClient( client = createOwnCloudClient(
account.getBaseUri(), account.getBaseUri(),
context.getApplicationContext(), context.getApplicationContext(),
true); // TODO remove dependency on OwnCloudClientFactory true,
connectionValidator); // TODO remove dependency on OwnCloudClientFactory
//the next two lines are a hack because okHttpclient is used as a singleton instead of being an //the next two lines are a hack because okHttpclient is used as a singleton instead of being an
//injected instance that can be deleted when required //injected instance that can be deleted when required

View File

@ -159,7 +159,7 @@ public abstract class RemoteOperation<T> implements Runnable {
if (mAccount != null && mContext != null) { if (mAccount != null && mContext != null) {
OwnCloudAccount ocAccount = new OwnCloudAccount(mAccount, mContext); OwnCloudAccount ocAccount = new OwnCloudAccount(mAccount, mContext);
mClient = SingleSessionManager.getDefaultSingleton(). mClient = SingleSessionManager.getDefaultSingleton().
getClientFor(ocAccount, mContext); getClientFor(ocAccount, mContext, SingleSessionManager.getConnectionValidator());
} else { } else {
throw new IllegalStateException("Trying to run a remote operation " + throw new IllegalStateException("Trying to run a remote operation " +
"asynchronously with no client and no chance to create one (no account)"); "asynchronously with no client and no chance to create one (no account)");