From 9fc332eef9733ad1d857ea2b470b260b271fd3ca Mon Sep 17 00:00:00 2001 From: masensio Date: Tue, 2 Jun 2015 09:37:46 +0200 Subject: [PATCH 1/8] Filter only '/' character in user input when version of server is 8.1 or later --- .../android/lib/common/OwnCloudClient.java | 11 +++++++ .../files/CreateRemoteFolderOperation.java | 4 +-- .../lib/resources/files/FileUtils.java | 32 ++++++++++++------- .../files/MoveRemoteFileOperation.java | 3 +- .../files/RenameRemoteFileOperation.java | 3 +- .../lib/resources/status/OwnCloudVersion.java | 6 ++++ 6 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/com/owncloud/android/lib/common/OwnCloudClient.java b/src/com/owncloud/android/lib/common/OwnCloudClient.java index b6804708..83ec07ad 100644 --- a/src/com/owncloud/android/lib/common/OwnCloudClient.java +++ b/src/com/owncloud/android/lib/common/OwnCloudClient.java @@ -51,6 +51,7 @@ import com.owncloud.android.lib.common.OwnCloudCredentialsFactory.OwnCloudAnonym import com.owncloud.android.lib.common.accounts.AccountUtils; 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; public class OwnCloudClient extends HttpClient { @@ -67,6 +68,8 @@ public class OwnCloudClient extends HttpClient { private int mInstanceNumber = 0; private Uri mBaseUri; + + private OwnCloudVersion mVersion = null; /** * Constructor @@ -436,4 +439,12 @@ public class OwnCloudClient extends HttpClient { } + public void setOwnCloudVersion(String version){ + OwnCloudVersion ver = new OwnCloudVersion(version); + mVersion = ver; + } + + public OwnCloudVersion getOwnCloudVersion(){ + return mVersion; + } } diff --git a/src/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java b/src/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java index 0d248e6f..0bfbb453 100644 --- a/src/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java +++ b/src/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java @@ -24,7 +24,6 @@ package com.owncloud.android.lib.resources.files; -import org.apache.commons.httpclient.HttpStatus; import org.apache.jackrabbit.webdav.client.methods.MkColMethod; import com.owncloud.android.lib.common.OwnCloudClient; @@ -73,7 +72,8 @@ public class CreateRemoteFolderOperation extends RemoteOperation { @Override protected RemoteOperationResult run(OwnCloudClient client) { RemoteOperationResult result = null; - boolean noInvalidChars = FileUtils.isValidPath(mRemotePath); + boolean noInvalidChars = FileUtils.isValidPath(mRemotePath, + client.getOwnCloudVersion().isVersionWithForbiddenCharacters()); if (noInvalidChars) { result = createFolder(client); if (!result.isSuccess() && mCreateFullPath && diff --git a/src/com/owncloud/android/lib/resources/files/FileUtils.java b/src/com/owncloud/android/lib/resources/files/FileUtils.java index a6fd29f6..e04e3bbf 100644 --- a/src/com/owncloud/android/lib/resources/files/FileUtils.java +++ b/src/com/owncloud/android/lib/resources/files/FileUtils.java @@ -27,9 +27,12 @@ package com.owncloud.android.lib.resources.files; import java.io.File; import com.owncloud.android.lib.common.utils.Log_OC; +import com.owncloud.android.lib.resources.status.OwnCloudVersion; public class FileUtils { + private static final String TAG = FileUtils.class.getSimpleName(); + public static final String PATH_SEPARATOR = "/"; @@ -40,39 +43,44 @@ public class FileUtils { } /** - * Validate the fileName to detect if contains any forbidden character: / , \ , < , > , : , " , | , ? , * + * Validate the fileName to detect if contains any forbidden character: / , \ , < , > , + * : , " , | , ? , * * @param fileName + * @param versionSupportsForbiddenChars * @return */ - public static boolean isValidName(String fileName) { + public static boolean isValidName(String fileName, boolean versionSupportsForbiddenChars) { boolean result = true; - Log_OC.d("FileUtils", "fileName =======" + fileName); - if (fileName.contains(PATH_SEPARATOR) || + Log_OC.d(TAG, "fileName =======" + fileName); + if ( (versionSupportsForbiddenChars && fileName.contains(PATH_SEPARATOR)) || + (!versionSupportsForbiddenChars && ( fileName.contains(PATH_SEPARATOR) || fileName.contains("\\") || fileName.contains("<") || fileName.contains(">") || - fileName.contains(":") || fileName.contains("\"") || fileName.contains("|") || - fileName.contains("?") || fileName.contains("*")) { + fileName.contains(":") || fileName.contains("\"") || fileName.contains("|") || + fileName.contains("?") || fileName.contains("*") ) ) ) { + result = false; } return result; } /** - * Validate the path to detect if contains any forbidden character: \ , < , > , : , " , | , ? , * + * Validate the path to detect if contains any forbidden character: \ , < , > , : , " , | , + * ? , * * @param path * @return */ - public static boolean isValidPath(String path) { + public static boolean isValidPath(String path, boolean versionSupportsForbidenChars) { boolean result = true; - Log_OC.d("FileUtils", "path ....... " + path); - if (path.contains("\\") || path.contains("<") || path.contains(">") || + Log_OC.d(TAG, "path ....... " + path); + if (!versionSupportsForbidenChars && + (path.contains("\\") || path.contains("<") || path.contains(">") || path.contains(":") || path.contains("\"") || path.contains("|") || - path.contains("?") || path.contains("*")) { + path.contains("?") || path.contains("*") ) ){ result = false; } return result; } - } diff --git a/src/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java index 1eb88765..f1535eb1 100644 --- a/src/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java @@ -89,7 +89,8 @@ public class MoveRemoteFileOperation extends RemoteOperation { protected RemoteOperationResult run(OwnCloudClient client) { /// check parameters - if (!FileUtils.isValidPath(mTargetRemotePath)) { + if (!FileUtils.isValidPath(mTargetRemotePath, + client.getOwnCloudVersion().isVersionWithForbiddenCharacters())) { return new RemoteOperationResult(ResultCode.INVALID_CHARACTER_IN_NAME); } diff --git a/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java index 4dc4c2c2..fa928b7c 100644 --- a/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java @@ -89,7 +89,8 @@ public class RenameRemoteFileOperation extends RemoteOperation { LocalMoveMethod move = null; - boolean noInvalidChars = FileUtils.isValidPath(mNewRemotePath); + boolean noInvalidChars = FileUtils.isValidPath(mNewRemotePath, + client.getOwnCloudVersion().isVersionWithForbiddenCharacters()); if (noInvalidChars) { try { diff --git a/src/com/owncloud/android/lib/resources/status/OwnCloudVersion.java b/src/com/owncloud/android/lib/resources/status/OwnCloudVersion.java index eb56f2d2..aa89cf3d 100644 --- a/src/com/owncloud/android/lib/resources/status/OwnCloudVersion.java +++ b/src/com/owncloud/android/lib/resources/status/OwnCloudVersion.java @@ -38,6 +38,8 @@ public class OwnCloudVersion implements Comparable { 0x04050000); public static final int MINIMUM_VERSION_FOR_SHARING_API = 0x05001B00; // 5.0.27 + + public static final int MINIMUM_VERSION_WITH_FORBIDDEN_CHARS = 0x08010000; // 8.1 private static final int MAX_DOTS = 3; @@ -120,6 +122,10 @@ public class OwnCloudVersion implements Comparable { public boolean isSharedSupported() { return (mVersion >= MINIMUM_VERSION_FOR_SHARING_API); } + + public boolean isVersionWithForbiddenCharacters() { + return (mVersion >= MINIMUM_VERSION_WITH_FORBIDDEN_CHARS); + } } From 2b09aa2a89eb38a9abc8e98d3a1bc356f5872a1e Mon Sep 17 00:00:00 2001 From: masensio Date: Tue, 2 Jun 2015 13:07:43 +0200 Subject: [PATCH 2/8] Parse and show the error of invalid characters coming from the server side. Show new message in CreationFolder --- .../InvalidCharacterExceptionParser.java | 144 ++++++++++++++++++ .../operations/RemoteOperationResult.java | 64 ++++++-- .../files/CreateRemoteFolderOperation.java | 14 +- 3 files changed, 209 insertions(+), 13 deletions(-) create mode 100644 src/com/owncloud/android/lib/common/operations/InvalidCharacterExceptionParser.java diff --git a/src/com/owncloud/android/lib/common/operations/InvalidCharacterExceptionParser.java b/src/com/owncloud/android/lib/common/operations/InvalidCharacterExceptionParser.java new file mode 100644 index 00000000..7f72efe9 --- /dev/null +++ b/src/com/owncloud/android/lib/common/operations/InvalidCharacterExceptionParser.java @@ -0,0 +1,144 @@ + +/* ownCloud Android Library is available under MIT license + * 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.operations; + +import android.util.Xml; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; + +import java.io.IOException; +import java.io.InputStream; + +/** + * Parser for Invalid Character server exception + * @author masensio on 02/06/2015. + */ +public class InvalidCharacterExceptionParser { + + private static final String EXCEPTION_STRING = "OC\\Connector\\Sabre\\Exception\\InvalidPath"; + + // No namespaces + private static final String ns = null; + + // Nodes for XML Parser + private static final String NODE_ERROR = "d:error"; + private static final String NODE_EXCEPTION = "s:exception"; + /** + * Parse is as response of Share API + * @param is + * @return if The exception is an Invalid Char Exception + * @throws XmlPullParserException + * @throws IOException + */ + public boolean parseXMLResponse(InputStream is) throws XmlPullParserException, + IOException { + boolean result = false; + + try { + // XMLPullParser + XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); + factory.setNamespaceAware(true); + + XmlPullParser parser = Xml.newPullParser(); + parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); + parser.setInput(is, null); + parser.nextTag(); + result = readError(parser); + + } finally { + is.close(); + } + return result; + } + + /** + * Parse OCS node + * @param parser + * @return List of ShareRemoteFiles + * @throws XmlPullParserException + * @throws IOException + */ + private boolean readError (XmlPullParser parser) throws XmlPullParserException, IOException { + String exception = ""; + parser.require(XmlPullParser.START_TAG, ns , NODE_ERROR); + while (parser.next() != XmlPullParser.END_TAG) { + if (parser.getEventType() != XmlPullParser.START_TAG) { + continue; + } + String name = parser.getName(); + // read NODE_EXCEPTION + if (name.equalsIgnoreCase(NODE_EXCEPTION)) { + exception = readText(parser); + } else { + skip(parser); + } + + } + return exception.equalsIgnoreCase(EXCEPTION_STRING); + + + } + + /** + * Skip tags in parser procedure + * @param parser + * @throws XmlPullParserException + * @throws IOException + */ + private void skip(XmlPullParser parser) throws XmlPullParserException, IOException { + if (parser.getEventType() != XmlPullParser.START_TAG) { + throw new IllegalStateException(); + } + int depth = 1; + while (depth != 0) { + switch (parser.next()) { + case XmlPullParser.END_TAG: + depth--; + break; + case XmlPullParser.START_TAG: + depth++; + break; + } + } + } + + /** + * Read the text from a node + * @param parser + * @return Text of the node + * @throws IOException + * @throws XmlPullParserException + */ + private String readText(XmlPullParser parser) throws IOException, XmlPullParserException { + String result = ""; + if (parser.next() == XmlPullParser.TEXT) { + result = parser.getText(); + parser.nextTag(); + } + return result; + } +} diff --git a/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java b/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java index 56492955..89848ac9 100644 --- a/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java +++ b/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java @@ -24,7 +24,9 @@ package com.owncloud.android.lib.common.operations; +import java.io.ByteArrayInputStream; import java.io.IOException; +import java.io.InputStream; import java.io.Serializable; import java.net.MalformedURLException; import java.net.SocketException; @@ -40,6 +42,7 @@ import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpStatus; import org.apache.jackrabbit.webdav.DavException; import org.json.JSONException; +import org.xmlpull.v1.XmlPullParserException; import android.accounts.Account; import android.accounts.AccountsException; @@ -47,6 +50,7 @@ import android.accounts.AccountsException; import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException; import com.owncloud.android.lib.common.network.CertificateCombinedException; import com.owncloud.android.lib.common.utils.Log_OC; +import com.owncloud.android.lib.resources.shares.ShareXMLParser; /** @@ -103,7 +107,8 @@ public class RemoteOperationResult implements Serializable { SHARE_FORBIDDEN, OK_REDIRECT_TO_NON_SECURE_CONNECTION, INVALID_MOVE_INTO_DESCENDANT, - PARTIAL_MOVE_DONE + PARTIAL_MOVE_DONE, + INVALID_CHARACTER_DETECT_IN_SERVER } private boolean mSuccess = false; @@ -117,7 +122,9 @@ public class RemoteOperationResult implements Serializable { public RemoteOperationResult(ResultCode code) { mCode = code; - mSuccess = (code == ResultCode.OK || code == ResultCode.OK_SSL || code == ResultCode.OK_NO_SSL || code == ResultCode.OK_REDIRECT_TO_NON_SECURE_CONNECTION); + mSuccess = (code == ResultCode.OK || code == ResultCode.OK_SSL || + code == ResultCode.OK_NO_SSL || + code == ResultCode.OK_REDIRECT_TO_NON_SECURE_CONNECTION); mData = null; } @@ -147,10 +154,11 @@ public class RemoteOperationResult implements Serializable { break; case HttpStatus.SC_FORBIDDEN: mCode = ResultCode.FORBIDDEN; - break; + break; default: mCode = ResultCode.UNHANDLED_HTTP_CODE; - Log_OC.d(TAG, "RemoteOperationResult has processed UNHANDLED_HTTP_CODE: " + httpCode); + Log_OC.d(TAG, "RemoteOperationResult has processed UNHANDLED_HTTP_CODE: " + + httpCode); } } } @@ -171,7 +179,38 @@ public class RemoteOperationResult implements Serializable { } } } - } + } + + public RemoteOperationResult(boolean success, String bodyResponse, int httpCode) { + mSuccess = success; + mHttpCode = httpCode; + + if (success) { + mCode = ResultCode.OK; + + } else if (httpCode > 0) { + switch (httpCode) { + case HttpStatus.SC_BAD_REQUEST: + + InputStream is = new ByteArrayInputStream(bodyResponse.getBytes()); + InvalidCharacterExceptionParser xmlParser = new InvalidCharacterExceptionParser(); + try { + if (xmlParser.parseXMLResponse(is)) + mCode = ResultCode.INVALID_CHARACTER_DETECT_IN_SERVER; + + } catch (Exception e) { + mCode = ResultCode.UNHANDLED_HTTP_CODE; + Log_OC.e(TAG, "Exception reading exception from server", e); + } + break; + default: + mCode = ResultCode.UNHANDLED_HTTP_CODE; + Log_OC.d(TAG, "RemoteOperationResult has processed UNHANDLED_HTTP_CODE: " + + httpCode); + } + } + + } public RemoteOperationResult(Exception e) { mException = e; @@ -264,7 +303,8 @@ public class RemoteOperationResult implements Serializable { } Throwable cause = mException.getCause(); Throwable previousCause = null; - while (cause != null && cause != previousCause && !(cause instanceof CertificateCombinedException)) { + while (cause != null && cause != previousCause && + !(cause instanceof CertificateCombinedException)) { previousCause = cause; cause = cause.getCause(); } @@ -314,8 +354,10 @@ public class RemoteOperationResult implements Serializable { return "Unrecovered transport exception"; } else if (mException instanceof AccountNotFoundException) { - Account failedAccount = ((AccountNotFoundException)mException).getFailedAccount(); - return mException.getMessage() + " (" + (failedAccount != null ? failedAccount.name : "NULL") + ")"; + Account failedAccount = + ((AccountNotFoundException)mException).getFailedAccount(); + return mException.getMessage() + " (" + + (failedAccount != null ? failedAccount.name : "NULL") + ")"; } else if (mException instanceof AccountsException) { return "Exception while using account"; @@ -352,7 +394,8 @@ public class RemoteOperationResult implements Serializable { return "The file name contains an forbidden character"; } - return "Operation finished with HTTP status code " + mHttpCode + " (" + (isSuccess() ? "success" : "fail") + ")"; + return "Operation finished with HTTP status code " + mHttpCode + " (" + + (isSuccess() ? "success" : "fail") + ")"; } @@ -384,7 +427,8 @@ public class RemoteOperationResult implements Serializable { * @return boolean true/false */ public boolean isNonSecureRedirection() { - return (mRedirectedLocation != null && !(mRedirectedLocation.toLowerCase().startsWith("https://"))); + return (mRedirectedLocation != null && + !(mRedirectedLocation.toLowerCase().startsWith("https://"))); } public String getAuthenticateHeader() { diff --git a/src/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java b/src/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java index 0bfbb453..89078ba3 100644 --- a/src/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java +++ b/src/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java @@ -28,6 +28,7 @@ import org.apache.jackrabbit.webdav.client.methods.MkColMethod; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.network.WebdavUtils; +import com.owncloud.android.lib.common.operations.InvalidCharacterExceptionParser; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; @@ -98,9 +99,16 @@ public class CreateRemoteFolderOperation extends RemoteOperation { try { mkcol = new MkColMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath)); int status = client.executeMethod(mkcol, READ_TIMEOUT, CONNECTION_TIMEOUT); - result = new RemoteOperationResult(mkcol.succeeded(), status, mkcol.getResponseHeaders()); - Log_OC.d(TAG, "Create directory " + mRemotePath + ": " + result.getLogMessage()); - client.exhaustResponse(mkcol.getResponseBodyAsStream()); + if ( status == 400 ) { + result = new RemoteOperationResult(mkcol.succeeded(), + mkcol.getResponseBodyAsString(), status); + Log_OC.d(TAG, mkcol.getResponseBodyAsString()); + + } else { + result = new RemoteOperationResult(mkcol.succeeded(), status, mkcol.getResponseHeaders()); + Log_OC.d(TAG, "Create directory " + mRemotePath + ": " + result.getLogMessage()); + } + client.exhaustResponse(mkcol.getResponseBodyAsStream()); } catch (Exception e) { result = new RemoteOperationResult(e); From 16c91473834c52e1493cb39c38654930e20b42a3 Mon Sep 17 00:00:00 2001 From: masensio Date: Wed, 3 Jun 2015 00:32:19 +0200 Subject: [PATCH 3/8] Parse and show the error of invalid characters coming from the server side: Move, Rename, Uploads --- .../operations/RemoteOperationResult.java | 10 ++++----- .../ChunkedUploadRemoteFileOperation.java | 17 +++++++++----- .../files/MoveRemoteFileOperation.java | 22 +++++++++++-------- .../files/RenameRemoteFileOperation.java | 20 ++++++++++------- .../files/UploadRemoteFileOperation.java | 15 +++++++++---- 5 files changed, 51 insertions(+), 33 deletions(-) diff --git a/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java b/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java index 89848ac9..2d9d957f 100644 --- a/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java +++ b/src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java @@ -42,7 +42,6 @@ import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpStatus; import org.apache.jackrabbit.webdav.DavException; import org.json.JSONException; -import org.xmlpull.v1.XmlPullParserException; import android.accounts.Account; import android.accounts.AccountsException; @@ -50,7 +49,6 @@ import android.accounts.AccountsException; import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException; import com.owncloud.android.lib.common.network.CertificateCombinedException; import com.owncloud.android.lib.common.utils.Log_OC; -import com.owncloud.android.lib.resources.shares.ShareXMLParser; /** @@ -64,10 +62,10 @@ import com.owncloud.android.lib.resources.shares.ShareXMLParser; public class RemoteOperationResult implements Serializable { /** Generated - should be refreshed every time the class changes!! */; - private static final long serialVersionUID = -9003837206000993465L; - - private static final String TAG = "RemoteOperationResult"; - + private static final long serialVersionUID = -4184015692120731701L; + + private static final String TAG = RemoteOperationResult.class.getSimpleName(); + public enum ResultCode { OK, OK_SSL, diff --git a/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java index 15284adb..1ae71bd8 100644 --- a/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java @@ -46,7 +46,7 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation private static final String OC_CHUNKED_HEADER = "OC-Chunked"; private static final String TAG = ChunkedUploadRemoteFileOperation.class.getSimpleName(); - public ChunkedUploadRemoteFileOperation(String storagePath, String remotePath, String mimeType) { + public ChunkedUploadRemoteFileOperation(String storagePath, String remotePath, String mimeType){ super(storagePath, remotePath, mimeType); } @@ -61,17 +61,21 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation raf = new RandomAccessFile(file, "r"); channel = raf.getChannel(); mEntity = new ChunkFromFileChannelRequestEntity(channel, mMimeType, CHUNK_SIZE, file); - //((ProgressiveDataTransferer)mEntity).addDatatransferProgressListeners(getDataTransferListeners()); + //((ProgressiveDataTransferer)mEntity). + // addDatatransferProgressListeners(getDataTransferListeners()); synchronized (mDataTransferListeners) { - ((ProgressiveDataTransferer)mEntity).addDatatransferProgressListeners(mDataTransferListeners); + ((ProgressiveDataTransferer)mEntity) + .addDatatransferProgressListeners(mDataTransferListeners); } long offset = 0; - String uriPrefix = client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath) + "-chunking-" + Math.abs((new Random()).nextInt(9000)+1000) + "-" ; + String uriPrefix = client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath) + + "-chunking-" + Math.abs((new Random()).nextInt(9000)+1000) + "-" ; long chunkCount = (long) Math.ceil((double)file.length() / CHUNK_SIZE); for (int chunkIndex = 0; chunkIndex < chunkCount ; chunkIndex++, offset += CHUNK_SIZE) { if (mPutMethod != null) { - mPutMethod.releaseConnection(); // let the connection available for other methods + mPutMethod.releaseConnection(); // let the connection available + // for other methods } mPutMethod = new PutMethod(uriPrefix + chunkCount + "-" + chunkIndex); mPutMethod.addRequestHeader(OC_CHUNKED_HEADER, OC_CHUNKED_HEADER); @@ -80,7 +84,8 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation mPutMethod.setRequestEntity(mEntity); status = client.executeMethod(mPutMethod); client.exhaustResponse(mPutMethod.getResponseBodyAsStream()); - Log_OC.d(TAG, "Upload of " + mLocalPath + " to " + mRemotePath + ", chunk index " + chunkIndex + ", count " + chunkCount + ", HTTP result status " + status); + Log_OC.d(TAG, "Upload of " + mLocalPath + " to " + mRemotePath + ", chunk index " + + chunkIndex + ", count " + chunkCount + ", HTTP result status " + status); if (!isSuccess(status)) break; } diff --git a/src/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java index f1535eb1..c2fb651a 100644 --- a/src/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java @@ -39,6 +39,7 @@ import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; +import com.owncloud.android.lib.common.utils.Log_OC; /** @@ -129,15 +130,18 @@ public class MoveRemoteFileOperation extends RemoteOperation { /// for other errors that could be explicitly handled, check first: /// http://www.webdav.org/specs/rfc4918.html#rfc.section.9.9.4 - } else { - - result = new RemoteOperationResult( - isSuccess(status), // move.succeeded()? trustful? - status, - move.getResponseHeaders() - ); - client.exhaustResponse(move.getResponseBodyAsStream()); - } + } else if (status == 400) { + result = new RemoteOperationResult(move.succeeded(), + move.getResponseBodyAsString(), status); + Log_OC.d(TAG, move.getResponseBodyAsString()); + } else { + result = new RemoteOperationResult( + isSuccess(status), // move.succeeded()? trustful? + status, + move.getResponseHeaders() + ); + client.exhaustResponse(move.getResponseBodyAsStream()); + } Log.i(TAG, "Move " + mSrcRemotePath + " to " + mTargetRemotePath + ": " + result.getLogMessage()); diff --git a/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java index fa928b7c..7f449560 100644 --- a/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java @@ -94,11 +94,9 @@ public class RenameRemoteFileOperation extends RemoteOperation { if (noInvalidChars) { try { - if (mNewName.equals(mOldName)) { return new RemoteOperationResult(ResultCode.OK); } - // check if a file with the new name already exists if (client.existsFile(mNewRemotePath)) { @@ -109,12 +107,18 @@ public class RenameRemoteFileOperation extends RemoteOperation { WebdavUtils.encodePath(mOldRemotePath), client.getWebdavUri() + WebdavUtils.encodePath(mNewRemotePath)); int status = client.executeMethod(move, RENAME_READ_TIMEOUT, RENAME_CONNECTION_TIMEOUT); - - move.getResponseBodyAsString(); // exhaust response, although not interesting - result = new RemoteOperationResult(move.succeeded(), status, move.getResponseHeaders()); - Log_OC.i(TAG, "Rename " + mOldRemotePath + " to " + mNewRemotePath + ": " + - result.getLogMessage()); - + + if (status == 400) { + result = new RemoteOperationResult(move.succeeded(), + move.getResponseBodyAsString(), status); + Log_OC.d(TAG, move.getResponseBodyAsString()); + } else { + move.getResponseBodyAsString(); // exhaust response, although not interesting + result = new RemoteOperationResult(move.succeeded(), status, + move.getResponseHeaders()); + Log_OC.i(TAG, "Rename " + mOldRemotePath + " to " + mNewRemotePath + ": " + + result.getLogMessage()); + } } catch (Exception e) { result = new RemoteOperationResult(e); Log_OC.e(TAG, "Rename " + mOldRemotePath + " to " + diff --git a/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java index 9043fe36..e3b2ff63 100644 --- a/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java @@ -43,6 +43,7 @@ import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.operations.OperationCancelledException; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; +import com.owncloud.android.lib.common.utils.Log_OC; /** * Remote operation performing the upload of a remote file to the ownCloud server. @@ -53,6 +54,8 @@ import com.owncloud.android.lib.common.operations.RemoteOperationResult; public class UploadRemoteFileOperation extends RemoteOperation { + private static final String TAG = UploadRemoteFileOperation.class.getSimpleName(); + protected static final String OC_TOTAL_LENGTH_HEADER = "OC-Total-Length"; protected String mLocalPath; @@ -87,10 +90,14 @@ public class UploadRemoteFileOperation extends RemoteOperation { } int status = uploadFile(client); - - result = new RemoteOperationResult(isSuccess(status), status, - (mPutMethod != null ? mPutMethod.getResponseHeaders() : null)); - + if (status == 400) { + result = new RemoteOperationResult(isSuccess(status), + mPutMethod.getResponseBodyAsString(), status); + Log_OC.d(TAG, mPutMethod.getResponseBodyAsString()); + } else { + result = new RemoteOperationResult(isSuccess(status), status, + (mPutMethod != null ? mPutMethod.getResponseHeaders() : null)); + } } catch (Exception e) { // TODO something cleaner with cancellations if (mCancellationRequested.get()) { From b8a3eb059c2c139a64876ab0191d72c24ab6f3ee Mon Sep 17 00:00:00 2001 From: masensio Date: Wed, 3 Jun 2015 11:09:32 +0200 Subject: [PATCH 4/8] Remove exhaust response in RenameRemoteFileOperation --- .../files/RenameRemoteFileOperation.java | 70 ++++++++++--------- 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java index 7f449560..4f27cb69 100644 --- a/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java @@ -93,42 +93,44 @@ public class RenameRemoteFileOperation extends RemoteOperation { client.getOwnCloudVersion().isVersionWithForbiddenCharacters()); if (noInvalidChars) { - try { - if (mNewName.equals(mOldName)) { - return new RemoteOperationResult(ResultCode.OK); - } - - // check if a file with the new name already exists - if (client.existsFile(mNewRemotePath)) { - return new RemoteOperationResult(ResultCode.INVALID_OVERWRITE); - } - - move = new LocalMoveMethod( client.getWebdavUri() + - WebdavUtils.encodePath(mOldRemotePath), - client.getWebdavUri() + WebdavUtils.encodePath(mNewRemotePath)); - int status = client.executeMethod(move, RENAME_READ_TIMEOUT, RENAME_CONNECTION_TIMEOUT); + try { + if (mNewName.equals(mOldName)) { + return new RemoteOperationResult(ResultCode.OK); + } - if (status == 400) { - result = new RemoteOperationResult(move.succeeded(), - move.getResponseBodyAsString(), status); - Log_OC.d(TAG, move.getResponseBodyAsString()); - } else { - move.getResponseBodyAsString(); // exhaust response, although not interesting - result = new RemoteOperationResult(move.succeeded(), status, - move.getResponseHeaders()); - Log_OC.i(TAG, "Rename " + mOldRemotePath + " to " + mNewRemotePath + ": " + - result.getLogMessage()); + // check if a file with the new name already exists + if (client.existsFile(mNewRemotePath)) { + return new RemoteOperationResult(ResultCode.INVALID_OVERWRITE); + } + + move = new LocalMoveMethod( client.getWebdavUri() + + WebdavUtils.encodePath(mOldRemotePath), + client.getWebdavUri() + WebdavUtils.encodePath(mNewRemotePath)); + int status = client.executeMethod(move, RENAME_READ_TIMEOUT, + RENAME_CONNECTION_TIMEOUT); + + if (status == 400) { + result = new RemoteOperationResult(move.succeeded(), + move.getResponseBodyAsString(), status); + Log_OC.d(TAG, move.getResponseBodyAsString()); + } else { + client.exhaustResponse(move.getResponseBodyAsStream());//exhaust response, + // although not interesting + result = new RemoteOperationResult(move.succeeded(), status, + move.getResponseHeaders()); + Log_OC.i(TAG, "Rename " + mOldRemotePath + " to " + mNewRemotePath + ": " + + result.getLogMessage()); + } + } catch (Exception e) { + result = new RemoteOperationResult(e); + Log_OC.e(TAG, "Rename " + mOldRemotePath + " to " + + ((mNewRemotePath==null) ? mNewName : mNewRemotePath) + ": " + + result.getLogMessage(), e); + + } finally { + if (move != null) + move.releaseConnection(); } - } catch (Exception e) { - result = new RemoteOperationResult(e); - Log_OC.e(TAG, "Rename " + mOldRemotePath + " to " + - ((mNewRemotePath==null) ? mNewName : mNewRemotePath) + ": " + - result.getLogMessage(), e); - - } finally { - if (move != null) - move.releaseConnection(); - } } else { result = new RemoteOperationResult(ResultCode.INVALID_CHARACTER_IN_NAME); } From 4ca0ff2203a84173dca984632a1131170a169f08 Mon Sep 17 00:00:00 2001 From: masensio Date: Wed, 3 Jun 2015 11:09:58 +0200 Subject: [PATCH 5/8] Parse error 500 and InvalidPathException for Uploads --- .../InvalidCharacterExceptionParser.java | 8 +++--- .../ChunkedUploadRemoteFileOperation.java | 25 +++++++++++++++-- .../files/UploadRemoteFileOperation.java | 27 ++++++++++++++++--- 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/src/com/owncloud/android/lib/common/operations/InvalidCharacterExceptionParser.java b/src/com/owncloud/android/lib/common/operations/InvalidCharacterExceptionParser.java index 7f72efe9..63d28319 100644 --- a/src/com/owncloud/android/lib/common/operations/InvalidCharacterExceptionParser.java +++ b/src/com/owncloud/android/lib/common/operations/InvalidCharacterExceptionParser.java @@ -35,11 +35,12 @@ import java.io.InputStream; /** * Parser for Invalid Character server exception - * @author masensio on 02/06/2015. + * @author masensio */ public class InvalidCharacterExceptionParser { private static final String EXCEPTION_STRING = "OC\\Connector\\Sabre\\Exception\\InvalidPath"; + private static final String EXCEPTION_UPLOAD_STRING = "OCP\\Files\\InvalidPathException"; // No namespaces private static final String ns = null; @@ -48,7 +49,7 @@ public class InvalidCharacterExceptionParser { private static final String NODE_ERROR = "d:error"; private static final String NODE_EXCEPTION = "s:exception"; /** - * Parse is as response of Share API + * Parse is as an Invalid Path Exception * @param is * @return if The exception is an Invalid Char Exception * @throws XmlPullParserException @@ -98,7 +99,8 @@ public class InvalidCharacterExceptionParser { } } - return exception.equalsIgnoreCase(EXCEPTION_STRING); + return exception.equalsIgnoreCase(EXCEPTION_STRING) || + exception.equalsIgnoreCase(EXCEPTION_UPLOAD_STRING); } diff --git a/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java index 1ae71bd8..7ab9e2d8 100644 --- a/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java @@ -24,8 +24,10 @@ package com.owncloud.android.lib.resources.files; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.io.RandomAccessFile; import java.nio.channels.FileChannel; import java.util.Random; @@ -37,6 +39,8 @@ import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.network.ChunkFromFileChannelRequestEntity; import com.owncloud.android.lib.common.network.ProgressiveDataTransferer; import com.owncloud.android.lib.common.network.WebdavUtils; +import com.owncloud.android.lib.common.operations.InvalidCharacterExceptionParser; +import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.utils.Log_OC; @@ -83,9 +87,26 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation ((ChunkFromFileChannelRequestEntity) mEntity).setOffset(offset); mPutMethod.setRequestEntity(mEntity); status = client.executeMethod(mPutMethod); + + // TODO: Detect INVALID_CHARACTER_DETECT_IN SERVER in a better way? + if (status == 400 || status == 500) { + InvalidCharacterExceptionParser xmlParser = new InvalidCharacterExceptionParser(); + InputStream is = new ByteArrayInputStream( + mPutMethod.getResponseBodyAsString().getBytes()); + try { + mForbiddenCharsInServer = xmlParser.parseXMLResponse(is); + + } catch (Exception e) { + mForbiddenCharsInServer = false; + Log_OC.e(TAG, "Exception reading exception from server", e); + } + } + client.exhaustResponse(mPutMethod.getResponseBodyAsStream()); - Log_OC.d(TAG, "Upload of " + mLocalPath + " to " + mRemotePath + ", chunk index " + - chunkIndex + ", count " + chunkCount + ", HTTP result status " + status); + Log_OC.d(TAG, "Upload of " + mLocalPath + " to " + mRemotePath + + ", chunk index " + chunkIndex + ", count " + chunkCount + + ", HTTP result status " + status); + if (!isSuccess(status)) break; } diff --git a/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java index e3b2ff63..9fcd6515 100644 --- a/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java @@ -24,8 +24,10 @@ package com.owncloud.android.lib.resources.files; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.util.HashSet; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; @@ -40,6 +42,7 @@ import com.owncloud.android.lib.common.network.FileRequestEntity; import com.owncloud.android.lib.common.network.OnDatatransferProgressListener; import com.owncloud.android.lib.common.network.ProgressiveDataTransferer; import com.owncloud.android.lib.common.network.WebdavUtils; +import com.owncloud.android.lib.common.operations.InvalidCharacterExceptionParser; import com.owncloud.android.lib.common.operations.OperationCancelledException; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; @@ -62,6 +65,7 @@ public class UploadRemoteFileOperation extends RemoteOperation { protected String mRemotePath; protected String mMimeType; protected PutMethod mPutMethod = null; + protected boolean mForbiddenCharsInServer = false; private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false); protected Set mDataTransferListeners = new HashSet(); @@ -90,10 +94,10 @@ public class UploadRemoteFileOperation extends RemoteOperation { } int status = uploadFile(client); - if (status == 400) { - result = new RemoteOperationResult(isSuccess(status), - mPutMethod.getResponseBodyAsString(), status); - Log_OC.d(TAG, mPutMethod.getResponseBodyAsString()); + // TODO: Detect INVALID_CHARACTER_DETECT_IN SERVER in a better way? + if (mForbiddenCharsInServer){ + result = new RemoteOperationResult( + RemoteOperationResult.ResultCode.INVALID_CHARACTER_DETECT_IN_SERVER); } else { result = new RemoteOperationResult(isSuccess(status), status, (mPutMethod != null ? mPutMethod.getResponseHeaders() : null)); @@ -127,6 +131,21 @@ public class UploadRemoteFileOperation extends RemoteOperation { mPutMethod.addRequestHeader(OC_TOTAL_LENGTH_HEADER, String.valueOf(f.length())); mPutMethod.setRequestEntity(mEntity); status = client.executeMethod(mPutMethod); + + // TODO: Detect INVALID_CHARACTER_DETECT_IN SERVER in a better way? + if (status == 400 || status == 500) { + InvalidCharacterExceptionParser xmlParser = new InvalidCharacterExceptionParser(); + InputStream is = new ByteArrayInputStream( + mPutMethod.getResponseBodyAsString().getBytes()); + try { + mForbiddenCharsInServer = xmlParser.parseXMLResponse(is); + + } catch (Exception e) { + mForbiddenCharsInServer = false; + Log_OC.e(TAG, "Exception reading exception from server", e); + } + } + client.exhaustResponse(mPutMethod.getResponseBodyAsStream()); } finally { From 1811be1b52a5d80a70eb6a9eab93201cb8063af1 Mon Sep 17 00:00:00 2001 From: masensio Date: Tue, 16 Jun 2015 10:39:40 +0200 Subject: [PATCH 6/8] Prevent NullPointException when OwncloudVersion is null in CreateRemoteFolderOperation --- .../files/CreateRemoteFolderOperation.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java b/src/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java index 89078ba3..79a7de2f 100644 --- a/src/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java +++ b/src/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java @@ -28,12 +28,11 @@ import org.apache.jackrabbit.webdav.client.methods.MkColMethod; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.network.WebdavUtils; -import com.owncloud.android.lib.common.operations.InvalidCharacterExceptionParser; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; import com.owncloud.android.lib.common.utils.Log_OC; - +import com.owncloud.android.lib.resources.status.OwnCloudVersion; /** @@ -58,7 +57,8 @@ public class CreateRemoteFolderOperation extends RemoteOperation { * Constructor * * @param remotePath Full path to the new directory to create in the remote server. - * @param createFullPath 'True' means that all the ancestor folders should be created if don't exist yet. + * @param createFullPath 'True' means that all the ancestor folders should be created + * if don't exist yet. */ public CreateRemoteFolderOperation(String remotePath, boolean createFullPath) { mRemotePath = remotePath; @@ -73,8 +73,10 @@ public class CreateRemoteFolderOperation extends RemoteOperation { @Override protected RemoteOperationResult run(OwnCloudClient client) { RemoteOperationResult result = null; - boolean noInvalidChars = FileUtils.isValidPath(mRemotePath, - client.getOwnCloudVersion().isVersionWithForbiddenCharacters()); + OwnCloudVersion version = client.getOwnCloudVersion(); + boolean versionWithForbiddenChars = + (version != null && version.isVersionWithForbiddenCharacters()); + boolean noInvalidChars = FileUtils.isValidPath(mRemotePath, versionWithForbiddenChars); if (noInvalidChars) { result = createFolder(client); if (!result.isSuccess() && mCreateFullPath && @@ -105,7 +107,8 @@ public class CreateRemoteFolderOperation extends RemoteOperation { Log_OC.d(TAG, mkcol.getResponseBodyAsString()); } else { - result = new RemoteOperationResult(mkcol.succeeded(), status, mkcol.getResponseHeaders()); + result = new RemoteOperationResult(mkcol.succeeded(), status, + mkcol.getResponseHeaders()); Log_OC.d(TAG, "Create directory " + mRemotePath + ": " + result.getLogMessage()); } client.exhaustResponse(mkcol.getResponseBodyAsStream()); From dcad9157aa0803e14de4a7fb73456903a4333e28 Mon Sep 17 00:00:00 2001 From: masensio Date: Tue, 16 Jun 2015 10:51:50 +0200 Subject: [PATCH 7/8] Prevent NullPointerException when OwncloudVersion is null in MoveRemoteFileOperation and RenameRemoteFileOperation --- .../lib/resources/files/MoveRemoteFileOperation.java | 10 +++++++--- .../lib/resources/files/RenameRemoteFileOperation.java | 9 ++++++--- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java index c2fb651a..ed68535d 100644 --- a/src/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/MoveRemoteFileOperation.java @@ -40,6 +40,7 @@ import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; import com.owncloud.android.lib.common.utils.Log_OC; +import com.owncloud.android.lib.resources.status.OwnCloudVersion; /** @@ -88,10 +89,13 @@ public class MoveRemoteFileOperation extends RemoteOperation { */ @Override protected RemoteOperationResult run(OwnCloudClient client) { - + + OwnCloudVersion version = client.getOwnCloudVersion(); + boolean versionWithForbiddenChars = + (version != null && version.isVersionWithForbiddenCharacters()); + /// check parameters - if (!FileUtils.isValidPath(mTargetRemotePath, - client.getOwnCloudVersion().isVersionWithForbiddenCharacters())) { + if (!FileUtils.isValidPath(mTargetRemotePath, versionWithForbiddenChars)) { return new RemoteOperationResult(ResultCode.INVALID_CHARACTER_IN_NAME); } diff --git a/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java index 30b88a86..0ceaf227 100644 --- a/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java @@ -34,6 +34,7 @@ import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; import com.owncloud.android.lib.common.utils.Log_OC; +import com.owncloud.android.lib.resources.status.OwnCloudVersion; /** @@ -88,9 +89,11 @@ public class RenameRemoteFileOperation extends RemoteOperation { RemoteOperationResult result = null; LocalMoveMethod move = null; - - boolean noInvalidChars = FileUtils.isValidPath(mNewRemotePath, - client.getOwnCloudVersion().isVersionWithForbiddenCharacters()); + + OwnCloudVersion version = client.getOwnCloudVersion(); + boolean versionWithForbiddenChars = + (version != null && version.isVersionWithForbiddenCharacters()); + boolean noInvalidChars = FileUtils.isValidPath(mNewRemotePath, versionWithForbiddenChars); if (noInvalidChars) { try { From 58deabb7738461da8cca36c0e64416cc441a61ae Mon Sep 17 00:00:00 2001 From: masensio Date: Tue, 16 Jun 2015 15:15:36 +0200 Subject: [PATCH 8/8] Changes from comments in Code Review --- .../resources/files/ChunkedUploadRemoteFileOperation.java | 7 +++---- .../lib/resources/files/UploadRemoteFileOperation.java | 4 +--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java index 7ab9e2d8..1fa9d5fd 100644 --- a/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java @@ -40,7 +40,6 @@ import com.owncloud.android.lib.common.network.ChunkFromFileChannelRequestEntity import com.owncloud.android.lib.common.network.ProgressiveDataTransferer; import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.operations.InvalidCharacterExceptionParser; -import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.utils.Log_OC; @@ -88,9 +87,9 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation mPutMethod.setRequestEntity(mEntity); status = client.executeMethod(mPutMethod); - // TODO: Detect INVALID_CHARACTER_DETECT_IN SERVER in a better way? - if (status == 400 || status == 500) { - InvalidCharacterExceptionParser xmlParser = new InvalidCharacterExceptionParser(); + if (status == 400) { + InvalidCharacterExceptionParser xmlParser = + new InvalidCharacterExceptionParser(); InputStream is = new ByteArrayInputStream( mPutMethod.getResponseBodyAsString().getBytes()); try { diff --git a/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java b/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java index 9fcd6515..25dc87f5 100644 --- a/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java +++ b/src/com/owncloud/android/lib/resources/files/UploadRemoteFileOperation.java @@ -94,7 +94,6 @@ public class UploadRemoteFileOperation extends RemoteOperation { } int status = uploadFile(client); - // TODO: Detect INVALID_CHARACTER_DETECT_IN SERVER in a better way? if (mForbiddenCharsInServer){ result = new RemoteOperationResult( RemoteOperationResult.ResultCode.INVALID_CHARACTER_DETECT_IN_SERVER); @@ -132,8 +131,7 @@ public class UploadRemoteFileOperation extends RemoteOperation { mPutMethod.setRequestEntity(mEntity); status = client.executeMethod(mPutMethod); - // TODO: Detect INVALID_CHARACTER_DETECT_IN SERVER in a better way? - if (status == 400 || status == 500) { + if (status == 400) { InvalidCharacterExceptionParser xmlParser = new InvalidCharacterExceptionParser(); InputStream is = new ByteArrayInputStream( mPutMethod.getResponseBodyAsString().getBytes());