From 69497645ec3703828c26f7e319975cecd62fb425 Mon Sep 17 00:00:00 2001 From: agarcia Date: Fri, 3 Jul 2020 15:27:55 +0200 Subject: [PATCH] Update dav4android and fix timestamp error depending on locale --- owncloudComLibrary/build.gradle | 2 +- .../common/http/methods/webdav/DavMethod.kt | 17 +- .../http/methods/webdav/OCDavResource.kt | 340 ------------------ 3 files changed, 10 insertions(+), 349 deletions(-) delete mode 100644 owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/OCDavResource.kt diff --git a/owncloudComLibrary/build.gradle b/owncloudComLibrary/build.gradle index a75309e4..ca70bc23 100644 --- a/owncloudComLibrary/build.gradle +++ b/owncloudComLibrary/build.gradle @@ -6,7 +6,7 @@ apply plugin: 'kotlin-allopen' dependencies { api 'com.squareup.okhttp3:okhttp:4.6.0' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion" - api 'com.gitlab.ownclouders:dav4android:oc_support_2.1' + api 'com.gitlab.ownclouders:dav4android:oc_support_2.1.2' api 'com.github.hannesa2:Logcat:1.6.0' api 'net.openid:appauth:0.7.1' diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/DavMethod.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/DavMethod.kt index aa160966..09efda64 100644 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/DavMethod.kt +++ b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/DavMethod.kt @@ -24,6 +24,7 @@ package com.owncloud.android.lib.common.http.methods.webdav import at.bitfire.dav4jvm.Dav4jvm.log +import at.bitfire.dav4jvm.DavOCResource import at.bitfire.dav4jvm.exception.HttpException import at.bitfire.dav4jvm.exception.RedirectException import com.owncloud.android.lib.common.http.HttpConstants @@ -43,11 +44,11 @@ import java.util.concurrent.TimeUnit * @author David González Verdugo */ abstract class DavMethod protected constructor(url: URL) : HttpBaseMethod(url) { - protected var mDavResource: OCDavResource + protected var mDavResource: DavOCResource init { val httpUrl = url.toHttpUrlOrNull() ?: throw MalformedURLException() - mDavResource = OCDavResource( + mDavResource = DavOCResource( okHttpClient, httpUrl, log @@ -95,7 +96,7 @@ abstract class DavMethod protected constructor(url: URL) : HttpBaseMethod(url) { // Connection parameters override fun setReadTimeout(readTimeout: Long, timeUnit: TimeUnit) { super.setReadTimeout(readTimeout, timeUnit) - mDavResource = OCDavResource( + mDavResource = DavOCResource( okHttpClient, httpUrl, log @@ -107,7 +108,7 @@ abstract class DavMethod protected constructor(url: URL) : HttpBaseMethod(url) { timeUnit: TimeUnit ) { super.setConnectionTimeout(connectionTimeout, timeUnit) - mDavResource = OCDavResource( + mDavResource = DavOCResource( okHttpClient, httpUrl, log @@ -116,7 +117,7 @@ abstract class DavMethod protected constructor(url: URL) : HttpBaseMethod(url) { override fun setFollowRedirects(followRedirects: Boolean) { super.setFollowRedirects(followRedirects) - mDavResource = OCDavResource( + mDavResource = DavOCResource( okHttpClient, httpUrl, log @@ -125,7 +126,7 @@ abstract class DavMethod protected constructor(url: URL) : HttpBaseMethod(url) { override fun setUrl(url: HttpUrl) { super.setUrl(url) - mDavResource = OCDavResource( + mDavResource = DavOCResource( okHttpClient, httpUrl, log @@ -134,7 +135,7 @@ abstract class DavMethod protected constructor(url: URL) : HttpBaseMethod(url) { override fun setRequestHeader(name: String, value: String) { super.setRequestHeader(name, value) - mDavResource = OCDavResource( + mDavResource = DavOCResource( okHttpClient, httpUrl, log @@ -150,7 +151,7 @@ abstract class DavMethod protected constructor(url: URL) : HttpBaseMethod(url) { ////////////////////////////// override fun setRetryOnConnectionFailure(retryOnConnectionFailure: Boolean) { super.setRetryOnConnectionFailure(retryOnConnectionFailure) - mDavResource = OCDavResource( + mDavResource = DavOCResource( okHttpClient, httpUrl, log diff --git a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/OCDavResource.kt b/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/OCDavResource.kt deleted file mode 100644 index 7edf43f8..00000000 --- a/owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/http/methods/webdav/OCDavResource.kt +++ /dev/null @@ -1,340 +0,0 @@ -package com.owncloud.android.lib.common.http.methods.webdav - -import at.bitfire.dav4jvm.DavResource -import at.bitfire.dav4jvm.DavResponseCallback -import at.bitfire.dav4jvm.IF_MATCH_HEADER -import at.bitfire.dav4jvm.Property -import at.bitfire.dav4jvm.QuotedStringUtils -import at.bitfire.dav4jvm.XmlUtils -import at.bitfire.dav4jvm.exception.DavException -import at.bitfire.dav4jvm.exception.HttpException -import okhttp3.HttpUrl -import okhttp3.OkHttpClient -import okhttp3.Request -import okhttp3.RequestBody -import okhttp3.RequestBody.Companion.toRequestBody -import okhttp3.Response -import java.io.IOException -import java.io.StringWriter -import java.util.logging.Logger - -class OCDavResource( - httpClient: OkHttpClient, - location: HttpUrl, - log: Logger -) : DavResource(httpClient, location, log) { - - /** - * Sends a PUT request to the resource. - * @param body new resource body to upload - * @param ifMatchETag value of "If-Match" header to set, or null to omit - * @param ifNoneMatch indicates whether "If-None-Match: *" ("don't overwrite anything existing") header shall be sent - * @param contentType - * @param ocTotalLength total length of resource body - * @param ocXOcMtimeHeader modification time - * @return true if the request was redirected successfully, i.e. #{@link #location} and maybe resource name may have changed - * @throws IOException on I/O error - * @throws HttpException on HTTP error - */ - @Throws(IOException::class, HttpException::class) - fun put( - body: RequestBody, - ifMatchETag: String?, - listOfHeaders: HashMap?, - callback: (response: Response) -> Unit - ) { - val requestBuilder = Request.Builder() - .put(body) - - listOfHeaders?.forEach { (name, value) -> - value?.let { - requestBuilder.header(name, value) - } - } - - if (ifMatchETag != null) - // only overwrite specific version - requestBuilder.header(IF_MATCH_HEADER, QuotedStringUtils.asQuotedString(ifMatchETag)) -// if (contentType != null) { -// requestBuilder.header(CONTENT_TYPE_HEADER, contentType) -// } -// if (ocTotalLength != null) { -// requestBuilder.header(OC_TOTAL_LENGTH_HEADER, ocTotalLength) -// } -// if (ocXOcMtimeHeader != null) { -// requestBuilder.header(OC_X_OC_MTIME_HEADER, ocXOcMtimeHeader) -// } - - followRedirects { - requestBuilder - .url(location) - val call = httpClient.newCall(requestBuilder.build()) - - this.call = call - call.execute() - }.use { response -> - callback(response) - checkStatus(response) - } - } - - /** - * Sends a MOVE request to the resource - * @param ocTotalLength total length of resource body - * @param ocXOcMtimeHeader modification time - */ - @Throws(IOException::class, HttpException::class, DavException::class) - fun move( - destination: String, - forceOverride: Boolean, - listOfHeaders: HashMap?, - callback: (response: Response) -> Unit - ) { - val requestBuilder = Request.Builder() - .method("MOVE", null) - .header("Content-Length", "0") - .header("Destination", destination) - - if (forceOverride) - requestBuilder.header("Overwrite", "F") - - listOfHeaders?.forEach { (name, value) -> - value?.let { - requestBuilder.header(name, value) - } - } -// if (ocTotalLength != null) -// requestBuilder.header(OC_TOTAL_LENGTH_HEADER, ocTotalLength) -// if (ocXOcMtimeHeader != null) -// requestBuilder.header(OC_X_OC_MTIME_HEADER, ocXOcMtimeHeader) - - followRedirects { - requestBuilder.url(location) - val call = httpClient.newCall(requestBuilder.build()) - this.call = call - call.execute() - }.use { response -> - callback(response) - checkStatus(response) - } - } - - @Throws(IOException::class, HttpException::class, DavException::class) - fun copy( - destination: String, - forceOverride: Boolean, - listOfHeaders: HashMap?, - callback: (response: Response) -> Unit - ) { - val requestBuilder = Request.Builder() - .method("COPY", null) - .header("Content-Length", "0") - .header("Destination", destination) - if (forceOverride) - requestBuilder.header("Overwrite", "F") - - listOfHeaders?.forEach { (name, value) -> - value?.let { - requestBuilder.header(name, value) - } - } - - followRedirects { - requestBuilder.url(location) - val call = httpClient.newCall(requestBuilder.build()) - - this.call = call - call.execute() - }.use { response -> - callback(response) - checkStatus(response) - } - } - - /** - * Sends a MKCOL request to this resource. Follows up to [MAX_REDIRECTS] redirects. - * - * @throws IOException on I/O error - * @throws HttpException on HTTP error - */ - @Throws(IOException::class, HttpException::class) - fun mkCol( - xmlBody: String?, - listOfHeaders: HashMap?, - callback: (response: Response) -> Unit - ) { - val requestBody = xmlBody?.toRequestBody(MIME_XML) - val requestBuilder = Request.Builder() - .method("MKCOL", requestBody) - .url(location) - listOfHeaders?.forEach { (name, value) -> - value?.let { - requestBuilder.header(name, value) - } - } - followRedirects { - val call = httpClient.newCall( - requestBuilder.build() - ) - this.call = call - call.execute() - }.use { response -> - callback(response) - checkStatus(response) - } - } - - /** - * Sends a GET request to the resource. Sends `Accept-Encoding: identity` to disable - * compression, because compression might change the ETag. - * - * Follows up to [MAX_REDIRECTS] redirects. - * - * @param accept value of Accept header (must not be null, but may be */*) - * @param callback called with server response unless an exception is thrown - * - * @throws IOException on I/O error - * @throws HttpException on HTTP error - */ - @Throws(IOException::class, HttpException::class) - fun get( - accept: String, - listOfHeaders: HashMap?, - callback: (response: Response) -> Unit - ) { - val requestBuilder = Request.Builder() - .get() - .url(location) - .header("Accept", accept) - .header("Accept-Encoding", "identity") // disable compression because it can change the ETag - - listOfHeaders?.forEach { (name, value) -> - value?.let { - requestBuilder.header(name, value) - } - } - - followRedirects { - val call = httpClient.newCall( - requestBuilder - .build() - ) - this.call = call - call.execute() - }.use { response -> - callback(response) - checkStatus(response) - } - } - - /** - * Sends a DELETE request to the resource. Warning: Sending this request to a collection will - * delete the collection with all its contents! - * - * Follows up to [MAX_REDIRECTS] redirects. - * - * @param ifMatchETag value of `If-Match` header to set, or null to omit - * @param callback called with server response unless an exception is thrown - * - * @throws IOException on I/O error - * @throws HttpException on HTTP errors, or when 207 Multi-Status is returned - * (because then there was probably a problem with a member resource) - */ - @Throws(IOException::class, HttpException::class) - fun delete( - ifMatchETag: String?, - listOfHeaders: HashMap?, - callback: (Response) -> Unit - ) { - followRedirects { - val requestBuilder = Request.Builder() - .delete() - .url(location) - if (ifMatchETag != null) - requestBuilder.header("If-Match", QuotedStringUtils.asQuotedString(ifMatchETag)) - listOfHeaders?.forEach { (name, value) -> - value?.let { - requestBuilder.header(name, value) - } - } - - val call = httpClient.newCall(requestBuilder.build()) - - this.call = call - call.execute() - }.use { response -> - callback(response) - checkStatus(response) - if (response.code == 207) - /* If an error occurs deleting a member resource (a resource other than - the resource identified in the Request-URI), then the response can be - a 207 (Multi-Status). […] (RFC 4918 9.6.1. DELETE for Collections) */ - throw HttpException(response) - } - } - - /** - * Sends a PROPFIND request to the resource. Expects and processes a 207 Multi-Status response. - * - * Follows up to [MAX_REDIRECTS] redirects. - * - * @param depth "Depth" header to send (-1 for `infinity`) - * @param reqProp properties to request - * @param callback called for every XML response element in the Multi-Status response - * - * @throws IOException on I/O error - * @throws HttpException on HTTP error - * @throws DavException on WebDAV error (like no 207 Multi-Status response) - */ - @Throws(IOException::class, HttpException::class, DavException::class) - fun propfind( - depth: Int, - vararg reqProp: Property.Name, - listOfHeaders: HashMap?, - callback: DavResponseCallback, - rawCallback: (response: Response) -> Unit - ) { - // build XML request body - val serializer = XmlUtils.newSerializer() - val writer = StringWriter() - serializer.setOutput(writer) - serializer.setPrefix("", XmlUtils.NS_WEBDAV) - serializer.setPrefix("CAL", XmlUtils.NS_CALDAV) - serializer.setPrefix("CARD", XmlUtils.NS_CARDDAV) - serializer.setPrefix("SABRE", XmlUtils.NS_SABREDAV) - serializer.setPrefix("OC", XmlUtils.NS_OWNCLOUD) - serializer.startDocument("UTF-8", null) - serializer.startTag(XmlUtils.NS_WEBDAV, "propfind") - serializer.startTag(XmlUtils.NS_WEBDAV, "prop") - for (prop in reqProp) { - serializer.startTag(prop.namespace, prop.name) - serializer.endTag(prop.namespace, prop.name) - } - serializer.endTag(XmlUtils.NS_WEBDAV, "prop") - serializer.endTag(XmlUtils.NS_WEBDAV, "propfind") - serializer.endDocument() - - val requestBuilder = Request.Builder() - .url(location) - .method("PROPFIND", writer.toString().toRequestBody(MIME_XML)) - .header("Depth", if (depth >= 0) depth.toString() else "infinity") - - listOfHeaders?.forEach { (name, value) -> - value?.let { - requestBuilder.header(name, value) - } - } - - followRedirects { - val call = httpClient.newCall( - requestBuilder.build() - ) - this.call = call - call.execute() - }.use { response -> - rawCallback(response) - processMultiStatus(response, callback) - } - } - -}