Skip to content
This repository was archived by the owner on Mar 19, 2024. It is now read-only.

Commit 84240ef

Browse files
theScrabiabelgardep
authored andcommitted
detach request logic from operation
1 parent 9d4b88c commit 84240ef

File tree

3 files changed

+130
-113
lines changed

3 files changed

+130
-113
lines changed

owncloudComLibrary/src/main/java/com/owncloud/android/lib/resources/status/GetRemoteStatusOperation.kt

Lines changed: 9 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,12 @@ package com.owncloud.android.lib.resources.status
2525

2626
import android.net.Uri
2727
import com.owncloud.android.lib.common.OwnCloudClient
28-
import com.owncloud.android.lib.common.http.HttpConstants
29-
import com.owncloud.android.lib.common.http.methods.nonwebdav.GetMethod
3028
import com.owncloud.android.lib.common.operations.RemoteOperation
3129
import com.owncloud.android.lib.common.operations.RemoteOperationResult
3230
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode
3331
import org.json.JSONException
34-
import org.json.JSONObject
3532
import timber.log.Timber
36-
import java.net.URL
37-
import java.util.concurrent.TimeUnit
33+
3834

3935
/**
4036
* Checks if the server is valid
@@ -45,6 +41,11 @@ import java.util.concurrent.TimeUnit
4541
* @author Abel García de Prada
4642
*/
4743
class GetRemoteStatusOperation : RemoteOperation<OwnCloudVersion>() {
44+
companion object {
45+
const val HTTPS_SCHEME = "https"
46+
const val HTTP_SCHEME = "http"
47+
}
48+
4849
override fun run(client: OwnCloudClient): RemoteOperationResult<OwnCloudVersion> {
4950
if (client.baseUri.scheme.isNullOrEmpty())
5051
client.baseUri = Uri.parse(HTTPS_SCHEME + "://" + client.baseUri.toString())
@@ -59,114 +60,17 @@ class GetRemoteStatusOperation : RemoteOperation<OwnCloudVersion>() {
5960
return result
6061
}
6162

62-
fun updateLocationWithRedirectPath(oldLocation: String, redirectedLocation: String): String {
63-
if (!redirectedLocation.startsWith("/"))
64-
return redirectedLocation
65-
val oldLocation = URL(oldLocation)
66-
return URL(oldLocation.protocol, oldLocation.host, oldLocation.port, redirectedLocation).toString()
67-
}
68-
69-
private fun checkIfConnectionIsRedirectedToNoneSecure(
70-
isConnectionSecure: Boolean,
71-
baseUrl: String,
72-
redirectedUrl: String
73-
): Boolean {
74-
return isConnectionSecure ||
75-
(baseUrl.startsWith(HTTPS_SCHEME) && redirectedUrl.startsWith(HTTP_SCHEME))
76-
}
77-
78-
private fun getGetMethod(url: String): GetMethod {
79-
return GetMethod(URL(url + OwnCloudClient.STATUS_PATH)).apply {
80-
setReadTimeout(TRY_CONNECTION_TIMEOUT, TimeUnit.SECONDS)
81-
setConnectionTimeout(TRY_CONNECTION_TIMEOUT, TimeUnit.SECONDS)
82-
}
83-
}
84-
85-
data class RequestResult(
86-
val getMethod: GetMethod,
87-
val status: Int,
88-
val result: RemoteOperationResult<OwnCloudVersion>,
89-
val redirectedToUnsecureLocation: Boolean
90-
)
91-
92-
fun requestAndFollowRedirects(baseLocation: String): RequestResult {
93-
var currentLocation = baseLocation
94-
var redirectedToUnsecureLocation = false
95-
var status: Int
96-
97-
while (true) {
98-
val getMethod = getGetMethod(currentLocation)
99-
100-
status = client.executeHttpMethod(getMethod)
101-
val result =
102-
if (isSuccess(status)) RemoteOperationResult<OwnCloudVersion>(ResultCode.OK)
103-
else RemoteOperationResult(getMethod)
104-
105-
if (result.redirectedLocation.isNullOrEmpty() || result.isSuccess) {
106-
return RequestResult(getMethod, status, result, redirectedToUnsecureLocation)
107-
} else {
108-
val nextLocation = updateLocationWithRedirectPath(currentLocation, result.redirectedLocation)
109-
redirectedToUnsecureLocation =
110-
checkIfConnectionIsRedirectedToNoneSecure(
111-
redirectedToUnsecureLocation,
112-
currentLocation,
113-
nextLocation
114-
)
115-
currentLocation = nextLocation
116-
}
117-
}
118-
}
119-
120-
private fun handleRequestResult(
121-
requestResult: RequestResult,
122-
baseUrl: String
123-
): RemoteOperationResult<OwnCloudVersion> {
124-
if (!isSuccess(requestResult.status))
125-
return RemoteOperationResult(requestResult.getMethod)
126-
127-
val respJSON = JSONObject(requestResult.getMethod.getResponseBodyAsString())
128-
if (!respJSON.getBoolean(NODE_INSTALLED))
129-
return RemoteOperationResult(ResultCode.INSTANCE_NOT_CONFIGURED)
130-
131-
val version = respJSON.getString(NODE_VERSION)
132-
val ocVersion = OwnCloudVersion(version)
133-
// the version object will be returned even if the version is invalid, no error code;
134-
// every app will decide how to act if (ocVersion.isVersionValid() == false)
135-
val result =
136-
if (requestResult.redirectedToUnsecureLocation) {
137-
RemoteOperationResult<OwnCloudVersion>(ResultCode.OK_REDIRECT_TO_NON_SECURE_CONNECTION)
138-
} else {
139-
if (baseUrl.startsWith(HTTPS_SCHEME)) RemoteOperationResult(ResultCode.OK_SSL)
140-
else RemoteOperationResult(ResultCode.OK_NO_SSL)
141-
}
142-
result.data = ocVersion
143-
return result
144-
}
145-
14663
private fun tryToConnect(client: OwnCloudClient): RemoteOperationResult<OwnCloudVersion> {
14764
val baseUrl = client.baseUri.toString()
14865
client.setFollowRedirects(false)
14966
return try {
150-
val requestResult = requestAndFollowRedirects(baseUrl)
151-
handleRequestResult(requestResult, baseUrl)
67+
val requestor = StatusRequestor()
68+
val requestResult = requestor.requestAndFollowRedirects(baseUrl, client)
69+
requestor.handleRequestResult(requestResult, baseUrl)
15270
} catch (e: JSONException) {
15371
RemoteOperationResult(ResultCode.INSTANCE_NOT_CONFIGURED)
15472
} catch (e: Exception) {
15573
RemoteOperationResult(e)
15674
}
15775
}
158-
159-
private fun isSuccess(status: Int): Boolean = status == HttpConstants.HTTP_OK
160-
161-
companion object {
162-
/**
163-
* Maximum time to wait for a response from the server when the connection is being tested,
164-
* in MILLISECONDs.
165-
*/
166-
private const val TRY_CONNECTION_TIMEOUT: Long = 5000
167-
private const val NODE_INSTALLED = "installed"
168-
private const val NODE_VERSION = "version"
169-
private const val HTTPS_SCHEME = "https"
170-
private const val HTTP_SCHEME = "http"
171-
}
17276
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package com.owncloud.android.lib.resources.status
2+
3+
import com.owncloud.android.lib.common.OwnCloudClient
4+
import com.owncloud.android.lib.common.http.HttpConstants
5+
import com.owncloud.android.lib.common.http.methods.nonwebdav.GetMethod
6+
import com.owncloud.android.lib.common.operations.RemoteOperationResult
7+
import org.json.JSONObject
8+
import java.net.URL
9+
import java.util.concurrent.TimeUnit
10+
11+
internal class StatusRequestor {
12+
13+
companion object {
14+
/**
15+
* Maximum time to wait for a response from the server when the connection is being tested,
16+
* in MILLISECONDs.
17+
*/
18+
private const val TRY_CONNECTION_TIMEOUT: Long = 5000
19+
private const val NODE_INSTALLED = "installed"
20+
private const val HTTPS_SCHEME = "https"
21+
private const val HTTP_SCHEME = "http"
22+
private const val NODE_VERSION = "version"
23+
}
24+
25+
private fun checkIfConnectionIsRedirectedToNoneSecure(
26+
isConnectionSecure: Boolean,
27+
baseUrl: String,
28+
redirectedUrl: String
29+
): Boolean {
30+
return isConnectionSecure ||
31+
(baseUrl.startsWith(HTTPS_SCHEME) && redirectedUrl.startsWith(
32+
HTTP_SCHEME
33+
))
34+
}
35+
36+
fun updateLocationWithRedirectPath(oldLocation: String, redirectedLocation: String): String {
37+
if (!redirectedLocation.startsWith("/"))
38+
return redirectedLocation
39+
val oldLocation = URL(oldLocation)
40+
return URL(oldLocation.protocol, oldLocation.host, oldLocation.port, redirectedLocation).toString()
41+
}
42+
43+
private fun getGetMethod(url: String): GetMethod {
44+
return GetMethod(URL(url + OwnCloudClient.STATUS_PATH)).apply {
45+
setReadTimeout(TRY_CONNECTION_TIMEOUT, TimeUnit.SECONDS)
46+
setConnectionTimeout(TRY_CONNECTION_TIMEOUT, TimeUnit.SECONDS)
47+
}
48+
}
49+
50+
data class RequestResult(
51+
val getMethod: GetMethod,
52+
val status: Int,
53+
val result: RemoteOperationResult<OwnCloudVersion>,
54+
val redirectedToUnsecureLocation: Boolean
55+
)
56+
57+
fun requestAndFollowRedirects(baseLocation: String, client: OwnCloudClient): RequestResult {
58+
var currentLocation = baseLocation
59+
var redirectedToUnsecureLocation = false
60+
var status: Int
61+
62+
while (true) {
63+
val getMethod = getGetMethod(currentLocation)
64+
65+
status = client.executeHttpMethod(getMethod)
66+
val result =
67+
if (isSuccess(status)) RemoteOperationResult<OwnCloudVersion>(RemoteOperationResult.ResultCode.OK)
68+
else RemoteOperationResult(getMethod)
69+
70+
if (result.redirectedLocation.isNullOrEmpty() || result.isSuccess) {
71+
return RequestResult(getMethod, status, result, redirectedToUnsecureLocation)
72+
} else {
73+
val nextLocation = updateLocationWithRedirectPath(currentLocation, result.redirectedLocation)
74+
redirectedToUnsecureLocation =
75+
checkIfConnectionIsRedirectedToNoneSecure(
76+
redirectedToUnsecureLocation,
77+
currentLocation,
78+
nextLocation
79+
)
80+
currentLocation = nextLocation
81+
}
82+
}
83+
}
84+
85+
private fun isSuccess(status: Int): Boolean = status == HttpConstants.HTTP_OK
86+
87+
fun handleRequestResult(
88+
requestResult: RequestResult,
89+
baseUrl: String
90+
): RemoteOperationResult<OwnCloudVersion> {
91+
if (!isSuccess(requestResult.status))
92+
return RemoteOperationResult(requestResult.getMethod)
93+
94+
val respJSON = JSONObject(requestResult.getMethod.getResponseBodyAsString() ?: "")
95+
if (!respJSON.getBoolean(NODE_INSTALLED))
96+
return RemoteOperationResult(RemoteOperationResult.ResultCode.INSTANCE_NOT_CONFIGURED)
97+
98+
val ocVersion = OwnCloudVersion(respJSON.getString(NODE_VERSION))
99+
// the version object will be returned even if the version is invalid, no error code;
100+
// every app will decide how to act if (ocVersion.isVersionValid() == false)
101+
val result =
102+
if (requestResult.redirectedToUnsecureLocation) {
103+
RemoteOperationResult<OwnCloudVersion>(RemoteOperationResult.ResultCode.OK_REDIRECT_TO_NON_SECURE_CONNECTION)
104+
} else {
105+
if (baseUrl.startsWith(HTTPS_SCHEME)) RemoteOperationResult(
106+
RemoteOperationResult.ResultCode.OK_SSL
107+
)
108+
else RemoteOperationResult(RemoteOperationResult.ResultCode.OK_NO_SSL)
109+
}
110+
result.data = ocVersion
111+
return result
112+
}
113+
}

owncloudComLibrary/src/test/java/com/owncloud/android/lib/GetRemoteStatusOperationTest.kt renamed to owncloudComLibrary/src/test/java/com/owncloud/android/lib/StatusRequestorTest.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,40 @@
11
package com.owncloud.android.lib
22

3-
import com.owncloud.android.lib.resources.status.GetRemoteStatusOperation
3+
import com.owncloud.android.lib.resources.status.StatusRequestor
44
import org.junit.Assert.assertEquals
55
import org.junit.Test
66

7-
class GetRemoteStatusOperationTest {
8-
private val remoteStatusOperation = GetRemoteStatusOperation()
7+
class StatusRequestorTest {
8+
private val requestor = StatusRequestor()
99

1010
@Test
1111
fun `update location with an absolute path`() {
12-
val newLocation = remoteStatusOperation.updateLocationWithRedirectPath(
12+
val newLocation = requestor.updateLocationWithRedirectPath(
1313
"https://cloud.somewhere.com", "https://cloud.somewhere.com/subdir"
1414
)
1515
assertEquals("https://cloud.somewhere.com/subdir", newLocation)
1616
}
1717

1818
@Test
19-
fun `update location with a smaler aboslute path`() {
2019

21-
val newLocation = remoteStatusOperation.updateLocationWithRedirectPath(
20+
fun `update location with a smaler aboslute path`() {
21+
val newLocation = requestor.updateLocationWithRedirectPath(
2222
"https://cloud.somewhere.com/subdir", "https://cloud.somewhere.com/"
2323
)
2424
assertEquals("https://cloud.somewhere.com/", newLocation)
2525
}
2626

2727
@Test
2828
fun `update location with a relative path`() {
29-
val newLocation = remoteStatusOperation.updateLocationWithRedirectPath(
29+
val newLocation = requestor.updateLocationWithRedirectPath(
3030
"https://cloud.somewhere.com", "/subdir"
3131
)
3232
assertEquals("https://cloud.somewhere.com/subdir", newLocation)
3333
}
3434

3535
@Test
3636
fun `update location by replacing the relative path`() {
37-
val newLocation = remoteStatusOperation.updateLocationWithRedirectPath(
37+
val newLocation = requestor.updateLocationWithRedirectPath(
3838
"https://cloud.somewhere.com/some/other/subdir", "/subdir"
3939
)
4040
assertEquals("https://cloud.somewhere.com/subdir", newLocation)

0 commit comments

Comments
 (0)