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:
parent
0e82f983b5
commit
7e4b43e7cb
@ -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")
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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,22 +370,20 @@ 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 {
|
mAccount.loadCredentials(getContext());
|
||||||
mAccount.loadCredentials(getContext());
|
// if mAccount.getCredentials().length() == 0 --> refresh failed
|
||||||
// if mAccount.getCredentials().length() == 0 --> refresh failed
|
setCredentials(mAccount.getCredentials());
|
||||||
setCredentials(mAccount.getCredentials());
|
credentialsWereRefreshed = true;
|
||||||
credentialsWereRefreshed = true;
|
|
||||||
|
|
||||||
} catch (AccountsException | IOException e) {
|
} catch (AccountsException | IOException e) {
|
||||||
Timber.e(e, "Error while trying to refresh auth token for %s",
|
Timber.e(e, "Error while trying to refresh auth token for %s",
|
||||||
mAccount.getSavedAccount().name
|
mAccount.getSavedAccount().name
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!credentialsWereRefreshed && mSingleSessionManager != null) {
|
if (!credentialsWereRefreshed && mSingleSessionManager != null) {
|
||||||
@ -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() {
|
||||||
|
@ -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
|
||||||
|
@ -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)");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user