mirror of
				https://github.com/owncloud/android-library.git
				synced 2025-10-31 02:17:41 +00:00 
			
		
		
		
	move OwnCloudClient redirect functionallity into redirection manager
This commit is contained in:
		
							parent
							
								
									412047b4c8
								
							
						
					
					
						commit
						7a2c61d3bf
					
				| @ -29,7 +29,6 @@ import android.accounts.AccountManager; | ||||
| import android.accounts.AccountsException; | ||||
| import android.net.Uri; | ||||
| 
 | ||||
| import at.bitfire.dav4jvm.exception.HttpException; | ||||
| import com.owncloud.android.lib.common.accounts.AccountUtils; | ||||
| import com.owncloud.android.lib.common.authentication.OwnCloudCredentials; | ||||
| import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory; | ||||
| @ -37,7 +36,6 @@ import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory | ||||
| import com.owncloud.android.lib.common.http.HttpClient; | ||||
| import com.owncloud.android.lib.common.http.HttpConstants; | ||||
| import com.owncloud.android.lib.common.http.methods.HttpBaseMethod; | ||||
| import com.owncloud.android.lib.common.network.RedirectionPath; | ||||
| import com.owncloud.android.lib.common.utils.RandomUtils; | ||||
| import com.owncloud.android.lib.resources.status.OwnCloudVersion; | ||||
| import okhttp3.Cookie; | ||||
| @ -48,8 +46,6 @@ import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import static com.owncloud.android.lib.common.http.HttpConstants.OC_X_REQUEST_ID; | ||||
| 
 | ||||
