Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Nested HTTP params on ruby HTTP requests

Reply
Thread Tools

Nested HTTP params on ruby HTTP requests

 
 
Dave Garcia
Guest
Posts: n/a
 
      06-04-2009
Hi,

I'm using ruby HTTP classes to send POST requests to a server. The
problem is that I'm posting some many-levels hierarchical structures on
my form . When POST parameters are simple key/value there's no
serialization problem with form_data method on PostRequest.

{ :a => :b} => "a=b"

When the values are arrays it works fine too

{ :a => [:b,:c,:d]} => "a[]=b&a[]=c&a[]=d"

But when values are hashes serialization doesn't work as expected.

For example
{ :a => [{:b => :c}, {:d => :e}]} => "a[][b]=c&a[][d]=e"

I don't know if there's any other way to do it but browsing the code it
seems that only one nesting level is supported (maybe is an issue on my
ruby version 1.8.6).

I developed a tiny serialization method. Is a quick and dirty code (the
first release I've made) but it works for me.

module FormSerializer
require "erb"
include ERB::Util

def serialize_form_data(data, path = "",serialized_params = [])
if data.kind_of? Hash
data.each_pair{|k,v| token = (path == "" ? url_encode(k) :
"[#{url_encode(k)}]"); serialize_form_data(v, "#{path}#{token}",
serialized_params)}
elsif data.kind_of? Array
data.each{|v| serialize_form_data(v, "#{path}[]",
serialized_params) }
else
#end of recursion
serialized_params << "#{path}=#{url_encode(data)}"
end

return serialized_params.join("&") if (path == "")
end


#{ :a => :b} = "a=b"
#{ :a => [:b,:c,:d]} = "a[]=b&a[]=c&a[]=d"
#{ :a => :b, :b => :c} = "a=b&b=c"
#{ :a => {:b => :c}} = "a[b] = c"
#{ :a => [{:b => :c}, {:d => :e}]} = "a[][b] = c & a[][d] = e"


end

After this I only needed to modify

def form_data(params, sep = '&')
self.body = serialize_form_data(params)
self.content_type = 'application/x-www-form-urlencoded'
end

I just finished the code some hours ago, basic testing has been
performed.
Hope this will be useful for anyone!

Best regards

Dave Garcia
--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
 
 
 
Brian Candler
Guest
Posts: n/a
 
      06-04-2009
Dave Garcia wrote:
> { :a => :b} => "a=b"
>
> When the values are arrays it works fine too
>
> { :a => [:b,:c,:d]} => "a[]=b&a[]=c&a[]=d"
>
> But when values are hashes serialization doesn't work as expected.
>
> For example
> { :a => [{:b => :c}, {:d => :e}]} => "a[][b]=c&a[][d]=e"


Well, firstly, you didn't say what framework is parsing this form data.
But also, in this example you're doing mixtures of arrays and hashes,
and I don't think that's likely to work. (Of course, feel free to make a
patch for whatever framework you're using, and submit it)

I think you'll have more luck with hashes of hashes:

a[b][c]=d&a[b][d]=e

will probably be deserialised as {'a'=>{'b'=>{'c'=>'d','e'=>'f'}}}

At least, I'm reasonably sure Rails can handle this. Rack had some
issues with its parsing of nested form-data parameters which may or may
not have been fixed yet. And if you're using some other framework with
its own parameter parsing, then you'll need to look at that separately.

> I don't know if there's any other way to do it but browsing the code it
> seems that only one nesting level is supported (maybe is an issue on my
> ruby version 1.8.6).


It's unlikely to be anything to do with your ruby version, unless the
deserialisation is being done by some code which is bundled with ruby
(the CGI library??)
--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
 
 
 
Brian Candler
Guest
Posts: n/a
 
      06-04-2009
Of course, I meant

a[b][c]=d&a[b][e]=f

will probably be deserialised as {'a'=>{'b'=>{'c'=>'d','e'=>'f'}}}
--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
Dave Garcia
Guest
Posts: n/a
 
      06-04-2009
Hi Brian,

On the client side:

params = {:a=>[{:d=>:e, :b=>:c}]}
serialize_form_data(params) # "a[][d]=e&a[][b]=c"

On the server side Rails 2.3.2 works fine deserializing my params are :

{"a"=>[{"b"=>"c", "d"=>"e"}], "action"=>"show",
"controller"=>"identities"}

Maybe you're right , I'll talk with the guys in RoR maybe they're
interested.

Best regards

Dave

Brian Candler wrote:
> Of course, I meant
>
> a[b][c]=d&a[b][e]=f
>
> will probably be deserialised as {'a'=>{'b'=>{'c'=>'d','e'=>'f'}}}


--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
Brian Candler
Guest
Posts: n/a
 
      06-04-2009
Dave Garcia wrote:
> On the client side:
>
> params = {:a=>[{:d=>:e, :b=>:c}]}
> serialize_form_data(params) # "a[][d]=e&a[][b]=c"
>
> On the server side Rails 2.3.2 works fine deserializing my params are :
>
> {"a"=>[{"b"=>"c", "d"=>"e"}], "action"=>"show",
> "controller"=>"identities"}


Then I've lost you, because that all seems to be working fine (both
serialize_form_data and RoR deserializing it)

So can you give an example of what the problem actually is?

> But when values are hashes serialization doesn't work as expected.
>
> For example
> { :a => [{:b => :c}, {:d => :e}]} => "a[][b]=c&a[][d]=e"


Maybe I misunderstood this. Is this what your code actually produces, or
what you expected it to produce? If not, what did you expect it to
produce?
--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
Dave Garcia
Guest
Posts: n/a
 
      06-05-2009
Hi Brian,

you're not lost I explained myself terrible, my fault .

Those example of serializations are produced by my code. I tested it
only sending post request vs rails, but it worked fine with all proposed
examples.

Sorry for by bad explanation.

Best regards

Dave

Brian Candler wrote:
> Dave Garcia wrote:
>> On the client side:
>>
>> params = {:a=>[{:d=>:e, :b=>:c}]}
>> serialize_form_data(params) # "a[][d]=e&a[][b]=c"
>>
>> On the server side Rails 2.3.2 works fine deserializing my params are :
>>
>> {"a"=>[{"b"=>"c", "d"=>"e"}], "action"=>"show",
>> "controller"=>"identities"}

>
> Then I've lost you, because that all seems to be working fine (both
> serialize_form_data and RoR deserializing it)
>
> So can you give an example of what the problem actually is?
>
>> But when values are hashes serialization doesn't work as expected.
>>
>> For example
>> { :a => [{:b => :c}, {:d => :e}]} => "a[][b]=c&a[][d]=e"

>
> Maybe I misunderstood this. Is this what your code actually produces, or
> what you expected it to produce? If not, what did you expect it to
> produce?


--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Asynchronous HTTP requests with ruby Eki Ruby 0 02-19-2012 01:36 PM
I can't seem to find an easy way to set Net::HTTP GET params David Sainte-claire Ruby 1 11-23-2009 05:25 PM
HTTP GET requests in a Ruby CGI Script Ben Aroia Ruby 5 03-30-2008 06:06 PM
params v.s. @params in rails? Barry Ruby 9 09-15-2005 03:12 AM
web requests and mobile requests Fernando Arámburu ASP .Net 1 04-08-2005 07:13 PM



Advertisments