okhttp: IllegalArgumentException: Unexpected char 0xea - android

I am sending Latin character as HTTP header from my android code using okhttp
Builder builder=new Builder();
builder.url(myURL);
builder.addHeader("Original-Filename", "tête-à-tête.pdf");
But, I am getting IllegalArgumentException: Unexpected char 0xea at 1
I am able to send the same header from Postman or by using HttpsURLConnection. Also, the character is an excepted header format as per HTTP1.1 documentation.
So, then why is okHttp not supporting the following character? Also, is there any workaround this without changing code on the server-side by doing Base64 encoding and decoding.
I am using okttp version 4.4.0. Also, I have already gone through https://github.com/square/okhttp/issues/2016 before anyone repeats the same thing.

For anyone looking for the answer, I found the answer.
We can use addUnsafeNonAscii to solve this issue.
Below is the simple code snippet of it
Headers headers = new Headers.Builder()
.addUnsafeNonAscii("Original-Filename", "tête-à-tête.pdf")
.build();
By doing this we can avoid server-side changes, although in the long term it is suggested to use Base64 encoding on client-side and decoding that on the server-side.

Related

Decode a string encoded with Brotli returned by Android Volley

I'm sending an http request to a website using Volley (POST and StringRequest). The call is correctly executed. However, I can see that the result is a string codified. When seeing the headers of the answer I can see it is encoded in br, which means brotli. How can I decode the answer to later read it as a JSON?
Should I change to OkHttp or another alternative?

Avoid '#' char getting url encoded during POST #FormUrlEncoded request

I've been busting my head for about two days now but neither I nor my colleagues seem to be able to disable URL encoding for a client_secret field in a #POST request when using Retrofit. We need to fetch an access token from an API endpoint that requires the following parameters in application/x-www-form-urlencoded format:
grant_type: "client_credentials"
scope: "CustomerService.WebApi"
client_id: "somerandomid"
client_secret: "XX#XXXXXXXXXXXXX"
The issue occurs when the '#' char in the client_secret field gets URL-encoded into %40 and our client's backend can't handle it. Using Postman, this encoding doesn't seem to happen and we successfully get a hit.
Here's what we have tried so far:
Specifying encoded=true inside the #Field/#FieldMap annotation
Removing the #FormUrlEncoded annotation and specifying it manually in the header while using a RequestBody as an In parameter and building the request body using a FormBuilder
Using both #FieldMap and #Field annotations but none of them worked
Setting disableHtmlEscaping() to the Gson instance used by the retrofit client
I've been looking at tons of stack posts and git issues but there doesn't seem to be a fix for POST requests. Some people blame the OkHTTP client, some Gson, and some Retrofit 2. JakeWharton advocates that Retrofit's test regarding the encoded=true flag does indeed work. Does anybody have a clue on how to resolve this?
P.S. Please do not mark this as a duplicate if the associated post doesn't have a valid answer (like most of the posts I've looked at).
OkHttp (and therefore Retrofit) follows this spec that requires # to be percent-escaped when encoded. I expect the same behavior is true of web browsers: they will also encode the # character.
You should direct your server’s maintainers to conform to the corresponding parsing spec. If they cannot, you may need to manually replace %40 with # on your outbound request body, perhaps with an OkHttp interceptor.

OkHttp POST request set withCredentials to True?

Can't get past Django Rest Framework Token Authorization because I can't set withCredentials=true using OkHttp RequestBuilder. (I'm referring to this https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials)
In javascript using axios.post this works fine. I'm having trouble converting this post request to android using OkHttp request builder.
Request builder only seems to give setter methods for Header and Body of post Request?
Tried reading through OkHttp documentation and I've also tried to send withCredentials=True as a header
Django Rest Framework backend not recognizing the token and not resolving the bearer token to a user.
If no class authenticates, request.user will be set to an instance > of django.contrib.auth.models.AnonymousUser, and request.auth > will be set to None.
I'm going to assume here that withCredentials is a query parameter.
Appending ?withCredentials=true. to the end of the URL will probably get things going for you.
An example in full might look like https://www.example.com?withCredentials=true.
With multiple parameters, it may look like https://www.example.com?withCredentials=true&otherParam=Stuff.

Retrofit incorrect response error on android

When i call any webService with expired token,the service returns code 498 with error message "your tokken is expired"..BUT the retrofit gives the response code 500 with error message " internel server error".
response.code() //500 instead of 498
I tested the same url with postman and its working fine but the issue is only with retrofit.
I am using same services on IOS with AFNetworking and its also working fine there.
Any body can help to figure out why this is happening? thanks in advance.
This is not a full answer, but it's too big for a comment.
5xx codes are server errors, this means that the server is crashing, not the app nor is retrofit buggy. The issue most likely is in the server, but can be caused by retrofit - yes, that's true.
My experience with all the questions that say: "I tried this insert random network call here with postman and it works, but retrofit returns 500" is because postman adds headers by default, which retrofit doesn't. The server implementation then expects these headers to be set and due to a faulty implementation crashes if said headers are missing.
I would check the headers retrofit is sending and the headers postman is sending and compare both and make sure which one crashes the server.
It can also be that OkHttp (Retrofit uses OkHttp under the hood) is adding some headers which the server cannot cope with. This would be stranger to me, but not impossible. I think it adds for example by default gzip and some servers might not handle this correctly.
If you have access to the server, than it might even be worth checking there the logs. They might point you right away to the issue.
I'm sorry but I cannot point you directly to the problem. These are just tips to get you started. Hope they help.

HTTP Response 411 Length Required, Http Client 4.0.1 Android

i'm sending an http request to the google reader api and getting an unusual response code. following the documentation, i've requested an auth code and included it in the header of every request. after performing the login, and getting an auth code, i tried accessing this url, which is part of the documentation:
http://www.google.com/reader/api/0/stream/items/contents
when i send the request, i get a 411 status code, which is supposed to mean "Length Required". the length, as i've found, is supposed to be the length, in octets, of the message body. there is no message body in this request. there is only a single header, the POST parameter i="item id" and the URL itself. i tried setting the "Content-Length" header to "0" and also to "-1" to no avail.
what's really interesting is that this same code worked fine before google changed their authorization procedure. it's apparent they've changed something else...
so my question is what EXACTLY would cause a 411 response code and how can i prevent it?
This error happens only with POST and PUT request types, as these two (sort of) expect to have a request body that includes the request parameters (plain textual as well as attachments).
However as the documentation suggests, this is largely an obsolete value, and realistically the web services should handle requests without relying on Content-Length.
So it's not the problem of a request sender, but it is (I would say) a bug on the service side.
Nevertheless, setting a Content-Length (mind the proper capitalisation) request header to 0 should be the workaround.

Categories

Resources