fuel icon indicating copy to clipboard operation
fuel copied to clipboard

Redirect 304 with a matched etag

Open kittinunf opened this issue 6 years ago • 2 comments

Feature Request

There is a case where our current Fuel couldn't handle properly.

val request = Fuel.get(url)
request['If-None-Match'] = 'some etag'

val response = request.responseObject(...)
// This will be fine if the etag doesn't match (the resource has changed) and you get a 200 or the like

// What happens if it DOES match and you get a 304? 
// - Do we throw? 
// - Could we return an empty body -- is there a nice way we can handle that?
// - Do we need a new API that basically tells you if you got "responseWithBodyOfType, responseWithoutBody"?

Description

To be able to correctly, handle 304 with a matched etag.

Proposed Solution

TBD

Alternatives I've considered

N/A

Additional context

N/A

kittinunf avatar Jan 22 '19 12:01 kittinunf

my current temporary solution for handling etags is:

fun download(): File {

        val cacheFile = directories.cacheHome.resolve("latest.jar")
        val etagFile = cacheFile.parentFile.resolve("${cacheFile.name}.etag.txt")

        val url = "fill-me-in"

        val (request, response, result) = url.httpGet()
            .apply {
                if (cacheFile.exists() && etagFile.exists()) {
                    header("If-None-Match", etagFile.readText())
                }
            }.response()

        if (response.statusCode == 304) {
            return cacheFile
        }
        return when (result) {
            is Result.Success -> {
                logger.info("statusCode: ${response.statusCode}")
                cacheFile.writeBytes(result.value)
                etagFile.writeText(response["ETag"].first())
                cacheFile
            }
            is Result.Failure -> {
                logger.info("statusCode: ${response.statusCode}")
                logger.error("invalid statusCode {} from {}", response.statusCode, url.encoded)
                logger.error("connection url: ${request.url}")
                logger.error("cUrl: ${request.cUrlString()}")
                logger.error("response: $response")
                logger.error("error: {}", result.error.toString())
                logger.error(result.error.exception) { "Download Failed" }
                exitProcess(-1)
            }
        }
    }

note that i could not use any .await methods from fuel-coroutines since they throw and i get a statuscode -1 in my code

i think i would like a method like: expect(etagheader: String, cachedContent: ByteArray) that sets the etag and sets up a response interceptor that inserts the value

NikkyAI avatar Jan 26 '19 07:01 NikkyAI

Yes, I think this shows the same behavior, hopefully #601 fixes your concern @NikkyAI about .await

kittinunf avatar Feb 26 '19 14:02 kittinunf