Accessing Raw Post Data

Rails conveniently packages post data in the params hash. The order
in which data is stored in a hash is typically not the order in which
the data was entered. Generally this is not a problem; however, there
are some unusual fact patterns in which it is. One of those fact
patterns involves PayPal’s Instant Payment Notification in which
PayPay expects to receive a copy of the params hash parroted back to
them with the elements in the exact order that they were posted.

I am aware that beginning with Ruby 1.9, the elements of a hash are
stored in the order that they were entered. However, I don’t have the
luxury of being that current. Accordingly, it appears that I am going
to have to parse the raw post data and enter it into either an ordered
hash or an array. My question is, how would I go about doing that?

Thanks for any input.

          ... doug

On Jan 13, 2010, at 9:59 AM, doug wrote:

stored in the order that they were entered. However, I don’t have the
luxury of being that current. Accordingly, it appears that I am going
to have to parse the raw post data and enter it into either an ordered
hash or an array. My question is, how would I go about doing that?

Thanks for any input.

         ... doug

Try raw_post
(http://api.rubyonrails.org/classes/ActionController/AbstractRequest.html#M000471)

Try raw_post (http://api.rubyonrails.org/classes/ActionController/AbstractRequest.h…)

Thanks for the suggestion. What I got to work for me was
request.rawpost. That yields a string containing the post data
formatted like a get request. I can take it from here. However, my
approach would be to use brute force to parse the data in that
string. Does anyone have a better methodology? Thanks.

       ... doug

To get an array of ordered keys for the POSTed keys/vals, you could do
something like:

 …
 if request.post?
  ordered_keys = request.raw_post.split(’&’).collect {|k_v|
CGI::unescape(k_v.split(’=’).first.to_s) }
 …

Thanks. That worked great for parsing the raw post data (and it took
me one step closer to final success). The remaining problem is that,
no matter how one slices it, I really need to get the data into an
ordered hash so that I can use the post_form method of Net::HTTP to
return it. Following on with your suggestion, I thought something
like this would work:

ordered_params=ActiveSupport::OrderedHash.new
ordered_keys.each do |key|
  ordered_params[key]=params[key]
end

The problem is that the ordered_params hash does not seem to be
ordered. Any thoughts on how I am going to get over this hurdle?

Thanks again for all the help.

        ... doug

I’d avoid using Net::HTTP to do anything but the most simple of
httpclient work. You’ll save a ton of time/effort by using a more
full featured httpclient to perform your POST.

There are a lot of ruby httpclient options out there. Which one to
use kind of depends on which one you like using that meets your
needs. A couple ruby httpclient libs you might want to look at:

Personally, these days I end up using curl or wget wrapped in ruby for
most of my httpclient work.

Jeff

I’d avoid using Net::HTTP to do anything

Thanks for the input. Your point is well taken.

None-the-less, I’d still like to be able to do this. The problem with
my code seems to be in this line:

ordered_params[key]=params[key]

This is an assignment statement to an element of an ordered hash.
Thus the left-hand-side is supposed to be representative of an element
of an ordered hash. I think the problem is that ‘key’ is a string.
This ordered hash thing doesn’t seem to work correctly when the hash
index is a string. For whatever reason, it only works correctly when
the hash index is a symbol. I think that if I could figure out how to
make ‘key’ a symbol, it would work. The problem is that I have no idea
how to do that. But we are straying away from the original topic.
Perhaps I should post this issue in a new thread. My original
question has been quite well answered.

Thanks again for the input.

       ... doug

To get an array of ordered keys for the POSTed keys/vals, you could do
something like:


if request.post?
ordered_keys = request.raw_post.split(’&’).collect {|k_v|
CGI::unescape(k_v.split(’=’).first.to_s) }

and then use those ordered_keys in to access the params vals to
accomplish your task that requires such ordering.

Jeff

$ irb

irb(main):001:0> “foo”.to_sym.class
=> Symbol

irb(main):002:0> :foo.to_s.class
=> String

Jeff

irb(main):001:0> “foo”.to_sym.class
=> Symbol

irb(main):002:0> :foo.to_s.class
=> String

VIOLA!!! That seems to be the missing link. Thanks ever so much. :slight_smile:

    ... doug

Doug J. wrote:

irb(main):001:0> “foo”.to_sym.class
=> Symbol

irb(main):002:0> :foo.to_s.class
=> String

VIOLA!!!

Viola: string instrument that I happen to play.
Voilà : French for “there it is”.
:slight_smile:

That seems to be the missing link. Thanks ever so much. :slight_smile:

Great. Now the lecture. Couldn’t figure out how turn a String into a
Symbol? Instead of posting to the list, your thought process should
have been something like this:

I need a method to turn a String into a Symbol.
That method deals with an instance of class String.
Therefore, it will probably be an instance method on String, or possibly
a constructor on Symbol.
OK, I’ll look in the rdoc for String and Symbol. I’ll pay particular
attention to the to_* methods, since that’s the Ruby convention for type
conversion.
If I can’t find it there, I’ll search the Web.
If all else fails, I’ll ask the list.

That is how to do efficient Ruby research.

    ... doug

Best,
–Â
Marnen Laibow-Koser
http://www.marnen.org
[email protected]

Click this link and bookmark the Code Search.

That’s really handy. Thanks a batch.

     ... doug

Doug J. wrote:

irb(main):001:0> “foo”.to_sym.class
=> Symbol

irb(main):002:0> :foo.to_s.class
=> String

VIOLA!!! That seems to be the missing link. Thanks ever so much. :slight_smile:

    ... doug

One thing more to consider doug is learning from what you just
discovered. I wrote a program that utilizes all of google’s api to
search anything and everything.

By writing this program which I call GoogleHack, I learned that there’s
a great hidden codebase within google.

Click this link and bookmark the Code Search. When you discover the
answer to some of your questions, particularly around things like this,
you can search in-depth for code examples and find some great hidden
feedback in the process.

http://www.google.com/codesearch?as_q=:foo.to_s&hl=en&as_lang=ruby&as_license_restrict=i&as_license=&as_package=&as_filename=&as_case=