kittinunf / fuel

The easiest HTTP networking library for Kotlin/Android
https://fuel.gitbook.io/documentation/
MIT License
4.57k stars 430 forks source link

httpGet can't send body in request #567

Open brihoumb opened 5 years ago

brihoumb commented 5 years ago

I'm creating an android app using Fuel for kotlin and i need to send a GET request to the server with a body but got "Exception : method does not support a request body: GET". How can I send a body with my GET request ?

I follow you my function:

fun getFunc (data: JSONObject, url : String): String {
    lateinit var ret : String

    thread {
        FuelManager.instance.basePath = "https://blih.epitech.eu"
        Fuel.upload(url, Method.GET)
            .source { _, _ -> File.createTempFile(".temp", ".tmp") }
            .body(data.toString().toByteArray())
            .header("Content-Type" to "application/json")
            .response { request, response, result ->
                val (bytes, error) = result
                if (bytes != null) {
                    println("[response bytes] ${String(bytes)}")
                }
                ret = response.toString()
                println("error: $error")
            }
    }
    Thread.sleep(1000)
    return ret
}
SleeplessByte commented 5 years ago

Hi there!

GET bodies don't work < 2.0.0; I am unsure if they work in 2.0.0 but I'll personally see if we can have that added!

brihoumb commented 5 years ago

Is there tricks for doing it now ? Or do I need to code it by myself until version 2.0.0 came out ?

iNoles commented 5 years ago

By according to HTTP Standard, GET should not have request body because it only do query strings. As for upload function, you should use POST methods.

SleeplessByte commented 5 years ago

@iNoles that was dropped from the RFC. GET requests may have bodies now.

melston commented 5 years ago

This answers a similar question I had. I have a GET request and I have to pass a structure to the server to generate a file and send it back. In my case the structure is small so I can put it all in query strings. However, there are other cases where it becomes a real burden to do so and it is much simpler to have a structured object that is serialized as JSON in the body of the request. Is there a way to accommodate this?

carlfindahl commented 4 years ago

Hi, I would also really like this feature to work :) Am struggling to interact with an API without this at the moment.

kittinunf commented 4 years ago

If anyone would love to take this, I am happy to accept PR :) Otherwise, I will try to see what I can do for this.

iNoles commented 4 years ago

Android's HttpURLConnection is extremely legacy in back to Java 6. OkHttp doesn't have this kind of the feature. in Ktor, It will give warning in https://github.com/ktorio/ktor/blob/master/ktor-client/ktor-client-android/jvm/src/io/ktor/client/engine/android/AndroidClientEngine.kt#L63

wfxr commented 4 years ago

Not allow to send body in GET request is a strange restriction. As @SleeplessByte said that unreasonable constraint was already dropped from the RFC. Meanwhile many famous projects' apis take body in GET request (Elasticsearch for example).

GET /_search
{
  "query": {
    "multi_match": {
      "query": "this is a test",
      "fields": [
        "subject",
        "message"
      ]
    }
  }
}

So will fuel plan to remove the restriction? Otherwise we have to use POST method to get something when the query is complicated (hope luckily the server support both post and get).

SleeplessByte commented 4 years ago

If anyone would love to take this, I am happy to accept PR :) Otherwise, I will try to see what I can do for this.

⬆️

wfxr commented 4 years ago

@SleeplessByte @kittinunf I am not sure but it seams that send or drop the body is controlled by this function. Maybe move Method.GET down is enough? I tried but didn't solve the compilation environment for this project. Is anyone else willing to help? https://github.com/kittinunf/fuel/blob/f16bd8e30c73812c20d46b5c0368829b4867daa2/fuel/src/main/kotlin/com/github/kittinunf/fuel/toolbox/HttpClient.kt#L274-L277

crtlib commented 3 years ago

I'm afraid there isn't much we can do to make it work as the underlying HttpURLConnection does some weird thing for some unknown to me backward compatibility reasons:

if (method.equals("GET")) {
    method = "POST"; // Backward compatibility
}

https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java#L1405

emanuele-dedonatis commented 3 years ago

I know GET should not have request body, but I need to fetch data from a site implemented in this way :(

I'm unable to send body with Fuel v2.3.1 but maybe what I found could help the fix: this is my code

val myGet = "https://webhook.site/210d9c41-b0a1-48fa-b2e5-0b28d89831c8"
    .httpGet()
    .jsonBody("""{"test":"EdVXcwrUCkJu2T2mUfAgzemvSDDxYqDLECvx24Wk"}""")
    .responseString { request, response, result ->
        println(request.cUrlString())
    }
myGet.join()

it prints this cURL that doesn't send body

curl -i -d "{\"test\":\"EdVXcwrUCkJu2T2mUfAgzemvSDDxYqDLECvx24Wk\"}" -H "Content-Type:application/json" https://webhook.site/210d9c41-b0a1-48fa-b2e5-0b28d89831c8

BUT if I add --request GET to the cURL it sends the body

curl -i --request GET -d "{\"test\":\"EdVXcwrUCkJu2T2mUfAgzemvSDDxYqDLECvx24Wk\"}" -H "Content-Type:application/json" https://webhook.site/210d9c41-b0a1-48fa-b2e5-0b28d89831c8
SleeplessByte commented 3 years ago

Hi @emanuele-dedonatis . Unfortunately we're still constraint by the underlying HTTP library.