Loading src/com/owncloud/android/lib/common/OwnCloudClient.java +11 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ 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; public class OwnCloudClient extends HttpClient { Loading @@ -69,6 +70,8 @@ public class OwnCloudClient extends HttpClient { private Uri mBaseUri; private OwnCloudVersion mVersion = null; /** * Constructor */ Loading Loading @@ -441,4 +444,12 @@ public class OwnCloudClient extends HttpClient { } public void setOwnCloudVersion(String version){ OwnCloudVersion ver = new OwnCloudVersion(version); mVersion = ver; } public OwnCloudVersion getOwnCloudVersion(){ return mVersion; } } src/com/owncloud/android/lib/common/operations/InvalidCharacterExceptionParser.java 0 → 100644 +146 −0 Original line number Diff line number Diff line /* 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 */ 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; // Nodes for XML Parser private static final String NODE_ERROR = "d:error"; private static final String NODE_EXCEPTION = "s:exception"; /** * Parse is as an Invalid Path Exception * @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) || exception.equalsIgnoreCase(EXCEPTION_UPLOAD_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; } } src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java +53 −11 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -60,7 +62,7 @@ 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 = 25745846447996048L; private static final long serialVersionUID = -1909603208238358633L; private static final String TAG = RemoteOperationResult.class.getSimpleName(); Loading Loading @@ -103,7 +105,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; Loading @@ -118,7 +121,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; } Loading Loading @@ -151,7 +156,8 @@ public class RemoteOperationResult implements Serializable { 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); } } } Loading @@ -174,6 +180,37 @@ 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; Loading Loading @@ -265,7 +302,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(); } Loading Loading @@ -315,8 +353,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"; Loading Loading @@ -353,7 +393,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") + ")"; } Loading Loading @@ -385,7 +426,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() { Loading src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java +31 −6 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -37,6 +39,7 @@ 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.utils.Log_OC; Loading @@ -61,17 +64,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); Loading @@ -79,8 +86,26 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation ((ChunkFromFileChannelRequestEntity) mEntity).setOffset(offset); mPutMethod.setRequestEntity(mEntity); status = client.executeMethod(mPutMethod); if (status == 400) { 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; } Loading src/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java +18 −7 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -33,7 +32,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; /** Loading @@ -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; Loading @@ -73,7 +73,10 @@ public class CreateRemoteFolderOperation extends RemoteOperation { @Override protected RemoteOperationResult run(OwnCloudClient client) { RemoteOperationResult result = null; boolean noInvalidChars = FileUtils.isValidPath(mRemotePath); 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 && Loading @@ -98,8 +101,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()); 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) { Loading Loading
src/com/owncloud/android/lib/common/OwnCloudClient.java +11 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ 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; public class OwnCloudClient extends HttpClient { Loading @@ -69,6 +70,8 @@ public class OwnCloudClient extends HttpClient { private Uri mBaseUri; private OwnCloudVersion mVersion = null; /** * Constructor */ Loading Loading @@ -441,4 +444,12 @@ public class OwnCloudClient extends HttpClient { } public void setOwnCloudVersion(String version){ OwnCloudVersion ver = new OwnCloudVersion(version); mVersion = ver; } public OwnCloudVersion getOwnCloudVersion(){ return mVersion; } }
src/com/owncloud/android/lib/common/operations/InvalidCharacterExceptionParser.java 0 → 100644 +146 −0 Original line number Diff line number Diff line /* 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 */ 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; // Nodes for XML Parser private static final String NODE_ERROR = "d:error"; private static final String NODE_EXCEPTION = "s:exception"; /** * Parse is as an Invalid Path Exception * @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) || exception.equalsIgnoreCase(EXCEPTION_UPLOAD_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; } }
src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java +53 −11 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -60,7 +62,7 @@ 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 = 25745846447996048L; private static final long serialVersionUID = -1909603208238358633L; private static final String TAG = RemoteOperationResult.class.getSimpleName(); Loading Loading @@ -103,7 +105,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; Loading @@ -118,7 +121,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; } Loading Loading @@ -151,7 +156,8 @@ public class RemoteOperationResult implements Serializable { 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); } } } Loading @@ -174,6 +180,37 @@ 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; Loading Loading @@ -265,7 +302,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(); } Loading Loading @@ -315,8 +353,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"; Loading Loading @@ -353,7 +393,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") + ")"; } Loading Loading @@ -385,7 +426,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() { Loading
src/com/owncloud/android/lib/resources/files/ChunkedUploadRemoteFileOperation.java +31 −6 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -37,6 +39,7 @@ 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.utils.Log_OC; Loading @@ -61,17 +64,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); Loading @@ -79,8 +86,26 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation ((ChunkFromFileChannelRequestEntity) mEntity).setOffset(offset); mPutMethod.setRequestEntity(mEntity); status = client.executeMethod(mPutMethod); if (status == 400) { 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; } Loading
src/com/owncloud/android/lib/resources/files/CreateRemoteFolderOperation.java +18 −7 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -33,7 +32,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; /** Loading @@ -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; Loading @@ -73,7 +73,10 @@ public class CreateRemoteFolderOperation extends RemoteOperation { @Override protected RemoteOperationResult run(OwnCloudClient client) { RemoteOperationResult result = null; boolean noInvalidChars = FileUtils.isValidPath(mRemotePath); 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 && Loading @@ -98,8 +101,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()); 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) { Loading