Skip to content

Http-Client decodes semicolons ";", error with PostgREST #60756

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
BenjaminLeseur opened this issue Jun 11, 2025 · 2 comments
Closed

Http-Client decodes semicolons ";", error with PostgREST #60756

BenjaminLeseur opened this issue Jun 11, 2025 · 2 comments

Comments

@BenjaminLeseur
Copy link

BenjaminLeseur commented Jun 11, 2025

Symfony version(s) affected

5.4 - 7.3

Description

Hello,
Http-Client decodes semicolons ; in https://github.com/symfony/symfony/blob/5.4/src/Symfony/Component/HttpClient/HttpClientTrait.php#L663 making this library not friendly to use with PostgREST (PgREST).

Personally, I do not understand why the code does not rely only on http_build_query() and what it is better to decode some characters.

PostgREST needs to have the encoded version %3B of ;, otherwise it cut the string and throw an error.

curl 'http://localhost:3009/my_table?tags=ov.%7Baaa%3Bbbb%7D' # -> OK, one result
curl 'http://localhost:3009/my_table?tags=ov.%7Baaa;bbb%7D' # -> KO, error
# `{"code":"22P02","details":"Unexpected end of input.","hint":null,"message":"malformed array literal: \"{aaa\""}`

How to reproduce

Run theses SQL queries:

create table my_table as select 1 AS id, ARRAY['aaa;bbb'] AS tags;
grant select on my_table to app_user;
-- SQL: (operator `&&` is the same as `overlap(var1, var2)`)
select * from my_table where tags && '{aaa;bbb}'; -- -> OK, one result
select * from my_table where tags && '{aaa%3Bbbb}'; -- -> OK, empty

Characters reminder:

  • urlencode { is %7B
  • urlencode } is %7D
  • urlencode ; is %3B
<?php
require 'vendor/autoload.php';

$client = \Symfony\Component\HttpClient\HttpClient::create();

$query = [
    'tags' => 'ov.{aaa;bbb}',
];
$request = $client->request('GET', 'http://localhost:3009/my_table', [
    'query' => $query,
]);

dump(
    \http_build_query($query), // good: "tags=ov.%7Baaa%3Bbbb%7D"
    \urlencode($query['tags']), // good: "ov.%7Baaa%3Bbbb%7D"
    \rawurlencode($query['tags']), // good: "ov.%7Baaa%3Bbbb%7D"
    \parse_url($request->getInfo()['url'], \PHP_URL_QUERY), // wrong: "tags=ov.%7Baaa;bbb%7D"
    // { } are still encoded but not ;
);

// Call to PostgREST
dump($request->getStatusCode()); // 400
dump($request->getContent(false));
// "{"code":"22P02","details":"Unexpected end of input.","hint":null,"message":"malformed array literal: \"{aaa\""}"

// Manual encoding
$request = $client->request('GET', 'http://localhost:3009/my_table?tags=ov.%7Baaa%3Bbbb%7D');
dump($request->getStatusCode()); // 200
dump($request->getContent(false));
// "[{"id":1,"tags":["aaa;bbb"]}]"

Possible Solution

  • Remove the decoding of ; in HttpClientTrait.

Additional Context

No response

@nicolas-grekas
Copy link
Member

nicolas-grekas commented Jun 11, 2025

You don't have to let the client do the encoding: if its logic doesn't fit your need, you can encode on your side:
$client->request('GET', 'http://localhost:3009/my_table?'.http_build_query($query))
encoding URIs is a quite difficult topic, with a very wide range of behaviors

You should also open an issue on pgrest to ask them to fix that behavior on their side.

@BenjaminLeseur
Copy link
Author

Yes, you're right.

Thank you for your prompt reply. Have a nice day!

@nicolas-grekas nicolas-grekas closed this as not planned Won't fix, can't repro, duplicate, stale Jun 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants