bruno icon indicating copy to clipboard operation
bruno copied to clipboard

(+) plus symbol in query parameter turns into space instead of encoding as %2B

Open abdulmahamaliyev opened this issue 1 year ago • 2 comments

I have checked the following:

  • [X] I use the newest version of bruno.
  • [X] I've searched existing issues and found nothing related to my issue.

Describe the bug

Updated bruno recently and some of old requests don't work because + sign in query parameter gets replaced by a space.

As a workaround, replacing (+) sign with %2B resolves the issue.

I'm at work so can't provide screenshot right now

.bru file to reproduce the bug

No response

Screenshots/Live demo link

N/A

abdulmahamaliyev avatar Sep 25 '24 03:09 abdulmahamaliyev

Could you add some examples?

mroderick avatar Sep 27 '24 08:09 mroderick

I went through this elsewhere, but its not a bug spaces can be interpreted as + or %20. https://en.wikipedia.org/wiki/Query_string

alifemove avatar Oct 03 '24 18:10 alifemove

Could you provide some examples?

Hey @mroderick,
Here is an example that demonstrates this behavior:

https://github.com/user-attachments/assets/799da1d8-f158-4101-a727-c668c4c7703f

As @alifemove mentioned, this is not a bug. A query string can contain either + or %20 to represent spaces. Additionally, @abdulmahamaliyev, using %2B would be a good enhancement, and I agree with that.

Pragadesh-45 avatar Oct 04 '24 05:10 Pragadesh-45

I faced this bug myself today, and was thoroughly confused by it. Thought it was a bug in my code, rather than bruno.

A solution would be:

  • Anything that's input in the param is treated as if it wasn't encoded yet, so if you write + in the param it will be converted to %2B
  • Anything that's input in the url is treated as if it was already encoded. So if you write + in the url, it will be converted to %20 or in the param field.

But when I input a string in the param, I expect it to be treated as a string that will be encoded still, instead of verbatim copying it to the url

Dunky13 avatar Nov 13 '24 13:11 Dunky13

Workaround I created was a collection pre-request script:

const [url,params] = req.url.split('?');
if(!params) return;
const encodedParams = params.split('&').map((kv) => {
  const [k,v] = kv.split('=');
  return `${k}=${encodeURIComponent(v)}`;
}).join('&');
req.setUrl(`${url}?${encodedParams}`);

Dunky13 avatar Nov 13 '24 13:11 Dunky13

As this is not a bug this should be closed. The standards say that + is to be treated as a space, which is what Bruno is doing. Any workarounds being created or changes to Bruno would be going against the standards. Standards also say if you want a literal + you should use %2B, which was stated in the original issue that %2B works, because again, Bruno is working as it should.

alifemove avatar Nov 13 '24 14:11 alifemove

@alifemove I agree that the + in the url should be treated as a space, as is the spec (and Bruno)

But there is also part of user expectation, that when they (me included) put a + in the param value field, to be treated as a string literal, and be encoded as such. Hence, in my first comment here I suggested that the + in the url bar would be treated according to the spec as a whitespace, but the + in a param field, would be treated as string literal, and to be encoded. Since as a user it's not unreasonable to expect that input fields are as seen. - not everyone is fully aware of the intricacies of the spec. Hope that makes sense

Dunky13 avatar Nov 13 '24 14:11 Dunky13

Also one more point I'd like to add based on the video above. Bruno decodes from the url into the param fields (+ in url becomes in param field) But doesn't encode the other way around (param field is not encoded into the url)

Hence inconsistent behaviour :)

Dunky13 avatar Nov 13 '24 21:11 Dunky13

Following up to https://github.com/usebruno/bruno/issues/3187#issuecomment-2473690689, the script should split only the first occurrence of the = in the event you have parameters like &filter=id=1234.

const [url,params] = req.url.split('?');
if(!params) return;
const encodedParams = params.split('&').map((kv) => {
  const [k,...vs] = kv.split('=');
  const v = vs.join("=")
  return `${k}=${encodeURIComponent(v)}`;
}).join('&');
req.setUrl(`${url}?${encodedParams}`);

drwelby avatar Dec 09 '24 18:12 drwelby

Previously this message contained a wrong optimization. Please ignore this for future reference

Dunky13 avatar Dec 09 '24 18:12 Dunky13

Good point! Here's a slightly more optimized, split can set a limit

Limit works differently than you'd expect (unless you're coming from Java?)

[k,v] = "filter=a=1 and b=2".split('=', 2);

will result in a k = "filter" and v = a

drwelby avatar Dec 09 '24 19:12 drwelby

Good point! Here's a slightly more optimized, split can set a limit

Limit works differently than you'd expect (unless you're coming from Java?)

[k,v] = "filter=a=1 and b=2".split('=', 2);

will result in a k = "filter" and v = a

Damn you're right. Scratch my previous suggestion!

Dunky13 avatar Dec 09 '24 19:12 Dunky13

ran into the same issue. its sad that the features hasn't been added yet :(

xidsyed avatar Feb 12 '25 15:02 xidsyed

This issue has been resolved by #5089 and is available starting from v2.8.0.

URL encoding is no longer visibly applied in the UI — both the Params table and the Request URL field now display values exactly as entered by the user. Bruno will continue to send encoded values to the API server (unless URL encoding is explicitly disabled in the Settings tab for each request).

🔧 Note: URL encoding is enabled by default for newly created requests. However, for backward compatibility, requests from older collections will require manual enabling of this setting if needed.

Closing this issue now. Feel free to reopen it if you continue to experience the problem.

maintainer-bruno avatar Aug 06 '25 07:08 maintainer-bruno