httprb / http

HTTP (The Gem! a.k.a. http.rb) - a fast Ruby HTTP client with a chainable API, streaming support, and timeouts
MIT License
3.01k stars 321 forks source link

GET requests with body params? #729

Open davidmilo opened 2 years ago

davidmilo commented 2 years ago

I am dealing with API which requites that all params to GET requests is passed as body.

I could not figure out how to make such a request with httprb.

.get("my url to api endpoint", body: "event_type=#{event_name}" does not work.

Is there something I am not seeing or it is just not supported right now?

I know GET with params is not the best practice but standard supports it and it is third party API so can't change that 😢

tarcieri commented 2 years ago

The body: should be sent regardless of the HTTP method used:

https://github.com/httprb/http/blob/main/lib/http/client.rb#L176-L190

Can you provide a complete reproduction of the issue?

davidmilo commented 2 years ago

This curl returns 200 response with expected data:

curl --location --request GET 'https://amplitude.com/api/2/taxonomy/event-property' \
--header 'Authorization: Basic MzcwNWMyNGVmMWY5OGMxM2Y3OGY4OTNmN2ZiNDQ5NjI6ZTIwNGMxMjA2ZTc2NDhkZDJjMTI5YjMwM2NlMGQ0OWE=' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'event_type=area_view'

I tried this:

HTTP.basic_auth(user: "3705c24ef1f98c13f78f893f7fb44962", pass: "e204c1206e7648dd2c129b303ce0d49a")
    .get("https://amplitude.com/api/2/taxonomy/event_property", form: { event_type: "area_view" })
    .status
# => 404

I tried this:

HTTP.basic_auth(user: "3705c24ef1f98c13f78f893f7fb44962", pass: "e204c1206e7648dd2c129b303ce0d49a")
    .get("https://amplitude.com/api/2/taxonomy/event_property", body: "event_type=area_view")
    .status
# => <html><title>404: Not Found</title><body>404: Not Found</body></html>

I finally managed to get it to work with this:

HTTP.headers("Authorization" => "Basic MzcwNWMyNGVmMWY5OGMxM2Y3OGY4OTNmN2ZiNDQ5NjI6ZTIwNGMxMjA2ZTc2NDhkZDJjMTI5YjMwM2NlMGQ0OWE=")
    .headers("Content-Type" => "application/x-www-form-urlencoded")
    .get("https://amplitude.com/api/2/taxonomy/event-property", form: { event_type: "area_view" }).status
# => 200

Feel free to use credentials used here. I made a test project so there is on hard hitting that url with those credentials. I will remove it after this gets resolved.

ixti commented 1 year ago
HTTP.basic_auth(user: "3705c24ef1f98c13f78f893f7fb44962", pass: "e204c1206e7648dd2c129b303ce0d49a")

Generates same headers as:

HTTP.headers("Authorization" => "Basic MzcwNWMyNGVmMWY5OGMxM2Y3OGY4OTNmN2ZiNDQ5NjI6ZTIwNGMxMjA2ZTc2NDhkZDJjMTI5YjMwM2NlMGQ0OWE=")

Thus, I'm a bit confused with what could be wrong. Can you try verbose logging?

HTTP.use(logging: { logger: Logger.new($stderr) })
    .basic_auth(...)