ktor icon indicating copy to clipboard operation
ktor copied to clipboard

Can't set FormUrlEncoded header for ktor http client request

Open wilyarti opened this issue 6 years ago • 12 comments

Ktor Version

1.1.1

Ktor Engine Used(client or server and name)

Apache

JVM Version, Operating System and Relevant Context

Ubuntu 18.04 Information:Kotlin: kotlinc-jvm 1.3.11 (JRE 1.8.0_191-8u191-b12-0ubuntu0.18.04.1-b12)

Feedback

I am trying to POST a request to an API that uses Content-Type: application/x-www-form-urlencoded.

val message = client.post<Unit> {
    url(URL("https://tapi.telstra.com/v2/oauth/token"))
    contentType(ContentType.Application.FormUrlEncoded)
    body = getAuth(client_id = "overriddenkey", client_secret = "overridenpass")
}

I get the error: io.ktor.http.UnsafeHeaderException: Header Content-Type is controlled by the engine and cannot be set explicitly

I can't figure out how to set the headers in the client constructor. The documentation https://ktor.io/clients/http-client/calls/requests.html specifies that custom headers can be set using HttpRequestBuilder.

How do I specify the contentType and set the header data? I could not figure it out from your documentation.

wilyarti avatar Jan 16 '19 23:01 wilyarti

Hi, we bumped into this problem a while ago as well. Going through the code, I believe that the current way of doing this is by using FormDataContent like so (without specifying a contentType):

body = FormDataContent(parametersOf( "client_id" to "overriddenkey", "client_secret" to "overridenpass") )

Last time I checked this was not stated somewhere in the documentation though.

tasmalinakis avatar Jan 18 '19 09:01 tasmalinakis

Thanks that seems to work. Although I still need to also be able to set the body of the message with JSON to communicate with the API.

But at least I am 50% there now.

wilyarti avatar Jan 19 '19 00:01 wilyarti

I'm having this same issue, I need to add the header and the body, but seems like it's not possible to add both, which makes the API call fail. Has anyone found a workaround for this?

francos avatar Jul 13 '19 15:07 francos

@e5l I will start changing documentation in few days, any comments related to PR are welcome.

semyannikov avatar May 27 '20 21:05 semyannikov

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.

oleg-larshin avatar Aug 10 '20 15:08 oleg-larshin

Anyone fixed this problem? help, the same problem.

woniupapa avatar Nov 28 '20 10:11 woniupapa

Anyone fixed this problem? help, the same problem.

I haven't looked at this issues in a long time. What I did at the time was use a different http client.

wilyarti avatar Nov 28 '20 10:11 wilyarti

1591606717481_ pic 1601606717561_ pic 1611606717644_ pic 1621606718988_ pic Please help me!,There are many pictures.

woniupapa avatar Nov 30 '20 06:11 woniupapa

@wilyarti I don't know how to post with formdata content.

woniupapa avatar Nov 30 '20 06:11 woniupapa

@wilyarti Dear Wilyarti, I removed //contentType(ContentType.Application.Json) code,It work!!!

woniupapa avatar Nov 30 '20 13:11 woniupapa

@wilyarti as a workaround you can override a contentType property of the OutgoingContent class. Here is an example:

val message = client.post<String> {
    url(URL("https://httpbin.org/post"))
    body = object : OutgoingContent.ByteArrayContent() {
        override val contentType = ContentType.Application.FormUrlEncoded
        override fun bytes(): ByteArray {
            return """{"x": 123}""".toByteArray(Charsets.UTF_8)
        }
    }
}

Stexxe avatar Jul 07 '21 10:07 Stexxe

@e5l I'm currently working on this. to override contentType, it must be removed from UnsafeHeadersArray in HttpHeaders.kt. Is it ok to remove this from UnsafeHeadersArray?

EhsanMsz avatar Mar 04 '22 16:03 EhsanMsz