Okhttp: Ampersand "&" in the request in the filter body is not encoded as "%26"

Created on 18 Sep 2019  路  7Comments  路  Source: square/okhttp

When the field value contains the ampersand "&" for example, "Brothers & Co" and I use that value like filter in the query, after encoding string to query I have ampersand "&" in the filter body, like this:
https://example.eu/exsource/User?ormat=json&$filter=(username%20eq%20%27examlpleusername%27%20and%20filtername%20eq%20%2Brothers%20&%20Co%27)&asOfDate=2019-09-13

So this request does not work and I become Http response with status code 500. For correct work I should to convert it to "%26" additionally.

bug

Most helpful comment

I鈥檓 sorry I misunderstood the original report here. I was under the impression that URLs constructed by OkHttp with our HttpUrl.Builder were not correctly encoding &. But in this case the URL in is the URL out, and that鈥檚 working as designed.

I believe the real problem is whatever creates this URL:

https://example.eu/exsource/User?ormat=json&$filter=(username%20eq%20%27examlpleusername%27%20and%20filtername%20eq%20%2Brothers%20&%20Co%27)&asOfDate=2019-09-13

If you use HttpUrl.Builder to make it, it鈥檒l do the right thing.

    HttpUrl url = new HttpUrl.Builder()
        .scheme("https")
        .host("example.eu")
        .encodedPath("/exsource/User")
        .addQueryParameter("ormat", "json")
        .addQueryParameter("$filter",
            "username eq 'examlpleusername' and filtername eq Brothers & Co")
        .addQueryParameter("asOfDate", "2019-09-13")
        .build();

    System.out.println(url);
https://example.eu/exsource/User?ormat=json&%24filter=username%20eq%20%27examlpleusername%27%20and%20filtername%20eq%20Brothers%20%26%20Co&asOfDate=2019-09-13

All 7 comments

Seems like a bug. Which version are you using?

Now I am using the latest version - 4.2.0

@Valentin0810 Could you please add the snippet of the code that fails to encode the ampersand. I am trying to investigate the issue so i can take it up but it seems to be working fine. Thanks.

@archibishop The snippet of the code that fails to encode the ampersand:

String url = "https://example.eu/exsource/User?format=json&$filter=filtername eq 'Brothers & Co'";
Request request = new Request.Builder().url(url).build();
new OkHttpClient.Builder().build().newCall(request).execute();

Thank you very much for your efforts.

Do you expect OkHttp to parse the query part of the URL? How should it know that the first & is to be used as is while the second shall be encoded? Maybe it would be better to build the URL using a library or a helper method.

You could use okhttp3.HttpUrl to build the URL instead of using a raw string.

I am working on something to fix this issue but for now you can use what has been suggested by @lutzhorn.

I鈥檓 sorry I misunderstood the original report here. I was under the impression that URLs constructed by OkHttp with our HttpUrl.Builder were not correctly encoding &. But in this case the URL in is the URL out, and that鈥檚 working as designed.

I believe the real problem is whatever creates this URL:

https://example.eu/exsource/User?ormat=json&$filter=(username%20eq%20%27examlpleusername%27%20and%20filtername%20eq%20%2Brothers%20&%20Co%27)&asOfDate=2019-09-13

If you use HttpUrl.Builder to make it, it鈥檒l do the right thing.

    HttpUrl url = new HttpUrl.Builder()
        .scheme("https")
        .host("example.eu")
        .encodedPath("/exsource/User")
        .addQueryParameter("ormat", "json")
        .addQueryParameter("$filter",
            "username eq 'examlpleusername' and filtername eq Brothers & Co")
        .addQueryParameter("asOfDate", "2019-09-13")
        .build();

    System.out.println(url);
https://example.eu/exsource/User?ormat=json&%24filter=username%20eq%20%27examlpleusername%27%20and%20filtername%20eq%20Brothers%20%26%20Co&asOfDate=2019-09-13
Was this page helpful?
0 / 5 - 0 ratings