kittinunf / fuel

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

Fuel generates wrong request #726

Open RankoR opened 4 years ago

RankoR commented 4 years ago

Bug Report

Description

I have this code:

val (request, response, result) = Fuel
            .post(iamUrl)
            .jsonBody(jwtPayload)
            .response()

jwtPayload is a JSON string like {"jwt": "..."}

If I call request.cUrlString(), and execute curl command from the output, it works fine:

curl -i -X POST -d "{\"jwt\":\"...\"}" -H "Accept:application/json" -H "Content-Type:application/json" https://iam.api.cloud.yandex.net/iam/v1/tokens

HTTP/2 200 
content-type: application/json
x-request-id: 8bee05fb-dac6-9ca1-9eb5-4e7f78b9e309
x-envoy-upstream-service-time: 27
grpc-status: 0
grpc-message: 
content-length: 821
date: Wed, 25 Mar 2020 21:18:05 GMT
server: envoy

{
 "iamToken": "...",
 "expiresAt": "2020-03-26T09:18:05.707983Z"
}

But the Fuel's request ends with backend's 503 error:

--> POST https://iam.api.cloud.yandex.net/iam/v1/tokens
Body : {"jwt":"..."}
Headers : (1)
Content-Type : application/json

<-- 503 https://iam.api.cloud.yandex.net/iam/v1/tokens
Response : Service Unavailable
Length : 95
Body : upstream connect error or disconnect/reset before headers. reset reason: connection termination
Headers : (4)
date : Wed, 25 Mar 2020 21:25:04 GMT
server : envoy
content-type : text/plain
content-length : 95

Simple HttpsUrlConnection implementation also works fine:

        val type = "application/json"
        val u = URL(iamUrl)
        val conn: HttpsURLConnection = u.openConnection() as HttpsURLConnection
        conn.setDoOutput(true)
        conn.setRequestMethod("POST")
        conn.setRequestProperty("Content-Type", type)
        conn.setRequestProperty("Accept", type)
        conn.setRequestProperty("Content-Length", jwtPayload.length.toString())
        val os: OutputStream = conn.outputStream
        os.write(jwtPayload.toByteArray())
        val text = conn.inputStream.reader().readText()

        println(text)
{
 "iamToken": "...",
 "expiresAt": "2020-03-26T10:08:10.229141Z"
}

Environment

Development Machine

kittinunf commented 4 years ago

Isn't 503 temporarily unavailable?

503 SERVICE UNAVAILABLE
The server is currently unable to handle the request due to a temporary overload or scheduled maintenance, which will likely be alleviated after some delay

Do you think the server's fault in here? It looks like not on our fault? Can you see the server's log what wrong over there?

RankoR commented 4 years ago

@kittinunf curl request, generated by Fuel, works fine. Manually built HttpsUrlConnection request works fine too.

I think that server does not handle wrong request properly and responds with 503 instead of 400, but anyway Fuel seems to send wrong data.

I don't have server logs, this server belongs to Yandex.

I wanted to send bug report to Yandex too (because they do not handle bad requests properly), but I can't, because I can't see full raw request (Fuel debug logs are not enough)

kittinunf commented 4 years ago

True dat! Please allow me to investigate on this, I will create the yandex account and investigate.

AngryJKirk commented 3 years ago

I have the same issue here.

And yeah, the backend is Yandex.Cloud (Yandex Translate API).

I guess they reinvented the wheel one more time since it's that specific :)

OS: Windows 11 Pro Insider Preview 22454.1000 IDE: IDEA 2021.2.1 Fuel version: 2.3.1 Kotlin version: 1.5.21