mirror of
https://github.com/owncloud/android-library.git
synced 2025-06-06 15:36:45 +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