Pass GET parameters with Ruby Curb

2019-05-09 11:46发布

问题:

I'm trying to use Curb (curb.rubyforge.org) to call a RESTful API that needs parameters supplied in a get request.

I want to fetch a URL like http://foo.com/bar.xml?bla=blablabla. I'd like to be able to do something like

Curl::Easy.perform("http://foo.com/bar.xml", :bla => 'blablabla') {|curl|
    curl.set_some_headers_if_necessary
}

but so far, the only way I can see to do this is by manually including the ?bla=blablabla in the URL and doing the encoding myself. Surely there is a right way to do this, but I can't figure it out reading the documentation.

回答1:

If you don't mind using ActiveSupport '~> 3.0', there's an easy workaround - to_query method, which converts hash to query string ready to be used in URL.

# active_support cherry-pick
require 'active_support/core_ext/object/to_query'

params = { :bla => 'blablabla' }

Curl::Easy.perform("http://foo.com/bar.xml?" + params.to_query) {|curl|
    curl.set_some_headers_if_necessary
}


回答2:

To pass get parameters with the ruby curb gem you could use

Curl::postalize(params)

This functions actually falls back to URI.encode_www_form(params) in the curb gem implementation. https://github.com/taf2/curb/blob/f89bb4baca3fb3482dfc26bde8f0ade9f1a4b2c2/lib/curl.rb

An example on how to use this would be

curl = Curl::Easy.new
curl.url = "#{base_url}?#{Curl::postalize(params)}"
curl.perform

To access the curl return string you could use.

data = curl.body_str

The second alternatives would be

curl = Curl::Easy.new
curl.url = Curl::urlalize(base_url, params)
curl.perform
data = curl.body_str

Do note that Curl::urlalize might be slightly flawed see this pull for postalize that has fix this flaw but the urlalize still uses the old implementation.



回答3:

How about simply passing a URI escape'd url to the perform(http_get) method?

See http://www.ruby-doc.org/stdlib-1.9.3/libdoc/uri/rdoc/URI/Escape.html

Curl::Easy.perform(URI.escape("http://foo.com/bar.xml?bla=blablabla").to_s) {|curl|
    curl.set_some_headers_if_necessary
}


回答4:

Have you considered a different gem? rest-client works fairly well and lets you do:

RestClient.get 'http://example.com/resource', {:params => {:id => 50, 'foo' => 'bar'}}

(I realize you asked about Curb. I don't have any experience with Curb, sorry. rest-client has been pretty reliable every time I've used it).