Loading src/main/java/at/bitfire/dav4android/DavResource.kt +37 −0 Original line number Diff line number Diff line Loading @@ -127,6 +127,43 @@ open class DavResource @JvmOverloads constructor( } } /** * Sends a COPY request for this resource. Follows up to [MAX_REDIRECTS] redirects. * * @param destination where the resource shall be copied to * @param forceOverride whether resources are overwritten when they already exist in destination * * @throws IOException on I/O error * @throws HttpException on HTTP error * @throws DavException on WebDAV error */ @Throws(IOException::class, HttpException::class, DavException::class) fun copy(destination:HttpUrl, forceOverride:Boolean, callback: (response: Response) -> Unit) { val requestBuilder = Request.Builder() .method("COPY", null) .header("Content-Length", "0") .header("Destination", destination.toString()) if(forceOverride) requestBuilder.header("Overwrite", "F") followRedirects { requestBuilder.url(location) httpClient.newCall(requestBuilder .build()) .execute() }.use{ response -> checkStatus(response) if (response.code() == 207) /* Multiple resources were to be affected by the COPY, but errors on some of them prevented the operation from taking place. [_] (RFC 4918 9.8.5. Status Codes for COPY Method) */ throw HttpException(response) callback(response) } } /** * Sends a MKCOL request to this resource. Follows up to [MAX_REDIRECTS] redirects. * Loading src/test/java/at/bitfire/dav4android/DavResourceTest.kt +62 −0 Original line number Diff line number Diff line Loading @@ -136,6 +136,68 @@ class DavResourceTest { } } @Test fun testCopy() { val url = sampleUrl() val destination = url.resolve("test")!! /* POSITIVE TEST CASES */ // no preconditions, 201 Created, resulted in the creation of a new resource mockServer.enqueue(MockResponse() .setResponseCode(HttpURLConnection.HTTP_CREATED)) var called = false DavResource(httpClient, url).let { dav -> dav.copy(destination, false) { called = true } assertTrue(called) assertEquals(destination, dav.location) } var rq = mockServer.takeRequest() assertEquals("COPY", rq.method) assertEquals(url.encodedPath(), rq.path) assertEquals(destination.toString(), rq.getHeader("Destination")) assertNull(rq.getHeader("Overwrite")) // no preconditions, 204 No content, resource successfully copied to a preexisting // destination resource mockServer.enqueue(MockResponse() .setResponseCode(HttpURLConnection.HTTP_NO_CONTENT)) called = false DavResource(httpClient, url).let { dav -> dav.copy(destination, true) { called = true } assertTrue(called) assertEquals(destination, dav.location) } rq = mockServer.takeRequest() assertEquals("COPY", rq.method) assertEquals(url.encodedPath(), rq.path) assertEquals(destination.toString(), rq.getHeader("Destination")) assertEquals("F", rq.getHeader("Overwrite")) /* NEGATIVE TEST CASES */ // 207 multi-status (e.g. errors on some of resources affected by // the COPY prevented the operation from taking place) mockServer.enqueue(MockResponse() .setResponseCode(207)) try { called = false DavResource(httpClient, url).let { dav -> dav.copy(destination, false) { called = true } fail("Expected HttpException") } } catch(e: HttpException) { assertFalse(called) } } @Test fun testGet() { val url = sampleUrl() Loading Loading
src/main/java/at/bitfire/dav4android/DavResource.kt +37 −0 Original line number Diff line number Diff line Loading @@ -127,6 +127,43 @@ open class DavResource @JvmOverloads constructor( } } /** * Sends a COPY request for this resource. Follows up to [MAX_REDIRECTS] redirects. * * @param destination where the resource shall be copied to * @param forceOverride whether resources are overwritten when they already exist in destination * * @throws IOException on I/O error * @throws HttpException on HTTP error * @throws DavException on WebDAV error */ @Throws(IOException::class, HttpException::class, DavException::class) fun copy(destination:HttpUrl, forceOverride:Boolean, callback: (response: Response) -> Unit) { val requestBuilder = Request.Builder() .method("COPY", null) .header("Content-Length", "0") .header("Destination", destination.toString()) if(forceOverride) requestBuilder.header("Overwrite", "F") followRedirects { requestBuilder.url(location) httpClient.newCall(requestBuilder .build()) .execute() }.use{ response -> checkStatus(response) if (response.code() == 207) /* Multiple resources were to be affected by the COPY, but errors on some of them prevented the operation from taking place. [_] (RFC 4918 9.8.5. Status Codes for COPY Method) */ throw HttpException(response) callback(response) } } /** * Sends a MKCOL request to this resource. Follows up to [MAX_REDIRECTS] redirects. * Loading
src/test/java/at/bitfire/dav4android/DavResourceTest.kt +62 −0 Original line number Diff line number Diff line Loading @@ -136,6 +136,68 @@ class DavResourceTest { } } @Test fun testCopy() { val url = sampleUrl() val destination = url.resolve("test")!! /* POSITIVE TEST CASES */ // no preconditions, 201 Created, resulted in the creation of a new resource mockServer.enqueue(MockResponse() .setResponseCode(HttpURLConnection.HTTP_CREATED)) var called = false DavResource(httpClient, url).let { dav -> dav.copy(destination, false) { called = true } assertTrue(called) assertEquals(destination, dav.location) } var rq = mockServer.takeRequest() assertEquals("COPY", rq.method) assertEquals(url.encodedPath(), rq.path) assertEquals(destination.toString(), rq.getHeader("Destination")) assertNull(rq.getHeader("Overwrite")) // no preconditions, 204 No content, resource successfully copied to a preexisting // destination resource mockServer.enqueue(MockResponse() .setResponseCode(HttpURLConnection.HTTP_NO_CONTENT)) called = false DavResource(httpClient, url).let { dav -> dav.copy(destination, true) { called = true } assertTrue(called) assertEquals(destination, dav.location) } rq = mockServer.takeRequest() assertEquals("COPY", rq.method) assertEquals(url.encodedPath(), rq.path) assertEquals(destination.toString(), rq.getHeader("Destination")) assertEquals("F", rq.getHeader("Overwrite")) /* NEGATIVE TEST CASES */ // 207 multi-status (e.g. errors on some of resources affected by // the COPY prevented the operation from taking place) mockServer.enqueue(MockResponse() .setResponseCode(207)) try { called = false DavResource(httpClient, url).let { dav -> dav.copy(destination, false) { called = true } fail("Expected HttpException") } } catch(e: HttpException) { assertFalse(called) } } @Test fun testGet() { val url = sampleUrl() Loading