| public class OwnCloudClient extends HttpClient { | ||||
| 
 | ||||
|     public static final String WEBDAV_FILES_PATH_4_0 = "/remote.php/dav/files/"; | ||||
| @ -57,7 +53,6 @@ public class OwnCloudClient extends HttpClient { | ||||
|     private static final String WEBDAV_UPLOADS_PATH_4_0 = "/remote.php/dav/uploads/"; | ||||
|     public static final String STATUS_PATH = "/status.php"; | ||||
| 
 | ||||
|     private static final int MAX_REDIRECTIONS_COUNT = 3; | ||||
|     private static final int MAX_REPEAT_COUNT_WITH_FRESH_CREDENTIALS = 1; | ||||
| 
 | ||||
|     private static byte[] sExhaustBuffer = new byte[1024]; | ||||
| @ -111,7 +106,8 @@ public class OwnCloudClient extends HttpClient { | ||||
|             status = method.execute(); | ||||
| 
 | ||||
|             if (mFollowRedirects) { | ||||
|                 status = followRedirection(method).getLastStatus(); | ||||
|                 RedirectionManager redirectionManager = new RedirectionManager(this); | ||||
|                 status = redirectionManager.followRedirection(method).getLastStatus(); | ||||
|             } | ||||
| 
 | ||||
|             repeatWithFreshCredentials = checkUnauthorizedAccess(status, repeatCounter); | ||||
| @ -123,90 +119,6 @@ public class OwnCloudClient extends HttpClient { | ||||
|         return status; | ||||
|     } | ||||
| 
 | ||||
|     private int executeRedirectedHttpMethod(HttpBaseMethod method) throws Exception { | ||||
|         boolean repeatWithFreshCredentials; | ||||
|         int repeatCounter = 0; | ||||
|         int status; | ||||
| 
 | ||||
|         do { | ||||
|             String requestId = RandomUtils.generateRandomUUID(); | ||||
| 
 | ||||
|             // Header to allow tracing requests in apache and ownCloud logs | ||||
|             Timber.d("Executing in request with id %s", requestId); | ||||
|             method.setRequestHeader(OC_X_REQUEST_ID, requestId); | ||||
|             method.setRequestHeader(HttpConstants.USER_AGENT_HEADER, SingleSessionManager.getUserAgent()); | ||||
|             method.setRequestHeader(HttpConstants.PARAM_SINGLE_COOKIE_HEADER, "true"); | ||||
|             method.setRequestHeader(HttpConstants.ACCEPT_ENCODING_HEADER, HttpConstants.ACCEPT_ENCODING_IDENTITY); | ||||
|             if (mCredentials.getHeaderAuth() != null) { | ||||
|                 method.setRequestHeader(HttpConstants.AUTHORIZATION_HEADER, mCredentials.getHeaderAuth()); | ||||
|             } | ||||
|             status = method.execute(); | ||||
| 
 | ||||
|             repeatWithFreshCredentials = checkUnauthorizedAccess(status, repeatCounter); | ||||
|             if (repeatWithFreshCredentials) { | ||||
|                 repeatCounter++; | ||||
|             } | ||||
|         } while (repeatWithFreshCredentials); | ||||
| 
 | ||||
|         return status; | ||||
|     } | ||||
| 
 | ||||
|     public RedirectionPath followRedirection(HttpBaseMethod method) throws Exception { | ||||
|         int redirectionsCount = 0; | ||||
|         int status = method.getStatusCode(); | ||||
|         RedirectionPath redirectionPath = new RedirectionPath(status, MAX_REDIRECTIONS_COUNT); | ||||
| 
 | ||||
|         while (redirectionsCount < MAX_REDIRECTIONS_COUNT && | ||||
|                 (status == HttpConstants.HTTP_MOVED_PERMANENTLY || | ||||
|                         status == HttpConstants.HTTP_MOVED_TEMPORARILY || | ||||
|                         status == HttpConstants.HTTP_TEMPORARY_REDIRECT) | ||||
|         ) { | ||||
| 
 | ||||
|             final String location = method.getResponseHeader(HttpConstants.LOCATION_HEADER) != null | ||||
|                     ? method.getResponseHeader(HttpConstants.LOCATION_HEADER) | ||||
|                     : method.getResponseHeader(HttpConstants.LOCATION_HEADER_LOWER); | ||||
| 
 | ||||
|             if (location != null) { | ||||
|                 Timber.d("#" + mInstanceNumber + "Location to redirect: " + location); | ||||
| 
 | ||||
|                 redirectionPath.addLocation(location); | ||||
| 
 | ||||
|                 // Release the connection to avoid reach the max number of connections per host | ||||
|                 // due to it will be set a different url | ||||
|                 exhaustResponse(method.getResponseBodyAsStream()); | ||||
| 
 | ||||
|                 method.setUrl(HttpUrl.parse(location)); | ||||
|                 final String destination = method.getRequestHeader("Destination") != null | ||||
|                         ? method.getRequestHeader("Destination") | ||||
|                         : method.getRequestHeader("destination"); | ||||
| 
 | ||||
|                 if (destination != null) { | ||||
|                     final int suffixIndex = location.lastIndexOf(getUserFilesWebDavUri().toString()); | ||||
|                     final String redirectionBase = location.substring(0, suffixIndex); | ||||
|                     final String destinationPath = destination.substring(mBaseUri.toString().length()); | ||||
| 
 | ||||
|                     method.setRequestHeader("destination", redirectionBase + destinationPath); | ||||
|                 } | ||||
|                 try { | ||||
|                     status = executeRedirectedHttpMethod(method); | ||||
|                 } catch (HttpException e) { | ||||
|                     if (e.getMessage().contains(Integer.toString(HttpConstants.HTTP_MOVED_TEMPORARILY))) { | ||||
|                         status = HttpConstants.HTTP_MOVED_TEMPORARILY; | ||||
|                     } else { | ||||
|                         throw e; | ||||
|                     } | ||||
|                 } | ||||
|                 redirectionPath.addStatus(status); | ||||
|                 redirectionsCount++; | ||||
| 
 | ||||
|             } else { | ||||
|                 Timber.d(" #" + mInstanceNumber + "No location to redirect!"); | ||||
|                 status = HttpConstants.HTTP_NOT_FOUND; | ||||
|             } | ||||
|         } | ||||
|         return redirectionPath; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Exhausts a not interesting HTTP response. Encouraged by HttpClient documentation. | ||||
|      * | ||||
| @ -322,7 +234,7 @@ public class OwnCloudClient extends HttpClient { | ||||
|      * @param repeatCounter | ||||
|      * @return | ||||
|      */ | ||||
|     private boolean checkUnauthorizedAccess(int status, int repeatCounter) { | ||||
|     public boolean checkUnauthorizedAccess(int status, int repeatCounter) { | ||||
|         boolean credentialsWereRefreshed = false; | ||||
| 
 | ||||
|         if (shouldInvalidateAccountCredentials(status)) { | ||||
| @ -402,4 +314,8 @@ public class OwnCloudClient extends HttpClient { | ||||
|     public void setFollowRedirects(boolean followRedirects) { | ||||
|         this.mFollowRedirects = followRedirects; | ||||
|     } | ||||
| 
 | ||||
|     public int getInstanceNumber() { | ||||
|         return mInstanceNumber; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,124 @@ | ||||
| package com.owncloud.android.lib.common; | ||||
| 
 | ||||
| import at.bitfire.dav4jvm.exception.HttpException; | ||||
| import com.owncloud.android.lib.common.SingleSessionManager; | ||||
| import com.owncloud.android.lib.common.authentication.OwnCloudCredentials; | ||||
| import com.owncloud.android.lib.common.http.HttpConstants; | ||||
| import com.owncloud.android.lib.common.http.methods.HttpBaseMethod; | ||||
| import com.owncloud.android.lib.common.network.RedirectionPath; | ||||
| import com.owncloud.android.lib.common.utils.RandomUtils; | ||||
| import okhttp3.HttpUrl; | ||||
| import timber.log.Timber; | ||||
| 
 | ||||
| import static com.owncloud.android.lib.common.http.HttpConstants.OC_X_REQUEST_ID; | ||||
| 
 | ||||
| class RedirectionManager { | ||||
|     private static final int MAX_REDIRECTIONS_COUNT = 3; | ||||
| 
 | ||||
|     private final OwnCloudClient ownCloudClient; | ||||
| 
 | ||||
|     public RedirectionManager(OwnCloudClient client) { | ||||
|         ownCloudClient = client; | ||||
|     } | ||||
| 
 | ||||
|     private int executeRedirectedHttpMethod(HttpBaseMethod method, OwnCloudCredentials credentials) throws Exception { | ||||
|         boolean repeatWithFreshCredentials; | ||||
|         int repeatCounter = 0; | ||||
|         int status; | ||||
| 
 | ||||
|         do { | ||||
|             String requestId = RandomUtils.generateRandomUUID(); | ||||
| 
 | ||||
|             // Header to allow tracing requests in apache and ownCloud logs | ||||
|             Timber.d("Executing in request with id %s", requestId); | ||||
|             method.setRequestHeader(OC_X_REQUEST_ID, requestId); | ||||
|             method.setRequestHeader(HttpConstants.USER_AGENT_HEADER, SingleSessionManager.getUserAgent()); | ||||
|             method.setRequestHeader(HttpConstants.PARAM_SINGLE_COOKIE_HEADER, "true"); | ||||
|             method.setRequestHeader(HttpConstants.ACCEPT_ENCODING_HEADER, HttpConstants.ACCEPT_ENCODING_IDENTITY); | ||||
|             if (credentials.getHeaderAuth() != null) { | ||||
|                 method.setRequestHeader(HttpConstants.AUTHORIZATION_HEADER, credentials.getHeaderAuth()); | ||||
|             } | ||||
|             status = method.execute(); | ||||
| 
 | ||||
|             repeatWithFreshCredentials = ownCloudClient.checkUnauthorizedAccess(status, repeatCounter); | ||||
|             if (repeatWithFreshCredentials) { | ||||
|                 repeatCounter++; | ||||
|             } | ||||
|         } while (repeatWithFreshCredentials); | ||||
| 
 | ||||
|         return status; | ||||
|     } | ||||
| 
 | ||||
|     private String getLocationFromMethod(HttpBaseMethod method) { | ||||
|         return method.getResponseHeader(HttpConstants.LOCATION_HEADER) != null | ||||
|                 ? method.getResponseHeader(HttpConstants.LOCATION_HEADER) | ||||
|                 : method.getResponseHeader(HttpConstants.LOCATION_HEADER_LOWER); | ||||
|     } | ||||
| 
 | ||||
|     private boolean shouldFollowRedirection(int redirectionsCount, int status) { | ||||
|         return (redirectionsCount < MAX_REDIRECTIONS_COUNT && | ||||
|                 (status == HttpConstants.HTTP_MOVED_PERMANENTLY || | ||||
|                         status == HttpConstants.HTTP_MOVED_TEMPORARILY || | ||||
|                         status == HttpConstants.HTTP_TEMPORARY_REDIRECT)); | ||||
|     } | ||||
| 
 | ||||
|     private String getDestinationFromMethod(HttpBaseMethod method) { | ||||
|         return method.getRequestHeader("Destination") != null | ||||
|                 ? method.getRequestHeader("Destination") | ||||
|                 : method.getRequestHeader("destination"); | ||||
|     } | ||||
| 
 | ||||
|     private String buildDestinationHeader(String location, String destination) { | ||||
|         final int suffixIndex = location.lastIndexOf(ownCloudClient.getUserFilesWebDavUri().toString()); | ||||
|         final String redirectionBase = location.substring(0, suffixIndex); | ||||
|         final String destinationPath = destination.substring(ownCloudClient.getBaseUri().toString().length()); | ||||
|         return redirectionBase + destinationPath; | ||||
|     } | ||||
| 
 | ||||
|     private int followRedirect(HttpBaseMethod method, String location, String destination) throws Exception { | ||||
|         if (destination != null) { | ||||
|             method.setRequestHeader("destination", buildDestinationHeader(location, destination)); | ||||
|         } | ||||
|         try { | ||||
|             return executeRedirectedHttpMethod(method, ownCloudClient.getCredentials()); | ||||
|         } catch (HttpException e) { | ||||
|             if (e.getMessage().contains(Integer.toString(HttpConstants.HTTP_MOVED_TEMPORARILY))) { | ||||
|                 return HttpConstants.HTTP_MOVED_TEMPORARILY; | ||||
|             } else { | ||||
|                 throw e; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public RedirectionPath followRedirection(HttpBaseMethod method) throws Exception { | ||||
|         int redirectionsCount = 0; | ||||
|         int status = method.getStatusCode(); | ||||
|         RedirectionPath redirectionPath = new RedirectionPath(status, MAX_REDIRECTIONS_COUNT); | ||||
| 
 | ||||
|         while (shouldFollowRedirection(redirectionsCount, status)) { | ||||
|             final String location = getLocationFromMethod(method); | ||||
| 
 | ||||
|             if (location != null) { | ||||
|                 Timber.d("#" + ownCloudClient.getInstanceNumber() + "Location to redirect: " + location); | ||||
| 
 | ||||
|                 redirectionPath.addLocation(location); | ||||
| 
 | ||||
|                 // Release the connection to avoid reach the max number of connections per host | ||||
|                 // due to it will be set a different url | ||||
|                 ownCloudClient.exhaustResponse(method.getResponseBodyAsStream()); | ||||
| 
 | ||||
|                 method.setUrl(HttpUrl.parse(location)); | ||||
|                 final String destination = getDestinationFromMethod(method); | ||||
| 
 | ||||
|                 status = followRedirect(method, location, destination); | ||||
|                 redirectionPath.addStatus(status); | ||||
|                 redirectionsCount++; | ||||
| 
 | ||||
|             } else { | ||||
|                 Timber.d(" #" + ownCloudClient.getInstanceNumber() + "No location to redirect!"); | ||||
|                 status = HttpConstants.HTTP_NOT_FOUND; | ||||
|             } | ||||
|         } | ||||
|         return redirectionPath; | ||||
|     } | ||||
| } | ||||
| @ -24,10 +24,6 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.authentication; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.OwnCloudClient; | ||||
| import com.owncloud.android.lib.common.http.HttpClient; | ||||
| import com.owncloud.android.lib.common.http.HttpConstants; | ||||
| 
 | ||||
| public class OwnCloudCredentialsFactory { | ||||
| 
 | ||||
|     public static final String CREDENTIAL_CHARSET = "UTF-8"; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user