Skip to content

Commit

Permalink
Added post method to DavResource (#47)
Browse files Browse the repository at this point in the history
Signed-off-by: Arnau Mora <[email protected]>
  • Loading branch information
ArnyminerZ authored Jun 11, 2024
1 parent ffdfc56 commit fa173ab
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 33 deletions.
27 changes: 2 additions & 25 deletions src/main/kotlin/at/bitfire/dav4jvm/DavCollection.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,12 @@ import at.bitfire.dav4jvm.exception.DavException
import at.bitfire.dav4jvm.exception.HttpException
import at.bitfire.dav4jvm.property.webdav.NS_WEBDAV
import at.bitfire.dav4jvm.property.webdav.SyncToken
import java.io.StringWriter
import java.util.logging.Logger
import okhttp3.HttpUrl
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import java.io.IOException
import java.io.StringWriter
import java.util.logging.Logger

/**
* Represents a WebDAV collection.
Expand All @@ -36,27 +34,6 @@ open class DavCollection @JvmOverloads constructor(
val NRESULTS = Property.Name(NS_WEBDAV, "nresults")
}

/**
* Sends a POST request. Primarily intended to be used with an Add-Member URL (RFC 5995).
*/
@Throws(IOException::class, HttpException::class)
fun post(body: RequestBody, ifNoneMatch: Boolean = false, callback: ResponseCallback) {
followRedirects {
val builder = Request.Builder()
.post(body)
.url(location)

if (ifNoneMatch)
// don't overwrite anything existing
builder.header("If-None-Match", "*")

httpClient.newCall(builder.build()).execute()
}.use { response ->
checkStatus(response)
callback.onResponse(response)
}
}

/**
* Sends a REPORT sync-collection request.
*
Expand Down
38 changes: 31 additions & 7 deletions src/main/kotlin/at/bitfire/dav4jvm/DavResource.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ import at.bitfire.dav4jvm.property.caldav.NS_CALDAV
import at.bitfire.dav4jvm.property.carddav.NS_CARDDAV
import at.bitfire.dav4jvm.property.webdav.NS_WEBDAV
import at.bitfire.dav4jvm.property.webdav.SyncToken
import java.io.EOFException
import java.io.IOException
import java.io.Reader
import java.io.StringWriter
import java.net.HttpURLConnection
import java.util.logging.Level
import java.util.logging.Logger
import okhttp3.Headers
import okhttp3.HttpUrl
import okhttp3.MediaType.Companion.toMediaType
Expand All @@ -30,13 +37,6 @@ import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserException
import java.io.EOFException
import java.io.IOException
import java.io.Reader
import java.io.StringWriter
import java.net.HttpURLConnection
import java.util.logging.Level
import java.util.logging.Logger
import at.bitfire.dav4jvm.Response as DavResponse

/**
Expand Down Expand Up @@ -417,6 +417,30 @@ open class DavResource @JvmOverloads constructor(
}
}

/**
* Sends a GET request to the resource. Follows up to [MAX_REDIRECTS] redirects.
*/
@Throws(IOException::class, HttpException::class)
fun post(body: RequestBody, ifNoneMatch: Boolean = false, headers: Headers? = null, callback: ResponseCallback) {
followRedirects {
val builder = Request.Builder()
.post(body)
.url(location)

if (ifNoneMatch)
// don't overwrite anything existing
builder.header("If-None-Match", "*")

if (headers != null)
builder.headers(headers)

httpClient.newCall(builder.build()).execute()
}.use { response ->
checkStatus(response)
callback.onResponse(response)
}
}

/**
* Sends a PUT request to the resource. Follows up to [MAX_REDIRECTS] redirects.
*
Expand Down
83 changes: 82 additions & 1 deletion src/test/kotlin/at/bitfire/dav4jvm/DavResourceTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import at.bitfire.dav4jvm.property.webdav.DisplayName
import at.bitfire.dav4jvm.property.webdav.GetContentType
import at.bitfire.dav4jvm.property.webdav.GetETag
import at.bitfire.dav4jvm.property.webdav.ResourceType
import java.net.HttpURLConnection
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
Expand All @@ -30,7 +31,6 @@ import org.junit.Assert.assertTrue
import org.junit.Assert.fail
import org.junit.Before
import org.junit.Test
import java.net.HttpURLConnection

class DavResourceTest {

Expand Down Expand Up @@ -310,6 +310,87 @@ class DavResourceTest {
assertTrue(called)
}

@Test
fun testPost() {
val url = sampleUrl()
val dav = DavResource(httpClient, url)

/* POSITIVE TEST CASES */

// 200 OK
mockServer.enqueue(
MockResponse()
.setResponseCode(HttpURLConnection.HTTP_OK)
.setHeader("ETag", "W/\"My Weak ETag\"")
.setHeader("Content-Type", "application/x-test-result")
.setBody(sampleText)
)
var called = false
dav.post(
body = "body".toRequestBody("application/x-test-result".toMediaType())
) { response ->
called = true
assertEquals(sampleText, response.body!!.string())

val eTag = GetETag.fromResponse(response)
assertEquals("My Weak ETag", eTag!!.eTag)
assertTrue(eTag.weak)
assertEquals("application/x-test-result".toMediaType(), GetContentType(response.body!!.contentType()!!).type)
}
assertTrue(called)

var rq = mockServer.takeRequest()
assertEquals("POST", rq.method)
assertEquals(url.encodedPath, rq.path)
assertTrue(rq.getHeader("Content-Type")?.contains("application/x-test-result") == true)
assertEquals("body", rq.body.readUtf8())

// 302 Moved Temporarily + 200 OK
mockServer.enqueue(
MockResponse()
.setResponseCode(HttpURLConnection.HTTP_MOVED_TEMP)
.setHeader("Location", "/target")
.setBody("This resource was moved.")
)
mockServer.enqueue(
MockResponse()
.setResponseCode(HttpURLConnection.HTTP_OK)
.setHeader("ETag", "\"StrongETag\"")
.setBody(sampleText)
)
called = false
dav.post(
body = "body".toRequestBody("application/x-test-result".toMediaType())
) { response ->
called = true
assertEquals(sampleText, response.body!!.string())
val eTag = GetETag(response.header("ETag")!!)
assertEquals("StrongETag", eTag.eTag)
assertFalse(eTag.weak)
}
assertTrue(called)

mockServer.takeRequest()
rq = mockServer.takeRequest()
assertEquals("POST", rq.method)
assertEquals("/target", rq.path)

// 200 OK without ETag in response
mockServer.enqueue(
MockResponse()
.setResponseCode(HttpURLConnection.HTTP_OK)
.setBody(sampleText)
)
called = false
dav.post(
body = "body".toRequestBody("application/x-test-result".toMediaType())
) { response ->
called = true
assertNull(response.header("ETag"))
}
assertTrue(called)
}

@Test
fun testMove() {
val url = sampleUrl()
Expand Down

0 comments on commit fa173ab

Please sign in to comment.