28
28
import android .accounts .AccountManager ;
29
29
import android .accounts .AccountsException ;
30
30
import android .net .Uri ;
31
- import android .util .Log ;
32
31
33
32
import at .bitfire .dav4jvm .exception .HttpException ;
34
33
import com .owncloud .android .lib .common .accounts .AccountUtils ;
38
37
import com .owncloud .android .lib .common .http .HttpClient ;
39
38
import com .owncloud .android .lib .common .http .HttpConstants ;
40
39
import com .owncloud .android .lib .common .http .methods .HttpBaseMethod ;
41
- import com .owncloud .android .lib .common .http .methods .nonwebdav .HttpMethod ;
42
40
import com .owncloud .android .lib .common .network .RedirectionPath ;
43
41
import com .owncloud .android .lib .common .utils .RandomUtils ;
44
42
import com .owncloud .android .lib .resources .status .OwnCloudVersion ;
@@ -70,26 +68,32 @@ public class OwnCloudClient extends HttpClient {
70
68
private Uri mBaseUri ;
71
69
private OwnCloudVersion mVersion = null ;
72
70
private OwnCloudAccount mAccount ;
73
- private ConnectionValidator mConnectionValidator ;
71
+ private final ConnectionValidator mConnectionValidator ;
72
+ private Object mRequestMutex = new Object ();
74
73
75
- private static Boolean mHoldRequests = false ;
74
+ // If set to true a mutex will be used to prevent parallel execution of the execute() method
75
+ // if false the execute() method can be called even though the mutex is already aquired.
76
+ // This is used for the ConnectionValidator, which has to be able to execute OperationsWhile all "normal" operations net
77
+ // to be set on hold.
78
+ private final Boolean mSynchronizeRequests ;
76
79
77
80
private SingleSessionManager mSingleSessionManager = null ;
78
81
79
82
private boolean mFollowRedirects ;
80
83
81
- public OwnCloudClient (Uri baseUri ) {
84
+ public OwnCloudClient (Uri baseUri , ConnectionValidator connectionValidator , boolean synchronizeRequests ) {
82
85
if (baseUri == null ) {
83
86
throw new IllegalArgumentException ("Parameter 'baseUri' cannot be NULL" );
84
87
}
85
88
mBaseUri = baseUri ;
89
+ mSynchronizeRequests = synchronizeRequests ;
86
90
87
91
mInstanceNumber = sIntanceCounter ++;
88
92
Timber .d ("#" + mInstanceNumber + "Creating OwnCloudClient" );
89
93
90
94
clearCredentials ();
91
95
clearCookies ();
92
- mConnectionValidator = new ConnectionValidator ( this ) ;
96
+ mConnectionValidator = connectionValidator ;
93
97
}
94
98
95
99
public void clearCredentials () {
@@ -99,10 +103,21 @@ public void clearCredentials() {
99
103
}
100
104
101
105
public int executeHttpMethod (HttpBaseMethod method ) throws Exception {
106
+ if (mSynchronizeRequests ) {
107
+ synchronized (mRequestMutex ) {
108
+ return saveExecuteHttpMethod (method );
109
+ }
110
+ } else {
111
+ return saveExecuteHttpMethod (method );
112
+ }
113
+ }
114
+
115
+ private int saveExecuteHttpMethod (HttpBaseMethod method ) throws Exception {
102
116
boolean repeatWithFreshCredentials ;
103
117
int repeatCounter = 0 ;
104
118
int status ;
105
119
120
+ boolean retry = false ;
106
121
do {
107
122
String requestId = RandomUtils .generateRandomUUID ();
108
123
@@ -117,44 +132,14 @@ public int executeHttpMethod(HttpBaseMethod method) throws Exception {
117
132
118
133
status = method .execute ();
119
134
stacklog (status , method );
120
- /*
121
- synchronized (mHoldRequests) {
122
- while (mHoldRequests) {
123
- while (true) {
124
- try {
125
- throw new Exception("Stack log");
126
- } catch (Exception e) {
127
- Timber.d( "HATL BEFORE" +
128
- "\nThread: " + Thread.currentThread().getName() +
129
- "\nobject: " + this.toString() +
130
- "\nMethod: " + method.getHttpUrl() +
131
- "\ntrace: " + ExceptionUtils.getStackTrace(e));
132
- }
133
- Thread.sleep(40000);
134
- }
135
- }
136
- status = method.execute();
137
- if (status == 302) {
138
- mHoldRequests = true;
139
- while (mHoldRequests) {
140
- try {
141
- throw new Exception("Stack log");
142
- } catch (Exception e) {
143
- Timber.d( "HALT AFTER" +
144
- "\nresponsecode: " + Integer.toString(status) +
145
- "\nThread: " + Thread.currentThread().getName() +
146
- "\nobject: " + this.toString() +
147
- "\nMethod: " + method.getHttpUrl() +
148
- "\ntrace: " + ExceptionUtils.getStackTrace(e));
149
- }
150
- Thread.sleep(40000);
151
- }
152
- }
153
135
136
+ if (status == HttpConstants .HTTP_MOVED_TEMPORARILY ) {
137
+ mConnectionValidator .validate (method , this );
138
+ retry = true ;
154
139
}
155
- */
156
140
157
141
if (mFollowRedirects ) {
142
+
158
143
status = followRedirection (method ).getLastStatus ();
159
144
}
160
145
@@ -163,6 +148,7 @@ public int executeHttpMethod(HttpBaseMethod method) throws Exception {
163
148
repeatCounter ++;
164
149
}
165
150
} while (repeatWithFreshCredentials );
151
+ // } while (retry);
166
152
167
153
return status ;
168
154
}
@@ -384,22 +370,20 @@ private boolean checkUnauthorizedAccess(int status, int repeatCounter) {
384
370
boolean credentialsWereRefreshed = false ;
385
371
386
372
if (shouldInvalidateAccountCredentials (status )) {
387
- boolean invalidated = invalidateAccountCredentials ();
388
-
389
- if (invalidated ) {
390
- if (getCredentials ().authTokenCanBeRefreshed () &&
391
- repeatCounter < MAX_REPEAT_COUNT_WITH_FRESH_CREDENTIALS ) {
392
- try {
393
- mAccount .loadCredentials (getContext ());
394
- // if mAccount.getCredentials().length() == 0 --> refresh failed
395
- setCredentials (mAccount .getCredentials ());
396
- credentialsWereRefreshed = true ;
397
-
398
- } catch (AccountsException | IOException e ) {
399
- Timber .e (e , "Error while trying to refresh auth token for %s" ,
400
- mAccount .getSavedAccount ().name
401
- );
402
- }
373
+ invalidateAccountCredentials ();
374
+
375
+ if (getCredentials ().authTokenCanBeRefreshed () &&
376
+ repeatCounter < MAX_REPEAT_COUNT_WITH_FRESH_CREDENTIALS ) {
377
+ try {
378
+ mAccount .loadCredentials (getContext ());
379
+ // if mAccount.getCredentials().length() == 0 --> refresh failed
380
+ setCredentials (mAccount .getCredentials ());
381
+ credentialsWereRefreshed = true ;
382
+
383
+ } catch (AccountsException | IOException e ) {
384
+ Timber .e (e , "Error while trying to refresh auth token for %s" ,
385
+ mAccount .getSavedAccount ().name
386
+ );
403
387
}
404
388
405
389
if (!credentialsWereRefreshed && mSingleSessionManager != null ) {
@@ -441,16 +425,14 @@ private boolean shouldInvalidateAccountCredentials(int httpStatusCode) {
441
425
* <p>
442
426
* {@link #shouldInvalidateAccountCredentials(int)} should be called first.
443
427
*
444
- * @return 'True' if invalidation was successful, 'false' otherwise.
445
428
*/
446
- private boolean invalidateAccountCredentials () {
429
+ private void invalidateAccountCredentials () {
447
430
AccountManager am = AccountManager .get (getContext ());
448
431
am .invalidateAuthToken (
449
432
mAccount .getSavedAccount ().type ,
450
433
mCredentials .getAuthToken ()
451
434
);
452
435
am .clearPassword (mAccount .getSavedAccount ()); // being strict, only needed for Basic Auth credentials
453
- return true ;
454
436
}
455
437
456
438
public boolean followRedirects () {
0 commit comments