mirror of
https://github.com/owncloud/android-library.git
synced 2025-06-07 16:06:08 +00:00
Merge branch 'develop' into forbidden_characters_from_server
Conflicts: src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java
This commit is contained in:
commit
060ca75f17
@ -49,6 +49,7 @@ import android.net.Uri;
|
||||
|
||||
import com.owncloud.android.lib.common.OwnCloudCredentialsFactory.OwnCloudAnonymousCredentials;
|
||||
import com.owncloud.android.lib.common.accounts.AccountUtils;
|
||||
import com.owncloud.android.lib.common.network.RedirectionPath;
|
||||
import com.owncloud.android.lib.common.network.WebdavUtils;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||
@ -56,7 +57,7 @@ import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||
public class OwnCloudClient extends HttpClient {
|
||||
|
||||
private static final String TAG = OwnCloudClient.class.getSimpleName();
|
||||
private static final int MAX_REDIRECTIONS_COUNT = 3;
|
||||
public static final int MAX_REDIRECTIONS_COUNT = 3;
|
||||
private static final String PARAM_SINGLE_COOKIE_HEADER = "http.protocol.single-cookie-header";
|
||||
private static final boolean PARAM_SINGLE_COOKIE_HEADER_VALUE = true;
|
||||
|
||||
@ -171,13 +172,13 @@ public class OwnCloudClient extends HttpClient {
|
||||
*
|
||||
* The timeouts are both in milliseconds; 0 means 'infinite';
|
||||
* < 0 means 'do not change the default'
|
||||
*
|
||||
*
|
||||
* @param method HTTP method request.
|
||||
* @param readTimeout Timeout to set for data reception
|
||||
* @param connectionTimeout Timeout to set for connection establishment
|
||||
*/
|
||||
public int executeMethod(HttpMethodBase method, int readTimeout, int connectionTimeout)
|
||||
throws HttpException, IOException {
|
||||
public int executeMethod(HttpMethodBase method, int readTimeout, int connectionTimeout) throws IOException {
|
||||
|
||||
int oldSoTimeout = getParams().getSoTimeout();
|
||||
int oldConnectionTimeout = getHttpConnectionManager().getParams().getConnectionTimeout();
|
||||
try {
|
||||
@ -194,55 +195,53 @@ public class OwnCloudClient extends HttpClient {
|
||||
getHttpConnectionManager().getParams().setConnectionTimeout(oldConnectionTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int executeMethod(HttpMethod method) throws IOException, HttpException {
|
||||
try { // just to log
|
||||
boolean customRedirectionNeeded = false;
|
||||
|
||||
try {
|
||||
method.setFollowRedirects(mFollowRedirects);
|
||||
} catch (Exception e) {
|
||||
/*
|
||||
if (mFollowRedirects)
|
||||
Log_OC.d(TAG, "setFollowRedirects failed for " + method.getName()
|
||||
+ " method, custom redirection will be used if needed");
|
||||
*/
|
||||
customRedirectionNeeded = mFollowRedirects;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Requests the received method.
|
||||
*
|
||||
* Executes the method through the inherited HttpClient.executedMethod(method).
|
||||
*
|
||||
* @param method HTTP method request.
|
||||
*/
|
||||
@Override
|
||||
public int executeMethod(HttpMethod method) throws IOException {
|
||||
try {
|
||||
// Update User Agent
|
||||
HttpParams params = method.getParams();
|
||||
String userAgent = OwnCloudClientManagerFactory.getUserAgent();
|
||||
params.setParameter(HttpMethodParams.USER_AGENT, userAgent);
|
||||
|
||||
Log_OC.d(TAG + " #" + mInstanceNumber, "REQUEST " +
|
||||
method.getName() + " " + method.getPath());
|
||||
|
||||
Log_OC.d(TAG + " #" + mInstanceNumber, "REQUEST " +
|
||||
method.getName() + " " + method.getPath());
|
||||
|
||||
// logCookiesAtRequest(method.getRequestHeaders(), "before");
|
||||
// logCookiesAtState("before");
|
||||
|
||||
int status = super.executeMethod(method);
|
||||
|
||||
if (customRedirectionNeeded) {
|
||||
status = patchRedirection(status, method);
|
||||
}
|
||||
method.setFollowRedirects(false);
|
||||
|
||||
int status = super.executeMethod(method);
|
||||
|
||||
if (mFollowRedirects) {
|
||||
status = followRedirection(method).getLastStatus();
|
||||
}
|
||||
|
||||
// logCookiesAtRequest(method.getRequestHeaders(), "after");
|
||||
// logCookiesAtState("after");
|
||||
// logSetCookiesAtResponse(method.getResponseHeaders());
|
||||
|
||||
return status;
|
||||
|
||||
|
||||
return status;
|
||||
|
||||
} catch (IOException e) {
|
||||
Log_OC.d(TAG + " #" + mInstanceNumber, "Exception occurred", e);
|
||||
throw e;
|
||||
//Log_OC.d(TAG + " #" + mInstanceNumber, "Exception occurred", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private int patchRedirection(int status, HttpMethod method) throws HttpException, IOException {
|
||||
|
||||
public RedirectionPath followRedirection(HttpMethod method) throws IOException {
|
||||
int redirectionsCount = 0;
|
||||
int status = method.getStatusCode();
|
||||
RedirectionPath result = new RedirectionPath(status, MAX_REDIRECTIONS_COUNT);
|
||||
while (redirectionsCount < MAX_REDIRECTIONS_COUNT &&
|
||||
( status == HttpStatus.SC_MOVED_PERMANENTLY ||
|
||||
status == HttpStatus.SC_MOVED_TEMPORARILY ||
|
||||
@ -257,18 +256,20 @@ public class OwnCloudClient extends HttpClient {
|
||||
Log_OC.d(TAG + " #" + mInstanceNumber,
|
||||
"Location to redirect: " + location.getValue());
|
||||
|
||||
String locationStr = location.getValue();
|
||||
result.addLocation(locationStr);
|
||||
|
||||
// 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.releaseConnection();
|
||||
|
||||
method.setURI(new URI(location.getValue(), true));
|
||||
method.setURI(new URI(locationStr, true));
|
||||
Header destination = method.getRequestHeader("Destination");
|
||||
if (destination == null) {
|
||||
destination = method.getRequestHeader("destination");
|
||||
}
|
||||
if (destination != null) {
|
||||
String locationStr = location.getValue();
|
||||
int suffixIndex = locationStr.lastIndexOf(
|
||||
(mCredentials instanceof OwnCloudBearerCredentials) ?
|
||||
AccountUtils.ODAV_PATH :
|
||||
@ -284,6 +285,7 @@ public class OwnCloudClient extends HttpClient {
|
||||
method.setRequestHeader(destination);
|
||||
}
|
||||
status = super.executeMethod(method);
|
||||
result.addStatus(status);
|
||||
redirectionsCount++;
|
||||
|
||||
} else {
|
||||
@ -291,7 +293,7 @@ public class OwnCloudClient extends HttpClient {
|
||||
status = HttpStatus.SC_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -359,7 +361,10 @@ public class OwnCloudClient extends HttpClient {
|
||||
mFollowRedirects = followRedirects;
|
||||
}
|
||||
|
||||
|
||||
public boolean getFollowRedirects() {
|
||||
return mFollowRedirects;
|
||||
}
|
||||
|
||||
private void logCookiesAtRequest(Header[] headers, String when) {
|
||||
int counter = 0;
|
||||
for (int i=0; i<headers.length; i++) {
|
||||
|
127
src/com/owncloud/android/lib/common/network/RedirectionPath.java
Normal file
127
src/com/owncloud/android/lib/common/network/RedirectionPath.java
Normal file
@ -0,0 +1,127 @@
|
||||
/* ownCloud Android Library is available under MIT license
|
||||
*
|
||||
* @author David A. Velasco
|
||||
*
|
||||
* Copyright (C) 2015 ownCloud Inc.
|
||||
*
|
||||
* 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.common.network;
|
||||
|
||||
import org.apache.http.HttpStatus;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
|
||||
/**
|
||||
* Aggregate saving the list of URLs followed in a sequence of redirections during the exceution of a
|
||||
* {@link com.owncloud.android.lib.common.operations.RemoteOperation}, and the status codes corresponding to all
|
||||
* of them.
|
||||
*
|
||||
* The last status code saved corresponds to the first response not being a redirection, unless the sequence exceeds
|
||||
* the maximum length of redirections allowed by the {@link com.owncloud.android.lib.common.OwnCloudClient} instance
|
||||
* that ran the operation.
|
||||
*
|
||||
* If no redirection was followed, the last (and first) status code contained corresponds to the original URL in the
|
||||
* request.
|
||||
*/
|
||||
public class RedirectionPath {
|
||||
|
||||
private int[] mStatuses = null;
|
||||
|
||||
private int mLastStatus = -1;
|
||||
|
||||
private String[] mLocations = null;
|
||||
|
||||
private int mLastLocation = -1;
|
||||
private int maxRedirections;
|
||||
|
||||
/**
|
||||
* Public constructor.
|
||||
*
|
||||
* @param status Status code resulting of executing a request on the original URL.
|
||||
* @param maxRedirections Maximum number of redirections that will be contained.
|
||||
* @throws IllegalArgumentException If 'maxRedirections' is < 0
|
||||
*/
|
||||
public RedirectionPath(int status, int maxRedirections) {
|
||||
if (maxRedirections < 0) {
|
||||
throw new IllegalArgumentException("maxRedirections MUST BE zero or greater");
|
||||
}
|
||||
mStatuses = new int[maxRedirections + 1];
|
||||
Arrays.fill(mStatuses, -1);
|
||||
mStatuses[++mLastStatus] = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new location URL to the list of followed redirections.
|
||||
*
|
||||
* @param location URL extracted from a 'Location' header in a redirection.
|
||||
*/
|
||||
public void addLocation(String location) {
|
||||
if (mLocations == null) {
|
||||
mLocations = new String[mStatuses.length - 1];
|
||||
}
|
||||
if (mLastLocation < mLocations.length - 1) {
|
||||
mLocations[++mLastLocation] = location;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a new status code to the list of status corresponding to followed redirections.
|
||||
*
|
||||
* @param status Status code from the response of another followed redirection.
|
||||
*/
|
||||
public void addStatus(int status) {
|
||||
if (mLastStatus < mStatuses.length - 1) {
|
||||
mStatuses[++mLastStatus] = status;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Last status code saved.
|
||||
*/
|
||||
public int getLastStatus() {
|
||||
return mStatuses[mLastStatus];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Last location followed corresponding to a permanent redirection (status code 301).
|
||||
*/
|
||||
public String getLastPermanentLocation() {
|
||||
for (int i = mLastStatus; i >= 0; i--) {
|
||||
if (mStatuses[i] == HttpStatus.SC_MOVED_PERMANENTLY && i <= mLastLocation) {
|
||||
return mLocations[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Count of locations.
|
||||
*/
|
||||
public int getRedirectionsCount() {
|
||||
return mLastLocation + 1;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -62,11 +62,11 @@ import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
public class RemoteOperationResult implements Serializable {
|
||||
|
||||
/** Generated - should be refreshed every time the class changes!! */;
|
||||
private static final long serialVersionUID = -4184015692120731701L;
|
||||
private static final long serialVersionUID = -1909603208238358633L;
|
||||
|
||||
private static final String TAG = RemoteOperationResult.class.getSimpleName();
|
||||
|
||||
public enum ResultCode {
|
||||
public enum ResultCode {
|
||||
OK,
|
||||
OK_SSL,
|
||||
OK_NO_SSL,
|
||||
@ -115,6 +115,7 @@ public class RemoteOperationResult implements Serializable {
|
||||
private ResultCode mCode = ResultCode.UNKNOWN_ERROR;
|
||||
private String mRedirectedLocation;
|
||||
private String mAuthenticate;
|
||||
private String mLastPermanentLocation = null;
|
||||
|
||||
private ArrayList<Object> mData;
|
||||
|
||||
@ -433,4 +434,12 @@ public class RemoteOperationResult implements Serializable {
|
||||
return mAuthenticate;
|
||||
}
|
||||
|
||||
public String getLastPermanentLocation() {
|
||||
return mLastPermanentLocation;
|
||||
}
|
||||
|
||||
public void setLastPermanentLocation(String lastPermanentLocation) {
|
||||
mLastPermanentLocation = lastPermanentLocation;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
|
||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||
import com.owncloud.android.lib.common.network.RedirectionPath;
|
||||
import com.owncloud.android.lib.common.network.WebdavUtils;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
||||
@ -52,7 +53,10 @@ public class ExistenceCheckRemoteOperation extends RemoteOperation {
|
||||
private Context mContext;
|
||||
private boolean mSuccessIfAbsent;
|
||||
|
||||
|
||||
/** Sequence of redirections followed. Available only after executing the operation */
|
||||
private RedirectionPath mRedirectionPath = null;
|
||||
// TODO move to {@link RemoteOperation}, that needs a nice refactoring
|
||||
|
||||
/**
|
||||
* Full constructor. Success of the operation will depend upon the value of successIfAbsent.
|
||||
*
|
||||
@ -75,9 +79,13 @@ public class ExistenceCheckRemoteOperation extends RemoteOperation {
|
||||
}
|
||||
RemoteOperationResult result = null;
|
||||
HeadMethod head = null;
|
||||
boolean previousFollowRedirects = client.getFollowRedirects();
|
||||
try {
|
||||
head = new HeadMethod(client.getWebdavUri() + WebdavUtils.encodePath(mPath));
|
||||
int status = client.executeMethod(head, TIMEOUT, TIMEOUT);
|
||||
client.setFollowRedirects(false);
|
||||
client.executeMethod(head, TIMEOUT, TIMEOUT);
|
||||
mRedirectionPath = client.followRedirection(head);
|
||||
int status = mRedirectionPath.getLastStatus();
|
||||
client.exhaustResponse(head.getResponseBodyAsStream());
|
||||
boolean success = (status == HttpStatus.SC_OK && !mSuccessIfAbsent) ||
|
||||
(status == HttpStatus.SC_NOT_FOUND && mSuccessIfAbsent);
|
||||
@ -97,6 +105,7 @@ public class ExistenceCheckRemoteOperation extends RemoteOperation {
|
||||
} finally {
|
||||
if (head != null)
|
||||
head.releaseConnection();
|
||||
client.setFollowRedirects(previousFollowRedirects);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -109,4 +118,19 @@ public class ExistenceCheckRemoteOperation extends RemoteOperation {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the sequence of redirections followed during the execution of the operation.
|
||||
*
|
||||
* @return Sequence of redirections followed, if any, or NULL if the operation was not executed.
|
||||
*/
|
||||
public RedirectionPath getRedirectionPath() {
|
||||
return mRedirectionPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 'True' if the operation was executed and at least one redirection was followed.
|
||||
*/
|
||||
public boolean wasRedirected() {
|
||||
return (mRedirectionPath != null && mRedirectionPath.getRedirectionsCount() > 0);
|
||||
}
|
||||
}
|
||||
|
@ -131,6 +131,7 @@ public class RenameRemoteFileOperation extends RemoteOperation {
|
||||
if (move != null)
|
||||
move.releaseConnection();
|
||||
}
|
||||
|
||||
} else {
|
||||
result = new RemoteOperationResult(ResultCode.INVALID_CHARACTER_IN_NAME);
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ public class RemoveRemoteShareOperation extends RemoteOperation {
|
||||
delete = new DeleteMethod(client.getBaseUri() + ShareUtils.SHARING_API_PATH + id);
|
||||
|
||||
delete.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
|
||||
|
||||
|
||||
status = client.executeMethod(delete);
|
||||
|
||||
if(isSuccess(status)) {
|
||||
|
@ -103,9 +103,7 @@ public class GetRemoteStatusOperation extends RemoteOperation {
|
||||
);
|
||||
get.releaseConnection();
|
||||
get = new GetMethod(redirectedLocation);
|
||||
status = client.executeMethod(
|
||||
get, TRY_CONNECTION_TIMEOUT, TRY_CONNECTION_TIMEOUT
|
||||
);
|
||||
status = client.executeMethod(get, TRY_CONNECTION_TIMEOUT, TRY_CONNECTION_TIMEOUT);
|
||||
mLatestResult = new RemoteOperationResult(
|
||||
(status == HttpStatus.SC_OK),
|
||||
status,
|
||||
|
Loading…
x
Reference in New Issue
Block a user