From 8a3956f83a1ea19aa81e0972ec627000a1c1db9c Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Sat, 3 Oct 2020 18:35:42 +0200 Subject: [PATCH 1/3] Handle http status code 308 for redirection The status code 308 (Permanent Redirect) is defined in RFC 7538 and used e.g. by Traefik for redirection. The used version of commons-httpclient doesn't yet include a constant for that status code so use the integer directly. Signed-off-by: Luca Weiss --- src/main/java/com/nextcloud/common/NextcloudClient.kt | 3 ++- .../java/com/owncloud/android/lib/common/OwnCloudClient.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/nextcloud/common/NextcloudClient.kt b/src/main/java/com/nextcloud/common/NextcloudClient.kt index 1e98726a75..1fe360c22e 100644 --- a/src/main/java/com/nextcloud/common/NextcloudClient.kt +++ b/src/main/java/com/nextcloud/common/NextcloudClient.kt @@ -113,7 +113,8 @@ class NextcloudClient(var baseUri: Uri, while (redirectionsCount < OwnCloudClient.MAX_REDIRECTIONS_COUNT && (status == HttpStatus.SC_MOVED_PERMANENTLY || status == HttpStatus.SC_MOVED_TEMPORARILY || - status == HttpStatus.SC_TEMPORARY_REDIRECT)) { + status == HttpStatus.SC_TEMPORARY_REDIRECT || + status == /* Permanent Redirect */ 308)) { var location = method.getResponseHeader("Location") if (location == null) { location = method.getResponseHeader("location") diff --git a/src/main/java/com/owncloud/android/lib/common/OwnCloudClient.java b/src/main/java/com/owncloud/android/lib/common/OwnCloudClient.java index 8b5732d11d..b564de51d6 100644 --- a/src/main/java/com/owncloud/android/lib/common/OwnCloudClient.java +++ b/src/main/java/com/owncloud/android/lib/common/OwnCloudClient.java @@ -242,7 +242,8 @@ public RedirectionPath followRedirection(HttpMethod method) throws IOException { while (redirectionsCount < MAX_REDIRECTIONS_COUNT && ( status == HttpStatus.SC_MOVED_PERMANENTLY || status == HttpStatus.SC_MOVED_TEMPORARILY || - status == HttpStatus.SC_TEMPORARY_REDIRECT) + status == HttpStatus.SC_TEMPORARY_REDIRECT || + status == /* Permanent Redirect */ 308) ) { Header location = method.getResponseHeader("Location"); From 6ee3c38a1e9b3a9813fe811ddc61f929b99f0b5a Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Sat, 3 Oct 2020 18:39:19 +0200 Subject: [PATCH 2/3] Activate Expect-Continue handshake for file upload In certain cases when we try to upload a file the server can respond back with a redirect and close the connection before we're done writing content to the server which results in a 'java.net.SocketException: Broken pipe' exception. We can solve that by asking the server first whether we can actually write data (the rest is handled by the httpclient library). See also: http://httpcomponents.10934.n7.nabble.com/Broken-pipe-Write-failed-when-making-Unauthorized-request-tp34235p34245.html Signed-off-by: Luca Weiss --- .../lib/resources/files/ChunkedFileUploadRemoteOperation.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/owncloud/android/lib/resources/files/ChunkedFileUploadRemoteOperation.java b/src/main/java/com/owncloud/android/lib/resources/files/ChunkedFileUploadRemoteOperation.java index 4ba9bc725b..7ad3f0ca9b 100644 --- a/src/main/java/com/owncloud/android/lib/resources/files/ChunkedFileUploadRemoteOperation.java +++ b/src/main/java/com/owncloud/android/lib/resources/files/ChunkedFileUploadRemoteOperation.java @@ -309,6 +309,7 @@ private RemoteOperationResult uploadChunk(OwnCloudClient client, String uploadFo private PutMethod createPutMethod(String uriPrefix) { putMethod = new PutMethod(uriPrefix); putMethod.setRequestEntity(entity); + putMethod.setUseExpectHeader(true); if (cancellationRequested.get()) { putMethod.abort(); // next method will throw an exception } From 20772a93cceafd3a60bcbbb161af2d155bdd8a8b Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Sat, 3 Oct 2020 18:40:52 +0200 Subject: [PATCH 3/3] Handle new webdav path on redirects Previously redirects with new webdav paths resulted in an IndexOutOfBoundsException as String.substring() was called with a -1 index. Signed-off-by: Luca Weiss --- src/main/java/com/nextcloud/common/NextcloudClient.kt | 6 +++++- .../com/owncloud/android/lib/common/OwnCloudClient.java | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/nextcloud/common/NextcloudClient.kt b/src/main/java/com/nextcloud/common/NextcloudClient.kt index 1fe360c22e..00f0d58fe4 100644 --- a/src/main/java/com/nextcloud/common/NextcloudClient.kt +++ b/src/main/java/com/nextcloud/common/NextcloudClient.kt @@ -133,7 +133,11 @@ class NextcloudClient(var baseUri: Uri, } if (destination != null) { - val suffixIndex = location.lastIndexOf(AccountUtils.WEBDAV_PATH_4_0) + var suffixIndex = location.lastIndexOf(AccountUtils.WEBDAV_PATH_4_0) + if (suffixIndex == -1) { + suffixIndex = location.lastIndexOf(AccountUtils.WEBDAV_PATH_9_0) + } + check (suffixIndex != -1) { "Failed to find webdav substring in $location" } val redirectionBase = location.substring(0, suffixIndex) val destinationStr = destination val destinationPath = destinationStr.substring(baseUri.toString().length) diff --git a/src/main/java/com/owncloud/android/lib/common/OwnCloudClient.java b/src/main/java/com/owncloud/android/lib/common/OwnCloudClient.java index b564de51d6..96f7cd3061 100644 --- a/src/main/java/com/owncloud/android/lib/common/OwnCloudClient.java +++ b/src/main/java/com/owncloud/android/lib/common/OwnCloudClient.java @@ -269,6 +269,12 @@ public RedirectionPath followRedirection(HttpMethod method) throws IOException { } if (destination != null) { int suffixIndex = locationStr.lastIndexOf(AccountUtils.WEBDAV_PATH_4_0); + if (suffixIndex == -1) { + suffixIndex = locationStr.lastIndexOf(AccountUtils.WEBDAV_PATH_9_0); + } + if (suffixIndex == -1) { + throw new IllegalStateException("Failed to find webdav substring in " + locationStr); + } String redirectionBase = locationStr.substring(0, suffixIndex); String destinationStr = destination.getValue();