p5-http-tiny icon indicating copy to clipboard operation
p5-http-tiny copied to clipboard

don't re-order multiple values for the same key with post_form

Open neilb opened this issue 6 years ago • 3 comments

I'm using an API that can take multiple strings, and returns a result for each string, in the same order as the strings were provided.

Initially I was doing this:

my $form_data = { 'q[]' => \@strings };
my $response  = $ua->post_form($url, $form_data, $headers);

But I found that depending on the strings, I wasn't getting the responses back in the expected order.

I just realised that the strings are being sorted, because of this line in www_form_urlencode():

return join("&", (ref $data eq 'ARRAY') ? (@terms) : (sort @terms) );

So for my case, I can fix it by doing this:

my $form_data = [ 'q[]' => \@strings ];

But I think that for the law of least surprise, I think a better behaviour would be to sort on the keys, but within a key to preserve the order.

neilb avatar Jul 15 '19 21:07 neilb

Here's one way to achieve that. In www_form_urlencode():

Change this line:

my @params = ref $data eq 'HASH' ? %$data : @$data;

To:

my @params = ref $data eq 'HASH'
           ? map { ($_, $data->{$_}) } sort keys %$data
           : @$data;

And then the final line becomes:

return join("&", @terms);

neilb avatar Jul 16 '19 11:07 neilb

I'm happy to submit a PR for this, if you're ok with this?

neilb avatar Jul 16 '19 14:07 neilb

Sorry to take so long to get to this. A PR with tests would be great.

xdg avatar Jul 20 '21 01:07 xdg