mirror of
				https://github.com/owncloud/android-library.git
				synced 2025-10-31 02:17:41 +00:00 
			
		
		
		
	Fix 301 redirections
This commit is contained in:
		
							parent
							
								
									1194b9a412
								
							
						
					
					
						commit
						3a79a86cd7
					
				| @ -27,6 +27,7 @@ package com.owncloud.android.lib.common; | |||||||
| import android.content.Context; | import android.content.Context; | ||||||
| import android.net.Uri; | import android.net.Uri; | ||||||
| 
 | 
 | ||||||
|  | import com.owncloud.android.lib.common.http.HttpClient; | ||||||
| import com.owncloud.android.lib.resources.status.GetRemoteStatusOperation; | import com.owncloud.android.lib.resources.status.GetRemoteStatusOperation; | ||||||
| 
 | 
 | ||||||
| public class OwnCloudClientFactory { | public class OwnCloudClientFactory { | ||||||
| @ -44,13 +45,13 @@ public class OwnCloudClientFactory { | |||||||
| 
 | 
 | ||||||
|         client.setFollowRedirects(followRedirects); |         client.setFollowRedirects(followRedirects); | ||||||
| 
 | 
 | ||||||
|         client.setContext(context); |         HttpClient.setContext(context); | ||||||
|         retriveCookisFromMiddleware(client); |         retrieveCookiesFromMiddleware(client); | ||||||
| 
 | 
 | ||||||
|         return client; |         return client; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static void retriveCookisFromMiddleware(OwnCloudClient client) { |     private static void retrieveCookiesFromMiddleware(OwnCloudClient client) { | ||||||
|         final GetRemoteStatusOperation statusOperation = new GetRemoteStatusOperation(); |         final GetRemoteStatusOperation statusOperation = new GetRemoteStatusOperation(); | ||||||
|         statusOperation.run(client); |         statusOperation.run(client); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -29,7 +29,6 @@ import com.owncloud.android.lib.common.operations.RemoteOperation | |||||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult | import com.owncloud.android.lib.common.operations.RemoteOperationResult | ||||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode | import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode | ||||||
| import com.owncloud.android.lib.resources.status.HttpScheme.HTTPS_PREFIX | import com.owncloud.android.lib.resources.status.HttpScheme.HTTPS_PREFIX | ||||||
| import com.owncloud.android.lib.resources.status.HttpScheme.HTTPS_SCHEME |  | ||||||
| import com.owncloud.android.lib.resources.status.HttpScheme.HTTP_PREFIX | import com.owncloud.android.lib.resources.status.HttpScheme.HTTP_PREFIX | ||||||
| import com.owncloud.android.lib.resources.status.HttpScheme.HTTP_SCHEME | import com.owncloud.android.lib.resources.status.HttpScheme.HTTP_SCHEME | ||||||
| import org.json.JSONException | import org.json.JSONException | ||||||
| @ -43,15 +42,13 @@ import timber.log.Timber | |||||||
|  * @author David González Verdugo |  * @author David González Verdugo | ||||||
|  * @author Abel García de Prada |  * @author Abel García de Prada | ||||||
|  */ |  */ | ||||||
| class GetRemoteStatusOperation : RemoteOperation<OwnCloudVersion>() { | class GetRemoteStatusOperation : RemoteOperation<RemoteServerInfo>() { | ||||||
| 
 | 
 | ||||||
|     public override fun run(client: OwnCloudClient): RemoteOperationResult<OwnCloudVersion> { |     public override fun run(client: OwnCloudClient): RemoteOperationResult<RemoteServerInfo> { | ||||||
|         client.baseUri = buildFullHttpsUrl(client.baseUri) |         client.baseUri = buildFullHttpsUrl(client.baseUri) | ||||||
| 
 | 
 | ||||||
|         var result = tryToConnect(client) |         var result = tryToConnect(client) | ||||||
|         if (!(result.code == ResultCode.OK || result.code == ResultCode.OK_SSL) |         if (!(result.code == ResultCode.OK || result.code == ResultCode.OK_SSL) && !result.isSslRecoverableException) { | ||||||
|             && !result.isSslRecoverableException |  | ||||||
|         ) { |  | ||||||
|             Timber.d("Establishing secure connection failed, trying non secure connection") |             Timber.d("Establishing secure connection failed, trying non secure connection") | ||||||
|             client.baseUri = client.baseUri.buildUpon().scheme(HTTP_SCHEME).build() |             client.baseUri = client.baseUri.buildUpon().scheme(HTTP_SCHEME).build() | ||||||
|             result = tryToConnect(client) |             result = tryToConnect(client) | ||||||
| @ -60,7 +57,7 @@ class GetRemoteStatusOperation : RemoteOperation<OwnCloudVersion>() { | |||||||
|         return result |         return result | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private fun tryToConnect(client: OwnCloudClient): RemoteOperationResult<OwnCloudVersion> { |     private fun tryToConnect(client: OwnCloudClient): RemoteOperationResult<RemoteServerInfo> { | ||||||
|         val baseUrl = client.baseUri.toString() |         val baseUrl = client.baseUri.toString() | ||||||
|         client.setFollowRedirects(false) |         client.setFollowRedirects(false) | ||||||
|         return try { |         return try { | ||||||
|  | |||||||
| @ -0,0 +1,30 @@ | |||||||
|  | /* ownCloud Android Library is available under MIT license | ||||||
|  | *   Copyright (C) 2020 ownCloud GmbH. | ||||||
|  | * | ||||||
|  | *   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  | *   of this software and associated documentation files (the "Software"), to deal | ||||||
|  | *   in the Software without restriction, including without limitation the rights | ||||||
|  | *   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  | *   copies of the Software, and to permit persons to whom the Software is | ||||||
|  | *   furnished to do so, subject to the following conditions: | ||||||
|  | * | ||||||
|  | *   The above copyright notice and this permission notice shall be included in | ||||||
|  | *   all copies or substantial portions of the Software. | ||||||
|  | * | ||||||
|  | *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||||||
|  | *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||||||
|  | *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||||||
|  | *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||||||
|  | *   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||||||
|  | *   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||||||
|  | *   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||||
|  | *   THE SOFTWARE. | ||||||
|  | * | ||||||
|  | */ | ||||||
|  | package com.owncloud.android.lib.resources.status | ||||||
|  | 
 | ||||||
|  | data class RemoteServerInfo( | ||||||
|  |     val ownCloudVersion: OwnCloudVersion, | ||||||
|  |     val baseUrl: String, | ||||||
|  |     val isSecureConnection: Boolean | ||||||
|  | ) | ||||||
| @ -28,9 +28,7 @@ import com.owncloud.android.lib.common.OwnCloudClient | |||||||
| import com.owncloud.android.lib.common.http.HttpConstants | import com.owncloud.android.lib.common.http.HttpConstants | ||||||
| import com.owncloud.android.lib.common.http.methods.nonwebdav.GetMethod | import com.owncloud.android.lib.common.http.methods.nonwebdav.GetMethod | ||||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult | import com.owncloud.android.lib.common.operations.RemoteOperationResult | ||||||
| 
 |  | ||||||
| import com.owncloud.android.lib.resources.status.HttpScheme.HTTPS_SCHEME | import com.owncloud.android.lib.resources.status.HttpScheme.HTTPS_SCHEME | ||||||
| import com.owncloud.android.lib.resources.status.HttpScheme.HTTP_SCHEME |  | ||||||
| import org.json.JSONObject | import org.json.JSONObject | ||||||
| import java.net.URL | import java.net.URL | ||||||
| import java.util.concurrent.TimeUnit | import java.util.concurrent.TimeUnit | ||||||
| @ -44,14 +42,21 @@ internal class StatusRequester { | |||||||
|      * we assume it was a debug setup. |      * we assume it was a debug setup. | ||||||
|      */ |      */ | ||||||
|     fun isRedirectedToNonSecureConnection( |     fun isRedirectedToNonSecureConnection( | ||||||
|         redirectedToUnsecureLocationBefore: Boolean, |         redirectedToNonSecureLocationBefore: Boolean, | ||||||
|         baseUrl: String, |         baseUrl: String, | ||||||
|         redirectedUrl: String |         redirectedUrl: String | ||||||
|     ) = redirectedToUnsecureLocationBefore |     ) = redirectedToNonSecureLocationBefore | ||||||
|             || (baseUrl.startsWith(HTTPS_SCHEME) |             || (baseUrl.startsWith(HTTPS_SCHEME) | ||||||
|             && !redirectedUrl.startsWith(HTTPS_SCHEME)) |             && !redirectedUrl.startsWith(HTTPS_SCHEME)) | ||||||
| 
 | 
 | ||||||
|     fun updateLocationWithRedirectPath(oldLocation: String, redirectedLocation: String): String { |     fun updateLocationWithRedirectPath(oldLocation: String, redirectedLocation: String): String { | ||||||
|  |         /** Redirection with different endpoint. | ||||||
|  |          * When asking for server.com/status.php and redirected to different.one/, we need to ask different.one/status.php | ||||||
|  |          */ | ||||||
|  |         if (redirectedLocation.endsWith('/')) { | ||||||
|  |             return redirectedLocation.trimEnd('/') + OwnCloudClient.STATUS_PATH | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         if (!redirectedLocation.startsWith("/")) |         if (!redirectedLocation.startsWith("/")) | ||||||
|             return redirectedLocation |             return redirectedLocation | ||||||
|         val oldLocationURL = URL(oldLocation) |         val oldLocationURL = URL(oldLocation) | ||||||
| @ -68,7 +73,8 @@ internal class StatusRequester { | |||||||
|     data class RequestResult( |     data class RequestResult( | ||||||
|         val getMethod: GetMethod, |         val getMethod: GetMethod, | ||||||
|         val status: Int, |         val status: Int, | ||||||
|         val redirectedToUnsecureLocation: Boolean |         val redirectedToUnsecureLocation: Boolean, | ||||||
|  |         val lastLocation: String | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     fun requestAndFollowRedirects(baseLocation: String, client: OwnCloudClient): RequestResult { |     fun requestAndFollowRedirects(baseLocation: String, client: OwnCloudClient): RequestResult { | ||||||
| @ -85,7 +91,7 @@ internal class StatusRequester { | |||||||
|                 else RemoteOperationResult(getMethod) |                 else RemoteOperationResult(getMethod) | ||||||
| 
 | 
 | ||||||
|             if (result.redirectedLocation.isNullOrEmpty() || result.isSuccess) { |             if (result.redirectedLocation.isNullOrEmpty() || result.isSuccess) { | ||||||
|                 return RequestResult(getMethod, status, redirectedToUnsecureLocation) |                 return RequestResult(getMethod, status, redirectedToUnsecureLocation, currentLocation) | ||||||
|             } else { |             } else { | ||||||
|                 val nextLocation = updateLocationWithRedirectPath(currentLocation, result.redirectedLocation) |                 val nextLocation = updateLocationWithRedirectPath(currentLocation, result.redirectedLocation) | ||||||
|                 redirectedToUnsecureLocation = |                 redirectedToUnsecureLocation = | ||||||
| @ -104,7 +110,7 @@ internal class StatusRequester { | |||||||
|     fun handleRequestResult( |     fun handleRequestResult( | ||||||
|         requestResult: RequestResult, |         requestResult: RequestResult, | ||||||
|         baseUrl: String |         baseUrl: String | ||||||
|     ): RemoteOperationResult<OwnCloudVersion> { |     ): RemoteOperationResult<RemoteServerInfo> { | ||||||
|         if (!requestResult.status.isSuccess()) |         if (!requestResult.status.isSuccess()) | ||||||
|             return RemoteOperationResult(requestResult.getMethod) |             return RemoteOperationResult(requestResult.getMethod) | ||||||
| 
 | 
 | ||||||
| @ -115,25 +121,35 @@ internal class StatusRequester { | |||||||
|         val ocVersion = OwnCloudVersion(respJSON.getString(NODE_VERSION)) |         val ocVersion = OwnCloudVersion(respJSON.getString(NODE_VERSION)) | ||||||
|         // the version object will be returned even if the version is invalid, no error code; |         // the version object will be returned even if the version is invalid, no error code; | ||||||
|         // every app will decide how to act if (ocVersion.isVersionValid() == false) |         // every app will decide how to act if (ocVersion.isVersionValid() == false) | ||||||
|         val result = |         val result: RemoteOperationResult<RemoteServerInfo> = | ||||||
|             if (requestResult.redirectedToUnsecureLocation) { |             if (requestResult.redirectedToUnsecureLocation) { | ||||||
|                 RemoteOperationResult<OwnCloudVersion>(RemoteOperationResult.ResultCode.OK_REDIRECT_TO_NON_SECURE_CONNECTION) |                 RemoteOperationResult(RemoteOperationResult.ResultCode.OK_REDIRECT_TO_NON_SECURE_CONNECTION) | ||||||
|             } else { |             } else { | ||||||
|                 if (baseUrl.startsWith(HTTPS_SCHEME)) RemoteOperationResult( |                 if (baseUrl.startsWith(HTTPS_SCHEME)) RemoteOperationResult(RemoteOperationResult.ResultCode.OK_SSL) | ||||||
|                     RemoteOperationResult.ResultCode.OK_SSL |  | ||||||
|                 ) |  | ||||||
|                 else RemoteOperationResult(RemoteOperationResult.ResultCode.OK_NO_SSL) |                 else RemoteOperationResult(RemoteOperationResult.ResultCode.OK_NO_SSL) | ||||||
|             } |             } | ||||||
|         result.data = ocVersion |         val finalUrl = URL(requestResult.lastLocation) | ||||||
|  |         val finalBaseUrl = URL( | ||||||
|  |             finalUrl.protocol, | ||||||
|  |             finalUrl.host, | ||||||
|  |             finalUrl.port, | ||||||
|  |             finalUrl.file.dropLastWhile { it != '/' }.trimEnd('/') | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |         result.data = RemoteServerInfo( | ||||||
|  |             ownCloudVersion = ocVersion, | ||||||
|  |             baseUrl = finalBaseUrl.toString(), | ||||||
|  |             isSecureConnection = finalBaseUrl.protocol.startsWith(HTTPS_SCHEME) | ||||||
|  |         ) | ||||||
|         return result |         return result | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     companion object { |     companion object { | ||||||
|         /** |         /** | ||||||
|          * Maximum time to wait for a response from the server when the connection is being tested, |          * Maximum time to wait for a response from the server when the connection is being tested, | ||||||
|          * in MILLISECONDs. |          * in milliseconds. | ||||||
|          */ |          */ | ||||||
|         private const val TRY_CONNECTION_TIMEOUT: Long = 5000 |         private const val TRY_CONNECTION_TIMEOUT = 5_000L | ||||||
|         private const val NODE_INSTALLED = "installed" |         private const val NODE_INSTALLED = "installed" | ||||||
|         private const val NODE_VERSION = "version" |         private const val NODE_VERSION = "version" | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -25,10 +25,10 @@ package com.owncloud.android.lib.resources.status.services | |||||||
| 
 | 
 | ||||||
| import com.owncloud.android.lib.common.OwnCloudClient | import com.owncloud.android.lib.common.OwnCloudClient | ||||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult | import com.owncloud.android.lib.common.operations.RemoteOperationResult | ||||||
| import com.owncloud.android.lib.resources.status.OwnCloudVersion | import com.owncloud.android.lib.resources.status.RemoteServerInfo | ||||||
| 
 | 
 | ||||||
| interface ServerInfoService { | interface ServerInfoService { | ||||||
|     fun checkPathExistence(path: String, isUserLogged: Boolean, client: OwnCloudClient): RemoteOperationResult<Boolean> |     fun checkPathExistence(path: String, isUserLogged: Boolean, client: OwnCloudClient): RemoteOperationResult<Boolean> | ||||||
| 
 | 
 | ||||||
|     fun getRemoteStatus(path: String, client: OwnCloudClient): RemoteOperationResult<OwnCloudVersion> |     fun getRemoteStatus(path: String, client: OwnCloudClient): RemoteOperationResult<RemoteServerInfo> | ||||||
| } | } | ||||||
|  | |||||||
| @ -23,7 +23,7 @@ import com.owncloud.android.lib.common.OwnCloudClient | |||||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult | import com.owncloud.android.lib.common.operations.RemoteOperationResult | ||||||
| import com.owncloud.android.lib.resources.files.CheckPathExistenceRemoteOperation | import com.owncloud.android.lib.resources.files.CheckPathExistenceRemoteOperation | ||||||
| import com.owncloud.android.lib.resources.status.GetRemoteStatusOperation | import com.owncloud.android.lib.resources.status.GetRemoteStatusOperation | ||||||
| import com.owncloud.android.lib.resources.status.OwnCloudVersion | import com.owncloud.android.lib.resources.status.RemoteServerInfo | ||||||
| import com.owncloud.android.lib.resources.status.services.ServerInfoService | import com.owncloud.android.lib.resources.status.services.ServerInfoService | ||||||
| 
 | 
 | ||||||
| class OCServerInfoService : ServerInfoService { | class OCServerInfoService : ServerInfoService { | ||||||
| @ -41,6 +41,6 @@ class OCServerInfoService : ServerInfoService { | |||||||
|     override fun getRemoteStatus( |     override fun getRemoteStatus( | ||||||
|         path: String, |         path: String, | ||||||
|         client: OwnCloudClient |         client: OwnCloudClient | ||||||
|     ): RemoteOperationResult<OwnCloudVersion> = |     ): RemoteOperationResult<RemoteServerInfo> = | ||||||
|         GetRemoteStatusOperation().execute(client) |         GetRemoteStatusOperation().execute(client) | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user